package org.cryptocoinpartners.module;
import java.math.BigDecimal;
import javax.annotation.Nullable;
import javax.inject.Inject;
import org.apache.commons.configuration.Configuration;
import org.cryptocoinpartners.esper.annotation.When;
import org.cryptocoinpartners.schema.Book;
import org.cryptocoinpartners.schema.DiscreteAmount;
import org.cryptocoinpartners.schema.Fill;
import org.cryptocoinpartners.schema.Market;
import org.cryptocoinpartners.schema.Offer;
import org.cryptocoinpartners.schema.Order;
import org.cryptocoinpartners.schema.OrderBuilder;
import org.cryptocoinpartners.schema.OrderBuilder.CommonOrderBuilder;
/**
* This simple Strategy first waits for Book data to arrive about the target Market, then it places a buy order
* at demostrategy.spread below the current bestAsk. Once it enters the trade, it places a sell order at
* demostrategy.spread above the current bestBid.
* This strategy ignores the available Positions in the Portfolio and always trades the amount set by demostrategy.volume on
* the Market specified by demostrategy.market
*
* @author Tim Olson
*/
@SuppressWarnings("UnusedDeclaration")
public class DemoStrategy extends SimpleStatefulStrategy {
@Inject
public DemoStrategy(Context context, Configuration config) {
// String marketSymbol = config.getString("demostrategy.market","BITFINEX:BTC.USD");
String marketSymbol = ("BITFINEX:BTC.USD");
market = context.getInjector().getInstance(Market.class).forSymbol(marketSymbol);
if (market == null)
throw new Error("Could not find Market for symbol " + marketSymbol);
BigDecimal volumeBD = new BigDecimal("1");// 100 satoshis
volumeCount = DiscreteAmount.roundedCountForBasis(volumeBD, market.getVolumeBasis());
}
@When("select * from Book")
void handleBook(Book b) {
if (b.getMarket().equals(market)) {
bestBid = b.getBestBid();
bestAsk = b.getBestAsk();
// if (bestBid != null && bestAsk != null) {
// ready();
// enterTrade();
// exitTrade();
// log.info("Portfolio: " + portfolio + " Total Value (" + portfolio.getBaseAsset() + "):"
// + portfolioService.getCashBalance().plus(portfolioService.getMarketValue()) + " (Cash Balance:" + portfolioService.getCashBalance()
// + " Open Trade Equity:" + portfolioService.getMarketValue() + ")");
// }
}
}
@Override
@SuppressWarnings("ConstantConditions")
protected OrderBuilder.CommonOrderBuilder buildEntryOrder() {
if (bestAsk == null)
return null;
DiscreteAmount limitPrice = bestBid.getPrice().decrement();
return order.create(context.getTime(), market, volumeCount).withLimitPrice(limitPrice);
}
@Override
@SuppressWarnings("ConstantConditions")
protected OrderBuilder.CommonOrderBuilder buildExitOrder(Order entryOrder) {
if (bestBid == null)
return null;
DiscreteAmount limitPrice = bestAsk.getPrice().increment();
return order.create(context.getTime(), market, -volumeCount).withLimitPrice(limitPrice);
}
//
private Offer bestBid;
private Offer bestAsk;
private final Market market;
private final long volumeCount;
@Override
@Nullable
protected CommonOrderBuilder buildStopOrder(Fill fill) {
// TODO Auto-generated method stub
return null;
}
}