├── LICENSE.md ├── README.md ├── onplan-connectors └── onplan-connector-igindex │ ├── pom.xml │ └── src │ ├── main │ └── java │ │ └── com │ │ └── onplan │ │ └── connector │ │ └── igindex │ │ ├── IgIndexConnection.java │ │ ├── IgIndexHistoricalPriceService.java │ │ ├── IgIndexInstrumentService.java │ │ ├── IgIndexMapper.java │ │ ├── IgIndexPriceService.java │ │ └── client │ │ ├── IgIndexClient.java │ │ ├── IgIndexClientRequest.java │ │ ├── IgIndexConnectionCredentials.java │ │ ├── IgIndexConstant.java │ │ └── IgIndexResponseParser.java │ └── test │ ├── java │ └── com │ │ └── onplan │ │ └── connector │ │ └── igindex │ │ └── client │ │ ├── IgIndexMapperTest.java │ │ └── IgIndexResponseParserTest.java │ └── resources │ ├── marketsEpicResponse.json │ └── marketsSearchTermResponse.json ├── onplan-core-adviser ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── onplan │ └── adviser │ ├── AbstractAdviserEvent.java │ ├── Adviser.java │ ├── AdviserEvent.java │ ├── TemplateMetaData.java │ ├── alert │ └── AlertEvent.java │ ├── automatedorder │ └── AutomatedOrderEvent.java │ ├── predicate │ ├── AbstractAdviserPredicate.java │ ├── AdviserPredicate.java │ └── PredicateExecutionContext.java │ └── strategy │ ├── AbstractStrategy.java │ ├── Strategy.java │ ├── StrategyExecutionContext.java │ ├── StrategyListener.java │ └── StrategyStatistics.java ├── onplan-core-connector ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── onplan │ │ └── connector │ │ ├── AbstractPriceService.java │ │ ├── AbstractServiceConnection.java │ │ ├── HistoricalPriceService.java │ │ ├── InstrumentService.java │ │ ├── PriceListener.java │ │ ├── PriceService.java │ │ ├── ServiceConnection.java │ │ ├── ServiceConnectionListener.java │ │ └── util │ │ ├── CompleteEnumMapper.java │ │ ├── Mapper.java │ │ └── PriceTickAggregator.java │ └── test │ └── java │ └── com │ ├── onpla │ └── adapter │ │ └── util │ │ ├── CompleteEnumMapperTest.java │ │ └── PriceTickAggregatorTest.java │ └── onplan │ └── util │ └── TestingConstants.java ├── onplan-core ├── pom.xml └── src │ └── main │ ├── java │ ├── com │ │ └── onplan │ │ │ ├── adviser │ │ │ ├── AdviserPredicateInfo.java │ │ │ ├── AlertInfo.java │ │ │ ├── SeverityLevel.java │ │ │ ├── StrategyInfo.java │ │ │ ├── StrategyStatisticsSnapshot.java │ │ │ └── TemplateInfo.java │ │ │ ├── domain │ │ │ ├── InstrumentType.java │ │ │ ├── PriceBarTimeFrame.java │ │ │ ├── configuration │ │ │ │ ├── AdviserPredicateConfiguration.java │ │ │ │ ├── AlertConfiguration.java │ │ │ │ └── StrategyConfiguration.java │ │ │ ├── persistent │ │ │ │ ├── AlertEventHistory.java │ │ │ │ ├── PersistentObject.java │ │ │ │ └── SystemEventHistory.java │ │ │ └── transitory │ │ │ │ ├── InstrumentInfo.java │ │ │ │ ├── Price.java │ │ │ │ ├── PriceBar.java │ │ │ │ ├── PriceTick.java │ │ │ │ └── VirtualMachineInfo.java │ │ │ ├── service │ │ │ ├── AlertServiceRemote.java │ │ │ ├── HistoricalPriceServiceRemote.java │ │ │ ├── InstrumentServiceRemote.java │ │ │ ├── PriceServiceRemote.java │ │ │ ├── ServiceConnectionInfo.java │ │ │ ├── StrategyServiceRemote.java │ │ │ └── VirtualMachineServiceRemote.java │ │ │ └── util │ │ │ ├── MorePreconditions.java │ │ │ ├── PriceBarUtil.java │ │ │ └── http │ │ │ ├── HttpClientRequest.java │ │ │ ├── HttpClientResponse.java │ │ │ ├── HttpMethod.java │ │ │ └── HttpStatus.java │ └── thrift │ │ └── com │ │ └── onplan │ │ └── client │ │ ├── VirtualMachineServiceRemote.java │ │ └── domain │ │ └── VirtualMachineInfo.java │ ├── javascript │ └── thrift │ │ ├── VirtualMachineServiceRemote.js │ │ ├── domain_types.js │ │ └── virtual-machine-service_types.js │ └── resources │ └── thrift │ ├── domain.thrift │ └── virtual-machine-service.thrift ├── onplan-service ├── pom.xml └── src │ ├── main │ ├── docker │ │ └── Dockerfile │ ├── java │ │ └── com │ │ │ └── onplan │ │ │ ├── adviser │ │ │ ├── AbstractChainedAdviser.java │ │ │ ├── AdviserConfigurationFactory.java │ │ │ ├── AdviserListener.java │ │ │ ├── ScriptingEngineUtils.java │ │ │ ├── StrategyConfigurationFactory.java │ │ │ ├── alert │ │ │ │ └── Alert.java │ │ │ ├── automatedorder │ │ │ │ └── AutomatedOrder.java │ │ │ ├── predicate │ │ │ │ ├── AdviserPredicateUtil.java │ │ │ │ ├── priceaction │ │ │ │ │ └── PriceSpikePredicate.java │ │ │ │ ├── pricepattern │ │ │ │ │ └── CandlestickHammerPredicate.java │ │ │ │ ├── pricevalue │ │ │ │ │ └── PriceValuePredicate.java │ │ │ │ └── scripting │ │ │ │ │ └── JavaScripPredicate.java │ │ │ └── strategy │ │ │ │ ├── StrategyUtil.java │ │ │ │ ├── scripting │ │ │ │ └── JavaScriptStrategy.java │ │ │ │ └── system │ │ │ │ └── IntegrationTestStrategy.java │ │ │ ├── notification │ │ │ ├── AmazonSQSNotificationChannel.java │ │ │ ├── MongoDbNotificationChannel.java │ │ │ ├── NotificationChannel.java │ │ │ ├── SmtpNotificationChannel.java │ │ │ └── TwitterNotificationChannel.java │ │ │ ├── persistence │ │ │ ├── AlertConfigurationDao.java │ │ │ ├── AlertEventHistoryDao.java │ │ │ ├── GenericDao.java │ │ │ ├── StrategyConfigurationDao.java │ │ │ ├── SystemEventHistoryDao.java │ │ │ └── mongodb │ │ │ │ ├── AbstractMongoDbDao.java │ │ │ │ ├── MongoDbAlertConfigurationDao.java │ │ │ │ ├── MongoDbAlertEventDao.java │ │ │ │ ├── MongoDbConnection.java │ │ │ │ ├── MongoDbPropertyNamingStrategy.java │ │ │ │ ├── MongoDbStrategyConfigurationDao.java │ │ │ │ └── MongoDbSystemEventDao.java │ │ │ ├── processing │ │ │ └── PriceServiceBus.java │ │ │ ├── scheduler │ │ │ ├── GarbageCollectionJob.java │ │ │ └── ServicesActivationJob.java │ │ │ ├── service │ │ │ ├── AlertService.java │ │ │ ├── EventNotificationService.java │ │ │ ├── InstrumentSubscriptionListener.java │ │ │ ├── StrategyService.java │ │ │ ├── SystemEvent.java │ │ │ ├── VirtualMachineService.java │ │ │ ├── impl │ │ │ │ ├── AbstractAdviserService.java │ │ │ │ ├── AdviserFactory.java │ │ │ │ ├── AlertServiceImpl.java │ │ │ │ ├── EventNotificationServiceImpl.java │ │ │ │ ├── StrategyPool.java │ │ │ │ ├── StrategyServiceImpl.java │ │ │ │ └── VirtualMachineServiceImpl.java │ │ │ └── placeholder │ │ │ │ └── AlertServicePlaceholder.java │ │ │ ├── startup │ │ │ ├── GuiceJobFactory.java │ │ │ ├── GuiceListener.java │ │ │ ├── GuiceModule.java │ │ │ ├── GuiceServletModule.java │ │ │ ├── IgIndexGuiceModule.java │ │ │ └── servlet │ │ │ │ ├── AlertServiceServlet.java │ │ │ │ ├── InstrumentServiceServlet.java │ │ │ │ ├── PriceServiceServlet.java │ │ │ │ ├── StartUpServlet.java │ │ │ │ ├── StrategyServiceServlet.java │ │ │ │ └── VirtualMachineServiceServlet.java │ │ │ └── util │ │ │ ├── ExceptionUtils.java │ │ │ ├── JsonUtils.java │ │ │ ├── PropertiesUtils.java │ │ │ ├── StringUtils.java │ │ │ └── ThreadUtils.java │ ├── resources │ │ ├── amazonaws.properties │ │ ├── broker.properties │ │ ├── email.properties │ │ ├── log4j.properties │ │ ├── mongodb.properties │ │ ├── notification.properties │ │ ├── system.properties │ │ └── twitter4j.properties │ └── webapp │ │ └── WEB-INF │ │ └── web.xml │ └── test │ ├── java │ └── com │ │ └── onplan │ │ ├── adviser │ │ ├── alert │ │ │ ├── TestingAlertConfigurationFactory.java │ │ │ └── TestingStrategyConfigurationFactory.java │ │ ├── predicate │ │ │ ├── TestingAdviserPredicateConfigurationFactory.java │ │ │ ├── TestingAdviserPredicateUtils.java │ │ │ ├── TestingPredicateExecutionContextFactory.java │ │ │ ├── priceaction │ │ │ │ └── PriceSpikePredicateTest.java │ │ │ ├── pricepattern │ │ │ │ └── CandlestickHammerPredicateTest.java │ │ │ └── scripting │ │ │ │ └── JavaScripPredicateTest.java │ │ └── strategy │ │ │ └── JavaScriptStrategyTest.java │ │ ├── benchmark │ │ └── service │ │ │ └── StrategyPoolBenchmark.java │ │ ├── connector │ │ └── DummyPriceService.java │ │ ├── dao │ │ ├── TestingAbstractDao.java │ │ ├── TestingAlertConfigurationDao.java │ │ └── TestingStrategyConfigurationDao.java │ │ ├── domain │ │ └── TestingPriceFactory.java │ │ ├── integration │ │ ├── AbstractIT.java │ │ ├── GuiceTestingModule.java │ │ ├── connector │ │ │ └── InstrumentServiceIT.java │ │ ├── persistence │ │ │ ├── AbstractDaoIT.java │ │ │ ├── AlertConfigurationDaoIT.java │ │ │ └── StrategyConfigurationDaoIT.java │ │ └── service │ │ │ └── StrategyServiceIT.java │ │ ├── service │ │ ├── AlertServiceImplTest.java │ │ ├── StrategyServiceImplTest.java │ │ ├── TestingHistoricalPriceService.java │ │ └── TestingInstrumentService.java │ │ └── util │ │ ├── DateTimeUtilTest.java │ │ ├── PriceUtilTest.java │ │ └── TestingConstants.java │ └── resources │ ├── broker-testing.properties │ ├── log4j.properties │ ├── mongodb-testing.properties │ ├── notification-testing.properties │ ├── system-testing.properties │ └── webdefault.xml └── onplan └── pom.xml /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Roberto Marchetto. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of Roberto Marchetto nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # onplan 2 | **This project is now called [Algobox](https://github.com/melphi/algobox)** 3 | -------------------------------------------------------------------------------- /onplan-connectors/onplan-connector-igindex/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | com.melphi 9 | onplan 10 | 1.0-SNAPSHOT 11 | ../onplan 12 | 13 | 14 | onplan-connector-igindex 15 | 1.0-SNAPSHOT 16 | jar 17 | 18 | 19 | 20 | 21 | org.apache.maven.plugins 22 | maven-compiler-plugin 23 | 3.2 24 | 25 | ${com.java.version} 26 | ${com.java.version} 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | com.melphi 36 | onplan-core 37 | 1.0-SNAPSHOT 38 | 39 | 40 | com.melphi 41 | onplan-core-connector 42 | 1.0-SNAPSHOT 43 | 44 | 45 | 46 | 47 | com.igindex 48 | ls-client 49 | 2.5.2 50 | 51 | 52 | 53 | 54 | com.fasterxml.jackson.core 55 | jackson-core 56 | 2.4.4 57 | 58 | 59 | com.fasterxml.jackson.core 60 | jackson-databind 61 | 2.4.4 62 | 63 | 64 | org.codehaus.jackson 65 | jackson-mapper-asl 66 | 1.9.13 67 | 68 | 69 | 70 | 71 | log4j 72 | log4j 73 | 1.2.17 74 | 75 | 76 | org.apache.commons 77 | commons-lang3 78 | 3.3.2 79 | 80 | 81 | 82 | 83 | junit 84 | junit 85 | test 86 | 4.11 87 | 88 | 89 | commons-io 90 | commons-io 91 | test 92 | 2.4 93 | 94 | 95 | -------------------------------------------------------------------------------- /onplan-connectors/onplan-connector-igindex/src/main/java/com/onplan/connector/igindex/IgIndexHistoricalPriceService.java: -------------------------------------------------------------------------------- 1 | package com.onplan.connector.igindex; 2 | 3 | import com.onplan.connector.HistoricalPriceService; 4 | import com.onplan.service.ServiceConnectionInfo; 5 | import com.onplan.domain.transitory.PriceBar; 6 | import org.apache.log4j.Logger; 7 | 8 | import java.util.Collection; 9 | 10 | import static com.google.common.base.Preconditions.checkNotNull; 11 | 12 | public final class IgIndexHistoricalPriceService implements HistoricalPriceService { 13 | private static final Logger LOGGER = Logger.getLogger(IgIndexHistoricalPriceService.class); 14 | 15 | private final IgIndexConnection igIndexConnection; 16 | 17 | public IgIndexHistoricalPriceService(IgIndexConnection igIndexConnection) { 18 | LOGGER.info("Setting IgIndexConnection in IgIndexHistoricalPriceService."); 19 | this.igIndexConnection = checkNotNull(igIndexConnection); 20 | } 21 | 22 | @Override 23 | public ServiceConnectionInfo getServiceConnectionInfo() { 24 | return igIndexConnection.getConnectionInfo(); 25 | } 26 | 27 | @Override 28 | public Collection getHistoricalPriceBars( 29 | String instrumentId, long barPeriod, long startTimestamp, long endTimestamp) { 30 | throw new IllegalArgumentException("Not yet implemented."); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /onplan-connectors/onplan-connector-igindex/src/main/java/com/onplan/connector/igindex/IgIndexInstrumentService.java: -------------------------------------------------------------------------------- 1 | package com.onplan.connector.igindex; 2 | 3 | import com.onplan.connector.InstrumentService; 4 | import com.onplan.service.ServiceConnectionInfo; 5 | import com.onplan.connector.igindex.client.IgIndexClient; 6 | import com.onplan.domain.transitory.InstrumentInfo; 7 | import org.apache.log4j.Logger; 8 | 9 | import java.io.IOException; 10 | import java.util.List; 11 | 12 | import static com.google.common.base.Preconditions.checkNotNull; 13 | import static com.onplan.connector.igindex.IgIndexMapper.getEpicByInstrumentId; 14 | 15 | public final class IgIndexInstrumentService implements InstrumentService { 16 | private static final Logger LOGGER = Logger.getLogger(IgIndexInstrumentService.class); 17 | 18 | private final IgIndexConnection igIndexConnection; 19 | private final IgIndexClient igIndexClient; 20 | 21 | public IgIndexInstrumentService(IgIndexConnection igIndexConnection) { 22 | LOGGER.info("Setting IgIndexConnection in IgIndexInstrumentService."); 23 | this.igIndexConnection = checkNotNull(igIndexConnection); 24 | this.igIndexClient = igIndexConnection.getIgIndexClient(); 25 | } 26 | 27 | @Override 28 | public ServiceConnectionInfo getServiceConnectionInfo() { 29 | return igIndexConnection.getConnectionInfo(); 30 | } 31 | 32 | @Override 33 | public InstrumentInfo getInstrumentInfo(String instrumentId) throws IOException { 34 | return igIndexClient.getInstrumentInfo(getEpicByInstrumentId(instrumentId)); 35 | } 36 | 37 | @Override 38 | public List findInstrumentsBySearchTerm(String searchTerm) throws Exception { 39 | try { 40 | return igIndexClient.findInstrumentsBySearchTerm(searchTerm); 41 | } catch (IOException e) { 42 | LOGGER.error(e.getMessage()); 43 | throw new Exception(e); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /onplan-connectors/onplan-connector-igindex/src/main/java/com/onplan/connector/igindex/client/IgIndexConnectionCredentials.java: -------------------------------------------------------------------------------- 1 | package com.onplan.connector.igindex.client; 2 | 3 | import com.google.common.base.MoreObjects; 4 | 5 | import static com.onplan.util.MorePreconditions.checkNotNullOrEmpty; 6 | 7 | public final class IgIndexConnectionCredentials { 8 | private String apiKey; 9 | private String clientSessionToken; 10 | private String accountSessionToken; 11 | private String lightStreamerEndpoint; 12 | 13 | public String getClientSessionToken() { 14 | return clientSessionToken; 15 | } 16 | 17 | public String getAccountSessionToken() { 18 | return accountSessionToken; 19 | } 20 | 21 | public String getLightStreamerEndpoint() { 22 | return lightStreamerEndpoint; 23 | } 24 | 25 | public String getApiKey() { 26 | return apiKey; 27 | } 28 | 29 | public static Builder newBuilder() { 30 | return new Builder(); 31 | } 32 | 33 | @Override 34 | public String toString() { 35 | return MoreObjects.toStringHelper(this) 36 | .add("apiKey", apiKey) 37 | .add("clientSessionToken", clientSessionToken) 38 | .add("accountSessionToken", accountSessionToken) 39 | .add("lightStreamerEndpoint", lightStreamerEndpoint) 40 | .toString(); 41 | } 42 | 43 | private IgIndexConnectionCredentials(String apiKey, String clientSessionToken, 44 | String accountSessionToken, String lightStreamerEndpoint) { 45 | this.apiKey = checkNotNullOrEmpty(apiKey); 46 | this.clientSessionToken = checkNotNullOrEmpty(clientSessionToken); 47 | this.accountSessionToken = checkNotNullOrEmpty(accountSessionToken); 48 | this.lightStreamerEndpoint = checkNotNullOrEmpty(lightStreamerEndpoint); 49 | } 50 | 51 | public static class Builder { 52 | private String apiKey; 53 | private String clientSessionToken; 54 | private String accountSessionToken; 55 | private String lightStreamerEndpoint; 56 | 57 | public Builder setClientSessionToken(String clientSessionToken) { 58 | this.clientSessionToken = checkNotNullOrEmpty(clientSessionToken); 59 | return this; 60 | } 61 | 62 | public Builder setAccountSessionToken(String accountSessionToken) { 63 | this.accountSessionToken = checkNotNullOrEmpty(accountSessionToken); 64 | return this; 65 | } 66 | 67 | public Builder setLightStreamerEndpoint(String lightStreamerEndpoint) { 68 | this.lightStreamerEndpoint = checkNotNullOrEmpty(lightStreamerEndpoint); 69 | return this; 70 | } 71 | 72 | public Builder setApiKey(String apiKey) { 73 | this.apiKey = apiKey; 74 | return this; 75 | } 76 | 77 | public IgIndexConnectionCredentials build() { 78 | return new IgIndexConnectionCredentials( 79 | apiKey, clientSessionToken, accountSessionToken, lightStreamerEndpoint); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /onplan-connectors/onplan-connector-igindex/src/main/java/com/onplan/connector/igindex/client/IgIndexConstant.java: -------------------------------------------------------------------------------- 1 | package com.onplan.connector.igindex.client; 2 | 3 | public final class IgIndexConstant { 4 | public static final String PROVIDER_NAME = "IG Index Ltd."; 5 | 6 | public static final String TAG_MARKETS = "markets"; 7 | public static final String TAG_INSTRUMENT = "instrument"; 8 | public static final String TAG_SNAPSHOT = "snapshot"; 9 | public static final String TAG_SESSION = "session"; 10 | public static final String TAG_EPIC = "epic"; 11 | public static final String TAG_NAME = "name"; 12 | public static final String TAG_TYPE = "type"; 13 | public static final String TAG_INSTRUMENT_NAME = "instrumentName"; 14 | public static final String TAG_INSTRUMENT_TYPE = "instrumentType"; 15 | public static final String TAG_EXPIRY = "expiry"; 16 | public static final String TAG_SCALING_FACTOR = "scalingFactor"; 17 | 18 | public static final String API_VERSION_1 = "1"; 19 | public static final String API_VERSION_2 = "2"; 20 | 21 | public static final String FIELD_LIGHT_STREAMER_ENDPOINT = "lightstreamerEndpoint"; 22 | 23 | public static final String HEADER_PARAMETER_CONTENT_TYPE = "Content-Type"; 24 | public static final String HEADER_PARAMETER_VALUE_JSON_UTF8 = "application/json; charset=UTF-8"; 25 | public static final String HEADER_PARAMETER_ACCEPT = "Accept"; 26 | public static final String HEADER_PARAMETER_API_KEY = "X-IG-API-KEY"; 27 | public static final String HEADER_PARAMETER_CLIENT_SESSION_TOKEN = "CST"; 28 | public static final String HEADER_PARAMETER_ACCOUNT_SESSION_TOKEN = "X-SECURITY-TOKEN"; 29 | public static final String HEADER_PARAMETER_VERSION = "Version"; 30 | } 31 | -------------------------------------------------------------------------------- /onplan-connectors/onplan-connector-igindex/src/test/java/com/onplan/connector/igindex/client/IgIndexMapperTest.java: -------------------------------------------------------------------------------- 1 | package com.onplan.connector.igindex.client; 2 | 3 | import org.junit.Test; 4 | 5 | import static com.onplan.connector.igindex.IgIndexMapper.getInstrumentIdByEpic; 6 | import static org.junit.Assert.assertEquals; 7 | 8 | public class IgIndexMapperTest { 9 | private static final String EPIC_EXAMPLE_1 = "CF.D.EURAUD.MAR.IP"; 10 | private static final String EPIC_EXAMPLE_2 = "CHART:IX.D.DAX.DAILY.IP:TICK"; 11 | private static final String INSTRUMENT_ID_EXAMPLE_1 = "CF.EURAUD.MAR"; 12 | private static final String INSTRUMENT_ID_EXAMPLE_2 = "IX.DAX.DAILY"; 13 | 14 | @Test 15 | public void testGetInstrumentIdByEpic() { 16 | assertEquals(INSTRUMENT_ID_EXAMPLE_1, getInstrumentIdByEpic(EPIC_EXAMPLE_1)); 17 | assertEquals(INSTRUMENT_ID_EXAMPLE_2, getInstrumentIdByEpic(EPIC_EXAMPLE_2)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /onplan-connectors/onplan-connector-igindex/src/test/java/com/onplan/connector/igindex/client/IgIndexResponseParserTest.java: -------------------------------------------------------------------------------- 1 | package com.onplan.connector.igindex.client; 2 | 3 | import com.google.common.base.Strings; 4 | import com.google.common.collect.Lists; 5 | import com.onplan.domain.transitory.InstrumentInfo; 6 | import org.apache.commons.io.IOUtils; 7 | import org.junit.Test; 8 | 9 | import java.io.IOException; 10 | import java.io.InputStream; 11 | import java.util.List; 12 | 13 | import static org.junit.Assert.assertNotNull; 14 | import static org.junit.Assert.assertTrue; 15 | 16 | public class IgIndexResponseParserTest { 17 | private static final String FILE_MARKET_SEARCH_TERM_RESPONSE = "marketsSearchTermResponse.json"; 18 | private static final String FILE_MARKET_EPIC_RESPONSE = "marketsEpicResponse.json"; 19 | 20 | @Test 21 | public void testCreateInstrumentInfoList() throws IOException { 22 | InputStream fileMarketSearchTermResponse = 23 | ClassLoader.getSystemResourceAsStream(FILE_MARKET_SEARCH_TERM_RESPONSE); 24 | List result = IgIndexResponseParser.createInstrumentInfoList( 25 | IOUtils.toString(fileMarketSearchTermResponse)); 26 | fileMarketSearchTermResponse.close(); 27 | 28 | assertNotNull(result); 29 | assertTrue(result.size() == 50); 30 | List instrumentIds = Lists.newArrayList(); 31 | for (InstrumentInfo instrumentInfo : result) { 32 | assertInstrumentInfo(instrumentInfo); 33 | // Assert instrumentId uniqueness. 34 | assertTrue(!instrumentIds.contains(instrumentInfo.getInstrumentId())); 35 | instrumentIds.add(instrumentInfo.getInstrumentId()); 36 | } 37 | } 38 | 39 | @Test 40 | public void testCreateInstrumentInfo() throws IOException { 41 | InputStream fileMarketEpicResponse = 42 | ClassLoader.getSystemResourceAsStream(FILE_MARKET_EPIC_RESPONSE); 43 | InstrumentInfo instrumentInfo = 44 | IgIndexResponseParser.createInstrumentInfo(IOUtils.toString(fileMarketEpicResponse)); 45 | fileMarketEpicResponse.close(); 46 | assertInstrumentInfo(instrumentInfo); 47 | } 48 | 49 | private static void assertInstrumentInfo(final InstrumentInfo instrumentInfo) { 50 | assertNotNull(instrumentInfo.getInstrumentType()); 51 | assertTrue(!Strings.isNullOrEmpty(instrumentInfo.getInstrumentName())); 52 | assertTrue(!Strings.isNullOrEmpty(instrumentInfo.getExpiry())); 53 | assertTrue(!Strings.isNullOrEmpty(instrumentInfo.getInstrumentId())); 54 | assertTrue(instrumentInfo.getPriceMinimalDecimalPosition() >= 0); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /onplan-connectors/onplan-connector-igindex/src/test/resources/marketsEpicResponse.json: -------------------------------------------------------------------------------- 1 | {"instrument":{"epic":"CS.D.EURUSD.TODAY.IP","expiry":"DFB","name":"Spot FX EUR/USD","forceOpenAllowed":true,"stopsLimitsAllowed":true,"lotSize":1.0,"unit":"AMOUNT","type":"CURRENCIES","controlledRiskAllowed":true,"streamingPricesAvailable":true,"marketId":"EURUSD","currencies":[{"code":"GBP","symbol":"£","baseExchangeRate":1.0,"exchangeRate":1.0,"isDefault":true},{"code":"USD","symbol":"$","baseExchangeRate":1.50799,"exchangeRate":0.62,"isDefault":false},{"code":"EUR","symbol":"E","baseExchangeRate":1.330565,"exchangeRate":0.81,"isDefault":false},{"code":"AUD","symbol":"A$","baseExchangeRate":1.93949,"exchangeRate":0.55,"isDefault":false}],"sprintMarketsMinimumExpiryTime":null,"sprintMarketsMaximumExpiryTime":null,"marginDepositBands":[{"min":0,"max":375,"margin":0.3,"currency":"USD"},{"min":375,"max":1875,"margin":0.5,"currency":"USD"},{"min":1875,"max":6251,"margin":4.0,"currency":"USD"},{"min":6251,"max":null,"margin":8.0,"currency":"USD"}],"marginFactor":0.25,"marginFactorUnit":"PERCENTAGE","slippageFactor":{"unit":"pct","value":20.0},"openingHours":null,"expiryDetails":{"lastDealingDate":"01/04/16 20:00","settlementInfo":"DFBs settle on the Last Dealing Day basis the middle of the IG price at 20:00, plus or minus half the IG spread."},"rolloverDetails":null,"newsCode":"EUR=","chartCode":"EURUSD","country":null,"valueOfOnePip":null,"onePipMeans":null,"contractSize":null,"specialInfo":null},"dealingRules":{"minStepDistance":{"unit":"POINTS","value":5.0},"minDealSize":{"unit":"POINTS","value":1.0},"minControlledRiskStopDistance":{"unit":"POINTS","value":7.5},"minNormalStopOrLimitDistance":{"unit":"POINTS","value":2.0},"maxStopOrLimitDistance":{"unit":"PERCENTAGE","value":75.0},"marketOrderPreference":"NOT_AVAILABLE","trailingStopsPreference":"AVAILABLE"},"snapshot":{"marketStatus":"TRADEABLE","netChange":13.4,"percentageChange":0.12,"updateTime":"08:17:54","delayTime":0,"bid":11332.7,"offer":11334.2,"high":11345.2,"low":11316.5,"binaryOdds":null,"decimalPlacesFactor":1,"scalingFactor":1,"controlledRiskExtraSpread":2}} 2 | -------------------------------------------------------------------------------- /onplan-core-adviser/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | onplan 7 | com.melphi 8 | 1.0-SNAPSHOT 9 | ../pom.xml 10 | 11 | 4.0.0 12 | 13 | onplan-core-adviser 14 | 1.0-SNAPSHOT 15 | 16 | 17 | 18 | 19 | com.melphi 20 | onplan-core 21 | 1.0-SNAPSHOT 22 | 23 | 24 | -------------------------------------------------------------------------------- /onplan-core-adviser/src/main/java/com/onplan/adviser/AbstractAdviserEvent.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser; 2 | 3 | import com.onplan.domain.transitory.PriceTick; 4 | 5 | import static com.google.common.base.Preconditions.checkArgument; 6 | import static com.google.common.base.Preconditions.checkNotNull; 7 | import static com.onplan.util.MorePreconditions.checkNotNullOrEmpty; 8 | 9 | /** 10 | * Basic class for adviser events. 11 | */ 12 | public abstract class AbstractAdviserEvent implements AdviserEvent { 13 | protected final String adviserId; 14 | protected final PriceTick priceTick; 15 | protected final long createdOn; 16 | 17 | public String getAdviserId() { 18 | return adviserId; 19 | } 20 | 21 | @Override 22 | public PriceTick getPriceTick() { 23 | return priceTick; 24 | } 25 | 26 | @Override 27 | public long getCreatedOn() { 28 | return createdOn; 29 | } 30 | 31 | public AbstractAdviserEvent(String adviserId, PriceTick priceTick, long createdOn) { 32 | this.adviserId = checkNotNullOrEmpty(adviserId); 33 | this.priceTick = checkNotNull(priceTick); 34 | checkArgument(createdOn > 0, "Expected a positive value for createdOn."); 35 | this.createdOn = createdOn; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /onplan-core-adviser/src/main/java/com/onplan/adviser/Adviser.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser; 2 | 3 | import com.onplan.domain.transitory.PriceTick; 4 | 5 | public interface Adviser { 6 | /** 7 | * Processes a price tick. 8 | * @param priceTick The price tick. 9 | */ 10 | public void onPriceTick(final PriceTick priceTick); 11 | } 12 | -------------------------------------------------------------------------------- /onplan-core-adviser/src/main/java/com/onplan/adviser/AdviserEvent.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser; 2 | 3 | import com.onplan.domain.transitory.PriceTick; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * Generic adviser event interface. 9 | */ 10 | public interface AdviserEvent extends Serializable { 11 | public PriceTick getPriceTick(); 12 | public long getCreatedOn(); 13 | } 14 | -------------------------------------------------------------------------------- /onplan-core-adviser/src/main/java/com/onplan/adviser/TemplateMetaData.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | 7 | @Documented 8 | @Retention(RetentionPolicy.RUNTIME) 9 | public @interface TemplateMetaData { 10 | String displayName(); 11 | String[] availableParameters() default {}; 12 | } 13 | -------------------------------------------------------------------------------- /onplan-core-adviser/src/main/java/com/onplan/adviser/alert/AlertEvent.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser.alert; 2 | 3 | import com.google.common.base.MoreObjects; 4 | import com.google.common.base.Objects; 5 | import com.onplan.adviser.AbstractAdviserEvent; 6 | import com.onplan.adviser.SeverityLevel; 7 | import com.onplan.domain.transitory.PriceTick; 8 | 9 | import static com.google.common.base.Preconditions.checkNotNull; 10 | import static com.onplan.util.MorePreconditions.checkNotNullOrEmpty; 11 | 12 | public final class AlertEvent extends AbstractAdviserEvent { 13 | private final String message; 14 | private final SeverityLevel severityLevel; 15 | 16 | public String getMessage() { 17 | return message; 18 | } 19 | 20 | public SeverityLevel getSeverityLevel() { 21 | return severityLevel; 22 | } 23 | 24 | public AlertEvent(String adviserId, SeverityLevel severityLevel, PriceTick priceTick, 25 | long createdOn, String message) { 26 | super(adviserId, priceTick, createdOn); 27 | this.message = checkNotNullOrEmpty(message); 28 | this.severityLevel = checkNotNull(severityLevel); 29 | } 30 | 31 | @Override 32 | public int hashCode() { 33 | return Objects.hashCode(adviserId, priceTick, createdOn, message, severityLevel); 34 | } 35 | 36 | @Override 37 | public boolean equals(Object o) { 38 | if (this == o) { 39 | return true; 40 | } 41 | if (o == null || getClass() != o.getClass()) { 42 | return false; 43 | } 44 | AlertEvent alertEvent = (AlertEvent) o; 45 | return Objects.equal(this.adviserId, alertEvent.adviserId) && 46 | Objects.equal(this.createdOn, alertEvent.createdOn) && 47 | Objects.equal(this.message, alertEvent.message) && 48 | Objects.equal(this.severityLevel, alertEvent.severityLevel) && 49 | Objects.equal(this.priceTick, alertEvent.priceTick); 50 | } 51 | 52 | @Override 53 | public String toString() { 54 | return MoreObjects.toStringHelper(this) 55 | .add("adviserId", adviserId) 56 | .add("createdOn", createdOn) 57 | .add("message", message) 58 | .add("severityLevel", severityLevel) 59 | .add("priceTick", priceTick) 60 | .toString(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /onplan-core-adviser/src/main/java/com/onplan/adviser/automatedorder/AutomatedOrderEvent.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser.automatedorder; 2 | 3 | import com.onplan.adviser.AbstractAdviserEvent; 4 | import com.onplan.domain.transitory.PriceTick; 5 | 6 | // TODO(robertom): Implement this class. 7 | public final class AutomatedOrderEvent extends AbstractAdviserEvent { 8 | protected AutomatedOrderEvent( 9 | String adviserId, String instrumentId, PriceTick priceTick, long createdOn) { 10 | super(adviserId, priceTick, createdOn); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /onplan-core-adviser/src/main/java/com/onplan/adviser/predicate/AbstractAdviserPredicate.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser.predicate; 2 | 3 | import com.google.common.base.MoreObjects; 4 | import com.google.common.base.Objects; 5 | import com.google.common.base.Strings; 6 | 7 | import java.util.Map; 8 | import java.util.Optional; 9 | 10 | import static com.google.common.base.Preconditions.checkNotNull; 11 | import static com.onplan.util.MorePreconditions.checkNotNullOrEmpty; 12 | 13 | public abstract class AbstractAdviserPredicate implements AdviserPredicate { 14 | protected final PredicateExecutionContext predicateExecutionContext; 15 | 16 | public AbstractAdviserPredicate(final PredicateExecutionContext predicateExecutionContext) { 17 | this.predicateExecutionContext = checkNotNull(predicateExecutionContext); 18 | } 19 | 20 | @Override 21 | public String getParameterValue(String parameterName) { 22 | checkNotNullOrEmpty(parameterName); 23 | return predicateExecutionContext.getParameterValue(parameterName); 24 | } 25 | 26 | @Override 27 | public Map getParametersCopy() { 28 | return predicateExecutionContext.getParametersCopy(); 29 | } 30 | 31 | public Optional getStringValue(String parameterName) { 32 | checkNotNullOrEmpty(parameterName); 33 | String propertyValue = getParameterValue(parameterName); 34 | return Strings.isNullOrEmpty(propertyValue) ? Optional.empty() : Optional.of(propertyValue); 35 | } 36 | 37 | public Optional getLongValue(String parameterName) { 38 | Optional propertyValue = getStringValue(parameterName); 39 | return propertyValue.isPresent() ? Optional.of(Long.parseLong(propertyValue.get())) 40 | : Optional.empty(); 41 | } 42 | 43 | public Optional getDoubleValue(String parameterName) { 44 | Optional propertyValue = getStringValue(parameterName); 45 | return propertyValue.isPresent() ? Optional.of(Double.parseDouble(propertyValue.get())) 46 | : Optional.empty(); 47 | } 48 | 49 | @Override 50 | public boolean equals(Object o) { 51 | if (this == o) { 52 | return true; 53 | } 54 | if (o == null || getClass() != o.getClass()) { 55 | return false; 56 | } 57 | AbstractAdviserPredicate adviserPredicate = (AbstractAdviserPredicate) o; 58 | return Objects.equal( 59 | this.predicateExecutionContext, adviserPredicate.predicateExecutionContext); 60 | } 61 | 62 | @Override 63 | public int hashCode() { 64 | return Objects.hashCode(predicateExecutionContext); 65 | } 66 | 67 | @Override 68 | public String toString() { 69 | return MoreObjects.toStringHelper(this) 70 | .add("predicateExecutionContext", predicateExecutionContext) 71 | .toString(); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /onplan-core-adviser/src/main/java/com/onplan/adviser/predicate/AdviserPredicate.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser.predicate; 2 | 3 | import com.onplan.domain.transitory.PriceTick; 4 | 5 | import java.util.Map; 6 | 7 | public interface AdviserPredicate { 8 | /** 9 | * Processes a {@link com.onplan.domain.transitory.PriceTick}, returns true if the predicate 10 | * is satisfied, false otherwise. 11 | * @param priceTick The price tick. 12 | */ 13 | public boolean apply(final PriceTick priceTick); 14 | 15 | /** 16 | * Initializes the predicate. 17 | */ 18 | public void init() throws Exception; 19 | 20 | /** 21 | * Returns the parameter value. 22 | * 23 | * @param parameterName The parameter key. 24 | */ 25 | public String getParameterValue(String parameterName); 26 | 27 | /** 28 | * Returns a copy of the parameters set. 29 | */ 30 | public Map getParametersCopy(); 31 | } 32 | -------------------------------------------------------------------------------- /onplan-core-adviser/src/main/java/com/onplan/adviser/predicate/PredicateExecutionContext.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser.predicate; 2 | 3 | import com.google.common.base.MoreObjects; 4 | import com.google.common.base.Objects; 5 | import com.google.common.collect.ImmutableMap; 6 | import com.onplan.service.HistoricalPriceServiceRemote; 7 | import com.onplan.service.InstrumentServiceRemote; 8 | 9 | import java.util.Map; 10 | 11 | import static com.google.common.base.Preconditions.checkNotNull; 12 | import static com.onplan.util.MorePreconditions.checkNotNullOrEmpty; 13 | 14 | public final class PredicateExecutionContext { 15 | private final HistoricalPriceServiceRemote historicalPriceService; 16 | private final InstrumentServiceRemote instrumentService; 17 | private final Map parameters; 18 | private final String instrumentId; 19 | 20 | public PredicateExecutionContext(HistoricalPriceServiceRemote historicalPriceService, 21 | InstrumentServiceRemote instrumentService, Map executionParameters, 22 | String instrumentId) { 23 | this.historicalPriceService = checkNotNull(historicalPriceService); 24 | this.instrumentService = checkNotNull(instrumentService); 25 | this.parameters = ImmutableMap.copyOf(checkNotNull(executionParameters)); 26 | this.instrumentId = checkNotNullOrEmpty(instrumentId); 27 | } 28 | 29 | public HistoricalPriceServiceRemote getHistoricalPriceService() { 30 | return historicalPriceService; 31 | } 32 | 33 | public InstrumentServiceRemote getInstrumentService() { 34 | return instrumentService; 35 | } 36 | 37 | public String getParameterValue(String parameterName) { 38 | //TODO(robertom): What if the user sets a null parameter in JavaScript? 39 | return parameters.get(parameterName); 40 | } 41 | 42 | public Map getParametersCopy() { 43 | return ImmutableMap.copyOf(parameters); 44 | } 45 | 46 | public String getInstrumentId() { 47 | return instrumentId; 48 | } 49 | 50 | @Override 51 | public boolean equals(Object o) { 52 | if (this == o) { 53 | return true; 54 | } 55 | if (o == null || getClass() != o.getClass()) { 56 | return false; 57 | } 58 | PredicateExecutionContext executionContext = (PredicateExecutionContext) o; 59 | return Objects.equal(this.historicalPriceService, executionContext.historicalPriceService) && 60 | Objects.equal(this.instrumentService, executionContext.instrumentService) && 61 | Objects.equal(this.instrumentId, executionContext.instrumentId) && 62 | Objects.equal(this.parameters, executionContext.parameters); 63 | } 64 | 65 | @Override 66 | public int hashCode() { 67 | return Objects.hashCode( 68 | historicalPriceService, instrumentService, instrumentId, parameters); 69 | } 70 | 71 | @Override 72 | public String toString() { 73 | return MoreObjects.toStringHelper(this) 74 | .add("instrumentId", instrumentId) 75 | .add("parameters", parameters) 76 | .toString(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /onplan-core-adviser/src/main/java/com/onplan/adviser/strategy/Strategy.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser.strategy; 2 | 3 | import com.onplan.adviser.Adviser; 4 | import com.onplan.adviser.StrategyStatisticsSnapshot; 5 | 6 | import java.util.Collection; 7 | import java.util.Map; 8 | 9 | public interface Strategy extends Adviser { 10 | /** 11 | * Returns the strategy unique id; 12 | */ 13 | public String getId(); 14 | 15 | /** 16 | * Initializes the strategy. 17 | */ 18 | public void init() throws Exception; 19 | 20 | /** 21 | * Returns the parameter value. 22 | * 23 | * @param parameterName The parameter name. 24 | */ 25 | public String getParameterValue(String parameterName); 26 | 27 | /** 28 | * Returns a copy of the parameters set. 29 | */ 30 | public Map getParametersCopy(); 31 | 32 | /** 33 | * Returns a copy of the instruments which the strategy listens to as defined in the 34 | * {@link StrategyExecutionContext}. 35 | */ 36 | public Collection getRegisteredInstruments(); 37 | 38 | /** 39 | * Returns a snapshot of the current strategy statistics. 40 | */ 41 | public StrategyStatisticsSnapshot getStrategyStatisticsSnapshot(); 42 | } 43 | -------------------------------------------------------------------------------- /onplan-core-adviser/src/main/java/com/onplan/adviser/strategy/StrategyExecutionContext.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser.strategy; 2 | 3 | import com.google.common.base.MoreObjects; 4 | import com.google.common.base.Objects; 5 | import com.google.common.collect.ImmutableMap; 6 | import com.onplan.service.HistoricalPriceServiceRemote; 7 | import com.onplan.service.InstrumentServiceRemote; 8 | 9 | import java.io.Serializable; 10 | import java.util.Map; 11 | import java.util.Set; 12 | 13 | import static com.google.common.base.Preconditions.checkNotNull; 14 | import static com.onplan.util.MorePreconditions.checkNotNullOrEmpty; 15 | 16 | public final class StrategyExecutionContext implements Serializable { 17 | private final String strategyId; 18 | private final HistoricalPriceServiceRemote historicalPriceService; 19 | private final InstrumentServiceRemote instrumentService; 20 | private final StrategyListener strategyListener; 21 | private final Map parameters; 22 | private final Set registeredInstruments; 23 | 24 | public String getStrategyId() { 25 | return this.strategyId; 26 | } 27 | 28 | public HistoricalPriceServiceRemote getHistoricalPriceService() { 29 | return historicalPriceService; 30 | } 31 | 32 | public InstrumentServiceRemote getInstrumentService() { 33 | return instrumentService; 34 | } 35 | 36 | public StrategyListener getStrategyListener() { 37 | return strategyListener; 38 | } 39 | 40 | public String getParameterValue(String parameterName) { 41 | //TODO(robertom): What if the user sets a null parameter in JavaScript? 42 | return parameters.get(parameterName); 43 | } 44 | 45 | public Map getParametersCopy() { 46 | return ImmutableMap.copyOf(parameters); 47 | } 48 | 49 | public Set getRegisteredInstruments() { 50 | return registeredInstruments; 51 | } 52 | 53 | public StrategyExecutionContext(String strategyId, 54 | HistoricalPriceServiceRemote historicalPriceService, 55 | InstrumentServiceRemote instrumentService, StrategyListener strategyListener, 56 | Map parameters, Set registeredInstruments) { 57 | this.strategyId = checkNotNullOrEmpty(strategyId); 58 | this.historicalPriceService = checkNotNull(historicalPriceService); 59 | this.instrumentService = checkNotNull(instrumentService); 60 | this.strategyListener = checkNotNull(strategyListener); 61 | this.parameters = checkNotNull(parameters); 62 | this.registeredInstruments = checkNotNull(registeredInstruments); 63 | } 64 | 65 | @Override 66 | public boolean equals(Object o) { 67 | if (this == o) { 68 | return true; 69 | } 70 | if (o == null || getClass() != o.getClass()) { 71 | return false; 72 | } 73 | StrategyExecutionContext executionContext = (StrategyExecutionContext) o; 74 | return Objects.equal(this.strategyId, executionContext.strategyId) && 75 | Objects.equal(this.parameters, executionContext.parameters) && 76 | Objects.equal(this.registeredInstruments, executionContext.registeredInstruments); 77 | } 78 | 79 | @Override 80 | public int hashCode() { 81 | return Objects.hashCode(strategyId, parameters, registeredInstruments); 82 | } 83 | 84 | @Override 85 | public String toString() { 86 | return MoreObjects.toStringHelper(this) 87 | .add("strategyId", strategyId) 88 | .add("parameters", parameters) 89 | .add("registeredInstruments", registeredInstruments) 90 | .toString(); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /onplan-core-adviser/src/main/java/com/onplan/adviser/strategy/StrategyListener.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser.strategy; 2 | 3 | import com.onplan.adviser.alert.AlertEvent; 4 | import com.onplan.adviser.automatedorder.AutomatedOrderEvent; 5 | 6 | // TODO(robertom): Looks cool but is it fast? Profile please! 7 | public interface StrategyListener { 8 | public void onNewOrder(final AutomatedOrderEvent automatedOrderEvent); 9 | public void onAlert(final AlertEvent alertEvent); 10 | } 11 | -------------------------------------------------------------------------------- /onplan-core-connector/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | onplan 7 | com.melphi 8 | 1.0-SNAPSHOT 9 | ../pom.xml 10 | 11 | 4.0.0 12 | 13 | onplan-core-connector 14 | 1.0-SNAPSHOT 15 | 16 | 17 | 18 | 19 | com.melphi 20 | onplan-core 21 | 1.0-SNAPSHOT 22 | 23 | 24 | 25 | 26 | com.google.guava 27 | guava 28 | 18.0 29 | 30 | 31 | org.apache.commons 32 | commons-lang3 33 | 3.3.2 34 | 35 | 36 | 37 | 38 | junit 39 | junit 40 | test 41 | 4.11 42 | 43 | 44 | -------------------------------------------------------------------------------- /onplan-core-connector/src/main/java/com/onplan/connector/AbstractPriceService.java: -------------------------------------------------------------------------------- 1 | package com.onplan.connector; 2 | 3 | import com.onplan.domain.transitory.PriceBar; 4 | import com.onplan.domain.transitory.PriceTick; 5 | 6 | import static com.google.common.base.Preconditions.checkArgument; 7 | import static com.google.common.base.Preconditions.checkNotNull; 8 | 9 | public abstract class AbstractPriceService implements PriceService { 10 | private PriceListener priceListener; 11 | 12 | @Override 13 | public void setPriceListener(PriceListener priceListener) { 14 | checkNotNull(priceListener); 15 | checkArgument(null == this.priceListener, "Price listener already set."); 16 | this.priceListener = priceListener; 17 | } 18 | 19 | protected void dispatchPriceTick(final PriceTick priceTick) { 20 | synchronized (priceListener) { 21 | priceListener.onPriceTick(priceTick); 22 | } 23 | } 24 | 25 | protected void dispatchPriceBar(final PriceBar priceBar) { 26 | synchronized (priceListener) { 27 | priceListener.onPriceBar(priceBar); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /onplan-core-connector/src/main/java/com/onplan/connector/AbstractServiceConnection.java: -------------------------------------------------------------------------------- 1 | package com.onplan.connector; 2 | 3 | import com.google.common.collect.Lists; 4 | 5 | import java.util.List; 6 | 7 | import static com.google.common.base.Preconditions.checkNotNull; 8 | 9 | public abstract class AbstractServiceConnection implements ServiceConnection { 10 | private final List serviceConnectionListeners = Lists.newArrayList(); 11 | 12 | @Override 13 | public void addServiceConnectionListener(ServiceConnectionListener serviceConnectionListener) { 14 | checkNotNull(serviceConnectionListener); 15 | synchronized (serviceConnectionListeners) { 16 | if (serviceConnectionListeners.contains(serviceConnectionListener)) { 17 | throw new IllegalArgumentException("ServiceConnectionListener already set."); 18 | } 19 | serviceConnectionListeners.add(serviceConnectionListener); 20 | } 21 | } 22 | 23 | @Override 24 | public void removeConnectionServiceListener(ServiceConnectionListener priceServiceListener) { 25 | checkNotNull(priceServiceListener); 26 | synchronized (serviceConnectionListeners) { 27 | if (serviceConnectionListeners.contains(priceServiceListener)) { 28 | serviceConnectionListeners.remove(priceServiceListener); 29 | } 30 | } 31 | } 32 | 33 | protected void dispatchServiceConnectionEstablishedEvent() { 34 | synchronized (serviceConnectionListeners) { 35 | for (ServiceConnectionListener serviceConnectionListener : serviceConnectionListeners) { 36 | serviceConnectionListener.onConnectionEstablished(); 37 | } 38 | } 39 | } 40 | 41 | protected void dispatchServiceDisconnectedEvent() { 42 | synchronized (serviceConnectionListeners) { 43 | for (ServiceConnectionListener serviceConnectionListener : serviceConnectionListeners) { 44 | serviceConnectionListener.onDisconnected(); 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /onplan-core-connector/src/main/java/com/onplan/connector/HistoricalPriceService.java: -------------------------------------------------------------------------------- 1 | package com.onplan.connector; 2 | 3 | import com.onplan.service.HistoricalPriceServiceRemote; 4 | 5 | public interface HistoricalPriceService extends HistoricalPriceServiceRemote { 6 | } 7 | -------------------------------------------------------------------------------- /onplan-core-connector/src/main/java/com/onplan/connector/InstrumentService.java: -------------------------------------------------------------------------------- 1 | package com.onplan.connector; 2 | 3 | import com.onplan.service.InstrumentServiceRemote; 4 | 5 | public interface InstrumentService extends InstrumentServiceRemote { 6 | } 7 | -------------------------------------------------------------------------------- /onplan-core-connector/src/main/java/com/onplan/connector/PriceListener.java: -------------------------------------------------------------------------------- 1 | package com.onplan.connector; 2 | 3 | import com.onplan.domain.transitory.PriceBar; 4 | import com.onplan.domain.transitory.PriceTick; 5 | 6 | public interface PriceListener { 7 | public void onPriceTick(final PriceTick priceTick); 8 | public void onPriceBar(final PriceBar priceBar); 9 | } 10 | -------------------------------------------------------------------------------- /onplan-core-connector/src/main/java/com/onplan/connector/PriceService.java: -------------------------------------------------------------------------------- 1 | package com.onplan.connector; 2 | 3 | import com.onplan.service.PriceServiceRemote; 4 | 5 | public interface PriceService extends PriceServiceRemote { 6 | public boolean isConnected(); 7 | public boolean isInstrumentSubscribed(String instrumentId); 8 | public void setPriceListener(PriceListener listener); 9 | public void subscribeInstrument(String instrumentId) throws Exception; 10 | public void unSubscribeInstrument(String instrumentId) throws Exception; 11 | } 12 | -------------------------------------------------------------------------------- /onplan-core-connector/src/main/java/com/onplan/connector/ServiceConnection.java: -------------------------------------------------------------------------------- 1 | package com.onplan.connector; 2 | 3 | import com.onplan.service.ServiceConnectionInfo; 4 | 5 | public interface ServiceConnection { 6 | public void connect(); 7 | public void disconnect(); 8 | public boolean isConnected(); 9 | public ServiceConnectionInfo getConnectionInfo(); 10 | public void addServiceConnectionListener(ServiceConnectionListener serviceConnectionListener); 11 | public void removeConnectionServiceListener(ServiceConnectionListener serviceConnectionListener); 12 | } 13 | -------------------------------------------------------------------------------- /onplan-core-connector/src/main/java/com/onplan/connector/ServiceConnectionListener.java: -------------------------------------------------------------------------------- 1 | package com.onplan.connector; 2 | 3 | public interface ServiceConnectionListener { 4 | public void onConnectionEstablished(); 5 | public void onDisconnected(); 6 | } 7 | -------------------------------------------------------------------------------- /onplan-core-connector/src/main/java/com/onplan/connector/util/CompleteEnumMapper.java: -------------------------------------------------------------------------------- 1 | package com.onplan.connector.util; 2 | 3 | import com.google.common.collect.ImmutableMap; 4 | import com.google.common.collect.ImmutableSet; 5 | import org.apache.commons.lang3.EnumUtils; 6 | 7 | import java.util.Collection; 8 | import java.util.List; 9 | 10 | import static com.google.common.base.Preconditions.checkArgument; 11 | import static com.google.common.base.Preconditions.checkNotNull; 12 | 13 | /** 14 | * Provides a complete key / value mapping in which the return value is an enumerated type. 15 | * In addition assures that all the possible values of the enumerated type are mapped. 16 | * 17 | * @param Return value of type enum. 18 | * @param Key value. 19 | */ 20 | public final class CompleteEnumMapper implements Mapper { 21 | private final ImmutableMap map; 22 | 23 | public static Builder newBuilder(Class enumClass) { 24 | return new Builder(enumClass); 25 | } 26 | 27 | private CompleteEnumMapper( 28 | ImmutableMap mapped, ImmutableSet unmapped, Class enumClass) { 29 | checkMapping(mapped.values(), unmapped, enumClass); 30 | this.map = checkNotNull(mapped); 31 | } 32 | 33 | @Override 34 | public V map(K key) { 35 | checkNotNull(key); 36 | return checkNotNull(map.get(key), String.format("Element [%s] not mapped.", key)); 37 | } 38 | 39 | private void checkMapping(Collection mapped, Collection unmapped, Class enumClass) { 40 | checkNotNull(mapped); 41 | checkNotNull(unmapped); 42 | checkNotNull(enumClass); 43 | for (V value : unmapped) { 44 | checkArgument(!mapped.contains(value), 45 | String.format("The unmapped element [%s] can not be in the mapped list.", value)); 46 | } 47 | List values = EnumUtils.getEnumList(enumClass); 48 | for (V value : values) { 49 | checkArgument(mapped.contains(value) || unmapped.contains(value), 50 | String.format("Element [%s] not mapped.", value)); 51 | } 52 | } 53 | 54 | public static class Builder { 55 | private final ImmutableMap.Builder mapped = ImmutableMap.builder(); 56 | private final Class enumClass; 57 | 58 | private ImmutableSet.Builder unmapped = ImmutableSet.builder(); 59 | 60 | public Builder(Class enumClass) { 61 | this.enumClass = checkNotNull(enumClass); 62 | } 63 | 64 | public Builder put(V value, K... keys) { 65 | checkNotNull(keys); 66 | checkNotNull(value); 67 | for (K key : keys) { 68 | mapped.put(key, value); 69 | } 70 | return this; 71 | } 72 | 73 | public Builder setUnmapped(V...values) { 74 | checkNotNull(values); 75 | unmapped = ImmutableSet.builder().add(values); 76 | return this; 77 | } 78 | 79 | public CompleteEnumMapper build() { 80 | return new CompleteEnumMapper(mapped.build(), unmapped.build(), enumClass); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /onplan-core-connector/src/main/java/com/onplan/connector/util/Mapper.java: -------------------------------------------------------------------------------- 1 | package com.onplan.connector.util; 2 | 3 | public interface Mapper { 4 | public V map(K object); 5 | } 6 | -------------------------------------------------------------------------------- /onplan-core-connector/src/test/java/com/onpla/adapter/util/CompleteEnumMapperTest.java: -------------------------------------------------------------------------------- 1 | package com.onpla.adapter.util; 2 | 3 | import com.onplan.connector.util.CompleteEnumMapper; 4 | import org.junit.Test; 5 | 6 | public class CompleteEnumMapperTest { 7 | @Test(expected = IllegalArgumentException.class) 8 | public void testUncompletedMap() { 9 | CompleteEnumMapper.newBuilder(SampleEnum.class) 10 | .put(SampleEnum.VALUE_A, "A") 11 | .setUnmapped(SampleEnum.VALUE_B) 12 | .build(); 13 | } 14 | 15 | @Test(expected = IllegalArgumentException.class) 16 | public void testWrongMapping() { 17 | CompleteEnumMapper.newBuilder(SampleEnum.class) 18 | .put(SampleEnum.VALUE_A, "A") 19 | .put(SampleEnum.VALUE_B, "C") 20 | .put(SampleEnum.VALUE_C, "C") 21 | .setUnmapped(SampleEnum.VALUE_C) 22 | .build(); 23 | } 24 | 25 | @Test 26 | public void testCompletedMap() { 27 | CompleteEnumMapper.newBuilder(SampleEnum.class) 28 | .put(SampleEnum.VALUE_A, "A") 29 | .put(SampleEnum.VALUE_B, "B", "C") 30 | .setUnmapped(SampleEnum.VALUE_C) 31 | .build(); 32 | } 33 | 34 | @Test(expected = NullPointerException.class) 35 | public void testElementNotFound() { 36 | CompleteEnumMapper map = CompleteEnumMapper.newBuilder(SampleEnum.class) 37 | .put(SampleEnum.VALUE_A, "A") 38 | .put(SampleEnum.VALUE_B, "B", "C") 39 | .setUnmapped(SampleEnum.VALUE_C) 40 | .build(); 41 | map.map("D"); 42 | } 43 | 44 | private enum SampleEnum { 45 | VALUE_A, 46 | VALUE_B, 47 | VALUE_C 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /onplan-core-connector/src/test/java/com/onplan/util/TestingConstants.java: -------------------------------------------------------------------------------- 1 | package com.onplan.util; 2 | 3 | import org.joda.time.DateTime; 4 | import org.joda.time.format.DateTimeFormat; 5 | 6 | public class TestingConstants { 7 | public static final DateTime DEFAULT_START_DATE = 8 | DateTime.parse("2010-05-05 08:00", DateTimeFormat.forPattern("yyyy-MM-dd hh:mm")); 9 | public static final String INSTRUMENT_EURUSD_ID = "EURUSD"; 10 | public static final String INSTRUMENT_DAX_ID = "DAX"; 11 | public static final long DEFAULT_SPREAD = 1; 12 | } 13 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/adviser/AdviserPredicateInfo.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser; 2 | 3 | import com.google.common.base.MoreObjects; 4 | import com.google.common.base.Objects; 5 | 6 | import java.util.Map; 7 | 8 | /** 9 | * Contains information about an adviser predicate. 10 | */ 11 | public final class AdviserPredicateInfo extends TemplateInfo { 12 | private Map executionParameters; 13 | 14 | public Map getExecutionParameters() { 15 | return executionParameters; 16 | } 17 | 18 | public void setExecutionParameters(Map executionParameters) { 19 | this.executionParameters = executionParameters; 20 | } 21 | 22 | public AdviserPredicateInfo() { 23 | // Intentionally empty. 24 | } 25 | 26 | public AdviserPredicateInfo(String displayName, String className, 27 | Iterable availableParameters, Map executionParameters) { 28 | super(displayName, className, availableParameters); 29 | this.executionParameters = executionParameters; 30 | } 31 | 32 | @Override 33 | public boolean equals(Object o) { 34 | if (this == o) { 35 | return true; 36 | } 37 | if (o == null || getClass() != o.getClass()) { 38 | return false; 39 | } 40 | AdviserPredicateInfo adviserPredicateInfo = (AdviserPredicateInfo) o; 41 | return Objects.equal(this.displayName, adviserPredicateInfo.displayName) && 42 | Objects.equal(this.className, adviserPredicateInfo.className) && 43 | Objects.equal(this.availableParameters, adviserPredicateInfo.availableParameters) && 44 | Objects.equal(this.executionParameters, adviserPredicateInfo.executionParameters); 45 | } 46 | 47 | @Override 48 | public int hashCode() { 49 | return Objects.hashCode( 50 | displayName, className, availableParameters, executionParameters, executionParameters); 51 | } 52 | 53 | @Override 54 | public String toString() { 55 | return MoreObjects.toStringHelper(this) 56 | .add("displayName", displayName) 57 | .add("className", className) 58 | .add("availableParameters", availableParameters) 59 | .add("executionParameters", executionParameters) 60 | .toString(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/adviser/SeverityLevel.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser; 2 | 3 | /** 4 | * Severity level. 5 | */ 6 | public enum SeverityLevel { 7 | LOW, 8 | MEDIUM, 9 | HIGH 10 | } 11 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/adviser/StrategyStatisticsSnapshot.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser; 2 | 3 | import com.google.common.base.MoreObjects; 4 | import com.google.common.base.Objects; 5 | 6 | import java.io.Serializable; 7 | 8 | /** 9 | * Strategy statistics snapshot. The completion time is the difference between the tick 10 | * received time and the strategy completion time, this includes the delay due to any other 11 | * strategy or routine which is executed before this strategy. 12 | */ 13 | public final class StrategyStatisticsSnapshot implements Serializable { 14 | private final long lastReceivedTickTimestamp; 15 | private final long receivedTicks; 16 | private final long eventsDispatchedCounter; 17 | private final long lastCompletionNanoTime; 18 | private final long maxCompletionNanoTime; 19 | private final long averageCompletionNanoTime; 20 | 21 | /** 22 | * Returns the completion time for the last received tick. 23 | */ 24 | public long getLastCompletionNanoTime() { 25 | return lastCompletionNanoTime; 26 | } 27 | 28 | public long getEventsDispatchedCounter() { 29 | return eventsDispatchedCounter; 30 | } 31 | 32 | public long getLastReceivedTickTimestamp() { 33 | return lastReceivedTickTimestamp; 34 | } 35 | 36 | public long getReceivedTicks() { 37 | return receivedTicks; 38 | } 39 | 40 | public long getMaxCompletionNanoTime() { 41 | return maxCompletionNanoTime; 42 | } 43 | 44 | public long getAverageCompletionNanoTime() { 45 | return averageCompletionNanoTime; 46 | } 47 | 48 | public StrategyStatisticsSnapshot(long lastReceivedTickTimestamp, long receivedTicks, 49 | long eventsDispatchedCounter, long lastCompletionNanoTime, long maxCompletionNanoTime, 50 | long averageCompletionNanoTime) { 51 | this.lastReceivedTickTimestamp = lastReceivedTickTimestamp; 52 | this.receivedTicks = receivedTicks; 53 | this.eventsDispatchedCounter = eventsDispatchedCounter; 54 | this.lastCompletionNanoTime = lastCompletionNanoTime; 55 | this.maxCompletionNanoTime = maxCompletionNanoTime; 56 | this.averageCompletionNanoTime = averageCompletionNanoTime; 57 | } 58 | 59 | @Override 60 | public boolean equals(Object o) { 61 | if (this == o) { 62 | return true; 63 | } 64 | if (o == null || getClass() != o.getClass()) { 65 | return false; 66 | } 67 | StrategyStatisticsSnapshot strategyStatistics = (StrategyStatisticsSnapshot) o; 68 | return Objects.equal( 69 | this.lastReceivedTickTimestamp, strategyStatistics.lastReceivedTickTimestamp) && 70 | Objects.equal(this.receivedTicks, strategyStatistics.receivedTicks) && 71 | Objects.equal(this.eventsDispatchedCounter, strategyStatistics.eventsDispatchedCounter) && 72 | Objects.equal(this.lastCompletionNanoTime, strategyStatistics.lastCompletionNanoTime) && 73 | Objects.equal(this.maxCompletionNanoTime, strategyStatistics.maxCompletionNanoTime) && 74 | Objects.equal(this.averageCompletionNanoTime, strategyStatistics.averageCompletionNanoTime); 75 | } 76 | 77 | @Override 78 | public int hashCode() { 79 | return Objects.hashCode(lastReceivedTickTimestamp, receivedTicks, eventsDispatchedCounter, 80 | lastCompletionNanoTime, maxCompletionNanoTime, averageCompletionNanoTime); 81 | } 82 | 83 | @Override 84 | public String toString() { 85 | return MoreObjects.toStringHelper(this) 86 | .add("lastReceivedTickTimestamp", lastReceivedTickTimestamp) 87 | .add("receivedTicks", receivedTicks) 88 | .add("eventsDispatchedCounter", eventsDispatchedCounter) 89 | .add("lastCompletionNanoTime", lastCompletionNanoTime) 90 | .add("maxCompletionNanoTime", maxCompletionNanoTime) 91 | .add("averageCompletionNanoTime", averageCompletionNanoTime) 92 | .toString(); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/adviser/TemplateInfo.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser; 2 | 3 | import com.google.common.base.MoreObjects; 4 | import com.google.common.base.Objects; 5 | 6 | import java.io.Serializable; 7 | 8 | /** 9 | * Contains information about a generic template. 10 | */ 11 | public class TemplateInfo implements Serializable { 12 | protected String displayName; 13 | protected String className; 14 | protected Iterable availableParameters; 15 | 16 | public String getDisplayName() { 17 | return displayName; 18 | } 19 | 20 | public String getClassName() { 21 | return className; 22 | } 23 | 24 | public Iterable getAvailableParameters() { 25 | return availableParameters; 26 | } 27 | 28 | public TemplateInfo() { 29 | // Intentionally empty. 30 | } 31 | 32 | public TemplateInfo(String displayName, String className, Iterable availableParameters) { 33 | this.displayName = displayName; 34 | this.className = className; 35 | this.availableParameters = availableParameters; 36 | } 37 | 38 | @Override 39 | public boolean equals(Object o) { 40 | if (this == o) { 41 | return true; 42 | } 43 | if (o == null || getClass() != o.getClass()) { 44 | return false; 45 | } 46 | TemplateInfo adviserPredicateInfo = (TemplateInfo) o; 47 | return Objects.equal(this.displayName, adviserPredicateInfo.displayName) && 48 | Objects.equal(this.className, adviserPredicateInfo.className) && 49 | Objects.equal(this.availableParameters, adviserPredicateInfo.availableParameters); 50 | } 51 | 52 | @Override 53 | public int hashCode() { 54 | return Objects.hashCode(displayName, className, availableParameters); 55 | } 56 | 57 | @Override 58 | public String toString() { 59 | return MoreObjects.toStringHelper(this) 60 | .add("displayName", displayName) 61 | .add("className", className) 62 | .add("availableParameters", availableParameters) 63 | .toString(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/domain/InstrumentType.java: -------------------------------------------------------------------------------- 1 | package com.onplan.domain; 2 | 3 | public enum InstrumentType { 4 | BINARY, 5 | COMMODITY, 6 | CURRENCY, 7 | INDEX, 8 | OPTION_COMMODITY, 9 | OPTION_CURRENCY, 10 | OPTION_INDEX, 11 | OPTION_RATE, 12 | OPTION_SHARE, 13 | RATE, 14 | SECTOR, 15 | SHARE, 16 | SPRINT_MARKET, 17 | UNKNOWN 18 | } 19 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/domain/PriceBarTimeFrame.java: -------------------------------------------------------------------------------- 1 | package com.onplan.domain; 2 | 3 | import static com.onplan.util.MorePreconditions.checkNotNullOrEmpty; 4 | 5 | public enum PriceBarTimeFrame { 6 | TICK(0), 7 | MINUTES_1(60 * 1000), 8 | MINUTES_5(60 * 5 * 1000), 9 | MINUTES_15(60 * 15 * 1000), 10 | HOURS_1(60 * 60 * 1000), 11 | HOURS_4(60 * 60 * 4 * 1000), 12 | DAYS_1(60 * 60 * 24 * 1000); 13 | 14 | private final int milliseconds; 15 | 16 | public int getIntervalMilliseconds() { 17 | return milliseconds; 18 | } 19 | 20 | private PriceBarTimeFrame(int milliseconds) { 21 | this.milliseconds = milliseconds; 22 | } 23 | 24 | public static PriceBarTimeFrame parseString(String timeFrame) { 25 | switch (checkNotNullOrEmpty(timeFrame)) { 26 | case "TICK": 27 | return TICK; 28 | case "MINUTES_1": 29 | return MINUTES_1; 30 | case "MINUTES_5": 31 | return MINUTES_5; 32 | case "MINUTES_15": 33 | return MINUTES_15; 34 | case "HOURS_1": 35 | return HOURS_1; 36 | case "HOURS_4": 37 | return HOURS_4; 38 | case "DAYS_1": 39 | return DAYS_1; 40 | default: 41 | throw new IllegalArgumentException( 42 | String.format("No matching value found for [%s].", timeFrame)); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/domain/configuration/AdviserPredicateConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.onplan.domain.configuration; 2 | 3 | import com.google.common.base.MoreObjects; 4 | import com.google.common.base.Objects; 5 | 6 | import java.io.Serializable; 7 | import java.util.Map; 8 | 9 | public final class AdviserPredicateConfiguration implements Serializable { 10 | private String className; 11 | private Map parameters; 12 | 13 | public String getClassName() { 14 | return className; 15 | } 16 | 17 | public void setClassName(String className) { 18 | this.className = className; 19 | } 20 | 21 | public Map getParameters() { 22 | return parameters; 23 | } 24 | 25 | public void setParameters(Map parameters) { 26 | this.parameters = parameters; 27 | } 28 | 29 | public AdviserPredicateConfiguration() { 30 | // Intentionally empty. 31 | } 32 | 33 | public AdviserPredicateConfiguration(String className, Map parameters) { 34 | this.className = className; 35 | this.parameters = parameters; 36 | } 37 | 38 | @Override 39 | public boolean equals(Object o) { 40 | if (this == o) { 41 | return true; 42 | } 43 | if (o == null || getClass() != o.getClass()) { 44 | return false; 45 | } 46 | AdviserPredicateConfiguration predicateConfiguration = (AdviserPredicateConfiguration) o; 47 | return Objects.equal(this.className, predicateConfiguration.className) && 48 | Objects.equal(this.parameters, predicateConfiguration.parameters); 49 | } 50 | 51 | @Override 52 | public int hashCode() { 53 | return Objects.hashCode(className, parameters); 54 | } 55 | 56 | @Override 57 | public String toString() { 58 | return MoreObjects.toStringHelper(this) 59 | .add("className", className) 60 | .add("parameters", parameters) 61 | .toString(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/domain/configuration/StrategyConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.onplan.domain.configuration; 2 | 3 | import com.google.common.base.MoreObjects; 4 | import com.google.common.base.Objects; 5 | import com.onplan.domain.persistent.PersistentObject; 6 | 7 | import java.util.Map; 8 | import java.util.Set; 9 | 10 | public final class StrategyConfiguration implements PersistentObject { 11 | private String id; 12 | private String className; 13 | private Map executionParameters; 14 | private Set instruments; 15 | 16 | public String getId() { 17 | return this.id; 18 | } 19 | 20 | public void setId(String id) { 21 | this.id = id; 22 | } 23 | 24 | public String getClassName() { 25 | return className; 26 | } 27 | 28 | public void setClassName(String className) { 29 | this.className = className; 30 | } 31 | 32 | public Map getExecutionParameters() { 33 | return executionParameters; 34 | } 35 | 36 | public void setExecutionParameters(Map parameters) { 37 | this.executionParameters = parameters; 38 | } 39 | 40 | public Set getInstruments() { 41 | return instruments; 42 | } 43 | 44 | public void setInstruments(Set instruments) { 45 | this.instruments = instruments; 46 | } 47 | 48 | public StrategyConfiguration() { 49 | // Intentionally empty. 50 | } 51 | 52 | public StrategyConfiguration(String id, String className, Map executionParameters, 53 | Set instruments) { 54 | this.id = id; 55 | this.className = className; 56 | this.executionParameters = executionParameters; 57 | this.instruments = instruments; 58 | } 59 | 60 | @Override 61 | public boolean equals(Object o) { 62 | if (this == o) { 63 | return true; 64 | } 65 | if (o == null || getClass() != o.getClass()) { 66 | return false; 67 | } 68 | StrategyConfiguration strategyConfiguration = (StrategyConfiguration) o; 69 | return Objects.equal(this.id, strategyConfiguration.id) && 70 | Objects.equal(this.className, strategyConfiguration.className) && 71 | Objects.equal(this.executionParameters, strategyConfiguration.executionParameters) && 72 | Objects.equal(this.instruments, strategyConfiguration.instruments); 73 | } 74 | 75 | @Override 76 | public int hashCode() { 77 | return Objects.hashCode(id, className, executionParameters, instruments); 78 | } 79 | 80 | @Override 81 | public String toString() { 82 | return MoreObjects.toStringHelper(this) 83 | .add("id", id) 84 | .add("className", className) 85 | .add("executionParameters", executionParameters) 86 | .add("instruments", instruments) 87 | .toString(); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/domain/persistent/AlertEventHistory.java: -------------------------------------------------------------------------------- 1 | package com.onplan.domain.persistent; 2 | 3 | import com.google.common.base.MoreObjects; 4 | import com.google.common.base.Objects; 5 | import com.onplan.adviser.SeverityLevel; 6 | import com.onplan.domain.transitory.PriceTick; 7 | 8 | public final class AlertEventHistory implements PersistentObject { 9 | private String id; 10 | private String adviserId; 11 | private PriceTick priceTick; 12 | private String message; 13 | private SeverityLevel severityLevel; 14 | private long createdOn; 15 | 16 | public String getMessage() { 17 | return message; 18 | } 19 | 20 | public void setMessage(String message) { 21 | this.message = message; 22 | } 23 | 24 | public SeverityLevel getSeverityLevel() { 25 | return severityLevel; 26 | } 27 | 28 | public void setSeverityLevel(SeverityLevel severityLevel) { 29 | this.severityLevel = severityLevel; 30 | } 31 | 32 | public String getAdviserId() { 33 | return adviserId; 34 | } 35 | 36 | public void setAdviserId(String adviserId) { 37 | this.adviserId = adviserId; 38 | } 39 | 40 | public PriceTick getPriceTick() { 41 | return priceTick; 42 | } 43 | 44 | public void setPriceTick(PriceTick priceTick) { 45 | this.priceTick = priceTick; 46 | } 47 | 48 | public long getCreatedOn() { 49 | return createdOn; 50 | } 51 | 52 | public void setCreatedOn(long createdOn) { 53 | this.createdOn = createdOn; 54 | } 55 | 56 | @Override 57 | public String getId() { 58 | return id; 59 | } 60 | 61 | @Override 62 | public void setId(String id) { 63 | this.id = id; 64 | } 65 | 66 | public AlertEventHistory() { 67 | // Intentionally empty. 68 | } 69 | 70 | public AlertEventHistory(String id, String adviserId, SeverityLevel severityLevel, 71 | PriceTick priceTick, long createdOn, String message) { 72 | this.adviserId = adviserId; 73 | this.severityLevel = severityLevel; 74 | this.priceTick = priceTick; 75 | this.message = message; 76 | this.createdOn = createdOn; 77 | } 78 | 79 | @Override 80 | public int hashCode() { 81 | return Objects.hashCode(id, adviserId, priceTick, createdOn, message, severityLevel); 82 | } 83 | 84 | @Override 85 | public boolean equals(Object o) { 86 | if (this == o) { 87 | return true; 88 | } 89 | if (o == null || getClass() != o.getClass()) { 90 | return false; 91 | } 92 | AlertEventHistory alertEvent = (AlertEventHistory) o; 93 | return Objects.equal(this.id, alertEvent.id) && 94 | Objects.equal(this.adviserId, alertEvent.adviserId) && 95 | Objects.equal(this.createdOn, alertEvent.createdOn) && 96 | Objects.equal(this.message, alertEvent.message) && 97 | Objects.equal(this.severityLevel, alertEvent.severityLevel) && 98 | Objects.equal(this.priceTick, alertEvent.priceTick); 99 | } 100 | 101 | @Override 102 | public String toString() { 103 | return MoreObjects.toStringHelper(this) 104 | .add("id", id) 105 | .add("adviserId", adviserId) 106 | .add("createdOn", createdOn) 107 | .add("message", message) 108 | .add("severityLevel", severityLevel) 109 | .add("priceTick", priceTick) 110 | .toString(); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/domain/persistent/PersistentObject.java: -------------------------------------------------------------------------------- 1 | package com.onplan.domain.persistent; 2 | 3 | import java.io.Serializable; 4 | 5 | public interface PersistentObject extends Serializable { 6 | public String getId(); 7 | public void setId(String id); 8 | } 9 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/domain/persistent/SystemEventHistory.java: -------------------------------------------------------------------------------- 1 | package com.onplan.domain.persistent; 2 | 3 | import com.google.common.base.MoreObjects; 4 | import com.google.common.base.Objects; 5 | 6 | public final class SystemEventHistory implements PersistentObject { 7 | private String id; 8 | private String className; 9 | private String message; 10 | private long createdOn; 11 | 12 | @Override 13 | public String getId() { 14 | return id; 15 | } 16 | 17 | @Override 18 | public void setId(String id) { 19 | this.id = id; 20 | } 21 | 22 | public String getClassName() { 23 | return className; 24 | } 25 | 26 | public void setClassName(String className) { 27 | this.className = className; 28 | } 29 | 30 | public String getMessage() { 31 | return message; 32 | } 33 | 34 | public void setMessage(String message) { 35 | this.message = message; 36 | } 37 | 38 | public long getCreatedOn() { 39 | return createdOn; 40 | } 41 | 42 | public void setCreatedOn(long createdOn) { 43 | this.createdOn = createdOn; 44 | } 45 | 46 | public SystemEventHistory() { 47 | // Intentionally empty. 48 | } 49 | 50 | public SystemEventHistory(String id, String className, String message, long createdOn) { 51 | this.id = id; 52 | this.className = className; 53 | this.message = message; 54 | this.createdOn = createdOn; 55 | } 56 | 57 | @Override 58 | public int hashCode() { 59 | return Objects.hashCode(id, className, message, createdOn); 60 | } 61 | 62 | @Override 63 | public boolean equals(Object o) { 64 | if (this == o) { 65 | return true; 66 | } 67 | if (o == null || getClass() != o.getClass()) { 68 | return false; 69 | } 70 | SystemEventHistory systemEvent = (SystemEventHistory) o; 71 | return Objects.equal(this.id, systemEvent.id) && 72 | Objects.equal(this.className, systemEvent.className) && 73 | Objects.equal(this.message, systemEvent.message) && 74 | Objects.equal(this.createdOn, systemEvent.createdOn); 75 | } 76 | 77 | @Override 78 | public String toString() { 79 | return MoreObjects.toStringHelper(this) 80 | .add("id", id) 81 | .add("className", className) 82 | .add("message", message) 83 | .add("createdOn", createdOn) 84 | .toString(); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/domain/transitory/InstrumentInfo.java: -------------------------------------------------------------------------------- 1 | package com.onplan.domain.transitory; 2 | 3 | import com.google.common.base.MoreObjects; 4 | import com.google.common.base.Objects; 5 | import com.onplan.domain.InstrumentType; 6 | 7 | import java.io.Serializable; 8 | 9 | import static com.google.common.base.Preconditions.checkNotNull; 10 | import static com.onplan.util.MorePreconditions.checkNotNullOrEmpty; 11 | 12 | public final class InstrumentInfo implements Serializable { 13 | private final String instrumentId; 14 | private final String instrumentName; 15 | private final int priceMinimalDecimalPosition; 16 | private final InstrumentType instrumentType; 17 | private final String expiry; 18 | 19 | public InstrumentInfo(String instrumentId, String instrumentName, InstrumentType instrumentType, 20 | int priceMinimalDecimalPosition, String expiry) { 21 | this.instrumentId = checkNotNullOrEmpty(instrumentId); 22 | this.instrumentName = checkNotNullOrEmpty(instrumentName); 23 | this.instrumentType = checkNotNull(instrumentType); 24 | this.priceMinimalDecimalPosition = priceMinimalDecimalPosition; 25 | this.expiry = checkNotNullOrEmpty(expiry); 26 | } 27 | 28 | public String getInstrumentId() { 29 | return instrumentId; 30 | } 31 | 32 | public int getPriceMinimalDecimalPosition() { 33 | return priceMinimalDecimalPosition; 34 | } 35 | 36 | public String getInstrumentName() { 37 | return instrumentName; 38 | } 39 | 40 | public InstrumentType getInstrumentType() { 41 | return instrumentType; 42 | } 43 | 44 | public String getExpiry() { 45 | return expiry; 46 | } 47 | 48 | @Override 49 | public boolean equals(Object o) { 50 | if (this == o) { 51 | return true; 52 | } 53 | if (o == null || getClass() != o.getClass()) { 54 | return false; 55 | } 56 | InstrumentInfo instrumentInfo = (InstrumentInfo) o; 57 | return Objects.equal(this.instrumentId, instrumentInfo.instrumentId) && 58 | Objects.equal(this.instrumentName, instrumentInfo.instrumentName) && 59 | Objects.equal(this.instrumentType, instrumentInfo.instrumentType) && 60 | Objects.equal(this.expiry, instrumentInfo.expiry) && 61 | Objects.equal(this.priceMinimalDecimalPosition, instrumentInfo.priceMinimalDecimalPosition); 62 | } 63 | 64 | @Override 65 | public int hashCode() { 66 | return Objects.hashCode( 67 | instrumentId, instrumentName, instrumentType, expiry, priceMinimalDecimalPosition); 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | return MoreObjects.toStringHelper(this) 73 | .add("instrumentId", instrumentId) 74 | .add("instrumentName", instrumentName) 75 | .add("instrumentType", instrumentType) 76 | .add("expiry", expiry) 77 | .add("priceMinimalDecimalPosition", priceMinimalDecimalPosition) 78 | .toString(); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/domain/transitory/Price.java: -------------------------------------------------------------------------------- 1 | package com.onplan.domain.transitory; 2 | 3 | import java.io.Serializable; 4 | 5 | public interface Price extends Serializable { 6 | public String getInstrumentId(); 7 | public long getTimestamp(); 8 | public double getClosePriceAsk(); 9 | public double getClosePriceBid(); 10 | } 11 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/domain/transitory/PriceTick.java: -------------------------------------------------------------------------------- 1 | package com.onplan.domain.transitory; 2 | 3 | import com.google.common.base.MoreObjects; 4 | import com.google.common.base.Objects; 5 | 6 | import static com.onplan.util.MorePreconditions.checkNotNullOrEmpty; 7 | 8 | public final class PriceTick implements Price { 9 | private final String instrumentId; 10 | private final long timestamp; 11 | private final double closePriceAsk; 12 | private final double closePriceBid; 13 | 14 | private transient final long receivedNanoTime; 15 | 16 | public String getInstrumentId() { 17 | return instrumentId; 18 | } 19 | 20 | public long getTimestamp() { 21 | return timestamp; 22 | } 23 | 24 | public double getClosePriceAsk() { 25 | return closePriceAsk; 26 | } 27 | 28 | public double getClosePriceBid() { 29 | return closePriceBid; 30 | } 31 | 32 | public long getReceivedNanoTime() { 33 | return receivedNanoTime; 34 | } 35 | 36 | public PriceTick( 37 | String instrumentID, long timestamp, double closePriceAsk, double closePriceBid) { 38 | this.instrumentId = checkNotNullOrEmpty(instrumentID); 39 | this.timestamp = timestamp; 40 | this.closePriceAsk = closePriceAsk; 41 | this.closePriceBid = closePriceBid; 42 | this.receivedNanoTime = System.nanoTime(); 43 | } 44 | 45 | @Override 46 | public boolean equals(Object o) { 47 | if (this == o) { 48 | return true; 49 | } 50 | if (o == null || getClass() != o.getClass()) { 51 | return false; 52 | } 53 | PriceTick priceTick = (PriceTick) o; 54 | return Objects.equal(this.instrumentId, priceTick.instrumentId) && 55 | Objects.equal(this.timestamp, priceTick.timestamp) && 56 | Objects.equal(this.closePriceAsk, priceTick.closePriceAsk) && 57 | Objects.equal(this.closePriceBid, priceTick.closePriceBid); 58 | } 59 | 60 | @Override 61 | public int hashCode() { 62 | return Objects.hashCode(instrumentId, timestamp, closePriceAsk, closePriceBid); 63 | } 64 | 65 | @Override 66 | public String toString() { 67 | return MoreObjects.toStringHelper(this) 68 | .add("instrumentId", instrumentId) 69 | .add("timestamp", timestamp) 70 | .add("closePriceAsk", closePriceAsk) 71 | .add("closePriceBid", closePriceBid) 72 | .toString(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/domain/transitory/VirtualMachineInfo.java: -------------------------------------------------------------------------------- 1 | package com.onplan.domain.transitory; 2 | 3 | import com.google.common.base.MoreObjects; 4 | import com.google.common.base.Objects; 5 | 6 | import java.io.Serializable; 7 | 8 | public final class VirtualMachineInfo implements Serializable { 9 | private final int availableProcessors; 10 | private final long maxMemory; 11 | private final long totalMemory; 12 | private final long freeMemory; 13 | private final long collectionsCount; 14 | private final double averageCollectionTime; 15 | 16 | public VirtualMachineInfo(int availableProcessors, long maxMemory, long totalMemory, 17 | long freeMemory, long collectionsCount, double averageCollectionTime) { 18 | this.availableProcessors = availableProcessors; 19 | this.maxMemory = maxMemory; 20 | this.totalMemory = totalMemory; 21 | this.freeMemory = freeMemory; 22 | this.collectionsCount = collectionsCount; 23 | this.averageCollectionTime = averageCollectionTime; 24 | } 25 | 26 | public long getCollectionsCount() { 27 | return collectionsCount; 28 | } 29 | 30 | public double getAverageCollectionTime() { 31 | return averageCollectionTime; 32 | } 33 | 34 | public long getTotalMemory() { 35 | return totalMemory; 36 | } 37 | 38 | public long getMaxMemory() { 39 | return maxMemory; 40 | } 41 | 42 | public long getFreeMemory() { 43 | return freeMemory; 44 | } 45 | 46 | public int getAvailableProcessors() { 47 | return availableProcessors; 48 | } 49 | 50 | @Override 51 | public String toString() { 52 | return MoreObjects.toStringHelper(this) 53 | .add("availableProcessors", availableProcessors) 54 | .add("maxMemory", maxMemory) 55 | .add("totalMemory", totalMemory) 56 | .add("freeMemory", freeMemory) 57 | .add("collectionsCount", collectionsCount) 58 | .add("averageCollectionTime", averageCollectionTime) 59 | .toString(); 60 | } 61 | 62 | @Override 63 | public int hashCode() { 64 | return Objects.hashCode(availableProcessors, maxMemory, totalMemory, freeMemory, 65 | collectionsCount, averageCollectionTime); 66 | } 67 | 68 | @Override 69 | public boolean equals(Object o) { 70 | if (this == o) { 71 | return true; 72 | } 73 | if (o == null || getClass() != o.getClass()) { 74 | return false; 75 | } 76 | VirtualMachineInfo virtualMachineInfo = (VirtualMachineInfo) o; 77 | return Objects.equal(this.availableProcessors, virtualMachineInfo.availableProcessors) && 78 | Objects.equal(this.maxMemory, virtualMachineInfo.maxMemory) && 79 | Objects.equal(this.totalMemory, virtualMachineInfo.totalMemory) && 80 | Objects.equal(this.freeMemory, virtualMachineInfo.freeMemory) && 81 | Objects.equal(this.collectionsCount, virtualMachineInfo.collectionsCount) && 82 | Objects.equal(this.averageCollectionTime, virtualMachineInfo.averageCollectionTime); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/service/AlertServiceRemote.java: -------------------------------------------------------------------------------- 1 | package com.onplan.service; 2 | 3 | import com.onplan.adviser.AlertInfo; 4 | import com.onplan.domain.configuration.AlertConfiguration; 5 | 6 | import java.io.Serializable; 7 | import java.util.List; 8 | 9 | public interface AlertServiceRemote extends Serializable { 10 | /** 11 | * Removes an alert by its id, returns true if the alert was found, false otherwise. 12 | * 13 | * @param alertId the alert id. 14 | */ 15 | public boolean removeAlert(String alertId) throws Exception; 16 | 17 | /** 18 | * Loads an alert with the provided configuration. Returns the id assigned to the alert. 19 | * If the alert id is set then replaces the previous alert with the new data. 20 | * 21 | * @param alertConfigurationConfiguration the alert configuration. 22 | */ 23 | public String addAlert(AlertConfiguration alertConfigurationConfiguration) throws Exception; 24 | 25 | /** 26 | * Loads a collection of sample alerts, deleting and replacing all the ones which have been 27 | * instantiated. 28 | * 29 | * @throws Exception error while loading the collection of sample alerts. 30 | */ 31 | public void loadSampleAlerts() throws Exception; 32 | 33 | /** 34 | * Returns the collection of alerts info. 35 | */ 36 | public List getAlertsInfo(); 37 | } 38 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/service/HistoricalPriceServiceRemote.java: -------------------------------------------------------------------------------- 1 | package com.onplan.service; 2 | 3 | import com.onplan.domain.transitory.PriceBar; 4 | 5 | import java.io.Serializable; 6 | import java.util.Collection; 7 | 8 | public interface HistoricalPriceServiceRemote extends Serializable { 9 | public ServiceConnectionInfo getServiceConnectionInfo(); 10 | public Collection getHistoricalPriceBars( 11 | String instrumentId, long barPeriod, long startTimestamp, long endTimestamp); 12 | } 13 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/service/InstrumentServiceRemote.java: -------------------------------------------------------------------------------- 1 | package com.onplan.service; 2 | 3 | import com.onplan.domain.transitory.InstrumentInfo; 4 | 5 | import java.io.IOException; 6 | import java.io.Serializable; 7 | import java.util.List; 8 | 9 | public interface InstrumentServiceRemote extends Serializable { 10 | public ServiceConnectionInfo getServiceConnectionInfo(); 11 | public InstrumentInfo getInstrumentInfo(String instrumentId) throws IOException; 12 | public List findInstrumentsBySearchTerm(String searchTerm) throws Exception; 13 | } 14 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/service/PriceServiceRemote.java: -------------------------------------------------------------------------------- 1 | package com.onplan.service; 2 | 3 | import com.onplan.domain.transitory.PriceTick; 4 | 5 | import java.io.Serializable; 6 | 7 | public interface PriceServiceRemote extends Serializable { 8 | public ServiceConnectionInfo getServiceConnectionInfo(); 9 | public PriceTick getLastPriceTick(String instrumentId); 10 | } 11 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/service/ServiceConnectionInfo.java: -------------------------------------------------------------------------------- 1 | package com.onplan.service; 2 | 3 | import java.io.Serializable; 4 | 5 | import static com.onplan.util.MorePreconditions.checkNotNullOrEmpty; 6 | 7 | public class ServiceConnectionInfo implements Serializable { 8 | private final String providerName; 9 | private final boolean isConnected; 10 | private final Long connectionUpdateTimestamp; 11 | 12 | public ServiceConnectionInfo(String providerName, boolean isConnected, Long connectionDate) { 13 | this.providerName = checkNotNullOrEmpty(providerName); 14 | this.isConnected = isConnected; 15 | this.connectionUpdateTimestamp = connectionDate; 16 | } 17 | 18 | /** 19 | * Returns the provider displayName. 20 | */ 21 | public String getProviderName() { 22 | return providerName; 23 | } 24 | 25 | /** 26 | * Returns true if the service is connected. 27 | */ 28 | public boolean getIsConnected() { 29 | return isConnected; 30 | } 31 | 32 | /** 33 | * Returns the timestamp of the last connection / disconnection. Returns null if any connection 34 | * attempt has ever been established. 35 | */ 36 | public Long getConnectionUpdateTimestamp() { 37 | return connectionUpdateTimestamp; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/service/StrategyServiceRemote.java: -------------------------------------------------------------------------------- 1 | package com.onplan.service; 2 | 3 | import com.onplan.adviser.StrategyInfo; 4 | import com.onplan.adviser.TemplateInfo; 5 | import com.onplan.domain.configuration.StrategyConfiguration; 6 | 7 | import java.io.Serializable; 8 | import java.util.List; 9 | 10 | public interface StrategyServiceRemote extends Serializable { 11 | /** 12 | * Removes an instantiated strategy by its id. 13 | * 14 | * @param strategyId the strategy id. 15 | */ 16 | public boolean removeStrategy(String strategyId) throws Exception; 17 | 18 | /** 19 | * Registers and initializes a strategy with the provided configuration. Returns the id of the 20 | * registered configuration. If the strategy id is already assigned it replaces the previous 21 | * strategy values with the new data. 22 | * 23 | * @param strategyConfiguration the strategy configuration. 24 | */ 25 | public String addStrategy(StrategyConfiguration strategyConfiguration) throws Exception; 26 | 27 | /** 28 | * Loads a collection of sample strategies, deleting and replacing all the ones which have been 29 | * instantiated. Returns the number of loaded strategies. 30 | * 31 | * @throws Exception error while loading the collection of sample strategies. 32 | */ 33 | public long loadSampleStrategies() throws Exception; 34 | 35 | /** 36 | * Returns the collection of strategies info which have been instantiated. 37 | */ 38 | public List getStrategiesInfo(); 39 | 40 | /** 41 | * Returns the ids of the available strategy templates. 42 | */ 43 | public List getStrategyTemplatesIds(); 44 | 45 | /** 46 | * Returns the strategy template info by the its class displayName or null if the template was 47 | * not found. 48 | * @param className The class displayName. 49 | */ 50 | public TemplateInfo getStrategyTemplateInfo(String className); 51 | } 52 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/service/VirtualMachineServiceRemote.java: -------------------------------------------------------------------------------- 1 | package com.onplan.service; 2 | 3 | import com.onplan.domain.transitory.VirtualMachineInfo; 4 | 5 | public interface VirtualMachineServiceRemote { 6 | /** 7 | * Returns the JVM information. 8 | */ 9 | VirtualMachineInfo getVirtualMachineInfo(); 10 | } 11 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/util/MorePreconditions.java: -------------------------------------------------------------------------------- 1 | package com.onplan.util; 2 | 3 | import com.google.common.base.Strings; 4 | 5 | import static com.google.common.base.Preconditions.checkArgument; 6 | 7 | /** 8 | * Additional preconditions. 9 | */ 10 | public final class MorePreconditions { 11 | public static final String TRUE = "true"; 12 | public static final String FALSE = "false"; 13 | 14 | /** 15 | * Returns the string passed as argument, making sure that the string is not null or empty. 16 | * 17 | * @param value The string value. 18 | * @param errorMessage The message to include in the exception if raised. 19 | * @return The string value passed as argument. 20 | * @exception java.lang.IllegalArgumentException The string is null or empty. 21 | */ 22 | public static String checkNotNullOrEmpty(final String value, final String errorMessage) 23 | throws IllegalArgumentException { 24 | if (Strings.isNullOrEmpty(value)) { 25 | throw new IllegalArgumentException(errorMessage); 26 | } 27 | return value; 28 | } 29 | 30 | /** 31 | * Returns the string passed as argument, making sure that the string is not null or empty. 32 | * 33 | * @param value The string value. 34 | * @return The string value passed as argument. 35 | * @exception java.lang.IllegalArgumentException The string is null or empty. 36 | */ 37 | public static String checkNotNullOrEmpty(final String value) throws IllegalArgumentException { 38 | return checkNotNullOrEmpty(value, "Required value is null or empty."); 39 | } 40 | 41 | /** 42 | * Returns the boolean translation of the string, making sure that the string has 43 | * a correct value (true or false). 44 | * 45 | * @param value The string which represents a boolean value (true or false). 46 | * @return The boolean translation of the string. 47 | * @exception java.lang.IllegalArgumentException The string can not be converted to a boolean. 48 | */ 49 | public static boolean checkAndGetBoolean(String value) throws IllegalArgumentException{ 50 | if (!Strings.isNullOrEmpty(value)) { 51 | value = value.trim(); 52 | } 53 | checkArgument(TRUE.equalsIgnoreCase(value) || FALSE.equalsIgnoreCase(value), 54 | String.format("Expected a boolean value of %s/%s but was [%s].", TRUE, FALSE, value)); 55 | return Boolean.getBoolean(value); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/util/PriceBarUtil.java: -------------------------------------------------------------------------------- 1 | package com.onplan.util; 2 | 3 | import com.onplan.domain.PriceBarTimeFrame; 4 | 5 | public final class PriceBarUtil { 6 | public static double getPricePips(final double price, final int minimalDecimalPosition) { 7 | return price * Math.pow(10, minimalDecimalPosition); 8 | } 9 | 10 | public static long getCurrentBarOpenTimestamp( 11 | long currentTimestamp, PriceBarTimeFrame priceBarTimeFrame) { 12 | long intervalMilliseconds = priceBarTimeFrame.getIntervalMilliseconds(); 13 | switch (priceBarTimeFrame) { 14 | case MINUTES_1: 15 | case MINUTES_15: 16 | return intervalMilliseconds * Math.floorDiv(currentTimestamp, intervalMilliseconds); 17 | default: 18 | throw new IllegalArgumentException( 19 | String.format("TimeFrame not supported [%s].", priceBarTimeFrame)); 20 | } 21 | } 22 | 23 | public static long getCurrentBarCloseTimestamp( 24 | long currentTimestamp, PriceBarTimeFrame priceBarTimeFrame) { 25 | long intervalMilliseconds = priceBarTimeFrame.getIntervalMilliseconds(); 26 | switch (priceBarTimeFrame) { 27 | case MINUTES_1: 28 | case MINUTES_15: 29 | long multiplier = Math.floorDiv(currentTimestamp, intervalMilliseconds) + 1; 30 | return (intervalMilliseconds * multiplier) - 1; 31 | default: 32 | throw new IllegalArgumentException( 33 | String.format("TimeFrame not supported [%s].", priceBarTimeFrame)); 34 | } 35 | } 36 | 37 | public static long getNextBarOpenTimestamp( 38 | long currentTimestamp, PriceBarTimeFrame priceBarTimeFrame) { 39 | return getCurrentBarCloseTimestamp(currentTimestamp, priceBarTimeFrame) + 1; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/util/http/HttpClientResponse.java: -------------------------------------------------------------------------------- 1 | package com.onplan.util.http; 2 | 3 | import com.google.common.base.MoreObjects; 4 | 5 | import java.util.Map; 6 | 7 | import static com.google.common.base.Preconditions.checkNotNull; 8 | 9 | public final class HttpClientResponse { 10 | private final String body; 11 | private final Map headers; 12 | private final int statusCode; 13 | 14 | public String getBody() { 15 | return body; 16 | } 17 | 18 | public Map getHeaders() { 19 | return headers; 20 | } 21 | 22 | public int getStatusCode() { 23 | return statusCode; 24 | } 25 | 26 | public HttpClientResponse(String body, Map header, int statusCode) { 27 | this.body = checkNotNull(body); 28 | this.headers = checkNotNull(header); 29 | this.statusCode = statusCode; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return MoreObjects.toStringHelper(this) 35 | .add("body", body) 36 | .add("headers", headers) 37 | .add("statusCode", statusCode) 38 | .toString(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/util/http/HttpMethod.java: -------------------------------------------------------------------------------- 1 | package com.onplan.util.http; 2 | 3 | public enum HttpMethod { 4 | POST, 5 | GET, 6 | DELETE, 7 | PUT 8 | } 9 | -------------------------------------------------------------------------------- /onplan-core/src/main/java/com/onplan/util/http/HttpStatus.java: -------------------------------------------------------------------------------- 1 | package com.onplan.util.http; 2 | 3 | public enum HttpStatus { 4 | ACCEPTED(202), 5 | BAD_GATEWAY(502), 6 | BAD_REQUEST(400), 7 | CONFLICT(409), 8 | CONTINUE(100), 9 | CREATED(201), 10 | EXPECTATION_FAILED(417), 11 | FAILED_DEPENDENCY(424), 12 | FORBIDDEN(403), 13 | GATEWAY_TIMEOUT(504), 14 | GONE(410), 15 | HTTP_VERSION_NOT_SUPPORTED(505), 16 | INSUFFICIENT_SPACE_ON_RESOURCE(419), 17 | INSUFFICIENT_STORAGE(507), 18 | INTERNAL_SERVER_ERROR(500), 19 | LENGTH_REQUIRED(411), 20 | LOCKED(423), 21 | METHOD_FAILURE(420), 22 | METHOD_NOT_ALLOWED(405), 23 | MOVED_PERMANENTLY(301), 24 | MOVED_TEMPORARILY(302), 25 | MULTI_STATUS(207), 26 | MULTIPLE_CHOICES(300), 27 | NO_CONTENT(204), 28 | NON_AUTHORITATIVE_INFORMATION(203), 29 | NOT_ACCEPTABLE(406), 30 | NOT_FOUND(404), 31 | NOT_IMPLEMENTED(501), 32 | NOT_MODIFIED(304), 33 | OK (200), 34 | PARTIAL_CONTENT(206), 35 | PAYMENT_REQUIRED(402), 36 | PRECONDITION_FAILED(412), 37 | PROCESSING(102), 38 | PROXY_AUTHENTICATION_REQUIRED(407), 39 | REQUEST_TIMEOUT(408), 40 | REQUEST_TOO_LONG(413), 41 | REQUEST_URI_TOO_LONG(414), 42 | REQUESTED_RANGE_NOT_SATISFIABLE(416), 43 | RESET_CONTENT(205), 44 | SEE_OTHER(303), 45 | SERVICE_UNAVAILABLE(503), 46 | SWITCHING_PROTOCOLS(101), 47 | TEMPORARY_REDIRECT(307), 48 | UNAUTHORIZED(401), 49 | UNPROCESSABLE_ENTITY(422), 50 | UNSUPPORTED_MEDIA_TYPE(415), 51 | USE_PROXY(305); 52 | 53 | private final int value; 54 | 55 | private HttpStatus(int value) { 56 | this.value = value; 57 | } 58 | 59 | public int value() { 60 | return value; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /onplan-core/src/main/javascript/thrift/virtual-machine-service_types.js: -------------------------------------------------------------------------------- 1 | // 2 | // Autogenerated by Thrift Compiler (0.9.3) 3 | // 4 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | // 6 | var thrift = require('thrift'); 7 | var Thrift = thrift.Thrift; 8 | var Q = thrift.Q; 9 | 10 | var domain_ttypes = require('./domain_types') 11 | 12 | 13 | var ttypes = module.exports = {}; 14 | if (typeof com === 'undefined') { 15 | com = {}; 16 | } 17 | if (typeof com.onplan === 'undefined') { 18 | com.onplan = {}; 19 | } 20 | if (typeof com.onplan.client === 'undefined') { 21 | com.onplan.client = {}; 22 | } 23 | -------------------------------------------------------------------------------- /onplan-core/src/main/resources/thrift/domain.thrift: -------------------------------------------------------------------------------- 1 | namespace java com.onplan.client.domain 2 | namespace js onplan.client.domain 3 | 4 | struct VirtualMachineInfo { 5 | 1: optional i32 availableProcessors 6 | 2: optional i64 maxMemory 7 | 3: optional i64 totalMemory 8 | 4: optional i64 freeMemory 9 | 5: optional i64 collectionsCount 10 | 6: optional double averageCollectionTime 11 | } 12 | -------------------------------------------------------------------------------- /onplan-core/src/main/resources/thrift/virtual-machine-service.thrift: -------------------------------------------------------------------------------- 1 | namespace java com.onplan.client 2 | namespace js com.onplan.client 3 | 4 | include "domain.thrift" 5 | 6 | service VirtualMachineServiceRemote { 7 | domain.VirtualMachineInfo getVirtualMachineInfo() 8 | } 9 | -------------------------------------------------------------------------------- /onplan-service/src/main/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM java:8 2 | VOLUME /tmp 3 | ADD gs-spring-boot-docker-0.1.0.jar app.jar 4 | RUN bash -c 'touch /app.jar' 5 | ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] 6 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/adviser/AbstractChainedAdviser.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | import com.google.common.collect.Iterables; 5 | import com.onplan.adviser.predicate.AdviserPredicate; 6 | import com.onplan.domain.transitory.PriceTick; 7 | 8 | import java.util.Optional; 9 | 10 | import static com.google.common.base.Preconditions.checkArgument; 11 | import static com.google.common.base.Preconditions.checkNotNull; 12 | import static com.onplan.util.MorePreconditions.checkNotNullOrEmpty; 13 | 14 | /** 15 | * Base class for advisers which are triggered by a satisfied chained list of predicates. 16 | * @param The adviser event type to be dispatched. 17 | */ 18 | public abstract class AbstractChainedAdviser implements Adviser { 19 | protected final String id; 20 | protected final String instrumentId; 21 | protected final Iterable predicatesChain; 22 | protected final AdviserListener adviserListener; 23 | protected final long createdOn; 24 | 25 | protected AbstractChainedAdviser(String id, Iterable predicatesChain, 26 | AdviserListener adviserListener, String instrumentId, long createdOn) { 27 | this.id = checkNotNullOrEmpty(id); 28 | this.instrumentId = checkNotNullOrEmpty(instrumentId); 29 | this.predicatesChain = ImmutableList.copyOf(checkNotNull(predicatesChain)); 30 | this.adviserListener = checkNotNull(adviserListener); 31 | this.createdOn = createdOn; 32 | checkArgument(!Iterables.isEmpty(predicatesChain), "Expected a non empty predicates chain."); 33 | } 34 | 35 | @Override 36 | public void onPriceTick(final PriceTick priceTick) { 37 | checkNotNull(priceTick); 38 | checkArgument(instrumentId.equals(priceTick.getInstrumentId()), String.format( 39 | "Expected instrument id [%s] but price was for [%s]", 40 | instrumentId, 41 | priceTick.getInstrumentId())); 42 | for (AdviserPredicate adviserPredicate : predicatesChain) { 43 | if (!adviserPredicate.apply(priceTick)) { 44 | return; 45 | } 46 | } 47 | Optional adviserEvent = prepareAdviserEvent(priceTick); 48 | if (adviserEvent.isPresent()) { 49 | adviserListener.onEvent(adviserEvent.get()); 50 | } 51 | } 52 | 53 | public String getId() { 54 | return id; 55 | } 56 | 57 | public Iterable getPredicatesChain() { 58 | return predicatesChain; 59 | } 60 | 61 | public long getCreatedOn() { 62 | return createdOn; 63 | } 64 | 65 | public String getInstrumentId() { 66 | return instrumentId; 67 | } 68 | 69 | /** 70 | * Called once the predicates chain has been satisfied. Returns the event to be dispatched 71 | * or an empty optional if other conditions are not satisfied. 72 | * @param priceTick The price tick. 73 | */ 74 | protected abstract Optional prepareAdviserEvent(final PriceTick priceTick); 75 | } 76 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/adviser/AdviserConfigurationFactory.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | import com.onplan.adviser.predicate.AdviserPredicate; 5 | import com.onplan.domain.configuration.AdviserPredicateConfiguration; 6 | import com.onplan.domain.configuration.AlertConfiguration; 7 | 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | public final class AdviserConfigurationFactory { 12 | public static AlertConfiguration createAlertConfiguration( 13 | Class predicateClass, String instrumentId, 14 | Map parameters, String alertMessage, boolean repeat, 15 | long createdOn) { 16 | AdviserPredicateConfiguration predicate = new AdviserPredicateConfiguration(); 17 | predicate.setClassName(predicateClass.getName()); 18 | predicate.setParameters(parameters); 19 | List predicateChain = ImmutableList.of(predicate); 20 | return new AlertConfiguration( 21 | null, 22 | alertMessage, 23 | SeverityLevel.MEDIUM, 24 | instrumentId, 25 | predicateChain, 26 | createdOn, 27 | repeat); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/adviser/AdviserListener.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser; 2 | 3 | public interface AdviserListener { 4 | public void onEvent(T event); 5 | } 6 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/adviser/ScriptingEngineUtils.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | import javax.script.ScriptEngine; 6 | import javax.script.ScriptEngineManager; 7 | 8 | import static com.google.common.base.Preconditions.checkNotNull; 9 | 10 | public final class ScriptingEngineUtils { 11 | private static final Logger LOGGER = Logger.getLogger(ScriptingEngineUtils.class); 12 | 13 | public static final String BINDING_NAME_CONTEXT = "ctx"; 14 | public static final String FUNCTION_INIT = "init"; 15 | public static final String FUNCTION_APPLY = "apply"; 16 | 17 | private static final String JAVASCRIPT_ENGINE_NAME = "nashorn"; 18 | 19 | private static ScriptEngineManager scriptEngineManager; 20 | 21 | public static ScriptEngine createJavaScriptEngine() { 22 | if (null == scriptEngineManager) { 23 | LOGGER.info(String.format("Loading [%s] script engine.", JAVASCRIPT_ENGINE_NAME)); 24 | scriptEngineManager = new ScriptEngineManager(); 25 | } 26 | return checkNotNull( 27 | scriptEngineManager.getEngineByName(JAVASCRIPT_ENGINE_NAME), 28 | String.format("Scripting engine [%s] not found.", JAVASCRIPT_ENGINE_NAME)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/adviser/StrategyConfigurationFactory.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser; 2 | 3 | import com.google.common.collect.ImmutableSet; 4 | import com.onplan.adviser.strategy.Strategy; 5 | import com.onplan.domain.configuration.StrategyConfiguration; 6 | 7 | import java.util.Map; 8 | 9 | public final class StrategyConfigurationFactory { 10 | public static StrategyConfiguration createStrategyConfiguration(Class clazz, 11 | String instrumentId, Map properties) { 12 | StrategyConfiguration strategyConfiguration = new StrategyConfiguration(); 13 | strategyConfiguration.setClassName(clazz.getName()); 14 | strategyConfiguration.setInstruments(ImmutableSet.of(instrumentId)); 15 | strategyConfiguration.setExecutionParameters(properties); 16 | return strategyConfiguration; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/adviser/automatedorder/AutomatedOrder.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser.automatedorder; 2 | 3 | import com.onplan.adviser.AbstractChainedAdviser; 4 | import com.onplan.adviser.AdviserListener; 5 | import com.onplan.adviser.predicate.AdviserPredicate; 6 | import com.onplan.domain.transitory.PriceTick; 7 | 8 | import java.util.Optional; 9 | 10 | // TODO(robertom): Implement hashCode, equals. 11 | public final class AutomatedOrder extends AbstractChainedAdviser { 12 | protected AutomatedOrder(String id, Iterable predicatesChain, 13 | AdviserListener adviserListener, String instrumentId, long createOd) { 14 | super(id, predicatesChain, adviserListener, instrumentId, createOd); 15 | } 16 | 17 | public static Builder newBuilder() { 18 | return new Builder(); 19 | } 20 | 21 | @Override 22 | protected Optional prepareAdviserEvent(PriceTick priceTick) { 23 | throw new IllegalArgumentException("Not yet implemented."); 24 | } 25 | 26 | public static class Builder { 27 | private String id; 28 | private Iterable predicatesChain; 29 | private String instrumentId; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/adviser/predicate/AdviserPredicateUtil.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser.predicate; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | import com.onplan.adviser.AdviserPredicateInfo; 5 | import com.onplan.adviser.TemplateInfo; 6 | import com.onplan.adviser.TemplateMetaData; 7 | 8 | import static com.google.common.base.Preconditions.checkNotNull; 9 | 10 | public final class AdviserPredicateUtil { 11 | public static TemplateInfo createAdviserPredicateTemplateInfo( 12 | Class clazz) { 13 | checkNotNull(clazz); 14 | TemplateMetaData adviserTemplate = clazz.getAnnotation(TemplateMetaData.class); 15 | checkNotNull(adviserTemplate, String.format( 16 | "Adviser predicate [%s] does not implement the annotation [%s].", 17 | clazz.getName(), 18 | TemplateMetaData.class.getName())); 19 | return new TemplateInfo( 20 | adviserTemplate.displayName(), 21 | clazz.getName(), 22 | ImmutableList.copyOf(adviserTemplate.availableParameters())); 23 | } 24 | 25 | public static AdviserPredicateInfo createAdviserPredicateInfo( 26 | final AdviserPredicate adviserPredicate) { 27 | checkNotNull(adviserPredicate); 28 | TemplateInfo templateInfo = createAdviserPredicateTemplateInfo(adviserPredicate.getClass()); 29 | return new AdviserPredicateInfo( 30 | templateInfo.getDisplayName(), 31 | templateInfo.getClassName(), 32 | templateInfo.getAvailableParameters(), 33 | adviserPredicate.getParametersCopy()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/adviser/predicate/priceaction/PriceSpikePredicate.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser.predicate.priceaction; 2 | 3 | import com.onplan.adviser.TemplateMetaData; 4 | import com.onplan.adviser.predicate.AbstractAdviserPredicate; 5 | import com.onplan.adviser.predicate.PredicateExecutionContext; 6 | import com.onplan.domain.PriceBarTimeFrame; 7 | import com.onplan.domain.transitory.PriceTick; 8 | 9 | import static com.onplan.util.PriceBarUtil.*; 10 | 11 | @TemplateMetaData( 12 | displayName = "Price spike", 13 | availableParameters = {PriceSpikePredicate.PROPERTY_MINIMUM_PIPS} 14 | ) 15 | public final class PriceSpikePredicate extends AbstractAdviserPredicate { 16 | public static final String PROPERTY_MINIMUM_PIPS = "minimumPips"; 17 | 18 | private int priceMinimalDecimalPosition; 19 | private double minimumPips; 20 | private long barOpenTimestamp = 0; 21 | private long barCloseTimestamp; 22 | private double openPriceAsk; 23 | private boolean eventDispatched = false; 24 | 25 | public PriceSpikePredicate(PredicateExecutionContext predicateExecutionContext) { 26 | super(predicateExecutionContext); 27 | } 28 | 29 | @Override 30 | public boolean apply(PriceTick priceTick) { 31 | if (barOpenTimestamp <= 0 || priceTick.getTimestamp() > barCloseTimestamp) { 32 | prepareNewBar(priceTick); 33 | return false; 34 | } 35 | final double pipsVariation = getPricePips( 36 | priceTick.getClosePriceAsk() - openPriceAsk, priceMinimalDecimalPosition); 37 | if (pipsVariation >= minimumPips && ! eventDispatched) { 38 | eventDispatched = true; 39 | return true; 40 | } 41 | return false; 42 | } 43 | 44 | @Override 45 | public void init() throws Exception { 46 | minimumPips = getLongValue(PROPERTY_MINIMUM_PIPS).get(); 47 | String instrumentId = predicateExecutionContext.getInstrumentId(); 48 | priceMinimalDecimalPosition = predicateExecutionContext.getInstrumentService() 49 | .getInstrumentInfo(instrumentId).getPriceMinimalDecimalPosition(); 50 | } 51 | 52 | private void prepareNewBar(PriceTick priceTick) { 53 | barOpenTimestamp = 54 | getCurrentBarOpenTimestamp(priceTick.getTimestamp(), PriceBarTimeFrame.MINUTES_1); 55 | barCloseTimestamp = 56 | getCurrentBarCloseTimestamp(priceTick.getTimestamp(), PriceBarTimeFrame.MINUTES_1); 57 | openPriceAsk = priceTick.getClosePriceAsk(); 58 | eventDispatched = false; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/adviser/predicate/pricepattern/CandlestickHammerPredicate.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser.predicate.pricepattern; 2 | 3 | import com.onplan.adviser.TemplateMetaData; 4 | import com.onplan.adviser.predicate.AbstractAdviserPredicate; 5 | import com.onplan.adviser.predicate.PredicateExecutionContext; 6 | import com.onplan.domain.PriceBarTimeFrame; 7 | import com.onplan.domain.transitory.PriceTick; 8 | import com.onplan.util.PriceBarUtil; 9 | 10 | import static com.onplan.util.MorePreconditions.checkNotNullOrEmpty; 11 | 12 | @TemplateMetaData( 13 | displayName = "Candlestick hammer", 14 | availableParameters = { 15 | CandlestickHammerPredicate.PROPERTY_TIME_FRAME, 16 | CandlestickHammerPredicate.PROPERTY_MINIMUM_CANDLE_SIZE 17 | } 18 | ) 19 | public final class CandlestickHammerPredicate extends AbstractAdviserPredicate { 20 | public static final String PROPERTY_TIME_FRAME = "timeFrame"; 21 | public static final String PROPERTY_MINIMUM_CANDLE_SIZE = "minimumCandleSize"; 22 | 23 | private PriceBarTimeFrame priceBarTimeFrame; 24 | private long barEndTimestamp = -1; 25 | private double openPrice; 26 | private double closePrice; 27 | private double highPrice; 28 | private double lowPrice; 29 | private boolean isFirstBar = true; 30 | private double minimumCandleSize; 31 | 32 | public CandlestickHammerPredicate(PredicateExecutionContext predicateExecutionContext) { 33 | super(predicateExecutionContext); 34 | } 35 | 36 | @Override 37 | public boolean apply(PriceTick priceTick) { 38 | if (priceTick.getTimestamp() > barEndTimestamp) { 39 | if (isFirstBar) { 40 | if (barEndTimestamp > 0) { 41 | isFirstBar = false; 42 | } 43 | } else if(isHammerPattern(openPrice, closePrice, highPrice, lowPrice)) { 44 | return true; 45 | } 46 | prepareNewBar(priceTick); 47 | } 48 | updateBarValues(priceTick); 49 | return false; 50 | } 51 | 52 | @Override 53 | public void init() throws Exception { 54 | String priceBarTimeFrameText = checkNotNullOrEmpty(getParameterValue(PROPERTY_TIME_FRAME)); 55 | priceBarTimeFrame = PriceBarTimeFrame.parseString(priceBarTimeFrameText); 56 | minimumCandleSize = getDoubleValue(PROPERTY_MINIMUM_CANDLE_SIZE).get(); 57 | } 58 | 59 | private boolean isHammerPattern( 60 | double openPrice, double closePrice, double highPrice, double lowPrice) { 61 | if (Math.abs(highPrice - lowPrice) < minimumCandleSize) { 62 | return false; 63 | } 64 | // Open and close must be in the upper or lower 2/5 of the bar. 65 | double offset = Math.abs(highPrice - lowPrice) * 0.4; 66 | double upperLimit = highPrice - offset; 67 | double lowerLimit = lowPrice + offset; 68 | return (openPrice > upperLimit && closePrice > upperLimit) || 69 | (openPrice < lowerLimit && closePrice < lowerLimit); 70 | } 71 | 72 | private void updateBarValues(PriceTick priceTick) { 73 | closePrice = priceTick.getClosePriceAsk(); 74 | if (priceTick.getClosePriceAsk() > highPrice) { 75 | highPrice = priceTick.getClosePriceAsk(); 76 | } else if (priceTick.getClosePriceAsk() < lowPrice) { 77 | lowPrice = priceTick.getClosePriceAsk(); 78 | } 79 | } 80 | 81 | private void prepareNewBar(PriceTick priceTick) { 82 | openPrice = priceTick.getClosePriceAsk(); 83 | closePrice = priceTick.getClosePriceAsk(); 84 | highPrice = priceTick.getClosePriceAsk(); 85 | lowPrice = priceTick.getClosePriceAsk(); 86 | barEndTimestamp = 87 | PriceBarUtil.getNextBarOpenTimestamp(priceTick.getTimestamp(), priceBarTimeFrame); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/adviser/predicate/scripting/JavaScripPredicate.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser.predicate.scripting; 2 | 3 | import com.onplan.adviser.TemplateMetaData; 4 | import com.onplan.adviser.predicate.AbstractAdviserPredicate; 5 | import com.onplan.adviser.predicate.PredicateExecutionContext; 6 | import com.onplan.domain.transitory.PriceTick; 7 | 8 | import javax.script.Invocable; 9 | import javax.script.ScriptContext; 10 | import javax.script.ScriptEngine; 11 | import javax.script.ScriptException; 12 | 13 | import static com.google.common.base.Preconditions.checkNotNull; 14 | import static com.onplan.adviser.ScriptingEngineUtils.*; 15 | 16 | @TemplateMetaData( 17 | displayName = "JavaScript predicate", 18 | availableParameters = {JavaScripPredicate.PARAMETER_JAVASCRIPT_EXPRESSION}) 19 | public class JavaScripPredicate extends AbstractAdviserPredicate { 20 | public static final String PARAMETER_JAVASCRIPT_EXPRESSION = "javascriptExpression"; 21 | 22 | private Invocable scriptEngine; 23 | private String javaScripExpression; 24 | 25 | public JavaScripPredicate(PredicateExecutionContext predicateExecutionContext) { 26 | super(predicateExecutionContext); 27 | } 28 | 29 | @Override 30 | public boolean apply(final PriceTick priceTick) { 31 | Object result = null; 32 | try { 33 | result = scriptEngine.invokeFunction(FUNCTION_APPLY, priceTick); 34 | } catch (Exception e) { 35 | // TODO(robertom): I think you can do better than this. 36 | throw new IllegalArgumentException(e); 37 | } 38 | return null != result && result.equals(true); 39 | } 40 | 41 | @Override 42 | public void init() throws Exception { 43 | javaScripExpression = checkNotNull(getParameterValue(PARAMETER_JAVASCRIPT_EXPRESSION)); 44 | ScriptEngine engine = createJavaScriptEngine(); 45 | /* 46 | * TODO(robertom): Wrap PredicateExecutionContext in a JavaScriptPredicateExecutionContext and 47 | * reintroduce PredicateExecutionContext.newBuilder(). 48 | */ 49 | engine.getContext().getBindings(ScriptContext.ENGINE_SCOPE) 50 | .put(BINDING_NAME_CONTEXT, predicateExecutionContext); 51 | try { 52 | engine.eval(javaScripExpression); 53 | } catch (Exception e) { 54 | throw new Exception( 55 | String.format("Error [%s] while parsing javascript expression [%s].", 56 | e.getMessage(), 57 | javaScripExpression), 58 | e); 59 | } 60 | this.scriptEngine = (Invocable) engine; 61 | try { 62 | scriptEngine.invokeFunction(FUNCTION_INIT); 63 | } catch (NoSuchMethodException e) { 64 | // Intentionally empty. 65 | } catch (ScriptException e) { 66 | throw new Exception( 67 | String.format("Error [%s] while calling initializing script with init().", 68 | e.getMessage()), 69 | e); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/adviser/strategy/StrategyUtil.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser.strategy; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | import com.onplan.adviser.StrategyInfo; 5 | import com.onplan.adviser.TemplateInfo; 6 | import com.onplan.adviser.TemplateMetaData; 7 | 8 | import static com.google.common.base.Preconditions.checkNotNull; 9 | 10 | public final class StrategyUtil { 11 | public static TemplateInfo getTemplateInfo(Class clazz) { 12 | TemplateMetaData templateMetaData = clazz.getAnnotation(TemplateMetaData.class); 13 | checkNotNull(templateMetaData, String.format( 14 | "Strategy [%s] does not implement the annotation [%s].", 15 | clazz.getName(), 16 | TemplateMetaData.class.getName())); 17 | return new TemplateInfo( 18 | templateMetaData.displayName(), 19 | clazz.getName(), 20 | ImmutableList.copyOf(templateMetaData.availableParameters())); 21 | } 22 | 23 | public static String getTemplateId(Class clazz) { 24 | return getTemplateInfo(clazz).getClassName(); 25 | } 26 | 27 | public static StrategyInfo getStrategyInfo(final Strategy strategy) { 28 | TemplateInfo templateInfo = getTemplateInfo(strategy.getClass()); 29 | return new StrategyInfo( 30 | templateInfo.getDisplayName(), 31 | templateInfo.getClassName(), 32 | templateInfo.getAvailableParameters(), 33 | strategy.getId(), 34 | strategy.getParametersCopy(), 35 | strategy.getRegisteredInstruments(), 36 | strategy.getStrategyStatisticsSnapshot()); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/adviser/strategy/scripting/JavaScriptStrategy.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser.strategy.scripting; 2 | 3 | import com.onplan.adviser.TemplateMetaData; 4 | import com.onplan.adviser.strategy.AbstractStrategy; 5 | import com.onplan.adviser.strategy.StrategyExecutionContext; 6 | import com.onplan.domain.transitory.PriceTick; 7 | 8 | import javax.script.Invocable; 9 | import javax.script.ScriptContext; 10 | import javax.script.ScriptEngine; 11 | import javax.script.ScriptException; 12 | 13 | import static com.google.common.base.Preconditions.checkNotNull; 14 | import static com.onplan.adviser.ScriptingEngineUtils.*; 15 | 16 | @TemplateMetaData( 17 | displayName = "JavaScript strategy", 18 | availableParameters = {JavaScriptStrategy.PARAMETER_JAVASCRIPT_EXPRESSION}) 19 | public class JavaScriptStrategy extends AbstractStrategy { 20 | public static final String PARAMETER_JAVASCRIPT_EXPRESSION = "javascriptExpression"; 21 | 22 | private Invocable scriptEngine; 23 | private String javaScripExpression; 24 | 25 | public JavaScriptStrategy(StrategyExecutionContext strategyExecutionContext) { 26 | super(strategyExecutionContext); 27 | } 28 | 29 | @Override 30 | public void init() throws Exception { 31 | javaScripExpression = checkNotNull(getParameterValue(PARAMETER_JAVASCRIPT_EXPRESSION)); 32 | ScriptEngine engine = createJavaScriptEngine(); 33 | /* 34 | * TODO(robertom): Wrap StrategyExecutionContext in a JavaScriptStrategyExecutionContext, 35 | * and reintroduce PredicateExecutionContext.newBuilder(). 36 | */ 37 | engine.getContext().getBindings(ScriptContext.ENGINE_SCOPE) 38 | .put(BINDING_NAME_CONTEXT, strategyExecutionContext); 39 | try { 40 | engine.eval(javaScripExpression); 41 | } catch (Exception e) { 42 | throw new Exception( 43 | String.format("Error [%s] while parsing javascript expression [%s].", 44 | e.getMessage(), 45 | javaScripExpression), 46 | e); 47 | } 48 | this.scriptEngine = (Invocable) engine; 49 | try { 50 | scriptEngine.invokeFunction(FUNCTION_INIT); 51 | } catch (NoSuchMethodException e) { 52 | // Intentionally empty. 53 | } catch (ScriptException e) { 54 | throw new Exception( 55 | String.format("Error [%s] while calling initializing script with init().", 56 | e.getMessage()), 57 | e); 58 | } 59 | } 60 | 61 | @Override 62 | public void onPriceTick(PriceTick priceTick) { 63 | try { 64 | scriptEngine.invokeFunction(FUNCTION_APPLY, priceTick); 65 | } catch (Exception e) { 66 | // TODO(robertom): Exceptions need to be managed. 67 | throw new IllegalArgumentException(e); 68 | } 69 | // TODO(robertom): Update statistics. 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/adviser/strategy/system/IntegrationTestStrategy.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser.strategy.system; 2 | 3 | import com.onplan.adviser.TemplateMetaData; 4 | import com.onplan.adviser.SeverityLevel; 5 | import com.onplan.adviser.strategy.AbstractStrategy; 6 | import com.onplan.adviser.strategy.StrategyExecutionContext; 7 | import com.onplan.domain.transitory.PriceTick; 8 | import org.joda.time.DateTime; 9 | import org.joda.time.DateTimeZone; 10 | 11 | @TemplateMetaData(displayName = "Integration test") 12 | public final class IntegrationTestStrategy extends AbstractStrategy { 13 | private int lastFiredOn = 0; 14 | 15 | public IntegrationTestStrategy(StrategyExecutionContext strategyExecutionContext) { 16 | super(strategyExecutionContext); 17 | } 18 | 19 | @Override 20 | public void onPriceTick(PriceTick priceTick) { 21 | int dayOfMonth = DateTime.now(DateTimeZone.UTC).getDayOfMonth(); 22 | if (lastFiredOn != dayOfMonth) { 23 | String message = String.format("Ping from integration test! Price [%s].", priceTick); 24 | dispatchAlertEvent(SeverityLevel.LOW, message, priceTick); 25 | lastFiredOn = dayOfMonth; 26 | updateStatistics(priceTick, true); 27 | } else { 28 | updateStatistics(priceTick, false); 29 | } 30 | } 31 | 32 | @Override 33 | public void init() throws Exception { 34 | // Intentionally empty. 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/notification/AmazonSQSNotificationChannel.java: -------------------------------------------------------------------------------- 1 | package com.onplan.notification; 2 | 3 | import com.amazonaws.auth.AWSCredentials; 4 | import com.amazonaws.auth.BasicAWSCredentials; 5 | import com.amazonaws.services.sqs.AmazonSQS; 6 | import com.amazonaws.services.sqs.AmazonSQSClient; 7 | import com.onplan.adviser.alert.AlertEvent; 8 | import com.onplan.service.SystemEvent; 9 | import org.apache.log4j.Logger; 10 | 11 | import javax.inject.Inject; 12 | import javax.inject.Named; 13 | import javax.inject.Singleton; 14 | 15 | import static com.google.common.base.Preconditions.checkNotNull; 16 | import static com.onplan.util.JsonUtils.createJson; 17 | import static com.onplan.util.MorePreconditions.checkNotNullOrEmpty; 18 | 19 | @Singleton 20 | public final class AmazonSQSNotificationChannel implements NotificationChannel { 21 | private static final Logger LOGGER = Logger.getLogger(AmazonSQSNotificationChannel.class); 22 | 23 | private final AmazonSQS sqsClient; 24 | private final String alertEventQueueUrl; 25 | private final String systemEventQueueUrl; 26 | 27 | @Inject 28 | public AmazonSQSNotificationChannel( 29 | @Named("amazonaws.accesskeyid") String accessKeyId, 30 | @Named("amazonaws.secretaccesskey") String secretAccessKey, 31 | @Named("notification.amazonsqs.alertEventQueueUrl") String alertEventQueueUrl, 32 | @Named("notification.amazonsqs.systemEventQueueUrl") String systemEventQueueUrl) { 33 | checkNotNullOrEmpty(accessKeyId); 34 | checkNotNullOrEmpty(secretAccessKey); 35 | // TODO(robertom): Encrypt passwords with something like ProfileCredentialsProvider 36 | AWSCredentials awsCredentials = new BasicAWSCredentials(accessKeyId, secretAccessKey); 37 | this.sqsClient = new AmazonSQSClient(awsCredentials); 38 | this.alertEventQueueUrl = checkNotNullOrEmpty(alertEventQueueUrl); 39 | this.systemEventQueueUrl = checkNotNullOrEmpty(systemEventQueueUrl); 40 | } 41 | 42 | @Override 43 | public void notifySystemEvent(final SystemEvent systemEvent) throws Exception { 44 | checkNotNull(systemEvent); 45 | LOGGER.info(String.format("Sending system event to Amazon SQS [%s] [%s].", 46 | systemEvent.getClassName(), systemEvent.getMessage())); 47 | sqsClient.sendMessage(systemEventQueueUrl, createJson(systemEvent)); 48 | } 49 | 50 | @Override 51 | public void notifyAlertEvent(final AlertEvent alertEvent) throws Exception { 52 | checkNotNull(alertEvent); 53 | LOGGER.info(String.format( 54 | "Sending alert event to Amazon SQS with message [%s].", alertEvent.getMessage())); 55 | sqsClient.sendMessage(alertEventQueueUrl, createJson(alertEvent)); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/notification/MongoDbNotificationChannel.java: -------------------------------------------------------------------------------- 1 | package com.onplan.notification; 2 | 3 | import com.onplan.adviser.alert.AlertEvent; 4 | import com.onplan.domain.persistent.AlertEventHistory; 5 | import com.onplan.domain.persistent.SystemEventHistory; 6 | import com.onplan.persistence.AlertEventHistoryDao; 7 | import com.onplan.persistence.SystemEventHistoryDao; 8 | import com.onplan.service.SystemEvent; 9 | 10 | import javax.inject.Inject; 11 | import javax.inject.Singleton; 12 | 13 | import static com.google.common.base.Preconditions.checkNotNull; 14 | 15 | /** 16 | * A notification channel which persists the events in the MongoDB database. 17 | */ 18 | @Singleton 19 | public class MongoDbNotificationChannel implements NotificationChannel { 20 | @Inject 21 | private AlertEventHistoryDao alertEventHistoryDao; 22 | 23 | @Inject 24 | private SystemEventHistoryDao systemEventHistoryDao; 25 | 26 | @Override 27 | public void notifySystemEvent(final SystemEvent systemEvent) throws Exception { 28 | checkNotNull(systemEvent); 29 | SystemEventHistory systemEventHistory = new SystemEventHistory( 30 | null, 31 | systemEvent.getClassName(), 32 | systemEvent.getMessage(), 33 | systemEvent.getCreatedOn()); 34 | systemEventHistoryDao.insert(systemEventHistory); 35 | } 36 | 37 | @Override 38 | public void notifyAlertEvent(final AlertEvent alertEvent) throws Exception { 39 | checkNotNull(alertEvent); 40 | AlertEventHistory alertEventHistory = new AlertEventHistory( 41 | null, 42 | alertEvent.getAdviserId(), 43 | alertEvent.getSeverityLevel(), 44 | alertEvent.getPriceTick(), 45 | alertEvent.getCreatedOn(), 46 | alertEvent.getMessage()); 47 | alertEventHistoryDao.insert(alertEventHistory); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/notification/NotificationChannel.java: -------------------------------------------------------------------------------- 1 | package com.onplan.notification; 2 | 3 | import com.onplan.adviser.alert.AlertEvent; 4 | import com.onplan.service.SystemEvent; 5 | 6 | /** 7 | * Common interface for events notification media. 8 | */ 9 | public interface NotificationChannel { 10 | /** 11 | * Notifies a {@link com.onplan.domain.persistent.SystemEventHistory}. 12 | * 13 | * @param systemEvent The system event to be notified. 14 | * @throws Exception Error while notifying the event. 15 | */ 16 | public void notifySystemEvent(final SystemEvent systemEvent) throws Exception; 17 | 18 | /** 19 | * Notifies a {@link com.onplan.domain.persistent.AlertEventHistory}. 20 | * 21 | * @param alertEvent The alert event to be notified. 22 | * @throws Exception Error while notifying the event. 23 | */ 24 | public void notifyAlertEvent(final AlertEvent alertEvent) throws Exception; 25 | } 26 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/notification/SmtpNotificationChannel.java: -------------------------------------------------------------------------------- 1 | package com.onplan.notification; 2 | 3 | import com.onplan.adviser.alert.AlertEvent; 4 | import com.onplan.service.SystemEvent; 5 | import org.apache.commons.mail.Email; 6 | import org.apache.commons.mail.EmailException; 7 | import org.apache.commons.mail.SimpleEmail; 8 | import org.apache.log4j.Logger; 9 | 10 | import javax.inject.Inject; 11 | import javax.inject.Named; 12 | import javax.inject.Singleton; 13 | 14 | import static com.google.common.base.Preconditions.checkNotNull; 15 | import static com.onplan.util.MorePreconditions.checkNotNullOrEmpty; 16 | 17 | @Singleton 18 | public final class SmtpNotificationChannel implements NotificationChannel { 19 | private static final Logger LOGGER = Logger.getLogger(SmtpNotificationChannel.class); 20 | 21 | private final String host; 22 | private final String username; 23 | private final String password; 24 | private final int port; 25 | private final boolean useSsl; 26 | private final String from; 27 | private final String to; 28 | 29 | @Inject 30 | public SmtpNotificationChannel( 31 | @Named("smtp.host") String host, 32 | @Named("smtp.username") String username, 33 | @Named("smtp.password") String password, 34 | @Named("smtp.port") String port, 35 | @Named("smtp.useSsl") String useSsl, 36 | @Named("notification.smtp.from") String from, 37 | @Named("notification.smtp.to") String to) { 38 | this.host = checkNotNullOrEmpty(host); 39 | this.username = checkNotNullOrEmpty(username); 40 | this.password = checkNotNullOrEmpty(password); 41 | this.port = Integer.valueOf(port); 42 | this.useSsl = Boolean.valueOf(useSsl); 43 | this.from = checkNotNullOrEmpty(from); 44 | this.to = checkNotNullOrEmpty(to); 45 | } 46 | 47 | @Override 48 | public void notifySystemEvent(final SystemEvent systemEvent) throws Exception { 49 | checkNotNull(systemEvent); 50 | LOGGER.info(String.format( 51 | "Sending system event email (SMTP) notification to [%s]. Subject: [%s]", 52 | to, 53 | systemEvent.getClassName())); 54 | createEmail(systemEvent.getClassName(), systemEvent.getMessage()).send(); 55 | } 56 | 57 | @Override 58 | public void notifyAlertEvent(final AlertEvent alertEvent) throws Exception { 59 | checkNotNull(alertEvent); 60 | String title = String.format( 61 | "[%s] alert, severity: [%s]", 62 | alertEvent.getPriceTick().getInstrumentId(), 63 | alertEvent.getSeverityLevel()); 64 | String message = alertEvent.getMessage(); 65 | LOGGER.info( 66 | String.format("Sending alert event email (SMTP) to [%s]. Subject: [%s]", to, title)); 67 | createEmail(title, message).send(); 68 | } 69 | 70 | private Email createEmail(final String title, final String body) throws EmailException { 71 | Email email = new SimpleEmail(); 72 | email.setHostName(host); 73 | email.setAuthentication(username, password); 74 | email.setSmtpPort(port); 75 | email.setSSLOnConnect(useSsl); 76 | email.setFrom(checkNotNullOrEmpty(from)); 77 | email.addTo(checkNotNullOrEmpty(to)); 78 | email.setSubject(title); 79 | email.setMsg(body); 80 | return email; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/notification/TwitterNotificationChannel.java: -------------------------------------------------------------------------------- 1 | package com.onplan.notification; 2 | 3 | import com.onplan.adviser.alert.AlertEvent; 4 | import com.onplan.service.SystemEvent; 5 | import com.onplan.util.StringUtils; 6 | import org.apache.log4j.Logger; 7 | import twitter4j.Twitter; 8 | import twitter4j.TwitterException; 9 | import twitter4j.TwitterFactory; 10 | 11 | import javax.inject.Inject; 12 | import javax.inject.Named; 13 | import javax.inject.Singleton; 14 | 15 | import static com.google.common.base.Preconditions.checkNotNull; 16 | import static com.onplan.util.MorePreconditions.checkNotNullOrEmpty; 17 | 18 | @Singleton 19 | public final class TwitterNotificationChannel implements NotificationChannel { 20 | private static final Logger LOGGER = Logger.getLogger(TwitterNotificationChannel.class); 21 | private static final int MESSAGE_MAX_LENGTH = 140; 22 | private static final String MESSAGE_TRIMMED_SUFFIX = ".."; 23 | 24 | private final Twitter twitterClient = TwitterFactory.getSingleton(); 25 | private final String recipientScreenName; 26 | 27 | @Inject 28 | public TwitterNotificationChannel( 29 | @Named("notification.twitter.recipientScreeName") String recipientScreenName) { 30 | this.recipientScreenName = checkNotNullOrEmpty(recipientScreenName); 31 | } 32 | 33 | private void sendDirectMessage(String destinationRecipientScreenName, String message) 34 | throws Exception { 35 | try { 36 | twitterClient.sendDirectMessage( 37 | destinationRecipientScreenName, 38 | StringUtils.trimText(message, MESSAGE_MAX_LENGTH, MESSAGE_TRIMMED_SUFFIX)); 39 | } catch (TwitterException e) { 40 | LOGGER.error(String.format( 41 | "Error while sending Twitter notification to recipient [%s]: [%s].", 42 | destinationRecipientScreenName, 43 | e.getMessage())); 44 | throw new Exception(e); 45 | } 46 | } 47 | 48 | @Override 49 | public void notifySystemEvent(SystemEvent systemEvent) throws Exception { 50 | checkNotNull(systemEvent); 51 | String message = String.format( 52 | "[%s]: [%s] severity: [%s]", 53 | systemEvent.getClassName(), 54 | systemEvent.getMessage()); 55 | LOGGER.info(String.format( 56 | "Sending system event Twitter notification to recipient [%s]: [%s]", 57 | recipientScreenName, 58 | message)); 59 | sendDirectMessage(recipientScreenName, message); 60 | } 61 | 62 | @Override 63 | public void notifyAlertEvent(AlertEvent alertEvent) throws Exception { 64 | checkNotNull(alertEvent); 65 | String message = String.format( 66 | "[%s]: [%s] severity: [%s]", 67 | alertEvent.getPriceTick().getInstrumentId(), 68 | alertEvent.getMessage(), 69 | alertEvent.getSeverityLevel()); 70 | LOGGER.info(String.format( 71 | "Sending alert event Twitter notification to recipient [%s]: [%s]", 72 | recipientScreenName, 73 | message)); 74 | sendDirectMessage(recipientScreenName, message); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/persistence/AlertConfigurationDao.java: -------------------------------------------------------------------------------- 1 | package com.onplan.persistence; 2 | 3 | import com.onplan.domain.configuration.AlertConfiguration; 4 | 5 | import java.util.List; 6 | 7 | public interface AlertConfigurationDao extends GenericDao { 8 | public List getSampleAlertsConfiguration(); 9 | } 10 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/persistence/AlertEventHistoryDao.java: -------------------------------------------------------------------------------- 1 | package com.onplan.persistence; 2 | 3 | import com.onplan.domain.persistent.AlertEventHistory; 4 | 5 | public interface AlertEventHistoryDao extends GenericDao { 6 | } 7 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/persistence/GenericDao.java: -------------------------------------------------------------------------------- 1 | package com.onplan.persistence; 2 | 3 | import com.onplan.domain.persistent.PersistentObject; 4 | 5 | import java.util.Collection; 6 | import java.util.List; 7 | 8 | public interface GenericDao { 9 | /** 10 | * Saves an object , making sure that its id is not already set. 11 | * Returns the object id. 12 | * 13 | * @param object The object to be saved. 14 | * @exception java.lang.Exception Error while inserting object. 15 | */ 16 | public String insert(T object) throws Exception; 17 | 18 | /** 19 | * Inserts a collection of object, making sure that their id are not already set. 20 | * 21 | * @param objects The collection of objects. 22 | * @exception java.lang.Exception Error while inserting objects. 23 | */ 24 | public void insertAll(Collection objects) throws Exception; 25 | 26 | /** 27 | * Inserts an object when its id is not already set otherwise updates the object from the 28 | * database. Returns the object id. 29 | * 30 | * @param object The object to be inserted or updated. 31 | * @exception java.lang.Exception Error while saving objects. 32 | */ 33 | public String save(T object) throws Exception; 34 | 35 | /** 36 | * Inserts or updates an object and returns the saved object. 37 | * 38 | * @param object The object to be inserted or updated. 39 | * @exception java.lang.Exception Error while saving objects. 40 | */ 41 | public T saveAndGet(T object) throws Exception; 42 | 43 | /** 44 | * Remove an object from the database. Returns true if the object was found, false otherwise. 45 | * 46 | * @param object The object to be removed. 47 | */ 48 | public boolean remove(T object); 49 | 50 | /** 51 | * Removes an object from the database by its id. Returns true if the object was found, 52 | * false otherwise. 53 | * 54 | * @param id The object id. 55 | */ 56 | public boolean removeById(String id); 57 | 58 | /** 59 | * Removes all the object which are stored in the current collection. 60 | */ 61 | public void removeAll(); 62 | 63 | /** 64 | * Returns an object by its id. 65 | * 66 | * @param id The object id. 67 | */ 68 | public T findById(String id); 69 | 70 | /** 71 | * Returns all the objects saved in the current collection. 72 | */ 73 | public List findAll(); 74 | } 75 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/persistence/StrategyConfigurationDao.java: -------------------------------------------------------------------------------- 1 | package com.onplan.persistence; 2 | 3 | import com.onplan.domain.configuration.StrategyConfiguration; 4 | 5 | import java.util.List; 6 | 7 | public interface StrategyConfigurationDao extends GenericDao { 8 | public List getSampleStrategiesConfiguration(); 9 | } 10 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/persistence/SystemEventHistoryDao.java: -------------------------------------------------------------------------------- 1 | package com.onplan.persistence; 2 | 3 | import com.onplan.domain.persistent.SystemEventHistory; 4 | 5 | public interface SystemEventHistoryDao extends GenericDao { 6 | } 7 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/persistence/mongodb/MongoDbAlertConfigurationDao.java: -------------------------------------------------------------------------------- 1 | package com.onplan.persistence.mongodb; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | import com.google.common.collect.ImmutableMap; 5 | import com.onplan.adviser.predicate.priceaction.PriceSpikePredicate; 6 | import com.onplan.adviser.predicate.pricepattern.CandlestickHammerPredicate; 7 | import com.onplan.domain.configuration.AlertConfiguration; 8 | import com.onplan.persistence.AlertConfigurationDao; 9 | import org.joda.time.DateTime; 10 | 11 | import javax.inject.Singleton; 12 | import java.util.List; 13 | 14 | import static com.onplan.adviser.AdviserConfigurationFactory.createAlertConfiguration; 15 | 16 | @Singleton 17 | public final class MongoDbAlertConfigurationDao extends AbstractMongoDbDao 18 | implements AlertConfigurationDao { 19 | private static final String ALERT_CONFIGURATION_COLLECTION = "alertConfiguration"; 20 | 21 | public MongoDbAlertConfigurationDao() { 22 | super(ALERT_CONFIGURATION_COLLECTION, AlertConfiguration.class); 23 | } 24 | 25 | // TODO(robertom): Load the sample alerts from JSON file. 26 | @Override 27 | public List getSampleAlertsConfiguration() { 28 | ImmutableList.Builder builder = ImmutableList.builder(); 29 | builder.add(createAlertConfiguration( 30 | PriceSpikePredicate.class, 31 | "CS.EURUSD.TODAY", 32 | ImmutableMap.of(PriceSpikePredicate.PROPERTY_MINIMUM_PIPS, "15"), 33 | "Price spike > 15 pips.", 34 | true, 35 | DateTime.now().getMillis())); 36 | builder.add(createAlertConfiguration( 37 | PriceSpikePredicate.class, 38 | "CS.AUDUSD.TODAY", 39 | ImmutableMap.of(PriceSpikePredicate.PROPERTY_MINIMUM_PIPS, "15"), 40 | "Price spike > 15 pips.", 41 | true, 42 | DateTime.now().getMillis())); 43 | builder.add(createAlertConfiguration( 44 | PriceSpikePredicate.class, 45 | "IX.DAX.DAILY", 46 | ImmutableMap.of(PriceSpikePredicate.PROPERTY_MINIMUM_PIPS, "15"), 47 | "Price spike > 15 pips.", 48 | true, 49 | DateTime.now().getMillis())); 50 | builder.add(createAlertConfiguration( 51 | CandlestickHammerPredicate.class, 52 | "IX.DAX.DAILY", 53 | ImmutableMap.of( 54 | CandlestickHammerPredicate.PROPERTY_TIME_FRAME, "MINUTES_15", 55 | CandlestickHammerPredicate.PROPERTY_MINIMUM_CANDLE_SIZE, "10"), 56 | "Candlestick hammer.", 57 | true, 58 | DateTime.now().getMillis())); 59 | builder.add(createAlertConfiguration( 60 | CandlestickHammerPredicate.class, 61 | "IX.FTSE.DAILY", 62 | ImmutableMap.of( 63 | CandlestickHammerPredicate.PROPERTY_TIME_FRAME, "MINUTES_15", 64 | CandlestickHammerPredicate.PROPERTY_MINIMUM_CANDLE_SIZE, "8"), 65 | "Candlestick hammer.", 66 | true, 67 | DateTime.now().getMillis())); 68 | builder.add(createAlertConfiguration( 69 | CandlestickHammerPredicate.class, 70 | "IX.DAX.DAILY", 71 | ImmutableMap.of( 72 | CandlestickHammerPredicate.PROPERTY_TIME_FRAME, "MINUTES_5", 73 | CandlestickHammerPredicate.PROPERTY_MINIMUM_CANDLE_SIZE, "8"), 74 | "Candlestick hammer.", 75 | true, 76 | DateTime.now().getMillis())); 77 | builder.add(createAlertConfiguration( 78 | CandlestickHammerPredicate.class, 79 | "IX.FTSE.DAILY", 80 | ImmutableMap.of( 81 | CandlestickHammerPredicate.PROPERTY_TIME_FRAME, "MINUTES_5", 82 | CandlestickHammerPredicate.PROPERTY_MINIMUM_CANDLE_SIZE, "6"), 83 | "Candlestick hammer.", 84 | true, 85 | DateTime.now().getMillis())); 86 | return builder.build(); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/persistence/mongodb/MongoDbAlertEventDao.java: -------------------------------------------------------------------------------- 1 | package com.onplan.persistence.mongodb; 2 | 3 | import com.onplan.domain.persistent.AlertEventHistory; 4 | import com.onplan.persistence.AlertEventHistoryDao; 5 | 6 | import javax.inject.Singleton; 7 | 8 | @Singleton 9 | public final class MongoDbAlertEventDao extends AbstractMongoDbDao 10 | implements AlertEventHistoryDao { 11 | private static final String ALERT_EVENT_COLLECTION = "alertEvent"; 12 | 13 | public MongoDbAlertEventDao() { 14 | super(ALERT_EVENT_COLLECTION, AlertEventHistory.class); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/persistence/mongodb/MongoDbConnection.java: -------------------------------------------------------------------------------- 1 | package com.onplan.persistence.mongodb; 2 | 3 | import com.google.common.base.Joiner; 4 | import com.mongodb.DB; 5 | import com.mongodb.MongoClient; 6 | import org.apache.log4j.Logger; 7 | 8 | import javax.inject.Inject; 9 | import javax.inject.Named; 10 | import javax.inject.Singleton; 11 | import java.net.UnknownHostException; 12 | 13 | import static com.google.common.base.Preconditions.checkNotNull; 14 | 15 | @Singleton 16 | public final class MongoDbConnection { 17 | private static final Logger LOGGER = Logger.getLogger(MongoDbConnection.class); 18 | 19 | @Inject 20 | @Named("mongodb.database") 21 | private String databaseName; 22 | 23 | @Inject 24 | @Named("mongodb.host") 25 | private String hostName; 26 | 27 | @Inject 28 | @Named("mongodb.port") 29 | private String portNumber; 30 | 31 | private DB database = null; 32 | 33 | public DB getDatabase() { 34 | if (null == database) { 35 | try { 36 | LOGGER.info(String.format("Connecting to MongoDd at [%s]:[%s].", hostName, portNumber)); 37 | MongoClient mongoClient = new MongoClient(hostName, Integer.parseInt(portNumber)); 38 | database = checkNotNull(mongoClient.getDB(databaseName)); 39 | LOGGER.info(String.format( 40 | "MongoDb initialized, available collections [%s].", 41 | Joiner.on(", ").join(database.getCollectionNames()))); 42 | } catch (UnknownHostException e) { 43 | LOGGER.error( 44 | String.format("Error while connecting to MongoDB at [%s]:[%s].", hostName, portNumber), 45 | e); 46 | throw new IllegalArgumentException(e); 47 | } 48 | } 49 | return database; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/persistence/mongodb/MongoDbPropertyNamingStrategy.java: -------------------------------------------------------------------------------- 1 | package com.onplan.persistence.mongodb; 2 | 3 | import com.fasterxml.jackson.databind.PropertyNamingStrategy; 4 | import com.fasterxml.jackson.databind.cfg.MapperConfig; 5 | import com.fasterxml.jackson.databind.introspect.AnnotatedField; 6 | import com.fasterxml.jackson.databind.introspect.AnnotatedMethod; 7 | 8 | /** 9 | * Renames the object id field to make it MongoDb compatible during the JSON transformation. 10 | */ 11 | public final class MongoDbPropertyNamingStrategy extends PropertyNamingStrategy { 12 | private static final String OBJECT_ID_FIELD_NAME = "id"; 13 | private static final String MONGO_ID_FIELD_NAME = "_id"; 14 | 15 | private static MongoDbPropertyNamingStrategy instance; 16 | 17 | private MongoDbPropertyNamingStrategy() { 18 | // Intentionally emtpy. 19 | } 20 | 21 | public static MongoDbPropertyNamingStrategy getInstance() { 22 | if (null == instance) { 23 | instance = new MongoDbPropertyNamingStrategy(); 24 | } 25 | return instance; 26 | } 27 | 28 | @Override 29 | public String nameForField(MapperConfig config, AnnotatedField field, String defaultName) { 30 | return OBJECT_ID_FIELD_NAME.equals(defaultName) 31 | ? MONGO_ID_FIELD_NAME 32 | : super.nameForField(config, field, defaultName); 33 | } 34 | 35 | @Override 36 | public String nameForSetterMethod( 37 | MapperConfig config, AnnotatedMethod method, String defaultName) { 38 | return OBJECT_ID_FIELD_NAME.equals(defaultName) 39 | ? MONGO_ID_FIELD_NAME 40 | : super.nameForSetterMethod(config, method, defaultName); 41 | } 42 | 43 | @Override 44 | public String nameForGetterMethod( 45 | MapperConfig config, AnnotatedMethod method, String defaultName) { 46 | return OBJECT_ID_FIELD_NAME.equals(defaultName) 47 | ? MONGO_ID_FIELD_NAME 48 | : super.nameForGetterMethod(config, method, defaultName); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/persistence/mongodb/MongoDbStrategyConfigurationDao.java: -------------------------------------------------------------------------------- 1 | package com.onplan.persistence.mongodb; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | import com.google.common.collect.ImmutableMap; 5 | import com.onplan.adviser.strategy.system.IntegrationTestStrategy; 6 | import com.onplan.domain.configuration.StrategyConfiguration; 7 | import com.onplan.persistence.StrategyConfigurationDao; 8 | 9 | import javax.inject.Singleton; 10 | import java.util.List; 11 | 12 | import static com.onplan.adviser.StrategyConfigurationFactory.createStrategyConfiguration; 13 | 14 | @Singleton 15 | public final class MongoDbStrategyConfigurationDao extends AbstractMongoDbDao 16 | implements StrategyConfigurationDao { 17 | private static final String STRATEGY_CONFIGURATION_COLLECTION = "strategyConfiguration"; 18 | 19 | public MongoDbStrategyConfigurationDao() { 20 | super(STRATEGY_CONFIGURATION_COLLECTION, StrategyConfiguration.class); 21 | } 22 | 23 | // TODO(robertom): Load the sample strategies from a file. 24 | @Override 25 | public List getSampleStrategiesConfiguration() { 26 | return ImmutableList.of(createStrategyConfiguration( 27 | IntegrationTestStrategy.class, 28 | "CS.EURUSD.TODAY", 29 | ImmutableMap.of())); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/persistence/mongodb/MongoDbSystemEventDao.java: -------------------------------------------------------------------------------- 1 | package com.onplan.persistence.mongodb; 2 | 3 | import com.onplan.domain.persistent.SystemEventHistory; 4 | import com.onplan.persistence.SystemEventHistoryDao; 5 | 6 | import javax.inject.Singleton; 7 | 8 | @Singleton 9 | public final class MongoDbSystemEventDao extends AbstractMongoDbDao 10 | implements SystemEventHistoryDao { 11 | private static final String SYSTEM_EVENT_COLLECTION = "systemEvent"; 12 | 13 | public MongoDbSystemEventDao() { 14 | super(SYSTEM_EVENT_COLLECTION, SystemEventHistory.class); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/scheduler/GarbageCollectionJob.java: -------------------------------------------------------------------------------- 1 | package com.onplan.scheduler; 2 | 3 | import org.apache.log4j.Logger; 4 | import org.quartz.DisallowConcurrentExecution; 5 | import org.quartz.Job; 6 | import org.quartz.JobExecutionContext; 7 | import org.quartz.JobExecutionException; 8 | 9 | @DisallowConcurrentExecution 10 | public class GarbageCollectionJob implements Job { 11 | private static final Logger LOGGER = Logger.getLogger(GarbageCollectionJob.class); 12 | 13 | @Override 14 | public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { 15 | LOGGER.warn("Calling System.gc()."); 16 | System.gc(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/service/AlertService.java: -------------------------------------------------------------------------------- 1 | package com.onplan.service; 2 | 3 | import com.onplan.adviser.alert.Alert; 4 | import com.onplan.domain.transitory.PriceTick; 5 | 6 | import java.util.List; 7 | 8 | public interface AlertService extends AlertServiceRemote { 9 | public void onPriceTick(final PriceTick priceTick); 10 | public void setInstrumentSubscriptionListener( 11 | InstrumentSubscriptionListener instrumentSubscriptionListener); 12 | public List getAlerts(); 13 | public boolean hasAlerts(); 14 | public void loadAllAlerts() throws Exception; 15 | public void unLoadAllAlerts() throws Exception; 16 | } 17 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/service/EventNotificationService.java: -------------------------------------------------------------------------------- 1 | package com.onplan.service; 2 | 3 | import com.onplan.adviser.alert.AlertEvent; 4 | 5 | /** 6 | * Notifies alerts and system events to the registered channels (eg. SMTP, JMS, Twitter, etc). 7 | */ 8 | public interface EventNotificationService { 9 | /** 10 | * Dispatches the alert event to via the active channels in a separated thread. 11 | * 12 | * @param alertEvent The alert event. 13 | */ 14 | public void notifyAlertEventAsync(AlertEvent alertEvent); 15 | 16 | /** 17 | * Dispatches the system event to via the active channels in a separated thread. 18 | * 19 | * @param systemEvent The system event. 20 | */ 21 | public void notifySystemEventAsync(final SystemEvent systemEvent); 22 | } 23 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/service/InstrumentSubscriptionListener.java: -------------------------------------------------------------------------------- 1 | package com.onplan.service; 2 | 3 | /** 4 | * Allows services to require an instrument subscription / un-subscription. 5 | */ 6 | public interface InstrumentSubscriptionListener { 7 | /** 8 | * Requires an instrument subscription. 9 | * 10 | * @param instrumentId The instrument id. 11 | */ 12 | public void onInstrumentSubscriptionRequest(final String instrumentId); 13 | 14 | /** 15 | * Requires an instrument un-subscription. 16 | * 17 | * @param instrumentId The instrument id. 18 | */ 19 | public void onInstrumentUnSubscriptionRequest(final String instrumentId); 20 | } 21 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/service/StrategyService.java: -------------------------------------------------------------------------------- 1 | package com.onplan.service; 2 | 3 | import com.onplan.adviser.strategy.Strategy; 4 | import com.onplan.domain.transitory.PriceTick; 5 | 6 | import java.util.List; 7 | 8 | public interface StrategyService extends StrategyServiceRemote { 9 | public void onPriceTick(final PriceTick priceTick); 10 | public void setInstrumentSubscriptionListener( 11 | InstrumentSubscriptionListener instrumentSubscriptionListener); 12 | public List getStrategies(); 13 | public void loadAllStrategies() throws Exception; 14 | public void unLoadAllStrategies() throws Exception; 15 | } 16 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/service/SystemEvent.java: -------------------------------------------------------------------------------- 1 | package com.onplan.service; 2 | 3 | import com.google.common.base.MoreObjects; 4 | import com.google.common.base.Objects; 5 | 6 | import java.io.Serializable; 7 | 8 | import static com.google.common.base.Preconditions.checkArgument; 9 | import static com.google.common.base.Preconditions.checkNotNull; 10 | import static com.onplan.util.MorePreconditions.checkNotNullOrEmpty; 11 | 12 | public final class SystemEvent implements Serializable { 13 | private final String className; 14 | private final String message; 15 | private final long createdOn; 16 | 17 | public String getClassName() { 18 | return className; 19 | } 20 | 21 | public String getMessage() { 22 | return message; 23 | } 24 | 25 | public long getCreatedOn() { 26 | return createdOn; 27 | } 28 | 29 | public SystemEvent(Class clazz, String message, long createdOn) { 30 | checkArgument(createdOn > 0); 31 | this.className = checkNotNull(clazz).getName(); 32 | this.message = checkNotNullOrEmpty(message); 33 | this.createdOn = createdOn; 34 | } 35 | 36 | @Override 37 | public int hashCode() { 38 | return Objects.hashCode(className, message, createdOn); 39 | } 40 | 41 | @Override 42 | public boolean equals(Object o) { 43 | if (this == o) { 44 | return true; 45 | } 46 | if (o == null || getClass() != o.getClass()) { 47 | return false; 48 | } 49 | SystemEvent systemEvent = (SystemEvent) o; 50 | return Objects.equal(this.className, systemEvent.className) && 51 | Objects.equal(this.message, systemEvent.message) && 52 | Objects.equal(this.createdOn, systemEvent.createdOn); 53 | } 54 | 55 | @Override 56 | public String toString() { 57 | return MoreObjects.toStringHelper(this) 58 | .add("className", className) 59 | .add("message", message) 60 | .add("createdOn", createdOn) 61 | .toString(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/service/VirtualMachineService.java: -------------------------------------------------------------------------------- 1 | package com.onplan.service; 2 | 3 | public interface VirtualMachineService extends VirtualMachineServiceRemote { 4 | } 5 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/service/impl/AbstractAdviserService.java: -------------------------------------------------------------------------------- 1 | package com.onplan.service.impl; 2 | 3 | import com.onplan.service.InstrumentSubscriptionListener; 4 | 5 | import static com.google.common.base.Preconditions.checkNotNull; 6 | import static com.onplan.util.MorePreconditions.checkNotNullOrEmpty; 7 | 8 | public abstract class AbstractAdviserService { 9 | private volatile InstrumentSubscriptionListener instrumentSubscriptionListener; 10 | 11 | public void setInstrumentSubscriptionListener( 12 | InstrumentSubscriptionListener instrumentSubscriptionListener) { 13 | this.instrumentSubscriptionListener = checkNotNull(instrumentSubscriptionListener); 14 | } 15 | 16 | protected void dispatchInstrumentSubscriptionRequired(final String instrumentId) { 17 | checkNotNullOrEmpty(instrumentId); 18 | if (null != instrumentSubscriptionListener) { 19 | instrumentSubscriptionListener.onInstrumentSubscriptionRequest(instrumentId); 20 | } 21 | } 22 | 23 | protected void dispatchInstrumentUnSubscriptionRequired(final String instrumentId) { 24 | checkNotNullOrEmpty(instrumentId); 25 | if (null != instrumentSubscriptionListener) { 26 | instrumentSubscriptionListener.onInstrumentUnSubscriptionRequest(instrumentId); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/service/impl/VirtualMachineServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.onplan.service.impl; 2 | 3 | import com.onplan.domain.transitory.VirtualMachineInfo; 4 | import com.onplan.service.VirtualMachineService; 5 | 6 | import javax.inject.Singleton; 7 | import java.lang.management.GarbageCollectorMXBean; 8 | import java.lang.management.ManagementFactory; 9 | import java.util.Collection; 10 | 11 | @Singleton 12 | public final class VirtualMachineServiceImpl implements VirtualMachineService { 13 | @Override 14 | public VirtualMachineInfo getVirtualMachineInfo() { 15 | long collectionsCount = 0; 16 | long cumulatedTime = 0; 17 | double averageCollectionTime = 0; 18 | Collection garbageCollectors = 19 | ManagementFactory.getGarbageCollectorMXBeans(); 20 | for (GarbageCollectorMXBean garbageCollector : garbageCollectors) { 21 | collectionsCount += garbageCollector.getCollectionCount(); 22 | cumulatedTime += garbageCollector.getCollectionTime(); 23 | } 24 | if(collectionsCount > 0) { 25 | averageCollectionTime = cumulatedTime / collectionsCount; 26 | } 27 | 28 | int availableProcessors = Runtime.getRuntime().availableProcessors(); 29 | long freeMemory = Runtime.getRuntime().freeMemory(); 30 | long totalMemory = Runtime.getRuntime().totalMemory(); 31 | long maxMemory = Runtime.getRuntime().maxMemory(); 32 | 33 | return new VirtualMachineInfo(availableProcessors, maxMemory, totalMemory, freeMemory, 34 | collectionsCount, averageCollectionTime); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/service/placeholder/AlertServicePlaceholder.java: -------------------------------------------------------------------------------- 1 | package com.onplan.service.placeholder; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | import com.onplan.adviser.AlertInfo; 5 | import com.onplan.adviser.alert.Alert; 6 | import com.onplan.domain.configuration.AlertConfiguration; 7 | import com.onplan.domain.transitory.PriceTick; 8 | import com.onplan.service.AlertService; 9 | import com.onplan.service.InstrumentSubscriptionListener; 10 | 11 | import javax.inject.Singleton; 12 | import java.util.List; 13 | 14 | /** 15 | * To save resources the AlertService can be replaced by this placeholder. 16 | */ 17 | @Singleton 18 | public final class AlertServicePlaceholder implements AlertService { 19 | private static final List ALERTS = ImmutableList.of(); 20 | 21 | @Override 22 | public void onPriceTick(PriceTick priceTick) { 23 | // Intentionally empty. 24 | } 25 | 26 | @Override 27 | public void setInstrumentSubscriptionListener( 28 | InstrumentSubscriptionListener instrumentSubscriptionListener) { 29 | // Intentionally empty. 30 | } 31 | 32 | @Override 33 | public List getAlerts() { 34 | return ALERTS; 35 | } 36 | 37 | @Override 38 | public boolean hasAlerts() { 39 | return false; 40 | } 41 | 42 | @Override 43 | public void loadAllAlerts() throws Exception { 44 | // Intentionally empty. 45 | } 46 | 47 | @Override 48 | public void unLoadAllAlerts() throws Exception { 49 | // Intentionally empty. 50 | } 51 | 52 | @Override 53 | public boolean removeAlert(String alertId) throws Exception { 54 | return false; 55 | } 56 | 57 | @Override 58 | public String addAlert(AlertConfiguration alertConfigurationConfiguration) throws Exception { 59 | return null; 60 | } 61 | 62 | @Override 63 | public void loadSampleAlerts() throws Exception { 64 | // Intentionally empty. 65 | } 66 | 67 | @Override 68 | public List getAlertsInfo() { 69 | return null; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/startup/GuiceJobFactory.java: -------------------------------------------------------------------------------- 1 | package com.onplan.startup; 2 | 3 | import com.google.inject.Injector; 4 | import org.apache.log4j.Logger; 5 | import org.quartz.Job; 6 | import org.quartz.JobDetail; 7 | import org.quartz.Scheduler; 8 | import org.quartz.SchedulerException; 9 | import org.quartz.spi.JobFactory; 10 | import org.quartz.spi.TriggerFiredBundle; 11 | 12 | import javax.inject.Inject; 13 | 14 | import static com.google.common.base.Preconditions.checkNotNull; 15 | 16 | /** 17 | * Provides Guice support for Quartz jobs. 18 | */ 19 | public class GuiceJobFactory implements JobFactory { 20 | private static final Logger LOGGER = Logger.getLogger(GuiceJobFactory.class); 21 | 22 | @Inject 23 | private Injector injector; 24 | 25 | @Override 26 | public Job newJob(TriggerFiredBundle triggerFiredBundle, Scheduler scheduler) 27 | throws SchedulerException { 28 | checkNotNull(injector); 29 | JobDetail jobDetail = triggerFiredBundle.getJobDetail(); 30 | Class jobClass = jobDetail.getJobClass(); 31 | try { 32 | return (Job) injector.getInstance(jobClass); 33 | } catch (Exception e) { 34 | LOGGER.error( 35 | String.format("Error while creating job class [%s]: [%s].", jobClass, e.getMessage()), e); 36 | throw new SchedulerException(e); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/startup/GuiceListener.java: -------------------------------------------------------------------------------- 1 | package com.onplan.startup; 2 | 3 | import com.google.inject.Guice; 4 | import com.google.inject.Injector; 5 | import com.google.inject.servlet.GuiceServletContextListener; 6 | 7 | public class GuiceListener extends GuiceServletContextListener { 8 | @Override 9 | protected Injector getInjector() { 10 | return Guice.createInjector( 11 | new IgIndexGuiceModule(), 12 | new GuiceModule(), 13 | new GuiceServletModule()); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/startup/GuiceModule.java: -------------------------------------------------------------------------------- 1 | package com.onplan.startup; 2 | 3 | import com.google.inject.AbstractModule; 4 | import com.google.inject.name.Names; 5 | import com.onplan.persistence.AlertConfigurationDao; 6 | import com.onplan.persistence.AlertEventHistoryDao; 7 | import com.onplan.persistence.StrategyConfigurationDao; 8 | import com.onplan.persistence.SystemEventHistoryDao; 9 | import com.onplan.persistence.mongodb.MongoDbAlertConfigurationDao; 10 | import com.onplan.persistence.mongodb.MongoDbAlertEventDao; 11 | import com.onplan.persistence.mongodb.MongoDbStrategyConfigurationDao; 12 | import com.onplan.persistence.mongodb.MongoDbSystemEventDao; 13 | import com.onplan.service.AlertService; 14 | import com.onplan.service.EventNotificationService; 15 | import com.onplan.service.StrategyService; 16 | import com.onplan.service.VirtualMachineService; 17 | import com.onplan.service.impl.AlertServiceImpl; 18 | import com.onplan.service.impl.EventNotificationServiceImpl; 19 | import com.onplan.service.impl.StrategyServiceImpl; 20 | import com.onplan.service.impl.VirtualMachineServiceImpl; 21 | import com.onplan.service.placeholder.AlertServicePlaceholder; 22 | import org.apache.log4j.Logger; 23 | 24 | import java.util.Properties; 25 | 26 | import static com.google.common.base.Preconditions.checkArgument; 27 | import static com.onplan.util.MorePreconditions.checkAndGetBoolean; 28 | import static com.onplan.util.PropertiesUtils.loadAllPropertiesFromClassPath; 29 | import static java.lang.String.format; 30 | 31 | public class GuiceModule extends AbstractModule { 32 | private static final Logger LOGGER = Logger.getLogger(GuiceModule.class); 33 | private static final String PROPERTY_ALERT_SERVICE_DISABLED = "system.alertservice.disabled"; 34 | 35 | @Override 36 | protected void configure() { 37 | Properties properties; 38 | try { 39 | properties = loadAllPropertiesFromClassPath(); 40 | checkArgument(!properties.isEmpty(), "No properties found."); 41 | Names.bindProperties(binder(), properties); 42 | } catch (Exception e) { 43 | LOGGER.error( 44 | format("Error while loading properties files from class path. [%s]", e.getMessage()), e); 45 | throw new IllegalArgumentException(e); 46 | } 47 | 48 | bind(StrategyConfigurationDao.class).to(MongoDbStrategyConfigurationDao.class); 49 | bind(AlertConfigurationDao.class).to(MongoDbAlertConfigurationDao.class); 50 | bind(AlertEventHistoryDao.class).to(MongoDbAlertEventDao.class); 51 | bind(SystemEventHistoryDao.class).to(MongoDbSystemEventDao.class); 52 | 53 | // To save resources AlertService can be disabled and replaced by a placeholder. 54 | if (checkAndGetBoolean(properties.getProperty(PROPERTY_ALERT_SERVICE_DISABLED))) { 55 | LOGGER.warn("AlertService disabled, using a placeholder instead of the real service."); 56 | bind(AlertService.class).to(AlertServicePlaceholder.class); 57 | } else { 58 | bind(AlertService.class).to(AlertServiceImpl.class); 59 | } 60 | 61 | bind(StrategyService.class).to(StrategyServiceImpl.class); 62 | bind(EventNotificationService.class).to(EventNotificationServiceImpl.class); 63 | bind(VirtualMachineService.class).to(VirtualMachineServiceImpl.class); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/startup/GuiceServletModule.java: -------------------------------------------------------------------------------- 1 | package com.onplan.startup; 2 | 3 | import com.google.inject.Singleton; 4 | import com.google.inject.servlet.ServletModule; 5 | import com.onplan.startup.servlet.*; 6 | 7 | public class GuiceServletModule extends ServletModule { 8 | @Override 9 | protected void configureServlets() { 10 | bind(StartUpServlet.class).in(Singleton.class); 11 | 12 | // Servlet. 13 | serve("/").with(StartUpServlet.class); 14 | 15 | // Remoting servlet. 16 | serve("/instrumentService").with(InstrumentServiceServlet.class); 17 | serve("/priceService").with(PriceServiceServlet.class); 18 | serve("/alertService").with(AlertServiceServlet.class); 19 | serve("/strategyService").with(StrategyServiceServlet.class); 20 | serve("/virtualMachineService").with(VirtualMachineServiceServlet.class); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/startup/IgIndexGuiceModule.java: -------------------------------------------------------------------------------- 1 | package com.onplan.startup; 2 | 3 | import com.google.inject.AbstractModule; 4 | import com.google.inject.Provides; 5 | import com.onplan.connector.HistoricalPriceService; 6 | import com.onplan.connector.InstrumentService; 7 | import com.onplan.connector.PriceService; 8 | import com.onplan.connector.ServiceConnection; 9 | import com.onplan.connector.igindex.IgIndexConnection; 10 | import com.onplan.connector.igindex.IgIndexHistoricalPriceService; 11 | import com.onplan.connector.igindex.IgIndexInstrumentService; 12 | import com.onplan.connector.igindex.IgIndexPriceService; 13 | import com.onplan.util.PropertiesUtils; 14 | 15 | import javax.inject.Singleton; 16 | import java.util.Properties; 17 | 18 | import static com.onplan.util.MorePreconditions.checkNotNullOrEmpty; 19 | 20 | /** 21 | * Guice module specific for IgIndex services. 22 | */ 23 | // TODO(robertom): Use configuration files for setting up the broker instead of hard coded classes. 24 | public class IgIndexGuiceModule extends AbstractModule { 25 | private static final String BROKER_PROPERTIES_FILE = "broker.properties"; 26 | 27 | private static IgIndexConnection igIndexServiceConnection; 28 | 29 | @Override 30 | protected void configure() { 31 | // Intentionally empty. 32 | } 33 | 34 | private static IgIndexConnection getIgIndexConnectionInstance() throws Exception { 35 | if (null == igIndexServiceConnection) { 36 | Properties properties = PropertiesUtils.loadPropertiesFromFile(BROKER_PROPERTIES_FILE); 37 | String apiKey = 38 | checkNotNullOrEmpty(properties.getProperty("com.onplan.connector.igindex.apiKey")); 39 | String username = 40 | checkNotNullOrEmpty(properties.getProperty("com.onplan.connector.igindex.username")); 41 | String password = 42 | checkNotNullOrEmpty(properties.getProperty("com.onplan.connector.igindex.password")); 43 | String serverUrl = 44 | checkNotNullOrEmpty(properties.getProperty("com.onplan.connector.igindex.severUrl")); 45 | igIndexServiceConnection = new IgIndexConnection(apiKey, username, password, serverUrl); 46 | } 47 | return igIndexServiceConnection; 48 | } 49 | 50 | @Provides 51 | private static ServiceConnection provideServiceConnection() throws Exception { 52 | return getIgIndexConnectionInstance(); 53 | } 54 | 55 | @Singleton 56 | @Provides 57 | private PriceService providePriceService() throws Exception { 58 | return new IgIndexPriceService(getIgIndexConnectionInstance()); 59 | } 60 | 61 | @Singleton 62 | @Provides 63 | private HistoricalPriceService provideHistoricalPriceService() throws Exception { 64 | return new IgIndexHistoricalPriceService(getIgIndexConnectionInstance()); 65 | } 66 | 67 | @Singleton 68 | @Provides 69 | private InstrumentService provideInstrumentService() throws Exception { 70 | return new IgIndexInstrumentService(getIgIndexConnectionInstance()); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/startup/servlet/AlertServiceServlet.java: -------------------------------------------------------------------------------- 1 | package com.onplan.startup.servlet; 2 | 3 | import com.caucho.hessian.server.HessianServlet; 4 | import com.onplan.service.AlertService; 5 | import com.onplan.service.AlertServiceRemote; 6 | 7 | import javax.inject.Inject; 8 | import javax.inject.Singleton; 9 | import javax.servlet.ServletException; 10 | 11 | @Singleton 12 | public class AlertServiceServlet extends HessianServlet { 13 | @Inject 14 | private AlertService alertService; 15 | 16 | @Override 17 | public void init() throws ServletException { 18 | setHome(alertService); 19 | setHomeAPI(AlertServiceRemote.class); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/startup/servlet/InstrumentServiceServlet.java: -------------------------------------------------------------------------------- 1 | package com.onplan.startup.servlet; 2 | 3 | import com.caucho.hessian.server.HessianServlet; 4 | import com.onplan.connector.InstrumentService; 5 | import com.onplan.service.InstrumentServiceRemote; 6 | 7 | import javax.inject.Inject; 8 | import javax.inject.Singleton; 9 | import javax.servlet.ServletException; 10 | 11 | @Singleton 12 | public class InstrumentServiceServlet extends HessianServlet { 13 | @Inject 14 | private InstrumentService instrumentService; 15 | 16 | @Override 17 | public void init() throws ServletException { 18 | setHome(instrumentService); 19 | setHomeAPI(InstrumentServiceRemote.class); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/startup/servlet/PriceServiceServlet.java: -------------------------------------------------------------------------------- 1 | package com.onplan.startup.servlet; 2 | 3 | import com.caucho.hessian.server.HessianServlet; 4 | import com.onplan.connector.PriceService; 5 | import com.onplan.service.PriceServiceRemote; 6 | 7 | import javax.inject.Inject; 8 | import javax.inject.Singleton; 9 | import javax.servlet.ServletException; 10 | 11 | @Singleton 12 | public class PriceServiceServlet extends HessianServlet { 13 | @Inject 14 | private PriceService priceService; 15 | 16 | @Override 17 | public void init() throws ServletException { 18 | setHome(priceService); 19 | setHomeAPI(PriceServiceRemote.class); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/startup/servlet/StartUpServlet.java: -------------------------------------------------------------------------------- 1 | package com.onplan.startup.servlet; 2 | 3 | import com.google.common.collect.ImmutableMap; 4 | import com.google.inject.Injector; 5 | import com.onplan.processing.PriceServiceBus; 6 | import com.onplan.scheduler.GarbageCollectionJob; 7 | import com.onplan.scheduler.ServicesActivationJob; 8 | import com.onplan.startup.GuiceJobFactory; 9 | import org.apache.log4j.Logger; 10 | import org.quartz.JobDetail; 11 | import org.quartz.Scheduler; 12 | import org.quartz.SchedulerException; 13 | import org.quartz.Trigger; 14 | import org.quartz.impl.StdSchedulerFactory; 15 | 16 | import javax.inject.Inject; 17 | import javax.inject.Singleton; 18 | import javax.servlet.ServletException; 19 | import javax.servlet.http.HttpServlet; 20 | import javax.servlet.http.HttpServletRequest; 21 | import javax.servlet.http.HttpServletResponse; 22 | import java.io.IOException; 23 | import java.util.Map; 24 | 25 | import static org.quartz.CronScheduleBuilder.cronSchedule; 26 | import static org.quartz.JobBuilder.newJob; 27 | import static org.quartz.SimpleScheduleBuilder.simpleSchedule; 28 | import static org.quartz.TriggerBuilder.newTrigger; 29 | 30 | @Singleton 31 | public class StartUpServlet extends HttpServlet { 32 | private static final Logger LOGGER = Logger.getLogger(StartUpServlet.class); 33 | private static final String HOME_PAGE_CONTENT = "" + 34 | "

OnPlan Service

" + 35 | "

Service is up and running!

" + 36 | ""; 37 | 38 | @Inject 39 | private GuiceJobFactory guiceJobFactory; 40 | 41 | @Inject 42 | private Injector injector; 43 | 44 | @Override 45 | public void init() throws ServletException { 46 | LOGGER.info("Application startup."); 47 | startPriceServiceBus(); 48 | startScheduler(); 49 | } 50 | 51 | @Override 52 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) 53 | throws ServletException, IOException { 54 | resp.getWriter().print(HOME_PAGE_CONTENT); 55 | resp.getWriter().flush(); 56 | } 57 | 58 | private void startScheduler() { 59 | LOGGER.info("Starting scheduler."); 60 | try { 61 | Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); 62 | scheduler.setJobFactory(guiceJobFactory); 63 | for (Map.Entry entry : createJobDetails().entrySet()) { 64 | scheduler.scheduleJob(entry.getKey(), entry.getValue()); 65 | } 66 | scheduler.start(); 67 | LOGGER.info("Scheduler started."); 68 | } catch (SchedulerException e) { 69 | LOGGER.error(String.format("Error while starting scheduler: [%s]", e.getMessage()), e); 70 | } 71 | } 72 | 73 | private void startPriceServiceBus() { 74 | LOGGER.info("Starting price service bus."); 75 | injector.getInstance(PriceServiceBus.class); 76 | } 77 | 78 | private Map createJobDetails() { 79 | ImmutableMap.Builder result = ImmutableMap.builder(); 80 | result.put( 81 | newJob(ServicesActivationJob.class) 82 | .withIdentity("servicesActivationJob") 83 | .build(), 84 | newTrigger() 85 | .withIdentity("everyMinuteTrigger") 86 | .withSchedule(simpleSchedule().withIntervalInMinutes(1).repeatForever()) 87 | .build()); 88 | result.put( 89 | newJob(GarbageCollectionJob.class) 90 | .withIdentity("garbageCollectionJob") 91 | .build(), 92 | newTrigger() 93 | .withIdentity("preMarketTrigger") 94 | .withSchedule(cronSchedule("0 55 6 * * ?")) 95 | .build()); 96 | return result.build(); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/startup/servlet/StrategyServiceServlet.java: -------------------------------------------------------------------------------- 1 | package com.onplan.startup.servlet; 2 | 3 | import com.caucho.hessian.server.HessianServlet; 4 | import com.onplan.service.StrategyService; 5 | import com.onplan.service.StrategyServiceRemote; 6 | 7 | import javax.inject.Inject; 8 | import javax.inject.Singleton; 9 | import javax.servlet.ServletException; 10 | 11 | @Singleton 12 | public class StrategyServiceServlet extends HessianServlet { 13 | @Inject 14 | private StrategyService strategyService; 15 | 16 | @Override 17 | public void init() throws ServletException { 18 | setHome(strategyService); 19 | setHomeAPI(StrategyServiceRemote.class); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/startup/servlet/VirtualMachineServiceServlet.java: -------------------------------------------------------------------------------- 1 | package com.onplan.startup.servlet; 2 | 3 | import com.caucho.hessian.server.HessianServlet; 4 | import com.onplan.service.VirtualMachineService; 5 | import com.onplan.service.VirtualMachineServiceRemote; 6 | 7 | import javax.inject.Inject; 8 | import javax.inject.Singleton; 9 | import javax.servlet.ServletException; 10 | 11 | @Singleton 12 | public class VirtualMachineServiceServlet extends HessianServlet { 13 | @Inject 14 | private VirtualMachineService virtualMachineService; 15 | 16 | @Override 17 | public void init() throws ServletException { 18 | setHome(virtualMachineService); 19 | setHomeAPI(VirtualMachineServiceRemote.class); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/util/ExceptionUtils.java: -------------------------------------------------------------------------------- 1 | package com.onplan.util; 2 | 3 | import static com.google.common.base.Preconditions.checkNotNull; 4 | 5 | public final class ExceptionUtils { 6 | public static String stackTraceToString(final Exception e) { 7 | checkNotNull(e); 8 | StringBuilder result = new StringBuilder(); 9 | StackTraceElement[] stackTraceElements = e.getStackTrace(); 10 | for (StackTraceElement stackTraceElement : stackTraceElements) { 11 | result.append(stackTraceElement.toString()).append('\n'); 12 | } 13 | return result.toString(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/util/JsonUtils.java: -------------------------------------------------------------------------------- 1 | package com.onplan.util; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.fasterxml.jackson.databind.ObjectReader; 5 | import com.fasterxml.jackson.databind.ObjectWriter; 6 | 7 | public final class JsonUtils { 8 | private static final ObjectWriter objectWriter; 9 | private static final ObjectReader objectReader; 10 | 11 | static { 12 | ObjectMapper objectMapper = new ObjectMapper(); 13 | objectWriter = objectMapper.writer(); 14 | objectReader = objectMapper.reader(); 15 | } 16 | 17 | // TODO(robertom): Check null values. 18 | public static String createJson(final Object object) throws Exception { 19 | return objectWriter.writeValueAsString(object); 20 | } 21 | 22 | // TODO(robertom): Check null values. 23 | public static T createObject(final String json) throws Exception { 24 | return objectReader.readValue(json); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/util/PropertiesUtils.java: -------------------------------------------------------------------------------- 1 | package com.onplan.util; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | import java.io.*; 6 | import java.net.URL; 7 | import java.util.Properties; 8 | import java.util.Set; 9 | 10 | import static com.google.common.base.Preconditions.checkArgument; 11 | import static com.google.common.base.Preconditions.checkNotNull; 12 | import static com.onplan.util.MorePreconditions.checkNotNullOrEmpty; 13 | import static java.lang.String.format; 14 | 15 | public final class PropertiesUtils { 16 | private static final Logger LOGGER = Logger.getLogger(PropertiesUtils.class); 17 | 18 | private static final FileFilter PROPERTIES_FILE_FILTER = new FileFilter() { 19 | @Override 20 | public boolean accept(File file) { 21 | return file.getName().endsWith(".properties"); 22 | } 23 | }; 24 | 25 | /** 26 | * Loads a property file from the class path as base path and returns the 27 | * {@link java.util.Properties} object. 28 | * 29 | * @param propertiesFile The property file. 30 | * @throws IOException Error while loading the properties file. 31 | */ 32 | public static Properties loadPropertiesFromFile(String propertiesFile) 33 | throws Exception { 34 | checkNotNullOrEmpty(propertiesFile); 35 | URL fileUrl = PropertiesUtils.class.getClassLoader().getResource(propertiesFile); 36 | checkNotNull(fileUrl, format("File [%s] not found.", propertiesFile)); 37 | return loadPropertiesFromFile(new File(fileUrl.getFile())); 38 | } 39 | 40 | /** 41 | * Loads all the property files found in the class path and merges the result in a single 42 | * {@link java.util.Properties} object. In case of duplicated keys raises an exception. 43 | * 44 | * @throws Exception Error while loading the properties file or files contain duplicated keys. 45 | */ 46 | public static Properties loadAllPropertiesFromClassPath() 47 | throws Exception { 48 | Properties result = new Properties(); 49 | URL baseUrl = checkNotNull( 50 | PropertiesUtils.class.getClassLoader().getResource("./"), "Class path not found."); 51 | File[] files = new File(baseUrl.getFile()).listFiles(PROPERTIES_FILE_FILTER); 52 | for (File file : files) { 53 | LOGGER.info(format("Loading property file [%s]", file.getName())); 54 | InputStream fileStream = new FileInputStream(file); 55 | Properties newProperties = new Properties(); 56 | newProperties.load(fileStream); 57 | fileStream.close(); 58 | checkNotIntersects(newProperties.keySet(), result.keySet()); 59 | result.putAll(newProperties); 60 | } 61 | return result; 62 | } 63 | 64 | private static Properties loadPropertiesFromFile(File file) throws IOException { 65 | checkNotNull(file); 66 | checkArgument(file.exists(), "File [%s] not found.", file.getName()); 67 | InputStream inputStream = new FileInputStream(file); 68 | Properties properties = new Properties(); 69 | properties.load(inputStream); 70 | inputStream.close(); 71 | return properties; 72 | } 73 | 74 | private static void checkNotIntersects(Set set1, Set set2) { 75 | checkNotNull(set1); 76 | checkNotNull(set2); 77 | for (Object object : set1) { 78 | if (set2.contains(object)) { 79 | throw new IllegalArgumentException(format("Element [%s] is duplicated.", object)); 80 | } 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/util/StringUtils.java: -------------------------------------------------------------------------------- 1 | package com.onplan.util; 2 | 3 | import com.google.common.base.Strings; 4 | 5 | import static com.onplan.util.MorePreconditions.checkNotNullOrEmpty; 6 | 7 | public final class StringUtils { 8 | /** 9 | * When the text exceeds the maxLength returns the text trimmed with the trimmedSuffix, otherwise 10 | * returns the full text. The resulting string always contains up to maxLength characters. 11 | * 12 | * @param text The text string. 13 | * @param maxLength The maximum length of the resulting string. 14 | * @param trimmedSuffix The trimmed suffix. 15 | */ 16 | public static String trimText(String text, int maxLength, String trimmedSuffix) { 17 | checkNotNullOrEmpty(trimmedSuffix); 18 | if (Strings.isNullOrEmpty(text)) { 19 | return text; 20 | } else if (text.length() > maxLength) { 21 | text = text.substring(maxLength - trimmedSuffix.length()); 22 | text += trimmedSuffix; 23 | } 24 | return text; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /onplan-service/src/main/java/com/onplan/util/ThreadUtils.java: -------------------------------------------------------------------------------- 1 | package com.onplan.util; 2 | 3 | /** 4 | * Thread utility class. 5 | */ 6 | public final class ThreadUtils { 7 | /** 8 | * Executes a runnable object in a new thread. 9 | * @param runnable The runnable object. 10 | */ 11 | public static void executeAsync(final Runnable runnable) { 12 | new Thread(runnable).start(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /onplan-service/src/main/resources/amazonaws.properties: -------------------------------------------------------------------------------- 1 | amazonaws.accesskeyid=${amazonaws.accesskeyid} 2 | amazonaws.secretaccesskey=${amazonaws.secretaccesskey} 3 | -------------------------------------------------------------------------------- /onplan-service/src/main/resources/broker.properties: -------------------------------------------------------------------------------- 1 | com.onplan.connector.igindex.apiKey=${com.onplan.adapter.igindex.apiKey} 2 | com.onplan.connector.igindex.username=${com.onplan.adapter.igindex.username} 3 | com.onplan.connector.igindex.password=${com.onplan.adapter.igindex.password} 4 | com.onplan.connector.igindex.severUrl=https://api.ig.com/gateway/deal 5 | -------------------------------------------------------------------------------- /onplan-service/src/main/resources/email.properties: -------------------------------------------------------------------------------- 1 | smtp.host=${smtp.host} 2 | smtp.username=${smtp.username} 3 | smtp.password=${smtp.password} 4 | smtp.port=${smtp.port} 5 | smtp.useSsl=${smtp.useSsl} -------------------------------------------------------------------------------- /onplan-service/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=${log4j.rootLogger} 2 | log4j.logger.com.onplan=${log4j.logger.com.onplan} 3 | 4 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 5 | log4j.appender.stdout.Target=System.out 6 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 7 | log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n 8 | 9 | log4j.appender.file=org.apache.log4j.FileAppender 10 | log4j.appender.file.File=log.out 11 | log4j.appender.file.ImmediateFlush=true 12 | log4j.appender.file.layout=org.apache.log4j.PatternLayout 13 | log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n 14 | -------------------------------------------------------------------------------- /onplan-service/src/main/resources/mongodb.properties: -------------------------------------------------------------------------------- 1 | mongodb.host=localhost 2 | mongodb.port=27017 3 | mongodb.database=onplan -------------------------------------------------------------------------------- /onplan-service/src/main/resources/notification.properties: -------------------------------------------------------------------------------- 1 | notification.notify.service.connection=true 2 | notification.notify.service.disconnection=true 3 | 4 | notification.mongodb.enabled=true 5 | 6 | notification.smtp.enabled=true 7 | notification.smtp.from=${notification.smtp.from} 8 | notification.smtp.to=${notification.smtp.to} 9 | 10 | notification.amazonsqs.enabled=true 11 | notification.amazonsqs.systemEventQueueUrl=${notification.amazonsqs.systemEventQueueUrl} 12 | notification.amazonsqs.alertEventQueueUrl=${notification.amazonsqs.alertEventQueueUrl} 13 | 14 | notification.twitter.enabled=true 15 | notification.twitter.recipientScreeName=${notification.twitter.recipientScreeName} -------------------------------------------------------------------------------- /onplan-service/src/main/resources/system.properties: -------------------------------------------------------------------------------- 1 | # All the time values are in UTC time 2 | market.forex.openTime=22:00 3 | market.forex.closeTime=22:00 4 | market.europeanIndexes.openTime=08:00 5 | market.europeanIndexes.closeTime=16:30 6 | 7 | system.alertservice.disabled=false 8 | -------------------------------------------------------------------------------- /onplan-service/src/main/resources/twitter4j.properties: -------------------------------------------------------------------------------- 1 | debug=false 2 | oauth.consumerKey=${twitter.consumerKey} 3 | oauth.consumerSecret=${twitter.consumerSecret} 4 | oauth.accessToken=${twitter.accessToken} 5 | oauth.accessTokenSecret=${twitter.accessTokenSecret} 6 | -------------------------------------------------------------------------------- /onplan-service/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | guiceFilter 7 | com.google.inject.servlet.GuiceFilter 8 | 9 | 10 | 11 | guiceFilter 12 | /* 13 | 14 | 15 | 16 | com.onplan.startup.GuiceListener 17 | 18 | 19 | -------------------------------------------------------------------------------- /onplan-service/src/test/java/com/onplan/adviser/alert/TestingAlertConfigurationFactory.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser.alert; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | import com.onplan.adviser.SeverityLevel; 5 | import com.onplan.domain.configuration.AlertConfiguration; 6 | 7 | import java.util.List; 8 | 9 | import static com.onplan.adviser.predicate.TestingAdviserPredicateConfigurationFactory.createSampleAdviserPredicateConfigurations; 10 | import static com.onplan.util.MorePreconditions.checkNotNullOrEmpty; 11 | import static com.onplan.util.TestingConstants.*; 12 | 13 | public class TestingAlertConfigurationFactory { 14 | public static AlertConfiguration createSampleAlertConfigurationWithNullId() { 15 | return createSampleAlertConfigurationWithNullId( 16 | INSTRUMENT_EURUSD_ID, DEFAULT_ALERT_MESSAGE, true); 17 | } 18 | 19 | public static AlertConfiguration createSampleAlertConfigurationWithNullId( 20 | String instrumentId, String message, boolean repeat) { 21 | checkNotNullOrEmpty(instrumentId); 22 | checkNotNullOrEmpty(message); 23 | return new AlertConfiguration( 24 | null, 25 | message, 26 | SeverityLevel.HIGH, 27 | instrumentId, 28 | createSampleAdviserPredicateConfigurations(), 29 | DEFAULT_CREATION_DATE.getMillis(), 30 | repeat); 31 | } 32 | 33 | public static List createSampleAlertConfigurationsWithNullId() { 34 | ImmutableList.Builder result = ImmutableList.builder(); 35 | for (int i = 0; i < INITIAL_ALERTS_LIST_SIZE; i++) { 36 | result.add(createSampleAlertConfigurationWithNullId( 37 | String.format("instrumentId%d", i), 38 | String.format("Alert message %d", i), 39 | (i % 2 == 0))); 40 | } 41 | return result.build(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /onplan-service/src/test/java/com/onplan/adviser/alert/TestingStrategyConfigurationFactory.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser.alert; 2 | 3 | import com.google.common.collect.ImmutableSet; 4 | import com.onplan.adviser.strategy.system.IntegrationTestStrategy; 5 | import com.onplan.domain.configuration.StrategyConfiguration; 6 | import com.onplan.util.TestingConstants; 7 | 8 | public class TestingStrategyConfigurationFactory { 9 | public static StrategyConfiguration createSampleStrategyConfigurationWithNullId() { 10 | return new StrategyConfiguration( 11 | null, 12 | IntegrationTestStrategy.class.getName(), 13 | TestingConstants.DEFAULT_ADVISER_PARAMETERS, 14 | ImmutableSet.of(TestingConstants.INSTRUMENT_EURUSD_ID)); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /onplan-service/src/test/java/com/onplan/adviser/predicate/TestingAdviserPredicateConfigurationFactory.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser.predicate; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | import com.google.common.collect.ImmutableMap; 5 | import com.onplan.adviser.predicate.priceaction.PriceSpikePredicate; 6 | import com.onplan.adviser.predicate.pricepattern.CandlestickHammerPredicate; 7 | import com.onplan.domain.configuration.AdviserPredicateConfiguration; 8 | 9 | import java.util.Collection; 10 | import java.util.Map; 11 | 12 | import static com.google.common.base.Preconditions.checkNotNull; 13 | 14 | public class TestingAdviserPredicateConfigurationFactory { 15 | public static AdviserPredicateConfiguration createSampleAdviserPredicateConfiguration( 16 | Class clazz, Map parameters) { 17 | checkNotNull(clazz); 18 | return new AdviserPredicateConfiguration(clazz.getName(), ImmutableMap.copyOf(parameters)); 19 | } 20 | 21 | public static Collection 22 | createSampleAdviserPredicateConfigurations() { 23 | return ImmutableList.of( 24 | createSampleAdviserPredicateConfiguration( 25 | PriceSpikePredicate.class, 26 | ImmutableMap.of(PriceSpikePredicate.PROPERTY_MINIMUM_PIPS, "10")), 27 | createSampleAdviserPredicateConfiguration( 28 | CandlestickHammerPredicate.class, 29 | ImmutableMap.of( 30 | CandlestickHammerPredicate.PROPERTY_TIME_FRAME, "MINUTES_1", 31 | CandlestickHammerPredicate.PROPERTY_MINIMUM_CANDLE_SIZE, "10"))); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /onplan-service/src/test/java/com/onplan/adviser/predicate/TestingAdviserPredicateUtils.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser.predicate; 2 | 3 | import java.util.Map; 4 | 5 | import static com.google.common.base.Preconditions.checkArgument; 6 | import static com.google.common.base.Preconditions.checkNotNull; 7 | import static com.onplan.util.MorePreconditions.checkNotNullOrEmpty; 8 | 9 | public class TestingAdviserPredicateUtils { 10 | public static final void checkAdviserPredicate(AdviserPredicate adviserPredicate) { 11 | checkNotNull(adviserPredicate); 12 | checkNotNull(adviserPredicate.getParametersCopy()); 13 | checkArgument(!adviserPredicate.getParametersCopy().isEmpty()); 14 | for (Map.Entry parameter : 15 | adviserPredicate.getParametersCopy().entrySet()) { 16 | checkNotNullOrEmpty(parameter.getValue()); 17 | checkNotNullOrEmpty(parameter.getKey()); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /onplan-service/src/test/java/com/onplan/adviser/predicate/TestingPredicateExecutionContextFactory.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser.predicate; 2 | 3 | import com.onplan.service.TestingHistoricalPriceService; 4 | import com.onplan.service.TestingInstrumentService; 5 | 6 | import java.util.Map; 7 | 8 | public class TestingPredicateExecutionContextFactory { 9 | public static PredicateExecutionContext createPredicateExecutionContext( 10 | Map executionParameters, String instrumentId) { 11 | return new PredicateExecutionContext( 12 | new TestingHistoricalPriceService(), 13 | new TestingInstrumentService(), 14 | executionParameters, 15 | instrumentId); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /onplan-service/src/test/java/com/onplan/adviser/strategy/JavaScriptStrategyTest.java: -------------------------------------------------------------------------------- 1 | package com.onplan.adviser.strategy; 2 | 3 | import com.google.common.collect.ImmutableMap; 4 | import com.google.common.collect.ImmutableSet; 5 | import com.onplan.adviser.predicate.scripting.JavaScripPredicate; 6 | import com.onplan.adviser.strategy.scripting.JavaScriptStrategy; 7 | import com.onplan.domain.TestingPriceFactory; 8 | import com.onplan.domain.transitory.PriceTick; 9 | import com.onplan.service.TestingHistoricalPriceService; 10 | import com.onplan.service.TestingInstrumentService; 11 | import com.onplan.util.TestingConstants; 12 | import org.junit.Test; 13 | 14 | import java.util.List; 15 | import java.util.Map; 16 | 17 | import static com.onplan.util.MorePreconditions.checkNotNullOrEmpty; 18 | import static com.onplan.util.TestingConstants.INSTRUMENT_EURUSD_ID; 19 | import static org.mockito.Mockito.mock; 20 | 21 | public class JavaScriptStrategyTest { 22 | private StrategyListener strategyListener = mock(StrategyListener.class); 23 | 24 | @Test(expected = Exception.class) 25 | public void testApplyScriptBadSyntax() throws Exception { 26 | String script = "this syntax is invalid!"; 27 | Strategy strategy = createStrategy(script); 28 | strategy.init(); 29 | } 30 | 31 | @Test 32 | public void testApplyScriptWithoutInit() throws Exception { 33 | String script = "apply = function(priceTick) {};"; 34 | Strategy strategy = createStrategy(script); 35 | strategy.init(); 36 | } 37 | 38 | @Test 39 | public void testApplyScriptWithMissingParameters() throws Exception { 40 | String script = "apply = function() {};"; 41 | Strategy strategy = createStrategy(script); 42 | strategy.init(); 43 | for (PriceTick priceTick : createPriceTicks()) { 44 | strategy.onPriceTick(priceTick); 45 | } 46 | } 47 | 48 | @Test 49 | public void testApplyScriptWithWrongParameters() throws Exception { 50 | String script = "apply = function(a, b) {};"; 51 | Strategy strategy = createStrategy(script); 52 | strategy.init(); 53 | for (PriceTick priceTick : createPriceTicks()) { 54 | strategy.onPriceTick(priceTick); 55 | } 56 | } 57 | 58 | private List createPriceTicks() { 59 | return TestingPriceFactory.createPriceTicks( 60 | INSTRUMENT_EURUSD_ID, 61 | new long[]{1, 2, 3, 4}, 62 | new double[]{0.00001, 0.00002, 0.00003, 0.00004}, 63 | 0.00001); 64 | } 65 | 66 | private Strategy createStrategy(String script) { 67 | return createStrategy(script, ImmutableMap.of()); 68 | } 69 | 70 | private Strategy createStrategy(String script, Map parameters) { 71 | checkNotNullOrEmpty(script); 72 | StrategyExecutionContext strategyExecutionContext = new StrategyExecutionContext( 73 | TestingConstants.DEFAULT_STRATEGY_ID, 74 | new TestingHistoricalPriceService(), 75 | new TestingInstrumentService(), 76 | strategyListener, 77 | ImmutableMap.builder() 78 | .put(JavaScripPredicate.PARAMETER_JAVASCRIPT_EXPRESSION, script) 79 | .putAll(parameters) 80 | .build(), 81 | ImmutableSet.of(INSTRUMENT_EURUSD_ID)); 82 | return new JavaScriptStrategy(strategyExecutionContext); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /onplan-service/src/test/java/com/onplan/benchmark/service/StrategyPoolBenchmark.java: -------------------------------------------------------------------------------- 1 | package com.onplan.benchmark.service; 2 | 3 | public class StrategyPoolBenchmark { 4 | // @Benchmark 5 | public void testProcessPriceTick() { 6 | try { 7 | Thread.sleep(10); 8 | } catch (InterruptedException e) { 9 | e.printStackTrace(); 10 | } 11 | System.out.println("End of benchmark!"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /onplan-service/src/test/java/com/onplan/connector/DummyPriceService.java: -------------------------------------------------------------------------------- 1 | package com.onplan.connector; 2 | 3 | import com.onplan.domain.transitory.PriceTick; 4 | import com.onplan.service.ServiceConnectionInfo; 5 | 6 | public class DummyPriceService implements PriceService { 7 | @Override 8 | public boolean isConnected() { 9 | return false; 10 | } 11 | 12 | @Override 13 | public ServiceConnectionInfo getServiceConnectionInfo() { 14 | throw new IllegalArgumentException("Not yet implemented."); 15 | } 16 | 17 | @Override 18 | public boolean isInstrumentSubscribed(String instrumentId) { 19 | throw new IllegalArgumentException("Not yet implemented."); 20 | } 21 | 22 | @Override 23 | public PriceTick getLastPriceTick(String instrumentId) { 24 | throw new IllegalArgumentException("Not yet implemented."); 25 | } 26 | 27 | @Override 28 | public void setPriceListener(PriceListener listener) { 29 | // Intentionally empty. 30 | } 31 | 32 | @Override 33 | public void subscribeInstrument(String instrumentId) throws Exception { 34 | throw new IllegalArgumentException("Not yet implemented."); 35 | } 36 | 37 | @Override 38 | public void unSubscribeInstrument(String instrumentId) throws Exception { 39 | throw new IllegalArgumentException("Not yet implemented."); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /onplan-service/src/test/java/com/onplan/dao/TestingAbstractDao.java: -------------------------------------------------------------------------------- 1 | package com.onplan.dao; 2 | 3 | import com.google.common.base.Strings; 4 | import com.google.common.collect.ImmutableList; 5 | import com.google.common.collect.Lists; 6 | import com.onplan.domain.persistent.PersistentObject; 7 | import com.onplan.persistence.GenericDao; 8 | 9 | import java.util.Collection; 10 | import java.util.List; 11 | import java.util.UUID; 12 | 13 | import static com.google.common.base.Preconditions.checkArgument; 14 | import static com.google.common.base.Preconditions.checkNotNull; 15 | import static com.onplan.util.MorePreconditions.checkNotNullOrEmpty; 16 | 17 | public abstract class TestingAbstractDao implements GenericDao { 18 | private final List records = Lists.newArrayList(); 19 | 20 | @Override 21 | public String insert(T object) throws Exception { 22 | checkNotNull(object); 23 | checkArgument(Strings.isNullOrEmpty(object.getId())); 24 | String id = createNewId(); 25 | checkArgument(!containsObject(id)); 26 | object.setId(id); 27 | records.add(object); 28 | return id; 29 | } 30 | 31 | @Override 32 | public void insertAll(Collection objects) throws Exception { 33 | for (T object : objects) { 34 | insert(object); 35 | } 36 | } 37 | 38 | @Override 39 | public String save(T object) throws Exception { 40 | checkNotNull(object); 41 | if (Strings.isNullOrEmpty(object.getId())) { 42 | return insert(object); 43 | } else { 44 | checkArgument(containsObject(object.getId())); 45 | for (T record : records) { 46 | if (object.getId().equals(record.getId())) { 47 | records.remove(record); 48 | break; 49 | } 50 | } 51 | records.add(object); 52 | return object.getId(); 53 | } 54 | } 55 | 56 | @Override 57 | public T saveAndGet(T object) throws Exception { 58 | checkNotNull(object); 59 | return findById(save(object)); 60 | } 61 | 62 | @Override 63 | public boolean remove(T object) { 64 | checkNotNull(object); 65 | return removeById(object.getId()); 66 | } 67 | 68 | @Override 69 | public boolean removeById(String id) { 70 | checkNotNullOrEmpty(id); 71 | for (T record : records) { 72 | if (id.equals(record.getId())) { 73 | records.remove(record); 74 | return true; 75 | } 76 | } 77 | return false; 78 | } 79 | 80 | @Override 81 | public void removeAll() { 82 | records.clear(); 83 | } 84 | 85 | @Override 86 | public T findById(String id) { 87 | for (T record : records) { 88 | if (id.equals(record.getId())) { 89 | return record; 90 | } 91 | } 92 | return null; 93 | } 94 | 95 | @Override 96 | public List findAll() { 97 | return ImmutableList.copyOf(records); 98 | } 99 | 100 | private String createNewId() { 101 | return UUID.randomUUID().toString(); 102 | } 103 | 104 | private boolean containsObject(String id) { 105 | if (records.stream().anyMatch(record -> id.equals(record.getId()))) { 106 | return true; 107 | } 108 | return false; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /onplan-service/src/test/java/com/onplan/dao/TestingStrategyConfigurationDao.java: -------------------------------------------------------------------------------- 1 | package com.onplan.dao; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | import com.google.common.collect.ImmutableMap; 5 | import com.onplan.adviser.strategy.system.IntegrationTestStrategy; 6 | import com.onplan.domain.configuration.StrategyConfiguration; 7 | import com.onplan.persistence.StrategyConfigurationDao; 8 | import com.onplan.util.TestingConstants; 9 | 10 | import java.util.List; 11 | 12 | import static com.onplan.adviser.StrategyConfigurationFactory.createStrategyConfiguration; 13 | 14 | public class TestingStrategyConfigurationDao 15 | extends TestingAbstractDao implements StrategyConfigurationDao { 16 | public TestingStrategyConfigurationDao() throws Exception { 17 | removeAll(); 18 | insertAll(getSampleStrategiesConfiguration()); 19 | } 20 | 21 | @Override 22 | public List getSampleStrategiesConfiguration() { 23 | return ImmutableList.of( 24 | createStrategyConfiguration( 25 | IntegrationTestStrategy.class, 26 | TestingConstants.INSTRUMENT_EURUSD_ID, 27 | ImmutableMap.of()), 28 | createStrategyConfiguration( 29 | IntegrationTestStrategy.class, 30 | TestingConstants.INSTRUMENT_AUDUSD_ID, 31 | ImmutableMap.of()), 32 | createStrategyConfiguration( 33 | IntegrationTestStrategy.class, 34 | TestingConstants.INSTRUMENT_DAX_ID, 35 | ImmutableMap.of()), 36 | createStrategyConfiguration( 37 | IntegrationTestStrategy.class, 38 | TestingConstants.INSTRUMENT_FTSE100_ID, 39 | ImmutableMap.of())); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /onplan-service/src/test/java/com/onplan/integration/AbstractIT.java: -------------------------------------------------------------------------------- 1 | package com.onplan.integration; 2 | 3 | import com.google.inject.Guice; 4 | import com.google.inject.Injector; 5 | 6 | import static com.google.common.base.Preconditions.checkNotNull; 7 | 8 | public abstract class AbstractIT { 9 | protected final Injector injector; 10 | 11 | public AbstractIT() { 12 | this.injector = checkNotNull(Guice.createInjector(new GuiceTestingModule())); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /onplan-service/src/test/java/com/onplan/integration/connector/InstrumentServiceIT.java: -------------------------------------------------------------------------------- 1 | package com.onplan.integration.connector; 2 | 3 | import com.google.common.base.Strings; 4 | import com.google.common.collect.Lists; 5 | import com.onplan.connector.InstrumentService; 6 | import com.onplan.domain.transitory.InstrumentInfo; 7 | import com.onplan.integration.AbstractIT; 8 | import org.junit.Test; 9 | 10 | import java.util.List; 11 | 12 | import static org.junit.Assert.assertNotNull; 13 | import static org.junit.Assert.assertTrue; 14 | 15 | public class InstrumentServiceIT extends AbstractIT { 16 | private static final String SEARCH_EXAMPLE = "EUR"; 17 | private static final String EPIC_EXAMPLE = "CF.EURAUD.MAR"; 18 | 19 | private InstrumentService instrumentService = injector.getInstance(InstrumentService.class); 20 | 21 | @Test 22 | public void testFindInstrumentsBySearchTerm() throws Exception { 23 | List result = instrumentService.findInstrumentsBySearchTerm(SEARCH_EXAMPLE); 24 | List instrumentIds = Lists.newArrayList(); 25 | assertTrue(!result.isEmpty()); 26 | for (InstrumentInfo instrumentInfo : result) { 27 | checkInstrumentInfo(instrumentInfo); 28 | // Assert instrumentId uniqueness. 29 | assertTrue(!instrumentIds.contains(instrumentInfo.getInstrumentId())); 30 | instrumentIds.add(instrumentInfo.getInstrumentId()); 31 | } 32 | } 33 | 34 | @Test 35 | public void testGetInstrumentInfo() throws Exception { 36 | InstrumentInfo instrumentInfo = instrumentService.getInstrumentInfo(EPIC_EXAMPLE); 37 | checkInstrumentInfo(instrumentInfo); 38 | } 39 | 40 | private static void checkInstrumentInfo(final InstrumentInfo instrumentInfo) { 41 | assertNotNull(instrumentInfo.getInstrumentType()); 42 | assertTrue(!Strings.isNullOrEmpty(instrumentInfo.getInstrumentName())); 43 | assertTrue(!Strings.isNullOrEmpty(instrumentInfo.getExpiry())); 44 | assertTrue(!Strings.isNullOrEmpty(instrumentInfo.getInstrumentId())); 45 | assertTrue(instrumentInfo.getPriceMinimalDecimalPosition() >= 0); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /onplan-service/src/test/java/com/onplan/integration/persistence/AlertConfigurationDaoIT.java: -------------------------------------------------------------------------------- 1 | package com.onplan.integration.persistence; 2 | 3 | import com.onplan.domain.configuration.AlertConfiguration; 4 | import com.onplan.persistence.AlertConfigurationDao; 5 | 6 | import java.util.Collection; 7 | 8 | import static com.onplan.adviser.alert.TestingAlertConfigurationFactory.createSampleAlertConfigurationWithNullId; 9 | import static com.onplan.adviser.alert.TestingAlertConfigurationFactory.createSampleAlertConfigurationsWithNullId; 10 | 11 | public class AlertConfigurationDaoIT extends AbstractDaoIT { 12 | public AlertConfigurationDaoIT() { 13 | super(AlertConfigurationDao.class); 14 | } 15 | 16 | @Override 17 | protected AlertConfiguration createSampleObjectWithNullId() { 18 | return createSampleAlertConfigurationWithNullId(); 19 | } 20 | 21 | @Override 22 | protected Collection createSampleObjectsWithNullId() { 23 | return createSampleAlertConfigurationsWithNullId(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /onplan-service/src/test/java/com/onplan/integration/persistence/StrategyConfigurationDaoIT.java: -------------------------------------------------------------------------------- 1 | package com.onplan.integration.persistence; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | import com.google.common.collect.ImmutableMap; 5 | import com.google.common.collect.ImmutableSet; 6 | import com.onplan.domain.configuration.StrategyConfiguration; 7 | import com.onplan.persistence.StrategyConfigurationDao; 8 | 9 | import java.util.Collection; 10 | 11 | public class StrategyConfigurationDaoIT extends AbstractDaoIT { 12 | public StrategyConfigurationDaoIT() { 13 | super(StrategyConfigurationDao.class); 14 | } 15 | 16 | @Override 17 | protected StrategyConfiguration createSampleObjectWithNullId() { 18 | return new StrategyConfiguration( 19 | null, 20 | "className", 21 | ImmutableMap.of("key1", "value1", "key2", "value2"), 22 | ImmutableSet.of("instrument1", "instrument2")); 23 | } 24 | 25 | @Override 26 | protected Collection createSampleObjectsWithNullId() { 27 | ImmutableList.Builder result = ImmutableList.builder(); 28 | for (int i = 0; i < INITIAL_COLLECTION_SIZE; i++) { 29 | result.add(new StrategyConfiguration( 30 | null, 31 | String.format("className-%s", i), 32 | ImmutableMap.of("key1", "value1", "key2", "value2"), 33 | ImmutableSet.of("instrument1", "instrument2"))); 34 | } 35 | return result.build(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /onplan-service/src/test/java/com/onplan/integration/service/StrategyServiceIT.java: -------------------------------------------------------------------------------- 1 | package com.onplan.integration.service; 2 | 3 | import com.google.common.base.Strings; 4 | import com.onplan.adviser.StrategyInfo; 5 | import com.onplan.adviser.strategy.Strategy; 6 | import com.onplan.domain.configuration.StrategyConfiguration; 7 | import com.onplan.integration.AbstractIT; 8 | import com.onplan.persistence.StrategyConfigurationDao; 9 | import com.onplan.service.StrategyService; 10 | import org.junit.Test; 11 | 12 | import java.util.List; 13 | 14 | import static org.junit.Assert.*; 15 | 16 | public class StrategyServiceIT extends AbstractIT { 17 | private StrategyService strategyService = injector.getInstance(StrategyService.class); 18 | private StrategyConfigurationDao strategyConfigurationDao = 19 | injector.getInstance(StrategyConfigurationDao.class); 20 | 21 | @Test 22 | public void testGetStrategiesTemplateInfo() { 23 | List result = strategyService.getStrategyTemplatesIds(); 24 | assertTrue(!result.isEmpty()); 25 | for (String templateId : result) { 26 | assertTrue(!Strings.isNullOrEmpty(templateId)); 27 | } 28 | } 29 | 30 | @Test 31 | public void testGetStrategiesInfo() { 32 | List result = strategyService.getStrategiesInfo(); 33 | assertTrue(!result.isEmpty()); 34 | for (StrategyInfo strategyInfo : result) { 35 | assertNotNull(strategyInfo.getId()); 36 | assertNotNull(strategyInfo.getDisplayName()); 37 | assertNotNull(strategyInfo.getClassName()); 38 | assertNotNull(strategyInfo.getAvailableParameters()); 39 | assertNotNull(strategyInfo.getRegisteredInstruments()); 40 | assertTrue(!strategyInfo.getRegisteredInstruments().isEmpty()); 41 | } 42 | } 43 | 44 | @Test 45 | public void testLoadSampleStrategies() throws Exception { 46 | strategyService.loadSampleStrategies(); 47 | List strategies = strategyService.getStrategies(); 48 | 49 | List sampleConfigurations = 50 | strategyConfigurationDao.getSampleStrategiesConfiguration(); 51 | List savedConfigurations = 52 | strategyConfigurationDao.findAll(); 53 | assertEquals(sampleConfigurations, savedConfigurations); 54 | 55 | fail("Complete this method by checking the loaded strategies and registered instruments."); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /onplan-service/src/test/java/com/onplan/service/TestingHistoricalPriceService.java: -------------------------------------------------------------------------------- 1 | package com.onplan.service; 2 | 3 | import com.onplan.connector.HistoricalPriceService; 4 | import com.onplan.domain.transitory.PriceBar; 5 | 6 | import java.util.Collection; 7 | 8 | import static com.onplan.util.TestingConstants.DEFAULT_SERVICE_CONNECTION_INFO; 9 | 10 | public class TestingHistoricalPriceService implements HistoricalPriceService { 11 | @Override 12 | public ServiceConnectionInfo getServiceConnectionInfo() { 13 | return DEFAULT_SERVICE_CONNECTION_INFO; 14 | } 15 | 16 | @Override 17 | public Collection getHistoricalPriceBars( 18 | String instrumentId, long barPeriod, long startTimestamp, long endTimestamp) { 19 | throw new IllegalArgumentException("Not yet implemented."); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /onplan-service/src/test/java/com/onplan/service/TestingInstrumentService.java: -------------------------------------------------------------------------------- 1 | package com.onplan.service; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | import com.onplan.connector.InstrumentService; 5 | import com.onplan.domain.InstrumentType; 6 | import com.onplan.domain.transitory.InstrumentInfo; 7 | import org.apache.log4j.Logger; 8 | 9 | import java.util.List; 10 | 11 | public class TestingInstrumentService implements InstrumentService { 12 | private static final Logger LOGGER = Logger.getLogger(TestingInstrumentService.class); 13 | 14 | private static final List availableInstruments = ImmutableList.of( 15 | new InstrumentInfo("CS.EURUSD.TODAY", "EURUSD", InstrumentType.CURRENCY, 4, "DAILY"), 16 | new InstrumentInfo("CS.AUDUSD.TODAY", "AUDUSD", InstrumentType.CURRENCY, 4, "DAILY"), 17 | new InstrumentInfo("IX.DAX.DAILY", "DAX", InstrumentType.INDEX, 0, "DAILY"), 18 | new InstrumentInfo("IX.FTSE.DAILY", "FTSE 100", InstrumentType.INDEX, 0, "DAILY")); 19 | 20 | @Override 21 | public ServiceConnectionInfo getServiceConnectionInfo() { 22 | throw new IllegalArgumentException("Not yet implemented."); 23 | } 24 | 25 | @Override 26 | public InstrumentInfo getInstrumentInfo(String instrumentId) { 27 | for (InstrumentInfo instrumentInfo : availableInstruments) { 28 | if (instrumentId.equals(instrumentInfo.getInstrumentId())) { 29 | return instrumentInfo; 30 | } 31 | } 32 | LOGGER.warn(String.format("Instrument [%s] not found.", instrumentId)); 33 | return null; 34 | } 35 | 36 | @Override 37 | public List findInstrumentsBySearchTerm(String searchTerm) throws Exception { 38 | throw new IllegalArgumentException("Not yet implemented."); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /onplan-service/src/test/java/com/onplan/util/DateTimeUtilTest.java: -------------------------------------------------------------------------------- 1 | package com.onplan.util; 2 | 3 | import com.onplan.domain.PriceBarTimeFrame; 4 | import org.joda.time.DateTime; 5 | import org.joda.time.format.DateTimeFormat; 6 | import org.junit.Test; 7 | 8 | import static com.onplan.util.PriceBarUtil.getCurrentBarCloseTimestamp; 9 | import static com.onplan.util.PriceBarUtil.getCurrentBarOpenTimestamp; 10 | import static org.junit.Assert.assertEquals; 11 | 12 | public class DateTimeUtilTest { 13 | private static final DateTime EXAMPLE_DATE = 14 | DateTime.parse("2001-02-02 08.00.00", DateTimeFormat.forPattern("yyyy-MM-dd hh.mm.ss")); 15 | 16 | @Test 17 | public void testGetCurrentBarOpenTimestamp15m() { 18 | long openTimestamp = getCurrentBarOpenTimestamp( 19 | EXAMPLE_DATE.toDate().getTime(), PriceBarTimeFrame.MINUTES_15); 20 | assertEquals(EXAMPLE_DATE.getMillis(), openTimestamp); 21 | openTimestamp = getCurrentBarOpenTimestamp( 22 | EXAMPLE_DATE.plusMinutes(14).plusSeconds(10).getMillis(), 23 | PriceBarTimeFrame.MINUTES_15); 24 | assertEquals(EXAMPLE_DATE.getMillis(), openTimestamp); 25 | } 26 | 27 | @Test 28 | public void testGetCurrentBarCloseTimestamp15m() { 29 | long closeTimestamp = getCurrentBarCloseTimestamp( 30 | EXAMPLE_DATE.minusMinutes(14).minusSeconds(10).minusMillis(100).toDate().getTime(), 31 | PriceBarTimeFrame.MINUTES_15); 32 | assertEquals(EXAMPLE_DATE.minusMillis(1).getMillis(), closeTimestamp); 33 | closeTimestamp = getCurrentBarCloseTimestamp( 34 | EXAMPLE_DATE.getMillis(), PriceBarTimeFrame.MINUTES_15); 35 | assertEquals(EXAMPLE_DATE.plusMinutes(15).minusMillis(1).getMillis(), closeTimestamp); 36 | } 37 | 38 | @Test 39 | public void testGetCurrentBarOpenTimestamp1m() { 40 | long openTimestamp = getCurrentBarOpenTimestamp( 41 | EXAMPLE_DATE.toDate().getTime(), PriceBarTimeFrame.MINUTES_1); 42 | assertEquals(EXAMPLE_DATE.getMillis(), openTimestamp); 43 | openTimestamp = getCurrentBarOpenTimestamp( 44 | EXAMPLE_DATE.plusSeconds(59).plusMillis(1).getMillis(), 45 | PriceBarTimeFrame.MINUTES_1); 46 | assertEquals(EXAMPLE_DATE.getMillis(), openTimestamp); 47 | } 48 | 49 | @Test 50 | public void testGetCurrentBarCloseTimestamp1() { 51 | long closeTimestamp = getCurrentBarCloseTimestamp( 52 | EXAMPLE_DATE.minusSeconds(50).minusMillis(1).toDate().getTime(), 53 | PriceBarTimeFrame.MINUTES_1); 54 | assertEquals(EXAMPLE_DATE.minusMillis(1).getMillis(), closeTimestamp); 55 | closeTimestamp = getCurrentBarCloseTimestamp( 56 | EXAMPLE_DATE.getMillis(), PriceBarTimeFrame.MINUTES_1); 57 | assertEquals(EXAMPLE_DATE.plusMinutes(1).minusMillis(1).getMillis(), closeTimestamp); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /onplan-service/src/test/java/com/onplan/util/PriceUtilTest.java: -------------------------------------------------------------------------------- 1 | package com.onplan.util; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertEquals; 6 | 7 | public class PriceUtilTest { 8 | @Test 9 | public void testGetPricePips() { 10 | assertEquals(12488.1, PriceBarUtil.getPricePips(1.24881, 4), 0); 11 | assertEquals(8520.9, PriceBarUtil.getPricePips(0.85209, 4), 0); 12 | assertEquals(99505.1, PriceBarUtil.getPricePips(9950.51, 1), 0); 13 | assertEquals(11830.1, PriceBarUtil.getPricePips(118.301, 2), 0); 14 | assertEquals(1187.4, PriceBarUtil.getPricePips(1187.4, 0), 0); 15 | assertEquals(10731, PriceBarUtil.getPricePips(10731, 0), 0); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /onplan-service/src/test/java/com/onplan/util/TestingConstants.java: -------------------------------------------------------------------------------- 1 | package com.onplan.util; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | import com.google.common.collect.ImmutableMap; 5 | import com.onplan.service.ServiceConnectionInfo; 6 | import org.joda.time.DateTime; 7 | import org.joda.time.format.DateTimeFormat; 8 | import org.joda.time.format.DateTimeFormatter; 9 | 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | public class TestingConstants { 14 | private static final DateTimeFormatter DATE_TIME_FORMAT = 15 | DateTimeFormat.forPattern("yyyy-MM-dd hh:mm"); 16 | 17 | public static final DateTime DEFAULT_CREATION_DATE = 18 | DateTime.parse("2012-11-06 08:00", DATE_TIME_FORMAT); 19 | public static final DateTime DEFAULT_START_DATE = 20 | DateTime.parse("2014-05-08 08:00", DATE_TIME_FORMAT); 21 | public static final DateTime DEFAULT_END_DATE = 22 | DateTime.parse("2014-05-08 08:15", DATE_TIME_FORMAT); 23 | public static final long DEFAULT_SPREAD = 1; 24 | public static final String DEFAULT_STRATEGY_ID = "2j8Jl20jHJ"; 25 | public static final String DEFAULT_ALERT_ID = "s2lwer09HJ"; 26 | public static final Map DEFAULT_ADVISER_PARAMETERS = 27 | ImmutableMap.of("key1", "value1", "key2", "value2"); 28 | public static final String DEFAULT_ALERT_MESSAGE = "Sample alert message."; 29 | 30 | public static final String INSTRUMENT_EURUSD_ID = "CS.EURUSD.TODAY"; 31 | public static final String INSTRUMENT_AUDUSD_ID = "CS.AUDUSD.TODAY"; 32 | public static final String INSTRUMENT_DAX_ID = "IX.DAX.DAILY"; 33 | public static final String INSTRUMENT_FTSE100_ID = "IX.FTSE.DAILY"; 34 | public static final List INSTRUMENT_IDS = ImmutableList.of( 35 | INSTRUMENT_EURUSD_ID, 36 | INSTRUMENT_AUDUSD_ID, 37 | INSTRUMENT_DAX_ID, 38 | INSTRUMENT_FTSE100_ID); 39 | 40 | public static final int INITIAL_ALERTS_LIST_SIZE = 7; 41 | public static final int INITIAL_PREDICATES_LIST_SIZE = 5; 42 | public static final int INITIAL_STRATEGIES_LIST_SIZE = 4; 43 | 44 | public static final double PRICE_VALUE_FROM = 0.99239020; 45 | public static final double PRICE_VALUE_TO = 1.00223423; 46 | 47 | public static final ServiceConnectionInfo DEFAULT_SERVICE_CONNECTION_INFO = 48 | new ServiceConnectionInfo("Testing Provider", true, DEFAULT_START_DATE.getMillis()); 49 | } 50 | -------------------------------------------------------------------------------- /onplan-service/src/test/resources/broker-testing.properties: -------------------------------------------------------------------------------- 1 | com.onplan.connector.igindex.apiKey=${com.onplan.adapter.igindex.apiKey} 2 | com.onplan.connector.igindex.username=${com.onplan.adapter.igindex.username} 3 | com.onplan.connector.igindex.password=${com.onplan.adapter.igindex.password} 4 | com.onplan.connector.igindex.severUrl=https://api.ig.com/gateway/deal 5 | -------------------------------------------------------------------------------- /onplan-service/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=WARN, stdout 2 | 3 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 4 | log4j.appender.stdout.Target=System.out 5 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 6 | log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n 7 | -------------------------------------------------------------------------------- /onplan-service/src/test/resources/mongodb-testing.properties: -------------------------------------------------------------------------------- 1 | mongodb.host=localhost 2 | mongodb.port=27017 3 | mongodb.database=onplan-testing -------------------------------------------------------------------------------- /onplan-service/src/test/resources/notification-testing.properties: -------------------------------------------------------------------------------- 1 | notification.notify.service.connection=true 2 | notification.notify.service.disconnection=true 3 | 4 | notification.mongodb.enabled=true 5 | 6 | notification.smtp.enabled=true 7 | notification.smtp.from=${notification.smtp.from} 8 | notification.smtp.to=${notification.smtp.to} 9 | 10 | notification.amazonsqs.enabled=true 11 | notification.amazonsqs.systemEventQueueUrl=${notification.amazonsqs.systemEventQueueUrl} 12 | notification.amazonsqs.alertEventQueueUrl=${notification.amazonsqs.alertEventQueueUrl} 13 | 14 | notification.twitter.enabled=true 15 | notification.twitter.recipientScreeName=${notification.twitter.recipientScreeName} 16 | -------------------------------------------------------------------------------- /onplan-service/src/test/resources/system-testing.properties: -------------------------------------------------------------------------------- 1 | # All the time values are in UTC time 2 | market.forex.openTime=22:00 3 | market.forex.closeTime=22:00 4 | market.europeanIndexes.openTime=08:00 5 | market.europeanIndexes.closeTime=16:30 6 | 7 | system.alertservice.disabled=false -------------------------------------------------------------------------------- /onplan/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | 1.8 9 | 1.0-SNAPSHOT 10 | 1.8 11 | WARN, stdout 12 | INFO 13 | UTF-8 14 | UTF-8 15 | 16 | 17 | 18 | 19 | development 20 | 21 | true 22 | 23 | 24 | 25 | 26 | com.melphi 27 | onplan 28 | 1.0-SNAPSHOT 29 | pom 30 | 31 | 32 | ../onplan-core 33 | ../onplan-core-connector 34 | ../onplan-core-adviser 35 | ../onplan-connectors/onplan-connector-igindex 36 | 37 | 38 | 39 | 40 | 41 | org.apache.maven.plugins 42 | maven-compiler-plugin 43 | 3.2 44 | 45 | ${com.java.version} 46 | ${com.java.version} 47 | 48 | 49 | 50 | 51 | 52 | --------------------------------------------------------------------------------