package org.cryptocoinpartners.bin; import java.util.Arrays; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; import javax.inject.Inject; import org.cryptocoinpartners.enumeration.TransactionType; import org.cryptocoinpartners.module.BasicPortfolioService; import org.cryptocoinpartners.module.BasicQuoteService; import org.cryptocoinpartners.module.Context; import org.cryptocoinpartners.module.MockOrderService; import org.cryptocoinpartners.module.SaveMarketData; import org.cryptocoinpartners.module.xchange.XchangeAccountService; import org.cryptocoinpartners.module.xchange.XchangeData; import org.cryptocoinpartners.schema.DiscreteAmount; import org.cryptocoinpartners.schema.Holding; import org.cryptocoinpartners.schema.Portfolio; import org.cryptocoinpartners.schema.ReplayFactory; import org.cryptocoinpartners.schema.StrategyInstance; import org.cryptocoinpartners.schema.Transaction; import org.cryptocoinpartners.schema.TransactionFactory; import org.cryptocoinpartners.service.OrderService; import org.cryptocoinpartners.util.ConfigUtil; import org.cryptocoinpartners.util.Replay; import org.joda.time.DateTime; import org.joda.time.Duration; import org.joda.time.Instant; import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; import com.espertech.esper.client.time.TimerControlEvent; /** * @author Tim Olson */ @SuppressWarnings("UnusedDeclaration") @Parameters(commandNames = { "paper" }, commandDescription = "Run strategies against live streaming data but use the mock order system instead of live trades") public class PaperTradeRunMode extends RunMode { @Inject protected transient TransactionFactory transactionFactory; @Inject protected transient ReplayFactory replayFactory; public List<String> positions = Arrays.asList("OKCOIN:USD", "1000000"); //private final Instant start = new DateTime(2014, 11, 01, 0, 0, 0, 0, DateTimeZone.UTC).toInstant(); final ExecutorService service = Executors.newSingleThreadExecutor(); private final Instant end = new DateTime(DateTime.now()).toInstant(); Semaphore paperSemaphore = new Semaphore(0); private final Instant start = end.minus(Duration.standardHours(25)).toInstant(); // new DateTime(2013, 12, 20, 0, 0, 0, 0, DateTimeZone.UTC).toInstant(); @Override public void run(Semaphore semaphore) { //context = Context.create(); Replay replay = replayFactory.between(start, end, true, paperSemaphore); context = replay.getContext(); context.attach(XchangeAccountService.class); context.attach(BasicQuoteService.class); context.attach(BasicPortfolioService.class); context.attach(MockOrderService.class); for (String strategyName : strategyNames) { StrategyInstance strategyInstance = new StrategyInstance(strategyName); context.attachInstance(strategyInstance); setUpInitialPortfolio(strategyInstance); // context.getInjector().getInstance(cls) } // Future future = service.submit(replay); //while (!future.isDone()) { //} replay.run(); //context.esperConfig.getEngineDefaults().getThreading().setInternalTimerEnabled(false); context.setTimeProvider(null); context.publish(new TimerControlEvent(TimerControlEvent.ClockType.CLOCK_INTERNAL)); // context.setTimeProvider(null); OrderService orderService = context.getInjector().getInstance(OrderService.class); // context.publish(new TimerControlEvent(TimerControlEvent.ClockType.CLOCK_INTERNAL)); // context.publish(new TimerControlEvent(TimerControlEvent.ClockType.CLOCK_INTERNAL)); if (ConfigUtil.combined().getBoolean("save.marketdata", true)) context.attach(SaveMarketData.class); context.attach(XchangeData.class); orderService.setTradingEnabled(true); // context.publish(new TimerControlEvent(TimerControlEvent.ClockType.CLOCK_INTERNAL)); // if (semaphore != null) // semaphore.release(); } private void setUpInitialPortfolio(StrategyInstance strategyInstance) { // @Inject // Portfolio portfolio; // ;= context.getInjector().getInstance(Portfolio.class); Portfolio portfolio = strategyInstance.getPortfolio(); if (positions.size() % 2 != 0) { System.err.println("You must supply an even number of arguments to the position switch. " + positions); } for (int i = 0; i < positions.size() - 1;) { Holding holding = Holding.forSymbol(positions.get(i++)); // Long str = (positions.get(i++)); DiscreteAmount amount = new DiscreteAmount(Long.parseLong(positions.get(i++)), holding.getAsset().getBasis()); DiscreteAmount price = new DiscreteAmount(0, holding.getAsset().getBasis()); Transaction initialCredit = transactionFactory.create(portfolio, holding.getExchange(), holding.getAsset(), TransactionType.CREDIT, amount, price); context.setPublishTime(initialCredit); context.publish(initialCredit); initialCredit.persit(); strategyInstance.getStrategy().init(); } } @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") @Parameter(description = "Strategy name to load", arity = 1, required = true) public List<String> strategyNames; private Context context; @Override public void run() { Semaphore semaphore = null; run(semaphore); } }