The following strategy generates wrong zigzag values in the Historical Tester.
Timeperiod: 30 mins
instrument: EUR/USD
tested interval: from 2011/01/01
package jforex.strategies.indicators;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
import com.dukascopy.api.*;
import com.dukascopy.api.IIndicators.MaType;
import com.dukascopy.api.indicators.IIndicator;
/**
* The strategy finds the last not null zigzag value unless it is more than
* [previousValueArraySize] candles in the past
*/
public class ZigZag implements IStrategy {
private IConsole console;
private IIndicators indicators;
private IChart chart;
@Configurable("Instrument")
public Instrument instrument = Instrument.EURUSD;
@Configurable("Period")
public Period selectedPeriod = Period.TEN_MINS;
//Zigzag parameters
private int extDepth = 12;
private int extDeviation = 5;
private int extBackstep = 3;
private int previousValueArraySize = 50;
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public void onStart(IContext context) throws JFException {
this.console = context.getConsole();
this.indicators = context.getIndicators();
this.chart = context.getChart(instrument);
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
print("start " + this.getClass().getSimpleName());
//uncomment to plot the indicator on the chart - this slows down the historical testing
//chart.addIndicator(indicators.getIndicator("ZIGZAG"), new Object[]{extDepth, extDeviation, extBackstep });
}
public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
if (!instrument.equals(this.instrument) || !period.equals(selectedPeriod))
return;
//the current zigzag value
double zigzag = indicators.zigzag(instrument, period, OfferSide.BID, extDepth, extDeviation, extBackstep, 1);
//the last [previousValueArraySize] values
double[] zigzagArray = indicators.zigzag(instrument, period, OfferSide.BID, extDepth, extDeviation, extBackstep,
Filter.NO_FILTER, previousValueArraySize, bidBar.getTime(), 0 );
double zigzagLastNotNull = Double.NaN;
int zigzagLastNotNullIndex = -1;
//find the latest not null zigzag value (newest values are at the end of the value array)
for(int i = previousValueArraySize -1 ; i > -1 ; i--){
if (!Double.valueOf(zigzagArray[i]).isNaN()){
zigzagLastNotNull = zigzagArray[i];
zigzagLastNotNullIndex = i;
break;
}
}
print(sdf.format(bidBar.getTime()) + " last zigzag=" + zigzag
+ "; last not null zigzag=" +zigzagLastNotNull +" canldes back: " + (previousValueArraySize - zigzagLastNotNullIndex)
+ "; last " +previousValueArraySize+ " values: " + arrayToString(zigzagArray) );
}
private void print(Object message) {
console.getOut().println(message);
}
public static String arrayToString(double [] arr){
String str = "";
for (int r=0; r<arr.length; r++) {
str += " [" + r + "]" + (new DecimalFormat("0.000000")).format(arr[r]) + ", ";
}
return str;
}
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 { }
}
As visible on the screenshot, the strategy calculates valid zigzag values at 00:00, 00:30, 01:00 and at 01:30 on 2011/01/04.
However the zigzag indicator on the chart shows valid zigzag values at 16:00 on 2011/01/03 and at 01:30 on 2011/01/04.
And this is not the only timeframe when the strategy generates valid zigzag values for consecutive bars. For example:
From 2011/01/05 00:00 there are 4 consecutive bars with `valid` zigzag value.
From 2011/01/05 07:00 there are 4 consecutive bars with `valid` zigzag value.
From 2011/01/06 07:00 there are 2 consecutive bars with `valid` zigzag value.
and so on...
Note: This strategy was provided by support here:
viewtopic.php?f=6&t=38916 By the way, why is that topic locked?
