Dukascopy
 
 
Wiki JStore Search Login

Indicator calculation works in Historical Tester but not live
 Post subject: Indicator calculation works in Historical Tester but not live Post rating: 0   New post Posted: Tue 14 Aug, 2012, 09:29 

User rating: 2
Joined: Sun 26 Jun, 2011, 07:05
Posts: 15
Location: Australia, Melbourne
Hi support,

Running the below code correctly calculates EMA and MACD values in backtest - these values are calculated onTick() based on 1HR Period. Correct output looks like this when run in historical tester:

Quote:
2012-08-14 08:25:08 AUD/USD tick at 2012.08.09 at 05:30:49 GMT during bar starting at 2012.08.09 at 05:00:00 GMT, ema = 1.056983923972477, macd histogram = 3.7210154314966273E-4
2012-08-14 08:25:08 AUD/USD tick at 2012.08.09 at 05:30:47 GMT during bar starting at 2012.08.09 at 05:00:00 GMT, ema = 1.0569890668296198, macd histogram = 3.778451328932082E-4
2012-08-14 08:25:08 AUD/USD tick at 2012.08.09 at 05:30:44 GMT during bar starting at 2012.08.09 at 05:00:00 GMT, ema = 1.0569822096867627, macd histogram = 3.701870132351477E-4
2012-08-14 08:27:12 Subscribing to: [AUD/USD] Hourly


However, when running the strategy live against a server (LIVE or DEMO server), zero length arrays are returned by IIndicator.ema() and IIndicator.macd()

Quote:
2012-08-14 08:27:22 AUD/USD - ERROR: Tick with emtpy indicator array: emaArray macdArray[2]
2012-08-14 08:27:18 AUD/USD - ERROR: Tick with emtpy indicator array: emaArray macdArray[2]
2012-08-14 08:27:17 AUD/USD - ERROR: Tick with emtpy indicator array: emaArray macdArray[2]
2012-08-14 08:27:16 AUD/USD - ERROR: Tick with emtpy indicator array: emaArray macdArray[2]
2012-08-14 08:27:12 Subscribing to: [AUD/USD] Hourly


This is the code:

//package strategies;
package singlejartest;

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

import com.dukascopy.api.*;
import com.dukascopy.api.IIndicators.AppliedPrice;
import com.dukascopy.api.feed.FeedDescriptor;
import com.dukascopy.api.feed.IFeedDescriptor;

public class TestStrategy2 implements IStrategy
{
    /////////////////////////////
    //constants used for console logging
    /////////////////////////////
    static final int INFO = 0;
    static final int WARNING = 1;
    static final int ERROR = 2;
   
    /////////////////////////////
    //input parameters
    /////////////////////////////
    @Configurable("EMA Period") public int _emaPeriod = 34;
    @Configurable("MACD Fast Period") public int _macdFastPeriod = 12;
    @Configurable("MACD Slow Period") public int _macdSlowPeriod = 26;
    @Configurable("MACD Signal Period") public int _macdSignalPeriod = 9;

    @Configurable("Debug Printing") public boolean _debugPrintFlag = true;
   
    /////////////////////////////
    //JForex interfaces for future use
    /////////////////////////////
    private IConsole _console;
    private IIndicators _indicators;
    private IHistory _history;
   
    private Set<Instrument> _instSet;   
    Period _period = Period.ONE_HOUR; //Period.createCustomPeriod(Unit.Hour, 2);//
   
    final SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd 'at' HH:mm:ss z");

    /////////////////////////////
    // helper methods
    /////////////////////////////
       
    private void debugPrint (int level, String strToPrint)
    {
        if (_debugPrintFlag)
        {
            switch (level)
            {
                case ERROR:
                    _console.getErr().println(strToPrint);
                    break;
                case WARNING:
                    _console.getWarn().println(strToPrint);
                    break;
                case INFO:
                default:
                    _console.getOut().println(strToPrint);
            }
        }
    }
       
 
    /////////////////////////////
    // IStrategy interface methods
    /////////////////////////////
   
    public void onStart(IContext context) throws JFException
    {
        _console = context.getConsole();
        _indicators = context.getIndicators();
        _history = context.getHistory();
       
        sdf.setTimeZone(TimeZone.getTimeZone("GMT"));

        //subscribe to instruments
        _instSet = new HashSet<Instrument>();
        _instSet.add(Instrument.AUDUSD);
        context.setSubscribedInstruments(_instSet);   
   
        debugPrint (INFO, "Subscribing to: " + _instSet.toString() + " " + _period);
    }
   
    public void onAccount(IAccount account) throws JFException {
    }

    public void onMessage(IMessage message) throws JFException {
    }

    public void onStop() throws JFException {
    }

    public void onTick(Instrument instrument, ITick tick) throws JFException
    {
        if (_instSet.contains(instrument))
        {
            try
            {
                long currentBarTime = _history.getBarStart(_period, tick.getTime());

                double emaArray[]  =  _indicators.ema(instrument, _period, OfferSide.BID, IIndicators.AppliedPrice.CLOSE, _emaPeriod, Filter.WEEKENDS, currentBarTime, currentBarTime);
                double[][] macdArray =  _indicators.macd(instrument, _period, OfferSide.BID, IIndicators.AppliedPrice.CLOSE, _macdFastPeriod, _macdSlowPeriod, _macdSignalPeriod, Filter.WEEKENDS, currentBarTime, currentBarTime);
                       
                if (emaArray != null && macdArray != null &&
                    emaArray.length > 0 && macdArray.length > 0)
                {
                    double ema = emaArray[0];
                    double macdHistogram = macdArray[2][0];

                    debugPrint (INFO, instrument + " tick at " + sdf.format(new Date(tick.getTime())) +
                                      " during bar starting at " + sdf.format(new Date(currentBarTime)) +
                                      ", ema = " + ema  +
                                      ", macd histogram = " + macdHistogram );
                }
                else
                {
                    String nullString = (emaArray == null ? "emaArray " : "") +
                                            (macdArray == null ? "macdArray" : "");
                    if (nullString.length() != 0)
                    {
                        debugPrint (ERROR, instrument.toString() + " - ERROR: Tick with null indicator array: " + nullString);
                    }
                   
                    String emptyString = (emaArray.length == 0 ? "emaArray " : "") +
                                         (macdArray.length == 0 ? "macdArray" : "") +
                                         (macdArray[2].length == 0 ? "macdArray[2]" : "");
                    if (emptyString.length() != 0)
                    {
                        debugPrint (ERROR, instrument.toString() + " - ERROR: Tick with emtpy indicator array: " + emptyString);
                    }
                   
                }
            }
            catch (JFException e)
            {
                debugPrint (ERROR, instrument.toString() + " " + "Exception: " + e.toString());
                e.printStackTrace();
            }
        }
    }
   
    public void onBar(Instrument inst, Period period, IBar askBar, IBar bidBar) throws JFException {
    }
}


Can you please help me get this working properly onTick() ?


thanks in advance,
C


 
 Post subject: Re: Indicator calculation works in Historical Tester but not live Post rating: 0   New post Posted: Tue 14 Aug, 2012, 09:31 

User rating: 2
Joined: Sun 26 Jun, 2011, 07:05
Posts: 15
Location: Australia, Melbourne
By the way... I need this to work for a strategy that uses indicators from a candlestick chart (e.g. 1HR) to make trading decisions onTick().


thanks in advance,
C


 
 Post subject: Re: APICLIENT-261 Indicator calculation works in Historical Tester but not live Post rating: 0   New post Posted: Fri 17 Aug, 2012, 11:23 

User rating: 2
Joined: Sun 26 Jun, 2011, 07:05
Posts: 15
Location: Australia, Melbourne
Hi Support,

I notice that you have moved this post from the KNOWLEDGE BASE section to the BUG REPORTS.

We have invested significant effort developing and optimising a strategy for quite a while now that relies on the values produced by the Historical Tester using the method call below (not the other overrides).

Please confirm that your intended fix will not alter the historical test results, but simply provide access to this same calculation against a Dukascopy server (LIVE or DEMO).



thanks in advance,
C


 
 Post subject: Re: APICLIENT-261 Indicator calculation works in Historical Tester but not live Post rating: 0   New post Posted: Tue 18 Sep, 2012, 10:14 
User avatar

User rating: 8
Joined: Tue 25 Oct, 2011, 23:02
Posts: 74
Location: Australia, Melbourne
Hello support,

I retested this bug on the demo server today (JForex Client 2.19.2, API 2.7.2.2) and confirmed that the ArrayIndexOutOfBounds exception still occurs in both forward and back tests.

Forward test against DEMO server:

Quote:
09:08:08 Strategy "TestStrategy3" is stopped at 2012-09-18 09:08:13.597 GMT on the local computer with parameters "EMA Period"=[34], "MACD Fast Period"=[12], "MACD Slow Period"=[26], "MACD Signal Period"=[9], "Debug Printing"=[true]. Reason: Stopped by Engine
09:08:08 Stopping "TestStrategy3" strategy at 2012-09-18 09:08:13.586 GMT on the local computer
09:08:05 java.lang.ArrayIndexOutOfBoundsException: 0 @ singlejartest.TestStrategy3.onTick(TestStrategy3.java:107)
09:07:59 java.lang.ArrayIndexOutOfBoundsException: 0 @ singlejartest.TestStrategy3.onTick(TestStrategy3.java:107)
09:07:59 java.lang.ArrayIndexOutOfBoundsException: 0 @ singlejartest.TestStrategy3.onTick(TestStrategy3.java:107)
09:07:59 java.lang.ArrayIndexOutOfBoundsException: 0 @ singlejartest.TestStrategy3.onTick(TestStrategy3.java:107)
09:07:55 Strategy "TestStrategy3" is started at 2012-09-18 09:07:59.752 GMT on the local computer with parameters "EMA Period"=[34], "MACD Fast Period"=[12], "MACD Slow Period"=[26], "MACD Signal Period"=[9], "Debug Printing"=[true]
09:07:55 Starting "TestStrategy3" strategy at 2012-09-18 09:07:59.705 GMT on the local computer


Back test using Historical Tester:

Quote:
...
2012-09-18 09:08:57 Strategy tester: java.lang.ArrayIndexOutOfBoundsException: 0 @ singlejartest.TestStrategy3.onTick(TestStrategy3.java:107)
2012-09-18 09:08:57 Strategy tester: java.lang.ArrayIndexOutOfBoundsException: 0 @ singlejartest.TestStrategy3.onTick(TestStrategy3.java:107)
2012-09-18 09:08:57 Strategy tester: java.lang.ArrayIndexOutOfBoundsException: 0 @ singlejartest.TestStrategy3.onTick(TestStrategy3.java:107)
2012-09-18 09:08:57 Strategy tester: java.lang.ArrayIndexOutOfBoundsException: 0 @ singlejartest.TestStrategy3.onTick(TestStrategy3.java:107)
2012-09-18 09:08:57 Strategy tester: java.lang.ArrayIndexOutOfBoundsException: 0 @ singlejartest.TestStrategy3.onTick(TestStrategy3.java:107)
...


The strategy I used was as follows:

//package strategies;
package singlejartest;
 
import java.util.*;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
 
import com.dukascopy.api.*;
import com.dukascopy.api.IIndicators.AppliedPrice;
import com.dukascopy.api.feed.FeedDescriptor;
import com.dukascopy.api.feed.IFeedDescriptor;
import com.dukascopy.api.feed.IBarFeedListener;
 
public class TestStrategy3 implements IStrategy
{
    /////////////////////////////
    //constants used for console logging
    /////////////////////////////
    static final int INFO = 0;
    static final int WARNING = 1;
    static final int ERROR = 2;
     
    /////////////////////////////
    //input parameters
    /////////////////////////////
    @Configurable("EMA Period") public int _emaPeriod = 34;
    @Configurable("MACD Fast Period") public int _macdFastPeriod = 12;
    @Configurable("MACD Slow Period") public int _macdSlowPeriod = 26;
    @Configurable("MACD Signal Period") public int _macdSignalPeriod = 9;
 
    @Configurable("Debug Printing") public boolean _debugPrintFlag = true;
     
    /////////////////////////////
    //JForex interfaces for future use
    /////////////////////////////
    private IConsole _console;
    private IIndicators _indicators;
    private IHistory _history;
     
    private Set<Instrument> _instSet;   
    Period _period = Period.createCustomPeriod(Unit.Hour, 2);
//    Period _period = Period.ONE_HOUR;
     
    final SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd 'at' HH:mm:ss z");
 
    /////////////////////////////
    // helper methods
    /////////////////////////////
         
    private void debugPrint (int level, String strToPrint)
    {
        if (_debugPrintFlag)
        {
            switch (level)
            {
                case ERROR:
                    _console.getErr().println(strToPrint);
                    break;
                case WARNING:
                    _console.getWarn().println(strToPrint);
                    break;
                case INFO:
                default:
                    _console.getOut().println(strToPrint);
            }
        }
    }
         
 
    /////////////////////////////
    // IStrategy interface methods
    /////////////////////////////
     
    public void onStart(IContext context) throws JFException
    {
        _console = context.getConsole();
        _indicators = context.getIndicators();
        _history = context.getHistory();
         
        sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
 
        //subscribe to instruments
        _instSet = new HashSet<Instrument>();
        _instSet.add(Instrument.AUDUSD);
        context.setSubscribedInstruments(_instSet);   

    }
     
    public void onAccount(IAccount account) throws JFException {
    }
 
    public void onMessage(IMessage message) throws JFException {
    }
 
    public void onStop() throws JFException {
    }
 
    public void onTick(Instrument instrument, ITick tick) throws JFException
    {
        if (_instSet.contains(instrument))
        {
            long currentBarTime = _history.getBarStart(_period, tick.getTime());

            double emaArray[]  =  _indicators.ema(instrument, _period, OfferSide.BID, IIndicators.AppliedPrice.CLOSE, _emaPeriod, Filter.WEEKENDS, currentBarTime, currentBarTime);
            double[][] macdArray =  _indicators.macd(instrument, _period, OfferSide.BID, IIndicators.AppliedPrice.CLOSE, _macdFastPeriod, _macdSlowPeriod, _macdSignalPeriod, Filter.WEEKENDS, currentBarTime, currentBarTime);
                     
            double ema = emaArray[0];
            double macdHistogram = macdArray[2][0];

            debugPrint (INFO, instrument + " tick at " + sdf.format(new Date(tick.getTime())) +
                              " during bar starting at " + sdf.format(new Date(currentBarTime)) +
                              ", ema = " + ema  +
                              ", macd histogram = " + macdHistogram );
        }
    }
     
    public void onBar(Instrument inst, Period period, IBar askBar, IBar bidBar) throws JFException {
    }
}



thanks,
f451


 
 Post subject: Re: APICLIENT-261 Indicator calculation works in Historical Tester but not live Post rating: 0   New post Posted: Tue 25 Sep, 2012, 08:14 
User avatar

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


 
 Post subject: Re: APICLIENT-261 Indicator calculation works in Historical Tester but not live Post rating: 0   New post Posted: Thu 27 Sep, 2012, 08:18 

User rating: 2
Joined: Sun 26 Jun, 2011, 07:05
Posts: 15
Location: Australia, Melbourne
Hi support,

I just tested the above TestStrategy3 against JForexClient v 2.20 with API version 2.7.3:

Quote:
2012-09-27 07:15:14 Strategy tester: java.lang.ArrayIndexOutOfBoundsException: 0 @ singlejartest.TestStrategy3.onTick(TestStrategy3.java:107)
2012-09-27 07:15:14 Strategy tester: java.lang.ArrayIndexOutOfBoundsException: 0 @ singlejartest.TestStrategy3.onTick(TestStrategy3.java:107)
2012-09-27 07:15:14 Strategy tester: java.lang.ArrayIndexOutOfBoundsException: 0 @ singlejartest.TestStrategy3.onTick(TestStrategy3.java:107)
2012-09-27 07:15:14 Strategy tester: java.lang.ArrayIndexOutOfBoundsException: 0 @ singlejartest.TestStrategy3.onTick(TestStrategy3.java:107)
2012-09-27 07:15:14 Strategy tester: java.lang.ArrayIndexOutOfBoundsException: 0 @ singlejartest.TestStrategy3.onTick(TestStrategy3.java:107)
2012-09-27 07:15:14 Strategy tester: java.lang.ArrayIndexOutOfBoundsException: 0 @ singlejartest.TestStrategy3.onTick(TestStrategy3.java:107)


Can you please move this back into the bugs section?


thanks,
C


 
 Post subject: Re: Indicator calculation works in Historical Tester but not live Post rating: 0   New post Posted: Fri 12 Oct, 2012, 09:15 

User rating: 2
Joined: Sun 26 Jun, 2011, 07:05
Posts: 15
Location: Australia, Melbourne
Hi Support,

Unfortunately this issue is still not resolved in JForex Client v2.20.3 - JForex API version 2.7.4.

Calculating indicator values on tick with a custom period (in this case 2HR) still returns the same array out of bounds error.

Quote:
2012-10-12 08:05:37 Strategy tester: java.lang.ArrayIndexOutOfBoundsException: 0 @ singlejartest.TestStrategy3.onTick(TestStrategy3.java:107)
2012-10-12 08:05:37 Strategy tester: java.lang.ArrayIndexOutOfBoundsException: 0 @ singlejartest.TestStrategy3.onTick(TestStrategy3.java:107)
2012-10-12 08:05:37 Strategy tester: java.lang.ArrayIndexOutOfBoundsException: 0 @ singlejartest.TestStrategy3.onTick(TestStrategy3.java:107)
2012-10-12 08:05:37 Strategy tester: java.lang.ArrayIndexOutOfBoundsException: 0 @ singlejartest.TestStrategy3.onTick(TestStrategy3.java:107)


Below is the code for the test program that demonstrates this bug.

//package strategies;
package singlejartest;
 
import java.util.*;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
 
import com.dukascopy.api.*;
import com.dukascopy.api.IIndicators.AppliedPrice;
import com.dukascopy.api.feed.FeedDescriptor;
import com.dukascopy.api.feed.IFeedDescriptor;
import com.dukascopy.api.feed.IBarFeedListener;
 
public class TestStrategy3 implements IStrategy
{
    /////////////////////////////
    //constants used for console logging
    /////////////////////////////
    static final int INFO = 0;
    static final int WARNING = 1;
    static final int ERROR = 2;
     
    /////////////////////////////
    //input parameters
    /////////////////////////////
    @Configurable("EMA Period") public int _emaPeriod = 34;
    @Configurable("MACD Fast Period") public int _macdFastPeriod = 12;
    @Configurable("MACD Slow Period") public int _macdSlowPeriod = 26;
    @Configurable("MACD Signal Period") public int _macdSignalPeriod = 9;
 
    @Configurable("Debug Printing") public boolean _debugPrintFlag = true;
     
    /////////////////////////////
    //JForex interfaces for future use
    /////////////////////////////
    private IConsole _console;
    private IIndicators _indicators;
    private IHistory _history;
     
    private Set<Instrument> _instSet;   
    Period _period = Period.createCustomPeriod(Unit.Hour, 2);
//    Period _period = Period.ONE_HOUR;
     
    final SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd 'at' HH:mm:ss z");
 
    /////////////////////////////
    // helper methods
    /////////////////////////////
         
    private void debugPrint (int level, String strToPrint)
    {
        if (_debugPrintFlag)
        {
            switch (level)
            {
                case ERROR:
                    _console.getErr().println(strToPrint);
                    break;
                case WARNING:
                    _console.getWarn().println(strToPrint);
                    break;
                case INFO:
                default:
                    _console.getOut().println(strToPrint);
            }
        }
    }
         
   
    /////////////////////////////
    // IStrategy interface methods
    /////////////////////////////
     
    public void onStart(IContext context) throws JFException
    {
        _console = context.getConsole();
        _indicators = context.getIndicators();
        _history = context.getHistory();
         
        sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
 
        //subscribe to instruments
        _instSet = new HashSet<Instrument>();
        _instSet.add(Instrument.AUDUSD);
        context.setSubscribedInstruments(_instSet);   
 
    }
     
    public void onAccount(IAccount account) throws JFException {
    }
 
    public void onMessage(IMessage message) throws JFException {
    }
 
    public void onStop() throws JFException {
    }
 
    public void onTick(Instrument instrument, ITick tick) throws JFException
    {
        if (_instSet.contains(instrument))
        {
            long currentBarTime = _history.getBarStart(_period, tick.getTime());
 
            double emaArray[]  =  _indicators.ema(instrument, _period, OfferSide.BID, IIndicators.AppliedPrice.CLOSE, _emaPeriod, Filter.WEEKENDS, currentBarTime, currentBarTime);
            double[][] macdArray =  _indicators.macd(instrument, _period, OfferSide.BID, IIndicators.AppliedPrice.CLOSE, _macdFastPeriod, _macdSlowPeriod, _macdSignalPeriod, Filter.WEEKENDS, currentBarTime, currentBarTime);
                     
            double ema = emaArray[0];
            double macdHistogram = macdArray[2][0];
 
            debugPrint (INFO, instrument + " tick at " + sdf.format(new Date(tick.getTime())) +
                              " during bar starting at " + sdf.format(new Date(currentBarTime)) +
                              ", ema = " + ema  +
                              ", macd histogram = " + macdHistogram );
        }
    }
     
    public void onBar(Instrument inst, Period period, IBar askBar, IBar bidBar) throws JFException {
    }
}


Please note: This bug was initially reported against API version 2.6.X where the test program worked in backtest but not against a live/demo server. Now this bug happens both in backtest and against a server.


thanks in advance,
C


 

Jump to:  

  © 1998-2024 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