Dukascopy
 
 
Wiki JStore Search Login

Attention! Read the forum rules carefully before posting a topic.

    Try to find an answer in Wiki before asking a question.
    Submit programming questions in this forum only.
    Off topics are strictly forbidden.

Any topics which do not satisfy these rules will be deleted.

Candlestick & MA strategy
 Post subject: Candlestick & MA strategy Post rating: 0   New post Posted: Thu 21 Jul, 2011, 13:18 

User rating: 0
Joined: Wed 20 Jul, 2011, 10:33
Posts: 6
Location: JM
Hi everyone i was wondering if anyone has created or worked with candlesticks in an automated strategy.

If you have and are willing to share some or part of your code with me this would be very helpful to me as i am currently doing a my Masters dissertation and need this for research.

The basic idea is to see if Japanese candlestick trading techniques as proposed Steve Nison have any power in predicting reversal patterns.

I am using a simple test with only a few candlesticks and a Moving average as basic indicator of trend.

If you have never done this before but are keen to help, this is the basic idea of what i am trying to accomplish.

I will use the only the engulfing pattern to illustrate the idea.


Start of Program
Sell signal


If ( the close price of the last bar is greater than the MA(5) &&
If the previous 2 candles formed a bearish engulfing pattern (green candle, flowed by red that is larger))
then
{ sell the instrument at 5 pips below its previous bar's low using a limit order }

Buy signal

If ( the close price of the last bar is less than the MA(5) &&
If the previous 2 candles formed a bullish engulfing pattern (red candle, flowed by green that is larger))
then
{ buy the instrument at 5 pips above its previous bar's high using a limit order }

Close Order

All orders should be closed at takeprofit or stoploss
or if 5 bars have passed and the limit order has not been filled.

End of Program


There is no need to include risks management code as there are plenty of examples on the forum. So we can simply assume a constant lot size of $10,000.

It would be extremely appreciative of your assistance as i am very new to java.

Cheers.


 
 Post subject: Re: Candlestick & MA strategy Post rating: 0   New post Posted: Mon 25 Jul, 2011, 15:24 

User rating: 0
Joined: Wed 20 Jul, 2011, 10:33
Posts: 6
Location: JM
This what i have been able to come up with so far. I am however having problem closing pending trades using goodtilltime. I keep getting the following error

"com.dukascopy.api.JFException: Good till time is incorrect @ jforex.BasicCandleSticks2.submitOrder(BasicCandleSticks2.java:143)"

I have tried using a fixed number "60000" and tried calculating a value as in the code below neither works. If you can help it would greatly be appreciated.

Cheers.

package jforex;
import java.util.*;
import javax.print.attribute.standard.OutputDeviceAssigned;

import com.dukascopy.api.*;
import com.dukascopy.api.IEngine.OrderCommand;
import com.dukascopy.api.IIndicators.AppliedPrice;
import com.dukascopy.api.IIndicators.MaType;

public class BasicCandleSticks implements IStrategy {
   
  public Instrument instrument = Instrument.EURUSD;   
  public Period period         = Period.ONE_HOUR;
  public double amount           = 0.001;
  public int stopLossPips      = 40;
  public int takeProfitPips    = 40;
  public double minMove        = 5;
  public int maxPendingBars    = 5;
 
     
    private IEngine engine;
    private IConsole console;
    private IHistory history;
    private IContext context;
    private IIndicators indicators;
    private IUserInterface userInterface;
   
    //variable to be used throughout the program
    int  trendMaPeriod  = 5;
    double trendMa      = 0;
    double previousOpen = 0;
    double previousClose= 0;
    int candlePattern   = 0;
    OrderCommand orderCmd;
    private IOrder activeOrder;
    boolean isBullish;
    boolean tradingAllowed = true;
   
   
   
    public void onStart(IContext context) throws JFException {
        this.engine = context.getEngine();
        this.console = context.getConsole();
        this.history = context.getHistory();
        this.context = context;
        this.indicators = context.getIndicators();
        this.userInterface = context.getUserInterface();
        System.out.println("------ Auto Trading Started!-----------");
    }

    public void onAccount(IAccount account) throws JFException {
    }

    public void onMessage(IMessage message) throws JFException {
    }

    public void onStop() throws JFException {
    System.out.println("------ Auto Trading Stopped!-----------");
    }

    public void onTick(Instrument instrument, ITick tick) throws JFException {
    }
   
    public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar)
    throws JFException
    {
       // set the value of the indicators used
        previousOpen  = this.history.getBar(instrument, period,OfferSide.BID, 1).getOpen();
        previousClose = this.history.getBar(instrument, period,OfferSide.BID, 1).getClose();
        trendMa          = this.indicators.ma(instrument, period, OfferSide.BID,AppliedPrice.CLOSE,trendMaPeriod, MaType.SMA,1);
        //candlePattern = this.indicators.cdlDarkCloudCover(instrument, period, OfferSide.BID, 0.50, 1);
        candlePattern = this.indicators.cdlEngulfing(instrument, period, OfferSide.BID, 1);
       
       
        //dukascopy does not differential between bullish and bearish engulfing patterns,
        //but this is important when considering the pattern as trading signal;
       
        if (previousOpen < previousClose)
            {isBullish = true;}
        else
            {isBullish = false;}
       
        //     if open and close  are > ma(5) and bearish engulfing pattern---- SELL

        if ((previousOpen >trendMa)&&(previousClose > trendMa)&& (candlePattern !=0) && !isBullish && positionsTotal(instrument) == 0 )
                // tradingAllowed)
        {
            submitOrder(amount, OrderCommand.PLACE_OFFER);
        }
       
        // if open and close are < ma(5) and bullishing engulfing pattern----BUY
        if ((previousOpen < trendMa)&&(previousClose < trendMa)&& (candlePattern !=0) && isBullish && positionsTotal(instrument) == 0 )//tradingAllowed)
        {
            submitOrder(amount, OrderCommand.PLACE_BID);
        }
       
    }

   
     private IOrder submitOrder(double amount, OrderCommand orderCmd) throws JFException{
          double stopLossPrice, takeProfitPrice,orderPrice;
         
          // we are only interested interested in orders that move a certain amount of pips in the correct direction
          double prevHigh = history.getBar(instrument, period, OfferSide.BID,1).getHigh();
          double prevLow  = history.getBar(instrument, period, OfferSide.ASK,1).getLow();
                 
   long goodTillTime = history.getTimeForNBarsForward(period, 0, maxPendingBars) - history.getStartTimeOfCurrentBar(instrument, period);
         
        //Calculating stop loss and take profit prices
          if (orderCmd == OrderCommand.PLACE_BID){
           stopLossPrice   = history.getLastTick(this.instrument).getBid() - this.stopLossPips * this.instrument.getPipValue();
           takeProfitPrice = history.getLastTick(this.instrument).getBid() + this.takeProfitPips * this.instrument.getPipValue();
           orderPrice      =  prevHigh + minMove * this.instrument.getPipValue();
          }else {
           stopLossPrice   =  history.getLastTick(this.instrument).getAsk() + this.stopLossPips * this.instrument.getPipValue();
           takeProfitPrice = history.getLastTick(this.instrument).getAsk() - this.takeProfitPips * this.instrument.getPipValue();
           orderPrice      =  prevLow - minMove * this.instrument.getPipValue();
          }           
          //Submitting an order for the specified instrument at the current market price       
          return engine.submitOrder(getLabel(this.instrument), this.instrument, orderCmd, amount, orderPrice,5, stopLossPrice, takeProfitPrice,goodTillTime);   
         }
     
     
        // count opened positions
        protected int positionsTotal(Instrument instrument) throws JFException {
            int counter = 0;
            activeOrder = null;
            for (IOrder order : engine.getOrders(instrument)) {
                if ((order.getState() == IOrder.State.FILLED) && order.getLabel().equals(getLabel(instrument))) {
                   
                    activeOrder = order;
                    counter++;
                }
            }
            return counter;
        }
     
     
        protected String getLabel(Instrument instrument) {
            String label = instrument.name();
            String usd     = "USD";
           
            if (label.substring(3).endsWith(usd))
                {   label = label.substring(0, 2);}
            else
                {   label = label.substring(3,6);}
               
            label = "ActiveOrder" + label;
           
            return label;
           
        }     
   
}


 
 Post subject: Re: Candlestick & MA strategy Post rating: 0   New post Posted: Wed 27 Jul, 2011, 13:32 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
Hi

Here is a strategy that should solve your problem:
package jforex;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

import com.dukascopy.api.*;
import com.dukascopy.api.IEngine.OrderCommand;
import com.dukascopy.api.IIndicators.AppliedPrice;
import com.dukascopy.api.IOrder.State;
import com.dukascopy.api.indicators.IIndicator;

public class CandleStrategy implements IStrategy {
   private IEngine engine;
   private IHistory history;
   private IIndicators indicators;
   private int counter = 0;
   private IConsole console;

   @Configurable("Instrument")
   public Instrument instrument = Instrument.EURUSD;
   @Configurable("Period")
   public Period selectedPeriod = Period.TEN_SECS; // the duration of a bar
   @Configurable("Moving average length")
   public int maLength = 5; // the number of bars that are considered in the calculation of the MA
   @Configurable("Order expiration interval")
   public int orderExpirationInterval = 5; // the number of periods after which an opened order will be closed
   @Configurable("Amount")
   public double amount = 0.02;
   @Configurable("Stop loss")
   public int stopLossPips = 10;
   @Configurable("Take profit")
   public int takeProfitPips = 90;
   @Configurable("Preferred price shift")
   public int priceShiftPips = 5; // the number of pips that is used to calculate the price of an order

   @SuppressWarnings("serial")
   private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") {{setTimeZone(TimeZone.getTimeZone("GMT"));}};
   
   public void onStart(IContext context) throws JFException {
      this.engine = context.getEngine();
      this.history = context.getHistory();
      this.indicators = context.getIndicators();
      this.console = context.getConsole();
      
      IIndicator indMax = indicators.getIndicator("MA");
      for (int i = 0; i < indMax.getIndicatorInfo().getNumberOfOptionalInputs(); i++){
          console.getOut().println( i + ": name = '"+ indMax.getOptInputParameterInfo(i).getName() + "' type = "+ indMax.getOptInputParameterInfo(i).getType());
      }
      
      context.getChart(instrument).addIndicator(indicators.getIndicator("MA"), new Object[]{maLength, IIndicators.MaType.SMA.ordinal()});
   }

   public void onAccount(IAccount account) throws JFException {
   }

   public void onMessage(IMessage message) throws JFException {
      String label = (message.getOrder() == null ? "" : message.getOrder().getLabel());
      print(label + " " + message.getType() + " " + message.getContent() );
   }

   public void onStop() throws JFException {
      // close all orders
      for (IOrder order : engine.getOrders()) {
         engine.getOrder(order.getLabel()).close();
      }
   }

   public void onTick(Instrument instrument, ITick tick) throws JFException {
   }

   public boolean isBearishEngulfingPattern(IBar firstBar, IBar secondBar) {
      return firstBar.getOpen() < firstBar.getClose()
            && firstBar.getClose() < secondBar.getOpen()
            && firstBar.getOpen() > secondBar.getClose();
   }

   public boolean isBullishEngulfingPattern(IBar firstBar, IBar secondBar) {
      return firstBar.getOpen() > firstBar.getClose()            
            && firstBar.getClose() > secondBar.getOpen()
            && firstBar.getOpen() < secondBar.getClose();
   }

   public void onBar(Instrument instrument, Period period, IBar askBar,
         IBar bidBar) throws JFException {
      
      if (!instrument.equals(this.instrument) || !period.equals(selectedPeriod))
         return;
      
      long currentTime = askBar.getTime() + period.getInterval();

      // Sell signal

      IBar firstBidBar = history.getBar(instrument, period, OfferSide.BID, 2);
      IBar secondBidBar = history.getBar(instrument, period, OfferSide.BID, 1);
      
      int shift = 0;

      double bidMA5 = indicators.ma(instrument, period, OfferSide.BID, IIndicators.AppliedPrice.CLOSE, maLength, IIndicators.MaType.SMA, shift);
      
      // If ( the close price of the last bar is greater than the MA(5) &&         
      // If the previous 2 candles formed a bearish engulfing pattern (green candle, flowed by red that is larger))
      if( bidMA5 < secondBidBar.getClose() && isBearishEngulfingPattern(firstBidBar, secondBidBar) )
      {
         submitOrder(OrderCommand.SELLLIMIT, secondBidBar, currentTime);
      }

      // Buy signal

      IBar firstAskBar = history.getBar(instrument, period, OfferSide.ASK, 2);
      IBar secondAskBar = history.getBar(instrument, period, OfferSide.ASK, 1);

      double askMA5 = indicators.ma(instrument, period, OfferSide.ASK, IIndicators.AppliedPrice.CLOSE, maLength, IIndicators.MaType.SMA, shift);

      // If ( the close price of the last bar is less than the MA(5) &&
      // If the previous 2 candles formed a bullish engulfing pattern (red candle, flowed by green that is larger))
      if( askMA5 > secondAskBar.getClose() && isBullishEngulfingPattern(firstAskBar, secondAskBar) )
      {
         submitOrder(OrderCommand.BUYLIMIT, secondAskBar, currentTime);
      }

      // Close orders for which 5 bars have passed and the limit order has not been filled.
      long expirationTime = currentTime - period.getInterval() * orderExpirationInterval;
      
      for (IOrder order : engine.getOrders())
      {
         if (order.getCreationTime() <= expirationTime && order.getState().equals(IOrder.State.OPENED) )
         {
            print(currentTime, "Order has expired and therefore was closed: "+order.getId());
            order.close();
         }
      }
   }

   private IOrder submitOrder(OrderCommand orderCmd, IBar lastBar, long currentTime) throws JFException {
      // All orders should be closed at takeprofit or stoploss
      double stopLossPrice, takeProfitPrice, price;

      // Calculating order price, stop loss and take profit prices
      if (orderCmd == OrderCommand.BUYLIMIT) {
         stopLossPrice = history.getLastTick(this.instrument).getBid() - getPipPrice(this.stopLossPips);
         takeProfitPrice = history.getLastTick(this.instrument).getBid() + getPipPrice(this.takeProfitPips);

         // buy the instrument at 5 pips above its previous bar's high using a limit order
         price = lastBar.getHigh() + getPipPrice(priceShiftPips);
         
      } else {
         stopLossPrice = history.getLastTick(this.instrument).getAsk() + getPipPrice(this.stopLossPips);
         takeProfitPrice = history.getLastTick(this.instrument).getAsk() - getPipPrice(this.takeProfitPips);   

         // sell the instrument at 5 pips below its previous bar's low using a limit order
         price = lastBar.getLow() - getPipPrice(priceShiftPips);
      }

      // Submitting an order
      return engine.submitOrder( getLabel(instrument), this.instrument, orderCmd, this.amount, price, 0, stopLossPrice,   takeProfitPrice);
   }

   protected String getLabel(Instrument instrument) {
      String label = instrument.name();
      label = label + (counter++) + "-";
      label = label.toUpperCase();
      return label;
   }

   private double getPipPrice(int pips) {
      return pips * this.instrument.getPipValue();
   }
   
   private void print( long time, Object o ) {
      print( sdf.format(time) + " " + o);
   }
   
   private void print(Object o){
      console.getOut().println( o );
   }

}


Some notes on your code:
  • Your code used only bid bars to find the candle patterns. It might be more appropriate to use ask bars for making buying orders and bid bars for selling.
  • To create a limit order use OrderCommand.BUYLIMIT and OrderCommand.SELLLIMIT, rather than PLACE_BID and PLACE_OFFER.
    More information on order commands can be found here: https://www.dukascopy.com/client/javadoc ... mmand.html.


 
 Post subject: Re: Candlestick & MA strategy Post rating: 0   New post Posted: Fri 29 Jul, 2011, 11:04 

User rating: 0
Joined: Wed 20 Jul, 2011, 10:33
Posts: 6
Location: JM
Wow that looks amazing will try it out and get back to you. Thanks very much all the help.


 
 Post subject: Re: Candlestick & MA strategy Post rating: 0   New post Posted: Wed 17 Aug, 2011, 14:58 

User rating: 0
Joined: Wed 20 Jul, 2011, 10:33
Posts: 6
Location: JM
Hi everyone just a follow up on this this is my final program if you could take a look and see if there are any obvious errors in login that would be much appreciated.

Also I am struggling with trying to back-test it over a year on a large EC2 server from amazon, does anyone have an recommendations or useful tips in how i could speed up the backtest.

package jforex;

import java.util.*;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

//import javax.print.attribute.standard.OutputDeviceAssigned;

import com.dukascopy.api.*;
import com.dukascopy.api.IEngine.OrderCommand;
import com.dukascopy.api.IIndicators.AppliedPrice;
import com.dukascopy.api.IIndicators.MaType;

//------------------------------------------------------------------

public class BasicCandleSticks implements IStrategy {
   
//Configurable parameters
   
  @Configurable("Instrument")
    public Instrument instrument = Instrument.EURUSD;
   
 // @Configurable("Period")
    public Period period          = Period.FIFTEEN_MINS;
   
   
   @Configurable("Amount")
    public double amount          = 0.01;
   
  @Configurable("Stop loss")
    public int stopLossPips      = 40;
   
   @Configurable("Take profit")
    public int takeProfitPips      = 80;
   
//    @Configurable("Order expiration interval")
    public int orderExpirationInterval = 5; // the number of periods after which an opened order will be closed
   
//    @Configurable("Preferred price shift")
    public int priceShiftPips = 5; // the number of pips that is used to calculate the price of an order
   
//    @Configurable("Lock-in Pips for Breakeven")
    public int lockPip              = 10;
   
//    @Configurable("Move stop to breakeven?")
    public boolean moveBE          = false; 
   
    @Configurable("Trailing stop in Pips")
    public int trailingStop         = 15;
   
//    @Configurable(" Bar Shift")
    public int barShift             = 0;
   
//    @Configurable("Use a trailing stop ?")
    public boolean useTrailingStop= true;     
   
//    @Configurable("Use trading hours ?")   
    public boolean useHourTrade    = true;
   
//    @Configurable("from hours ?")   
    public int     fromHourTrade        = 7;
   
//    @Configurable("to hours")   
    public int toHourTrade           = 19;
   
// create a variable that allows us to  alternate between candle stick patterns
   
    public enum candleSignal {//------------------Bullish Patterns
                              BullishEngulfing,
                              Hammer,
                              Piercing,
                              MorningStar,
                              MorningDojiStar,
                              WhiteMarubozu,
                              InvertedHammer,
                              ThreeWhiteSoldiers,
                              ThreeInsideUp,
                              ThreeOutsideUp,
                              BullishHarami,
                              BullishHaramiCross,
                              //------------------Bearish Patterns
                                BearishEngulfing,
                                ShootingStar,
                                DarkCloudCover,
                                EveningStar,
                                EveningDojiStar,
                                BlackMarubozu,
                                HangingMan,
                                ThreeBlackCrows,
                                ThreeInsideDown,
                                ThreeOutsideDown,
                                BearishHarami,
                                BearishHaramiCross
                            };

// @Configurable ("Penetration for Morning & Evening Stars")
    public double starPenetration = 0.3 ;
                         
    @Configurable(" Candlestick Pattern used :")
    public candleSignal thisPattern = candleSignal.BullishEngulfing;

    @Configurable(" used Bollinger Bands ?")   
    public boolean useBBands = false;
   
    @Configurable(" used RSI ?")   
    public boolean useRSI = false;   

   @Configurable(" used Candlesticks ?")
    public boolean useCandlesticks = true;
   
//    @Configurable(" Moving Average for filter :")   
    public int  trendMaPeriod  = 5;

   @SuppressWarnings("serial")
    private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") {{setTimeZone(TimeZone.getTimeZone("GMT"));}};   
 
     
    private IEngine engine;
    private IHistory history;
    private IIndicators indicators;
//    private IContext context;
    private IConsole console;
//    private IUserInterface userInterface;

   

    IOrder activeOrder;
   
   
   
   
    public void onStart(IContext context) throws JFException {
        this.engine = context.getEngine();
        this.history = context.getHistory();
        this.indicators = context.getIndicators();
//        this.context = context;
//        this.console = context.getConsole();
//        this.userInterface = context.getUserInterface();
        System.out.println("------ Auto Trading Started!-----------");
       
     
    }

    public void onAccount(IAccount account) throws JFException {
       
    }

    public void onMessage(IMessage message) throws JFException {
    }

    public void onStop() throws JFException {
   
        // close all orders
        for (IOrder order : engine.getOrders()) {
           engine.getOrder(order.getLabel()).close();
        }
       
    System.out.println("------ Auto Trading Stopped!-----------");
  }

    public void onTick(Instrument instrument, ITick tick) throws JFException {
       
        if (!instrument.equals(this.instrument)) // on need to check for instruments we use
                return;     
       
    //-------- Start StopManager --------------//   
        for (IOrder order : engine.getOrders(instrument)) {
            if (order.getState() == IOrder.State.FILLED) {

               
                boolean isLong     = order.isLong();
                double  open     = order.getOpenPrice();
                //double  stop     = order.getStopLossPrice();
                //double  spread     = tick.getBid()-tick.getAsk();
                //double  pip     = instrument.getPipValue();
                double     newStop;
               
                // long side order
                if (isLong)
                {   
                    // Move to break even
                    if (moveBE && tick.getAsk() > (open + getPipPrice(lockPip)))
                        {
                        // make it break even trade if the market has moved by the lockpips amount in our favour
                        newStop = tick.getAsk()- getPipPrice(lockPip);
                        order.setStopLossPrice(newStop);                     
                        }   
                    //Sets Trailing Step for Long Orders
                    if (useTrailingStop && order.getTrailingStep()== 0 &&
                        tick.getAsk() >=(open + getPipPrice(trailingStop)))
                        {
                        newStop = tick.getAsk()- getPipPrice(trailingStop);
                        order.setStopLossPrice(newStop, order.getStopLossSide(), trailingStop);
                        }
                    }
               
                // short side order
                else
                {                               
                    // Move to break even
                    if (moveBE && tick.getBid() < (open - getPipPrice(lockPip)))
                        {                           
                        newStop = tick.getBid() - getPipPrice(lockPip);
                        order.setStopLossPrice(newStop);
                        }
                    //Sets Trailing Step for short Orders
                    if (useTrailingStop && order.getTrailingStep()== 0 &&
                        tick.getBid() <=(open - (getPipPrice(trailingStop))))
                        {
                        newStop = tick.getBid()+ getPipPrice(trailingStop);
                        order.setStopLossPrice(newStop, order.getStopLossSide(), trailingStop);
                        }                   
                   
                }
            }
        }
    //-------- End   StopManager --------------//
    }
   
    // We open trades on bars
    public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar)
    throws JFException
    {
       
     
        if (!instrument.equals(this.instrument) || // only interested in instrument inputed, Dukascopy returns all instruments
            !period.equals(period)              || // only interested in period inputed
            takeProfitPips < stopLossPips       || // we don't want to consider any optimised parameters where take profit is less than stop loss
            (!useCandlesticks && !useRSI  && !useBBands)||
            (useCandlesticks  && useRSI   && useBBands)||
            (useCandlesticks  && !useRSI  && !useBBands)           
            )
            return;
       
       // we also want to ensure our nominal trader acts like a day trader, closes each day in a net zero position only trading Monday to Friday.
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        int _hours    = calendar.get(Calendar.HOUR_OF_DAY);
       
        //we have no interest in trading on weekends
        if(dayOfWeek == 1 || dayOfWeek == 7){ return;}

       
        if (useHourTrade)
        {
            if (fromHourTrade >toHourTrade){return;}
   
            if (!(_hours >= fromHourTrade && _hours <= toHourTrade ))
            {    //we want to close all orders that are opened and not trade anymore
                for (IOrder order : engine.getOrders())
                { order.close(); }
                return;
            }
        }
     
       
       // set the value of the indicators used
       
        IBar previousBidBar = history.getBar(instrument, period, OfferSide.BID, 1);
        IBar previousAskBar = history.getBar(instrument, period, OfferSide.ASK, 1);
        double prevClose = previousBidBar.getClose();
       
   
        long currentTime  = askBar.getTime() + period.getInterval();
        boolean isBullish = getBullish(thisPattern);
        boolean isBearish = getBearish(thisPattern);
       
        double upperBand1 = 0;
        double lowerBand1 = 0;
        double upperBand2 = 0;
        double lowerBand2 = 0;

        if(useBBands)
        {
            upperBand1 = indicators.bbands(this.instrument, this.period, OfferSide.BID, AppliedPrice.CLOSE, 20, 2, 2, MaType.EMA, 1)[0];
            lowerBand1 = indicators.bbands(this.instrument, this.period, OfferSide.ASK, AppliedPrice.CLOSE, 20, 2, 2, MaType.EMA, 1)[2];
            upperBand2 = indicators.bbands(this.instrument, this.period, OfferSide.BID, AppliedPrice.CLOSE, 20, 3, 3, MaType.EMA, 1)[0];
            lowerBand2 = indicators.bbands(this.instrument, this.period, OfferSide.ASK, AppliedPrice.CLOSE, 20, 3, 3, MaType.EMA, 1)[2];
        }
             
        double rsi = 0;
        if(useRSI)
        {
            rsi = indicators.rsi(this.instrument, this.period, OfferSide.BID, AppliedPrice.CLOSE, 14, 1);
        }
         
        // SELL SIGNAL
        if(
            (  useCandlesticks && !useRSI && !useBBands && !isBullish && isBearish && positionsTotal(instrument) == 0)||     // case of just candle signals
            (( useCandlesticks &&  useRSI && !useBBands && !isBullish && isBearish && positionsTotal(instrument) == 0) &&( rsi > 70))||
            (( useCandlesticks && !useRSI &&  useBBands && !isBullish && isBearish && positionsTotal(instrument) == 0) &&( upperBand1 <prevClose && upperBand2 > prevClose))||
            ((!useCandlesticks &&  useRSI && !useBBands && positionsTotal(instrument) == 0) &&( rsi > 70))||
            ((!useCandlesticks && !useRSI &&  useBBands && positionsTotal(instrument) == 0) &&( upperBand1 <prevClose && upperBand2 > prevClose))
          )
        {
         submitOrder(OrderCommand.SELLLIMIT, previousBidBar, currentTime);
        }
       
        // BUY SIGNAL
        if(
            (  useCandlesticks && !useRSI && !useBBands && isBullish && !isBearish && positionsTotal(instrument) == 0 )||
            (( useCandlesticks &&  useRSI && !useBBands && isBullish && !isBearish && positionsTotal(instrument) == 0 )&&(rsi < 30))||
            (( useCandlesticks && !useRSI &&  useBBands && isBullish && !isBearish && positionsTotal(instrument) == 0 )&&(lowerBand2 <prevClose && lowerBand1 > prevClose))||
            ((!useCandlesticks &&  useRSI && !useBBands && positionsTotal(instrument) == 0 )&&(rsi < 30))||
            ((!useCandlesticks && !useRSI &&  useBBands && positionsTotal(instrument) == 0 )&&(lowerBand2 <prevClose && lowerBand1 > prevClose))
          )   
        {
         submitOrder(OrderCommand.BUYLIMIT, previousAskBar, currentTime);
        }
       
        // Close orders for which 5 bars have passed and the limit order has not been filled.
        long expirationTime = currentTime - period.getInterval() * orderExpirationInterval;
         
        for (IOrder order : engine.getOrders())
        {
           if (order.getCreationTime() <= expirationTime && order.getState().equals(IOrder.State.OPENED) )
           {
              print(currentTime, "Order has expired and therefore was closed: "+order.getId());
              order.close();
           }
        }
       
    }

    private boolean getBearish(candleSignal p1) throws JFException {
        //
        int signal = 0;
        IBar askBar3 = history.getBar(instrument, period, OfferSide.ASK, 1);
        double ma = this.indicators.ma(instrument, period, OfferSide.BID,AppliedPrice.CLOSE,trendMaPeriod, MaType.SMA,1);
       
        //--------------------------
        switch (p1)
        {   
                       
        case BearishEngulfing:
                     if((askBar3.getClose() < askBar3.getOpen()) && askBar3.getOpen()  > ma)
                     { signal = this.indicators.cdlEngulfing(this.instrument, this.period, OfferSide.ASK, 1); }
                    else
                    {signal = 0;}
                      break;
       
        case ShootingStar:
                    if(askBar3.getOpen()> ma)
                     { signal = this.indicators.cdlShootingStar(this.instrument, this.period, OfferSide.ASK, 1); }
                    else
                    {signal = 0;}
                      break;
                     
        case DarkCloudCover:
                    if(askBar3.getOpen()> ma)
                     { signal = this.indicators.cdlDarkCloudCover(this.instrument, this.period, OfferSide.ASK,0.5,1); }
                    else
                    {signal = 0;}
                      break;   
                     
        case EveningStar:
                    if(askBar3.getOpen()> ma)
                     {
                    signal = this.indicators.cdlEveningStar(this.instrument, this.period, OfferSide.ASK,starPenetration ,1);}
                    else
                    {signal = 0;}
                      break;
                     
        case EveningDojiStar:
                    if(askBar3.getOpen()> ma)
                     {
                    signal = this.indicators.cdlEveningDojiStar(this.instrument, this.period, OfferSide.ASK,starPenetration ,1);}
                    else
                    {signal = 0;}
                      break;
                     
        case BlackMarubozu:
                    if((askBar3.getOpen() >askBar3.getClose())&&(askBar3.getOpen()> ma))
                     {
                    signal = this.indicators.cdlMarubozu(this.instrument, this.period, OfferSide.ASK,1);}
                    else
                    {signal = 0;}
                      break;
                 
        case HangingMan:
                    if(askBar3.getOpen()> ma)
                     {
                    signal = this.indicators.cdlHangingMan(this.instrument, this.period, OfferSide.ASK,1);}
                    else
                    {signal = 0;}
                      break;
                     
        case ThreeBlackCrows:
                    if(askBar3.getOpen()> ma)
                     {
                    signal = this.indicators.cdl3BlackCrows(this.instrument, this.period, OfferSide.ASK,1);}
                    else
                    {signal = 0;}
                      break;
                     
        case ThreeInsideDown:
                    if((askBar3.getOpen() >askBar3.getClose())&&(askBar3.getOpen()> ma))
                     {
                    signal = this.indicators.cdl3Inside(this.instrument, this.period, OfferSide.ASK,1);}
                    else
                    {signal = 0;}
                      break;
                     
        case ThreeOutsideDown:
                    if((askBar3.getOpen() >askBar3.getClose())&&(askBar3.getOpen()> ma))
                     {
                    signal = this.indicators.cdl3Outside(this.instrument, this.period, OfferSide.ASK,1);}
                    else
                    {signal = 0;}
                      break;     
                     
        case BearishHarami:
                    if((askBar3.getOpen() >askBar3.getClose())&&(askBar3.getOpen()> ma))
                     {
                    signal = this.indicators.cdlHarami(this.instrument, this.period, OfferSide.ASK,1);}
                    else
                    {signal = 0;}
                      break;
                     
        case BearishHaramiCross:
                    if((askBar3.getOpen() >askBar3.getClose())&&(askBar3.getOpen()> ma))
                     {
                    signal = this.indicators.cdlHaramiCross(this.instrument, this.period, OfferSide.ASK,1);}
                    else
                    {signal = 0;}
                      break;
                     
        default:     
                    System.out.println("Not a bearish candle signal.");
                    signal = 0;   
                    break;
          }
       
        //--------------------------
       
       
        if (signal != 0)
        { return true;}
        else
        { return false;}
    }

    private boolean getBullish(candleSignal p2) throws JFException {
        //
        int signal = 0;
        //IBar bidBar1 = history.getBar(instrument, period, OfferSide.BID, 3);
        //IBar bidBar2 = history.getBar(instrument, period, OfferSide.BID, 2);
        IBar bidBar3 = history.getBar(instrument, period, OfferSide.BID, 1);
        double ma = this.indicators.ma(instrument, period, OfferSide.BID,AppliedPrice.CLOSE,trendMaPeriod, MaType.SMA,1);
       
        //--------------------------
        switch (p2) {   
       
        case BullishEngulfing:
                     if((bidBar3.getClose()> bidBar3.getOpen())&& bidBar3.getOpen() < ma)
                     { signal = this.indicators.cdlEngulfing(this.instrument, this.period, OfferSide.BID,1);
                     }
                     else {signal = 0;}
                     break;
                       
        case Hammer:
                     if(bidBar3.getOpen() < ma)
                     { signal = this.indicators.cdlHammer(this.instrument, this.period, OfferSide.BID,1);
                     }
                     else {signal = 0;}
                     break;
                     
        case Piercing:
                     if(bidBar3.getOpen() < ma)
                     { signal = this.indicators.cdlPiercing(this.instrument, this.period, OfferSide.BID,1);
                     }
                     else {signal = 0;}
                     break;
                     
        case MorningStar:
                     if(bidBar3.getOpen() < ma)
                     { signal = this.indicators.cdlMorningStar(this.instrument, this.period, OfferSide.BID,starPenetration,1);
                     }
                     else {signal = 0;}
                     break;
                     
        case MorningDojiStar:
                     if(bidBar3.getOpen() < ma)
                     { signal = this.indicators.cdlMorningDojiStar(this.instrument, this.period, OfferSide.BID,starPenetration,1);
                     }
                     else {signal = 0;}
                     break;
                     
        case WhiteMarubozu:
                     if(bidBar3.getClose()> bidBar3.getOpen() && bidBar3.getOpen() < ma)
                     { signal = this.indicators.cdlMarubozu(this.instrument, this.period, OfferSide.BID,1);
                     }
                     else {signal = 0;}
                     break;                                 
                     
        case InvertedHammer:
                     if(bidBar3.getOpen() < ma)
                     { signal = this.indicators.cdlInvertedHammer(this.instrument, this.period, OfferSide.BID,1);
                     }
                     else {signal = 0;}
                     break;                                 
                     
        case ThreeWhiteSoldiers:
                     if(bidBar3.getOpen() < ma)
                     { signal = this.indicators.cdl3WhiteSoldiers(this.instrument, this.period, OfferSide.BID,1);
                     }
                     else {signal = 0;}
                     break;                                         
                         
        case ThreeInsideDown:
                    if((bidBar3.getOpen() < bidBar3.getClose())&&(bidBar3.getOpen()< ma))
                     {
                    signal = this.indicators.cdl3Inside(this.instrument, this.period, OfferSide.BID,1);}
                    else
                    {signal = 0;}
                      break;
                     
        case ThreeOutsideDown:
                    if((bidBar3.getOpen() < bidBar3.getClose())&&(bidBar3.getOpen()> ma))
                     {
                    signal = this.indicators.cdl3Outside(this.instrument, this.period, OfferSide.BID,1);}
                    else
                    {signal = 0;}
                      break;     
                     
        case BearishHarami:
                    if((bidBar3.getOpen() < bidBar3.getClose())&&(bidBar3.getOpen()> ma))
                     {
                    signal = this.indicators.cdlHarami(this.instrument, this.period, OfferSide.BID,1);}
                    else
                    {signal = 0;}
                      break;
                     
        case BearishHaramiCross:
                    if((bidBar3.getOpen() < bidBar3.getClose())&&(bidBar3.getOpen()> ma))
                     {
                    signal = this.indicators.cdlHaramiCross(this.instrument, this.period, OfferSide.BID,1);}
                    else
                    {signal = 0;}
                      break;                     
                     
        default:    System.out.println("Not a bullish candle signal.");
                    signal = 0;   
                    break;
        }           
        //--------------------------
       
        if (signal != 0)
        { return true;}
        else
        { return false;}
    }

    // submits the order passed from signals
    private IOrder submitOrder(OrderCommand orderCmd,IBar lastBar,long currentTime)
    // private IOrder submitOrder(double amount, OrderCommand orderCmd)
     throws JFException{
          double stopLossPrice, takeProfitPrice,price;
               
                      // Calculating order price, stop loss and take profit prices
                      if (orderCmd == OrderCommand.BUYLIMIT) {
                         stopLossPrice = history.getLastTick(this.instrument).getBid() - getPipPrice(this.stopLossPips);
                         takeProfitPrice = history.getLastTick(this.instrument).getBid() + getPipPrice(this.takeProfitPips);
                 
                         // buy the instrument at 5 pips above its previous bar's high using a limit order
                         price = lastBar.getHigh() + getPipPrice(priceShiftPips);
                         
                      } else {
                         stopLossPrice = history.getLastTick(this.instrument).getAsk() + getPipPrice(this.stopLossPips);
                         takeProfitPrice = history.getLastTick(this.instrument).getAsk() - getPipPrice(this.takeProfitPips);   
                 
                         // sell the instrument at 5 pips below its previous bar's low using a limit order
                         price = lastBar.getLow() - getPipPrice(priceShiftPips);
                      }
                 
                      // Submitting an order
                      return engine.submitOrder( getLabel(instrument), this.instrument, orderCmd, this.amount, price, 0, stopLossPrice, takeProfitPrice);
                   }
           
    // count opened positions
    protected int positionsTotal(Instrument instrument) throws JFException {
        int counter = 0;
        activeOrder = null;
        for (IOrder order : engine.getOrders(instrument)) {
            if ((order.getState() == IOrder.State.FILLED) && order.getLabel().equals(getLabel(instrument))) {
               
                activeOrder = order;
                counter++;
            }
        }
        return counter;
    }
 
    // creates the labels
    protected String getLabel(Instrument instrument) {
       
      String label = instrument.name();
      String usd     = "USD";
     
      if (label.substring(3).endsWith(usd))
          {   label = label.substring(0,3);}
      else
          {   label = label.substring(3,6);}
         
      label = "ActiveOrder" + label;
     
      return label;
       
     }
   
    private double getPipPrice(int pips) {
        return pips * this.instrument.getPipValue();
     }
   
    private void print( long time, Object o ) {
        print( sdf.format(time) + " " + o);
             }
             
    private void print(Object o){
        console.getOut().println( o );
     }
     
    public void print(String str) {
       
        console.getOut().println(str);
         
    }
               
    }



if you have a bit of time and fairly powerful computer and would like to give a helping hand let me know , its for my dissertation!!!

If you do want to help the testing year is 2004

i am currently testing the 15minute time frame on

EURUSD, GBPUSD, AUSUSD, USDCHF, USDJPY

i am selecting only 12 bullish candles or 12 bearish candles

optimizing stop loss and take profit with a step of 20, starting at 20 up to 120

and trailing stop with a step of 15, starting at 15 up to 45

Interms of the other parameters

i need optimization result for each currency pair for :

candlesticks only
candlesticks and rsi
candlesticks and bollinger
bollinger only
rsi only


Cheers and thanks much for any help or advice!!




As a student amazon ec2 is start to burn a hole in my pocket.. haha
cheers


 
 Post subject: Re: Candlestick & MA strategy Post rating: 0   New post Posted: Wed 17 Aug, 2011, 15:05 

User rating: 0
Joined: Wed 20 Jul, 2011, 10:33
Posts: 6
Location: JM
The idea is to pick the best bullish and bearish candlesticks for each of the 5 settings and currency pairs from the optimized results. These will then be tested over a subsequent period and academic examination carried out for my dissertation to evaluate if they have any predictive power. I hope this sounds really interesting and you all cant wait to help.

Cheers,
lance


 

Jump to:  

cron
  © 1998-2025 Dukascopy® Bank SA
On-line Currency forex trading with Swiss Forex Broker - ECN Forex Brokerage,
Managed Forex Accounts, introducing forex brokers, Currency Forex Data Feed and News
Currency Forex Trading Platform provided on-line by Dukascopy.com