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.

MACD and Stochastic
 Post subject: MACD and Stochastic Post rating: 0   New post Posted: Mon 16 Jan, 2012, 10:10 

User rating: 0
Joined: Mon 12 Dec, 2011, 17:08
Posts: 32
Location: Hungary,
Hi Support,
During running of the mentioned strategy (see attached file) I gave the following error massages:
08:37:26 at com.dukascopy.transport.client.i.run(Unknown Source)
08:37:26 at com.dukascopy.transport.client.a.c.run(Unknown Source)
08:37:26 at com.dukascopy.transport.client.a.d.execute(Unknown Source)
08:37:26 at com.dukascopy.dds2.greed.connection.b.a(Unknown Source)
08:37:26 at com.dukascopy.dds2.greed.connection.b.k(Unknown Source)
08:37:26 at com.dukascopy.charts.data.datacache.ah.b(Unknown Source)
08:37:26 at com.dukascopy.charts.data.datacache.bb.newTick(Unknown Source)
08:37:26 at com.dukascopy.charts.data.datacache.bb.b(Unknown Source)
08:37:26 at com.dukascopy.charts.data.datacache.b.b.a(Unknown Source)
08:37:26 at com.dukascopy.charts.data.datacache.b.b.d(Unknown Source)
08:37:26 at com.dukascopy.charts.data.datacache.d.g.a(Unknown Source)
08:37:26 at com.dukascopy.charts.data.datacache.d.g.d(Unknown Source)
08:37:26 at com.dukascopy.charts.data.datacache.d.g.f(Unknown Source)
08:37:26 at com.dukascopy.charts.data.datacache.priceaggregation.c.d(Unknown Source)
08:37:26 at com.dukascopy.charts.data.datacache.b.c.b(Unknown Source)
08:37:26 at com.dukascopy.charts.data.datacache.b.c.a(Unknown Source)
08:37:26 at com.dukascopy.charts.data.datacache.b.b.a(Unknown Source)
08:37:26 at com.dukascopy.charts.data.datacache.b.b.b(Unknown Source)
08:37:26 at com.dukascopy.charts.data.datacache.ah.b(Unknown Source)
08:37:26 at com.dukascopy.dds2.greed.agent.strategy.a.c.b.a(Unknown Source)
08:37:26 at jforex.strategies.indicators.MACD_STOCH_Strat$1.onBar(MACD_STOCH_Strat.java:171)
08:37:26 at jforex.strategies.indicators.MACD_STOCH_Strat$1.submitOrder(MACD_STOCH_Strat.java:236)
08:37:26 at com.dukascopy.api.impl.connect.u.submitOrder(Unknown Source)
08:37:26 at com.dukascopy.api.impl.connect.u.submitOrder(Unknown Source)
08:37:26 at com.dukascopy.api.impl.connect.u.submitOrder(Unknown Source)
08:37:26 com.dukascopy.api.JFException: Incorrect thread
The results of the backtests are really very impressive, so I wold be very grateful for some help.


Attachments:
MACD_STOCH_Strat.java [15.88 KiB]
Downloaded 488 times
DISCLAIMER: Dukascopy Bank SA's waiver of responsability - Documents, data or information available on this webpage may be posted by third parties without Dukascopy Bank SA being obliged to make any control on their content. Anyone accessing this webpage and downloading or otherwise making use of any document, data or information found on this webpage shall do it on his/her own risks without any recourse against Dukascopy Bank SA in relation thereto or for any consequences arising to him/her or any third party from the use and/or reliance on any document, data or information found on this webpage.
 
 Post subject: Re: Error messages during forward test of MACD and Stochasti Post rating: 0   New post Posted: Tue 17 Jan, 2012, 11:22 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
Please refer to:
viewtopic.php?f=85&t=45457


 
 Post subject: Re: Error messages during forward test of MACD and Stochasti Post rating: 0   New post Posted: Wed 18 Jan, 2012, 09:27 

User rating: 0
Joined: Mon 12 Dec, 2011, 17:08
Posts: 32
Location: Hungary,
Dear Support,
I tried to use the code on forward test on the working platform resulting the same error massages. I really don't know what can I do :( .
Is possible that the Jforex platform (both demo and live platforms) is not able to calculate the indicators for range bar chart?
If it is right would you be so kind to rewrite the code for normal chart with variable time frame?
Thank in advance: Kosza


 
 Post subject: Re: Error messages during forward test of MACD and Stochasti Post rating: 0   New post Posted: Wed 18 Jan, 2012, 09:51 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
Pardon, we did not assess correctly the exception cause, it is due to the fact that in the current implementation range bar feed runs in a different thread and you can submit orders only from strategy thread. With the next JForex-API release one will be able to submit orders from Range bar feed. Currently as a workaround, please consider enqueueing your order submission requests and processing them in onTick.


 
 Post subject: Re: Error messages during forward test of MACD and Stochasti Post rating: 0   New post Posted: Wed 18 Jan, 2012, 11:22 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
The following strategy queues OrderCommand objects. If you need any additional data, then consider creating your own object (e.g. MyTradeInfo) and use a queue of that object.
package jforex.strategies;

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

import com.dukascopy.api.*;
import com.dukascopy.api.IEngine.OrderCommand;
import com.dukascopy.api.bar.IRangeBar;
import com.dukascopy.api.listener.IRangeBarFeedListener;

/**
 * The strategy makes a BUY order on completion of a GREEN range bar
 * and SELL - on RED one.
 *
 */

@RequiresFullAccess
public class RangeBarsTrade implements IStrategy {

   @Configurable("Instrument")
   public Instrument instrument = Instrument.EURUSD;
   @Configurable("Price range")
   public int priceRangePips = 1;   
   @Configurable("Amount")
   public double amount = 0.001;
   @Configurable("Stop loss")
   public int stopLossPips = 3;
   @Configurable("Take profit")
   public int takeProfitPips = 5;

   
   private IEngine engine;
   private IConsole console;
   private IHistory history;
   
   private int orderCount;
   private IRangeBar prevRangeBar;
   
   private Queue<OrderCommand> orderCmds = new ConcurrentLinkedQueue<OrderCommand>();
   
   @Override
   public void onStart(IContext context) throws JFException {
      this.engine = context.getEngine();
      this.console = context.getConsole();
      this.history = context.getHistory();      

      console.getOut().println("start");
      
      context.subscribeToRangeBarFeed(Instrument.EURUSD, OfferSide.BID, PriceRange.valueOf(priceRangePips),
            new IRangeBarFeedListener() {
               public void onBar(Instrument instrument, OfferSide offerSide, PriceRange priceRange, IRangeBar bar) {

                  if(prevRangeBar == null){
                     prevRangeBar = bar;
                     return;
                  }

                  //add order command to queue - we can submit order only from strategy thread
                  try {
                     OrderCommand cmd = getCommand(bar, prevRangeBar);
                     orderCmds.offer(cmd);
                  } catch (JFException e) {
                     e.printStackTrace(console.getErr());
                  }                  
                  
                  prevRangeBar = bar;
               }
            });
   }

   @Override
   public void onTick(Instrument instrument, ITick tick) throws JFException {
      
      //execute all order commands made in range bar feed
      while(!orderCmds.isEmpty()){
         submitOrder(orderCmds.poll());
      }
   }

   @Override
   public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {}
   
   private OrderCommand getCommand(IBar curBar, IBar prevBar) throws JFException{
      
      return curBar.getClose() > prevBar.getClose()
         ? OrderCommand.BUY
         : OrderCommand.SELL;
   }
   
   private IOrder submitOrder(OrderCommand orderCmd) throws JFException {

      double stopLossPrice, takeProfitPrice;

      // Calculating stop loss and take profit prices
      if (orderCmd == OrderCommand.BUY) {
         stopLossPrice = history.getLastTick(this.instrument).getBid() - getPipPrice(this.stopLossPips);
         takeProfitPrice = history.getLastTick(this.instrument).getBid() + getPipPrice(this.takeProfitPips);
      } else {
         stopLossPrice = history.getLastTick(this.instrument).getAsk() + getPipPrice(this.stopLossPips);
         takeProfitPrice = history.getLastTick(this.instrument).getAsk() - getPipPrice(this.takeProfitPips);
      }

      // Submitting an order for the specified instrument at the current market price
      return engine.submitOrder("order" + ++orderCount, this.instrument, orderCmd, this.amount, 0, 5, stopLossPrice, takeProfitPrice);
   }
   
   private double getPipPrice(int pips) {
      return pips * this.instrument.getPipValue();
   }

   @Override
   public void onMessage(IMessage message) throws JFException {
      //if the message is related to order print its content
      if (message.getOrder() != null){
         console.getOut().println(message.getOrder().getLabel() + " " + message.getType() + " " + message.getContent());
      }
   }

   @Override
   public void onAccount(IAccount account) throws JFException {

   }

   @Override
   public void onStop() throws JFException {
      //close all orders on strategy stop
      for(IOrder o : engine.getOrders()){
         o.close();
      }
   }

}



Attachments:
RangeBarsTrade.java [3.77 KiB]
Downloaded 516 times
DISCLAIMER: Dukascopy Bank SA's waiver of responsability - Documents, data or information available on this webpage may be posted by third parties without Dukascopy Bank SA being obliged to make any control on their content. Anyone accessing this webpage and downloading or otherwise making use of any document, data or information found on this webpage shall do it on his/her own risks without any recourse against Dukascopy Bank SA in relation thereto or for any consequences arising to him/her or any third party from the use and/or reliance on any document, data or information found on this webpage.
 
 Post subject: Re: Error messages during forward test of MACD and Stochastic st Post rating: 0   New post Posted: Wed 18 Jan, 2012, 14:00 

User rating: 0
Joined: Mon 12 Dec, 2011, 17:08
Posts: 32
Location: Hungary,
Dear Support,
could you insert two additional possibilities to this code to maximize (variable) the number of the opened short / long positions and trailing stop?
Thanks in advance.


 
 Post subject: Re: Error messages during forward test of MACD and Stochastic st Post rating: 0   New post Posted: Wed 18 Jan, 2012, 14:28 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
kosza wrote:
could you insert two additional possibilities to this code to maximize (variable) the number of the opened short / long positions and trailing stop?
Please elaborate what in particular needs to be changed in the given example strategy.


 
 Post subject: Re: Error messages during forward test of MACD and Stochastic st Post rating: 0   New post Posted: Wed 18 Jan, 2012, 15:23 

User rating: 0
Joined: Mon 12 Dec, 2011, 17:08
Posts: 32
Location: Hungary,
The best would be a simple MACD histogramm strategy for range bar chart: MACD hyst(0)<0 and MACD hyst(1) >0 open long; close short,
MACD hyst(0)>0 and MACD hyst(1) <0 open long; close short,
with variable trailing stop
Thank


 
 Post subject: Re: Error messages during forward test of MACD and Stochastic st Post rating: 0   New post Posted: Wed 18 Jan, 2012, 17:58 

User rating: 0
Joined: Mon 12 Dec, 2011, 17:08
Posts: 32
Location: Hungary,
And for at last: Could you insert into the example strategy:
If macd hyst. >0 open long when the range bar candle (0) is decreasing (red) and the following range bar candle (1) is growing (green). Close long position at the first closed red candle.
If macd hyst. <0 open short when the range bar (0) is green and the following range bar (1) is red.
Close short at the first closed green candle.
Thank in advance: Kosza


 
 Post subject: Re: Error messages during forward test of MACD and Stochastic st Post rating: 0   New post Posted: Thu 19 Jan, 2012, 16:24 
User avatar

User rating:
Joined: Fri 31 Aug, 2007, 09:17
Posts: 6139
We took your originally posted strategy and added order request handling.
package jforex.strategies;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Iterator;
import java.util.Queue;
import java.util.TimeZone;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;

import com.dukascopy.api.*;
import com.dukascopy.api.IEngine.OrderCommand;
import com.dukascopy.api.IIndicators.MaType;
import com.dukascopy.api.bar.IRangeBar;
import com.dukascopy.api.indicators.IIndicator;
import com.dukascopy.api.listener.IRangeBarFeedListener;

/**
 * The strategy shows how to emulate range bar history.
 * Also it shows how to use range bar close prices with MA indicator.
 *
 */
@RequiresFullAccess
public class MACD_STOCH_Strat2 implements IStrategy {

    public static final int OPEN = 0;
    public static final int CLOSE = 1;
    public static final int HIGH = 2;
    public static final int LOW = 3;
    public static final int MED = 4;
    public static final int HIST = 2;
    private IConsole console;
    private IHistory history;
    private IEngine engine;
    private IIndicators indicators;
    private SimpleDateFormat sdf;   
    @Configurable("Price range (pips)")
    public int priceRangePips = 2;
    // range bars
    @Configurable("Instrument")
    public Instrument instrument = Instrument.EURUSD;
    @Configurable("Offer Side")
    public OfferSide offerSide = OfferSide.BID;
    @Configurable("Amount")
    public double amount = 0.02;
    @Configurable("Slippage")
    public double slippage = 0;
    @Configurable("Take profit pips")
    public int takeProfitPips = 0;
    @Configurable("Stop loss in pips")
    public int stopLossPips = 0;
    // MACD
    @Configurable("MACD Fast period")
    public int fastMACDPeriod = 12;
    @Configurable("MACD Slow period")
    public int slowMACDPeriod = 26;
    @Configurable("MACD Signal period")
    public int signalMACDPeriod = 9;
    // STOCH
    @Configurable("STOCH Fast K period")
    public int fastKPeriod = 5;
    @Configurable("STOCH Slow K period")
    public int slowKPeriod = 3;
    @Configurable("STOCH K MA Type")
    public MaType slowKMaType = MaType.SMA;
    @Configurable("STOCH Slow D period")
    public int slowDPeriod = 5;
    @Configurable("STOCH D MA Type")
    public MaType slowDMaType = MaType.SMA;
    public static DecimalFormat df = new DecimalFormat("0.00000");
    private PriceRange priceRange;
    private BlockingQueue<IRangeBar> rangeBars;
    private int maxShift = 1;
    private int period;
    private IIndicator macd;
    private IIndicator stoch;
   

    private IOrder order;
    private int counter;
   
    //Support: order request queue - it is filled in range bar feed and emptied in next onTick
   private Queue<OrderRequest> orderRequests = new ConcurrentLinkedQueue<OrderRequest>();

    @Override
    public void onStart(IContext context) throws JFException {

        this.history = context.getHistory();
        this.console = context.getConsole();
        this.indicators = context.getIndicators();

        this.engine = context.getEngine();

        priceRange = PriceRange.valueOf(priceRangePips);

        sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT"));


        macd = indicators.getIndicator("MACD");

        //set optional inputs
        macd.setOptInputParameter(0, fastMACDPeriod);
        macd.setOptInputParameter(1, slowMACDPeriod);
        macd.setOptInputParameter(2, signalMACDPeriod);

        stoch = indicators.getIndicator("STOCH");

        //set optional inputs
        stoch.setOptInputParameter(0, fastKPeriod);
        stoch.setOptInputParameter(1, slowKPeriod);
        stoch.setOptInputParameter(2, slowKMaType.ordinal());
        stoch.setOptInputParameter(3, slowDPeriod);
        stoch.setOptInputParameter(4, slowDMaType.ordinal());

        period = Math.max(macd.getLookback(), stoch.getLookback()) + 1;
        rangeBars = new ArrayBlockingQueue<IRangeBar>(maxShift + period);

        context.subscribeToRangeBarFeed(instrument, offerSide, priceRange,
                new IRangeBarFeedListener() {

                    public void onBar(Instrument instrument, OfferSide offerSide, PriceRange priceRange, IRangeBar bar) {
                       
                       //Support: reduced nesting
                        try {     
                           execOnBar(bar);                       
                        } catch (JFException ex) {
                            ex.printStackTrace(console.getErr());
                        }
                    }
        }
        );


    }
   
    private void execOnBar(IRangeBar bar) throws JFException{      
           
            double[][] closePrices = getClosePrices(bar);

            if (!isActive(order)) {
                order = null;
            }

            // MACD SIGNAL
            OrderCommand macdSign = null;
            OrderCommand stochSign = null;

            double[] macd0 = getMACD(closePrices[CLOSE], 0);
            double[] macd1 = getMACD(closePrices[CLOSE], 1);

            if (macd0[HIST] > 0 /*&& macd1[HIST] <= 0*/) {
                macdSign = OrderCommand.BUY;
            }
            if (macd0[HIST] < 0 /*&& macd1[HIST] >= 0*/) {
                macdSign = OrderCommand.SELL;
            }

            // STOCH SIGNAL 
            int K = 0;
            int D = 1;
            double[] stoch0 = getSTOCH(closePrices, 0);
            double[] stoch1 = getSTOCH(closePrices, 1);

            if (stoch0[K] > stoch0[D] && stoch1[K] <= stoch1[D]) {
                stochSign = OrderCommand.BUY;

            } else if (stoch0[K] < stoch0[D] && stoch1[K] >= stoch1[D]) {
                stochSign = OrderCommand.SELL;
            }

            // PLACE ORDER     
            //Support: we enqueue order instead of placing it
            orderRequests.offer(new OrderRequest(macdSign, stochSign));

   
    }
   
    //Support: object holding needed information for order submission - note that you can add here any additional information
    // that you may find relevant at the moment of the order creation
    private class OrderRequest{
       
       public final OrderCommand macdSign;
       public final OrderCommand stochSign;
       
       public OrderRequest(OrderCommand macdSign, OrderCommand stochSign){
          this.macdSign = macdSign;
          this.stochSign = stochSign;
       }
       
    }
   

    private double[][] getClosePrices(IRangeBar bar) {

        if (rangeBars.remainingCapacity() == 0) {
            //our queue is full
            //lets take out the oldest range bar
            print("Our Queue is full, Removing item: " + rangeBars.poll());
        }

        //store the new range bar
        rangeBars.offer(bar);

        if (rangeBars.remainingCapacity() > 0) {
            print("we do not have enough items for calculating indicator values");
            return null;
        }

        //get close prices                       
        double[][] closePrices = new double[5][rangeBars.size()];

        Iterator<IRangeBar> barsIterator = rangeBars.iterator();
        int i = 0;
        while (barsIterator.hasNext()) {
            IRangeBar rangeBar = barsIterator.next();

            closePrices[OPEN][i] = rangeBar.getOpen();
            closePrices[CLOSE][i] = rangeBar.getClose();
            closePrices[HIGH][i] = rangeBar.getHigh();
            closePrices[LOW][i] = rangeBar.getLow();
            closePrices[MED][i] = (rangeBar.getHigh() - rangeBar.getLow()) / 2;
           
            i++;
        }

        return closePrices;
    }
   
    private void placeOrder(OrderCommand stochSign, OrderCommand macdSign) throws JFException {
       
        if (stochSign == OrderCommand.BUY && macdSign == OrderCommand.BUY) {
            if (order != null) {
                if (!order.isLong()) {
                    order.close();
                    order = submitOrder(OrderCommand.BUY);
                }
            } else {
                order = submitOrder(OrderCommand.BUY);
            }

        } else if (stochSign == OrderCommand.SELL && macdSign == OrderCommand.SELL) {
            if (order != null) {
                if (order.isLong()) {
                    order.close();
                    order = submitOrder(OrderCommand.SELL);
                }
            } else {
                order = submitOrder(OrderCommand.SELL);
            }
        }
    }
   
    private IOrder submitOrder(OrderCommand orderCmd) throws JFException {

        double stopLossPrice = 0.0, takeProfitPrice = 0.0;

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

        return engine.submitOrder(getLabel(instrument), instrument, orderCmd, amount, 0, slippage, stopLossPrice, takeProfitPrice);
    }

    private void closeOrder(IOrder order) throws JFException {
        if (order == null) {
            return;
        }
        if (order.getState() != IOrder.State.CLOSED && order.getState() != IOrder.State.CREATED && order.getState() != IOrder.State.CANCELED) {
            order.close();
            order = null;
        }
    }

    private boolean isActive(IOrder order) throws JFException {
        if (order != null && order.getState() != IOrder.State.CLOSED && order.getState() != IOrder.State.CREATED && order.getState() != IOrder.State.CANCELED) {
            return true;
        }
        return false;
    }

    private double getPipPrice(int pips) {
        return pips * instrument.getPipValue();
    }

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

    private double[] getMACD(double[] priceArr, int shift) {

        //set inputs
        macd.setInputParameter(0, priceArr);

        //set outputs
        double[][] resultArr = new double[3][priceArr.length];
        macd.setOutputParameter(0, resultArr[0]);
        macd.setOutputParameter(1, resultArr[1]);
        macd.setOutputParameter(2, resultArr[2]);

        macd.calculate(0, priceArr.length - 1);

        int index = resultArr[0].length - shift - 1 - macd.getLookback();
        double[] result = {resultArr[0][index], resultArr[1][index], resultArr[2][index]};
        return result;
    }

    private double[] getSTOCH(double[][] priceArr, int shift) {

        //set inputs
        stoch.setInputParameter(0, priceArr);

        //set outputs
        double[][] resultArr = new double[2][priceArr[0].length];
        stoch.setOutputParameter(0, resultArr[0]);
        stoch.setOutputParameter(1, resultArr[1]);

        //calculate
        stoch.calculate(0, priceArr[0].length - 1);

        int index = resultArr[0].length - shift - 1 - stoch.getLookback();
        double[] result = {resultArr[0][index], resultArr[1][index]};
        return result;
    }

    @Override
    public void onTick(Instrument instrument, ITick tick) throws JFException {
      //execute all order commands made in range bar feed
      while(!orderRequests.isEmpty()){
         OrderRequest orderRequest = orderRequests.poll();
         placeOrder(orderRequest.stochSign, orderRequest.macdSign);
      }
    }

    @Override
    public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
    }

    @Override
    public void onMessage(IMessage message) throws JFException {
    }

    @Override
    public void onAccount(IAccount account) throws JFException {
    }

    @Override
    public void onStop() throws JFException {
    }

    private void print(Object... o) {
        for (Object ob : o) {
            //console.getOut().print(ob + "  ");
            if (ob instanceof double[]) {
                print((double[]) ob);
            } else if (ob instanceof double[]) {
                print((double[][]) ob);
            } else if (ob instanceof Long) {
                print(dateToStr((Long) ob));
            } else if (ob instanceof Double) {
                print((Double) ob);
            } else {
                print2(ob);
            }
            print(" ");
        }

        console.getOut().println();
    }

    private void print(Object o) {
        console.getOut().println(o);
    }

    private void print2(Object o) {
        console.getOut().print(o);
    }

    private void printTime(Long time) {
        console.getOut().println(dateToStr(time));
    }

    private void print(double[] arr) {
        print(arrayToString(arr));
    }

    private void print(double[][] arr) {
        print(arrayToString(arr));
    }

    private void print(double ddd) {
        print((new DecimalFormat("#.#######")).format(ddd));
    }

    private void printIndicatorInfos(IIndicator ind) {
        for (int i = 0; i < ind.getIndicatorInfo().getNumberOfInputs(); i++) {
            print(ind.getIndicatorInfo().getName() + " Input " + ind.getInputParameterInfo(i).getName() + " " + ind.getInputParameterInfo(i).getType());
        }
        for (int i = 0; i < ind.getIndicatorInfo().getNumberOfOptionalInputs(); i++) {
            print(ind.getIndicatorInfo().getName() + " Opt Input " + ind.getOptInputParameterInfo(i).getName() + " " + ind.getOptInputParameterInfo(i).getType());
        }
        for (int i = 0; i < ind.getIndicatorInfo().getNumberOfOutputs(); i++) {
            print(ind.getIndicatorInfo().getName() + " Output " + ind.getOutputParameterInfo(i).getName() + " " + ind.getOutputParameterInfo(i).getType());
        }
        console.getOut().println();
    }

    public static String arrayToString(double[] arr) {
        String str = "";
        for (int r = 0; r < arr.length; r++) {
            str += "[" + r + "] " + (new DecimalFormat("#.#######")).format(arr[r]) + "; ";
        }
        return str;
    }

    public static String arrayToString(double[][] arr) {
        String str = "";
        if (arr == null) {
            return "null";
        }
        for (int r = 0; r < arr.length; r++) {
            for (int c = 0; c < arr[r].length; c++) {
                str += "[" + r + "][" + c + "] " + (new DecimalFormat("#.#######")).format(arr[r][c]);
            }
            str += "; ";
        }
        return str;
    }

    public String toDecimalToStr(double d) {
        return (new DecimalFormat("#.#######")).format(d);
    }

    public String dateToStr(Long time) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") {

            {
                setTimeZone(TimeZone.getTimeZone("GMT"));
            }
        };
        return sdf.format(time);
    }
}

Attachment:
MACD_STOCH_Strat2.java [15.41 KiB]
Downloaded 561 times
The changed places are supplied with comments starting with "//Support:".


 
 Post subject: Re: MACD and Stochastic Post rating: 0   New post Posted: Mon 23 Jan, 2012, 18:31 

User rating: 2
Joined: Wed 18 May, 2011, 17:36
Posts: 49
Location: FranceFrance
Hello Kosza and support.
I found your strategy very interesting.
I have tested the strategy on history at the end of the day and in real time with demo account during the same day with the same parameters.
1/ The positions are not the same. In real Time, more losses, and more winnings in historical tester. Sometime, one SHORT is followed by an other short trade in demo and by a LONG in historical tester.... (The historical tester is more profitable than the real time). Is it a problem with indicator range bar based? How to correct this bug? Is the historical tester wrong or the real time have a problem in the code?

2/ The strategy has been stopped two times in the day with the same message "com.dukascopy.api.JFException: state is CLOSED @ jforex.strategies.MACD_STOCH_Strat2.placeOrder(MACD_STOCH_Strat2.java:246). What does it means?

3/ Same message on the control strat panel all the day : ex: "Our Queue is full, Removing item: StartTime: 2012-01-23 15:40:10.634 EndTime: 2012-01-23 15:40:36.437 O: 1.30404 C: 1.30423 H: 1.30423 L: 1.30403 V: 87.78 FEC: 30". Is it normal?

4/ Could you point in the strategy where is the function requested by Kosza wich reverse the trade when the range bar turn from red to green...? Is it active?

5/ Could you add a break even function to limit profit turn into losses ?

THANKS for answer (sorry for my poor english)


 
 Post subject: Re: MACD and Stochastic Post rating: 0   New post Posted: Tue 24 Jan, 2012, 10:42 

User rating: 0
Joined: Mon 12 Dec, 2011, 17:08
Posts: 32
Location: Hungary,
Hi Math06 and Support,
I have the same experiences. During backtests the results are more than impressive. The strategy worked with minimal losses, but the forward tests in real time is not so good. For testing the problem I simplified the code to open and close positions following only the MACD histogram signals. In real time forward test (last 24 h) this simple strategy resulted in more than 20 % loss while the backtest gave approximately +10 %. This is not so good... Because the starting times were not exactly the same I have decided to test this simplified code in real time for a week without break in a freshly opened demo account. (For this would be very useful the using of the remote server, but after starting "she" immediately throw me out over and over.)
In summary, anything doesn't match with range bars...


 
 Post subject: Re: MACD and Stochastic Post rating: 0   New post Posted: Tue 24 Jan, 2012, 10:45 

User rating: 0
Joined: Mon 12 Dec, 2011, 17:08
Posts: 32
Location: Hungary,
A break even function would be really very useful.


 
 Post subject: Re: MACD and Stochastic Post rating: 0   New post Posted: Tue 24 Jan, 2012, 17:51 

User rating: 2
Joined: Wed 18 May, 2011, 17:36
Posts: 49
Location: FranceFrance
Hi Kosza and Support,

same bug today : "com.dukascopy.api.JFException: state is CLOSED @ jforex.strategies.MACD_STOCH_Strat2.placeOrder(MACD_STOCH_Strat2.java:236).
The strategy has been stopped for the day... :cry:
@ support: could you please answer to my previous post questions? MANY THANKS IN ADVANCE.
@ Kosza: 1/could you share your strat without stoch ?
2/ Do you think the backtest results are wrong or is it a bug in the real time demo test ? I guess the problem come with indicator based on range bars but is it the macd or the stoc which cause trouble? or both?

CHEERS

math


 
 Post subject: Re: MACD and Stochastic Post rating: 0   New post Posted: Tue 24 Jan, 2012, 18:21 

User rating: 0
Joined: Mon 12 Dec, 2011, 17:08
Posts: 32
Location: Hungary,
Hi Math,
Here is the simple MACD code. I have no too much idea about the problem. More exactly I simply have no idea, and I think that in the present situation to try/to develop strategies based on range bar is not a very productive work. By my opinion more probable the presence of a bug in historical range bars/indicator. I only think this, so don't take it too seriously. Unfortunately my coding knowledge is very poor...


Attachments:
SIMPLEMACD_Strat2.java [14.9 KiB]
Downloaded 521 times
DISCLAIMER: Dukascopy Bank SA's waiver of responsability - Documents, data or information available on this webpage may be posted by third parties without Dukascopy Bank SA being obliged to make any control on their content. Anyone accessing this webpage and downloading or otherwise making use of any document, data or information found on this webpage shall do it on his/her own risks without any recourse against Dukascopy Bank SA in relation thereto or for any consequences arising to him/her or any third party from the use and/or reliance on any document, data or information found on this webpage.
 
 Post subject: Re: MACD and Stochastic Post rating: 0   New post Posted: Tue 24 Jan, 2012, 18:34 

User rating: 2
Joined: Wed 18 May, 2011, 17:36
Posts: 49
Location: FranceFrance
Thanks i will test it.
same for me, i m a poor spaghetti coder (paste+paste+paste +compile+modify+paste +test)!!!!
Hope support will answer...

cheers,
Math


 
 Post subject: Re: Error messages during forward test of MACD and Stochastic st Post rating: 0   New post Posted: Tue 24 Jan, 2012, 19:11 

User rating: 2
Joined: Wed 18 May, 2011, 17:36
Posts: 49
Location: FranceFrance
kosza wrote:
The best would be a simple MACD histogramm strategy for range bar chart: MACD hyst(0)<0 and MACD hyst(1) >0 open long; close short,
MACD hyst(0)>0 and MACD hyst(1) <0 open long; close short,
with variable trailing stop
Thank


... and a trailing stop add to the break even should help to have some correct results! thanks


 
 Post subject: Re: MACD and Stochastic Post rating: 0   New post Posted: Tue 24 Jan, 2012, 19:48 

User rating: 2
Joined: Wed 18 May, 2011, 17:36
Posts: 49
Location: FranceFrance
Test on last week historical tester with SIMPLEMACDSTRAT2 : results are good.
Have a look at SIMPLESTOCSTRAT2.... it is better.... :lol:


Attachments:
SIMPLESTOC_Strat2.java [14.9 KiB]
Downloaded 558 times
DISCLAIMER: Dukascopy Bank SA's waiver of responsability - Documents, data or information available on this webpage may be posted by third parties without Dukascopy Bank SA being obliged to make any control on their content. Anyone accessing this webpage and downloading or otherwise making use of any document, data or information found on this webpage shall do it on his/her own risks without any recourse against Dukascopy Bank SA in relation thereto or for any consequences arising to him/her or any third party from the use and/or reliance on any document, data or information found on this webpage.
 
 Post subject: Re: MACD and Stochastic Post rating: 0   New post Posted: Wed 25 Jan, 2012, 10:46 

User rating: 0
Joined: Mon 12 Dec, 2011, 17:08
Posts: 32
Location: Hungary,
Hi Math and Support
Very nice, but I'm afraid these results doesn't mean too much. I've backtested the simple MACD str. with extremly good yields for the last day (24.01). The real time demo test was absolutely different. I don't know the reasons, but I think, I will make same pause in the strategy development / testing on base of range bars, until the bug ( if exists) will fixed.
Cheers
Kosza


 
 Post subject: Re: MACD and Stochastic Post rating: 0   New post Posted: Wed 25 Jan, 2012, 10:52 

User rating: 2
Joined: Wed 18 May, 2011, 17:36
Posts: 49
Location: FranceFrance
Hello support, have you find any solution or answer to this topic please?


 

Jump to:  

  © 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