package jforex; import com.dukascopy.api.*; import java.util.*; public class Linnux_DEZ2010 implements IStrategy { /// --- Strategy interfaces which are used to execute trades, request indicators, etc --- /// private IContext context = null; private IEngine engine = null; private IChart chart = null; private IHistory history = null; private IIndicators indicators = null; private IConsole console = null; private IOrder order = null; public IAccount account; ////////// --- Private and Public Variables ---////////// private double volume = 4; private int profitLimit = 75; private int lossLimit = 55; private double bidPrice; private double askPrice; private double accountEquity; public double lockPip = 5.5; public boolean moveBE = true; private double myTotalPositiveProfit = 0.0; private boolean closedOrder = false; ////////// --- Periods for Tendence Market --- ////////// private static final Period PeriodTurbo = Period.ONE_MIN; private static final Period PeriodSmall = Period.FIFTEEN_MINS; private static final Period PeriodLong = Period.ONE_HOUR; private int fastMA = 4; private int longMA = 12; @Override public void onStart(IContext context) throws JFException { this.engine = context.getEngine(); this.indicators = context.getIndicators(); this.history = context.getHistory(); this.console = context.getConsole(); this.context = context; } @Override public void onStop() throws JFException { } @Override public void onBar(Instrument instrument, Period period, IBar askbar, IBar bidbar) throws JFException { if(period == Period.FIFTEEN_MINS) { if (askbar.getVolume() == 0) return; if (isTradingAllowed()) { double openPrice = bidbar.getOpen(); askPrice = askbar.getClose(); bidPrice = bidbar.getClose(); ////////// --- Indicators for Verify Trend --- ////////// double sma50 = this.indicators.ema(instrument, period, OfferSide.BID, IIndicators.AppliedPrice.CLOSE, 50, 0); double sma100 = this.indicators.ema(instrument, period, OfferSide.BID, IIndicators.AppliedPrice.CLOSE, 100, 0); double sma200 = this.indicators.ema(instrument, period, OfferSide.BID, IIndicators.AppliedPrice.CLOSE, 200, 0); ////////// --- Indicator for Verify BreakOut --- ////////// double [] bands = this.indicators.bbands(instrument, period, OfferSide.BID, IIndicators.AppliedPrice.CLOSE, 150, 1, 1, IIndicators.MaType.DEMA, 0); if (positionsTotal(instrument) == 0) { ////////// --- Condition for BUY --- ////////// if (bidPrice > bands[0] && openPrice < bands[0] && bidPrice > sma50 && bidPrice > sma100 && bidPrice > sma200 && tendance(instrument, bidbar)==1) { buy(instrument, engine, profitLimit, lossLimit, volume); } else ////////// --- Condition for Sell --- ////////// if (bidPrice < bands[2] && openPrice > bands[2] && bidPrice < sma50 && bidPrice < sma100 && bidPrice < sma200 && tendance(instrument, bidbar)==3) { sell(instrument, engine, profitLimit, lossLimit, volume); } } //this.setTrailingStop(instrument, 25); ////////// --- TrailingStop --- ////////// myTrailingStop(instrument, askbar, 150.5 * instrument.getPipValue(), 90.5 * instrument.getPipValue(), 5.5 * instrument.getPipValue()); } } } @Override public void onTick(Instrument instrument, ITick tick) throws JFException { closeOrder(); for (IOrder order : engine.getOrders(instrument)) { if (order.getState() == IOrder.State.FILLED) { boolean isLong; double open, stop, diff, newStop; String label = order.getLabel(); IChart chart; isLong = order.isLong(); open = order.getOpenPrice(); stop = order.getStopLossPrice(); diff = (open - stop); // stop loss distance if (isLong) { // long side order if (moveBE && diff > 0 && tick.getBid() > (open + diff)) { // make it breakeven trade + lock in a few pips newStop = open + instrument.getPipValue() * lockPip; order.setStopLossPrice(newStop); console.getOut().println(label + ": Moved stop to breakeven"); chart = this.context.getChart(instrument); chart.draw(label + "_BE", IChart.Type.SIGNAL_UP, tick.getTime(), newStop); } } else { // short side order // Move to breakeven if (moveBE && diff < 0 && tick.getAsk() < (open + diff)) { // diff is negative // make it breakeven trade + lock in a few pips newStop = open - (instrument.getPipValue() * lockPip); order.setStopLossPrice(newStop); console.getOut().println(label + ": Moved stop to breakeven"); chart = this.context.getChart(instrument); chart.draw(label + "_BE", IChart.Type.SIGNAL_DOWN, tick.getTime(), newStop); } } } } } @Override public void onMessage(IMessage message) throws JFException { if (message != null && message.getType() == IMessage.Type.ORDER_CLOSE_OK) { IOrder lastOne = message.getOrder(); double profitsLoss = lastOne.getProfitLossInPips(); console.getOut().println("Linnux_Order : "+lastOne.getLabel()+ " "+ lastOne.getOrderCommand()+ " Pips: "+profitsLoss); } } protected String getLabel(Instrument instrument) { String label = instrument.name(); long time = new java.util.Date().getTime(); label = label.substring(0, 2) + label.substring(3, 5); label = label + time; label = label.toLowerCase(); return label; } @Override public void onAccount(IAccount account) throws JFException {this.account = account;} //************************ Managing Tools Methods ************************ ////////// --- Method for Sell --- ////////// public void sell(Instrument instrument, IEngine engine, int takeProfitPipLevel, int endLossPipLevel, double volumeParam) throws JFException { engine.submitOrder(getLabel(instrument), instrument, IEngine.OrderCommand.SELL, volumeParam, 0, 3, bidPrice + instrument.getPipValue() *endLossPipLevel, bidPrice - instrument.getPipValue() * takeProfitPipLevel); } ////////// --- Method for Buy --- ////////// public void buy(Instrument instrument, IEngine engine, int takeProfitPipLevel, int endLossPipLevel, double volumeParam) throws JFException { engine.submitOrder(getLabel(instrument), instrument, IEngine.OrderCommand.BUY, volumeParam, 0, 3, askPrice - instrument.getPipValue() * endLossPipLevel, askPrice + instrument.getPipValue() * takeProfitPipLevel); } ////////// --- Method for TrailingStop --- ////////// protected void myTrailingStop(Instrument instrument, IBar bar, double defaultTakeProfit, double defaultStopLoss, double minStopLoss) throws JFException { double newStopLoss; double sign; double open; double close; double current; double reduction; for (IOrder order : engine.getOrders()) { if (order.getState() == IOrder.State.FILLED) { sign = order.isLong() ? 1 : -1; open = order.getOpenPrice(); close = bar.getClose() + sign * defaultTakeProfit; current = bar.getClose(); reduction = 1.0 - Math.pow((current - open) / (close - open), 2); newStopLoss = current - sign * defaultStopLoss * reduction; newStopLoss = sign * Math.min(sign * newStopLoss, sign * (current - sign * minStopLoss)); if (sign * newStopLoss > sign * (order.getStopLossPrice() + sign * instrument.getPipValue())) { order.setStopLossPrice(newStopLoss, OfferSide.ASK); } } } } ////////// --- count opened positions --- ////////// protected int positionsTotal(Instrument instrument) throws JFException { int counter = 0; for (IOrder order : engine.getOrders(instrument)) { if (order.getState() == IOrder.State.FILLED) { counter++; } } return counter; } ////////// --- Method for Verify the Market Tendance --- ////////// public int tendance(Instrument instrument, IBar bidbar) throws JFException { if((MADirection(instrument,this.PeriodTurbo,this.fastMA, this.longMA)==0) && (MADirection(instrument,this.PeriodSmall,this.fastMA, this.longMA)==0) && (MADirection(instrument,this.PeriodLong,this.fastMA, this.longMA)==0)){ //this.console.getOut().println("Ma UP"); return 3; } if((MADirection(instrument,this.PeriodTurbo,this.fastMA, this.longMA)==1) && (MADirection(instrument,this.PeriodSmall,this.fastMA, this.longMA)==1) && (MADirection(instrument,this.PeriodLong,this.fastMA, this.longMA)==1)){ // this.console.getOut().println("Ma Down"); return 1; } return 2; } ////////// --- Method for Verify if fast MA is over slow MA --- ////////// public int MADirection(Instrument instrument,Period period, int ma1, int ma2)throws JFException { double fastMA = indicators.ema(instrument, period, OfferSide.BID, IIndicators.AppliedPrice.MEDIAN_PRICE, ma1, 0); double slowMA = indicators.ema(instrument, period, OfferSide.BID, IIndicators.AppliedPrice.MEDIAN_PRICE, ma2, 0); if(fastMA>slowMA){return(1);} else{return(0);} } ///////// --- Method for Rule: max. one position only --- ////////// public boolean isTradingAllowed() {return (this.account.getUseOfLeverage() == 0d);} ////////// --- Method for Rule: bellow 25% max win --- ////////// public void closeOrder() throws JFException { List orderList = engine.getOrders(); for (IOrder order : orderList) { if (order.getState() == IOrder.State.CLOSED) { if (order.getProfitLossInUSD() > 0){ myTotalPositiveProfit += order.getProfitLossInUSD(); closedOrder = true; } } } for (IOrder order : orderList) { if (order.getState() == IOrder.State.FILLED) { if ((order.getProfitLossInUSD() > myTotalPositiveProfit*0.25) && closedOrder == true){ order.close(); } } } } }