Hello Support,
I would like to ask you to fix following bug in JForex DEMO 2.6.68
Trading strategy running on RANGE BARS backtest does not receive correct values of DEMA or TEMA indicators from the JForex.
Please see following example strategy:
package rangebartest;
import com.dukascopy.api.IIndicators.AppliedPrice;
import com.dukascopy.api.IIndicators.MaType;
import com.dukascopy.api.*;
import com.dukascopy.api.feed.FeedDescriptor;
import com.dukascopy.api.feed.IFeedDescriptor;
import com.dukascopy.api.feed.IRangeBar;
import com.dukascopy.api.feed.IRangeBarFeedListener;
import java.util.Calendar;
import java.util.TimeZone;
public class RangeBarTest implements IStrategy, IRangeBarFeedListener {
@Configurable("Instrument") public Instrument selectedInstrument = Instrument.EURUSD;
@Configurable("OfferSide") public OfferSide selectedOfferSide = OfferSide.BID;
@Configurable("Range bar size (in pips)") public int selectedRangeBarSizeInPips = 5;
@Configurable("MA TimePeriod") public int selectedMATimePeriod = 14;
@Configurable("MA Type") public MaType selectedMAType = MaType.EMA;
@Configurable("MA Filter") public Filter selectedFilter = Filter.WEEKENDS;
private IContext context;
private IIndicators indicators;
private IConsole console;
private PriceRange selectedPriceRange;
private IFeedDescriptor feedDescriptor;
@Override
public void onStart(IContext context) throws JFException {
try {
if (context.getChart(selectedInstrument)==null) {
throw new Exception("At first please open the "+selectedInstrument+" price chart in your JForex");
}
if (context.getChart(selectedInstrument).getPriceRange()==null) {
throw new Exception("The "+selectedInstrument+" price chart has to be in RANGE BARS");
}
if (context.getChart(selectedInstrument).getPriceRange().getPipCount()!=selectedRangeBarSizeInPips) {
throw new Exception("The "+selectedInstrument+" RANGE bars has to have "+selectedRangeBarSizeInPips+" pips size.");
}
this.context = context;
this.indicators = context.getIndicators();
this.console = context.getConsole();
this.selectedPriceRange = PriceRange.valueOf(selectedRangeBarSizeInPips);
this.context.subscribeToRangeBarFeed(selectedInstrument, selectedOfferSide, selectedPriceRange, this);
this.feedDescriptor = new FeedDescriptor();
feedDescriptor.setDataType(DataType.PRICE_RANGE_AGGREGATION);
feedDescriptor.setFilter(selectedFilter);
feedDescriptor.setInstrument(selectedInstrument);
feedDescriptor.setOfferSide(selectedOfferSide);
feedDescriptor.setPriceRange(selectedPriceRange);
} catch (Exception ex) {
throw new JFException(ex.getMessage(), ex.getCause());
}
}
@Override
public void onTick(Instrument instrument, ITick tick) throws JFException {
}
@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 {
}
@Override
public void onBar(Instrument instrument, OfferSide offerSide, PriceRange priceRange, IRangeBar bar) {
try {
if (instrument.equals(selectedInstrument) && offerSide.equals(selectedOfferSide) && priceRange.getPipCount()==selectedRangeBarSizeInPips) {
Double ma0 = (Double)indicators.calculateIndicator(feedDescriptor, new OfferSide[] {selectedOfferSide}, selectedMAType.name(), new AppliedPrice[] {AppliedPrice.CLOSE}, new Object[] {selectedMATimePeriod}, 0)[0];
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
calendar.setTimeInMillis(bar.getTime());
String startTime = toStringCalendar(calendar);
calendar.setTimeInMillis(bar.getEndTime());
String endTime = toStringCalendar(calendar);
console.getOut().println("START_TIME="+startTime+" END_TIME="+endTime+" OPEN="+bar.getOpen()+" CLOSE="+bar.getClose()+" HIGH="+bar.getHigh()+" LOW="+bar.getLow()+" MovinAverage="+ma0);
}
} catch (Exception ex) {
console.getErr().println(ex.getMessage());
}
}
private String toStringCalendar(Calendar calendar) {
String result;
int day = calendar.get(Calendar.DAY_OF_MONTH);
String s_day;
if (((int)day/10)==0) {
s_day = "0"+day;
} else {
s_day = ""+day;
}
int month = calendar.get(Calendar.MONTH)+1;
String s_month;
if (((int)month/10)==0) {
s_month = "0"+month;
} else {
s_month = ""+month;
}
int year = calendar.get(Calendar.YEAR);
String s_year;
if (((int)year/10)==0) {
s_year = "0"+year;
} else {
s_year = ""+year;
}
int hour = calendar.get(Calendar.HOUR_OF_DAY);
String s_hour;
if (((int)hour/10)==0) {
s_hour = "0"+hour;
} else {
s_hour = ""+hour;
}
int minute = calendar.get(Calendar.MINUTE);
String s_minute;
if (((int)minute/10)==0) {
s_minute = "0"+minute;
} else {
s_minute = ""+minute;
}
int second = calendar.get(Calendar.SECOND);
String s_second;
if (((int)second/10)==0) {
s_second = "0"+second;
} else {
s_second = ""+second;
}
int milisecond = calendar.get(Calendar.MILLISECOND);
String s_milisecond;
if (((int)milisecond/100)==0) {
s_milisecond = "0"+milisecond;
} else {
s_milisecond = ""+milisecond;
}
if (((int)milisecond/10)==0) {
s_milisecond = "0"+s_milisecond;
}
result = s_day+"."+s_month+"."+s_year+" "+s_hour+":"+s_minute+":"+s_second+"."+s_milisecond;
return result;
}
}
If you will run this strategy with EMA or SMA for example, then the values received from the JForex are correct.
BUT if you will try to run it with DEMA or TEMA then you will see that the values are NOT correct.
When could be this bug fixed please?
Thank you
Have a nice day
Marek Lorenc
https://www.LorencSoftware.com