|
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.
IIndicator.macd giving different results then JF client |
JohanRens
|
Post subject: IIndicator.macd giving different results then JF client |
Post rating: 0
|
Posted: Wed 29 Jun, 2011, 14:16
|
|
User rating: -
|
Hello,
I'm working on a relatively simple MACD strategy, but I cannot get the IIndicator instance to give me the same numbers as generated in the JForex client. They're always a little off. I do apply the same offerside, period, appliedprice etc. yet I cannot reproduce the results that can be found in the Jforex client. It's definately not a timing issue either, just the numbers being up to about 10% off.
Any help would be greatly appreciated, I really cannot find the cause for this.
Johan
|
|
|
|
 |
API Support
|
Post subject: Re: IIndicator.macd giving different results then JF client |
Post rating: 0
|
Posted: Wed 29 Jun, 2011, 14:37
|
|
User rating: ∞
Joined: Fri 31 Aug, 2007, 09:17 Posts: 6139
|
There are multiple things and parameters that might cause the results to differ, for example, a common cause is the time zone which should be adjusted to GMT. Could you please provide a source code fragment which brings different results from that of JForex client?
|
|
|
|
 |
JohanRens
|
Post subject: Re: IIndicator.macd giving different results then JF client |
Post rating: 0
|
Posted: Wed 29 Jun, 2011, 15:11
|
|
User rating: -
|
Wow, thanks for your quick reply. Here a more elaborate outline of the problem. package singlejartest;
import com.dukascopy.api.*;
public class MACDstrategy implements IStrategy { private IEngine engine = null; private IIndicators indicators = null; private int tagCounter = 0; private IConsole console; private IHistory history; double macdResult []; double lastmacdResult []; double stopLoss; double takeProfit; IOrder openOrder; ITick lastTick; private static final int NONE = 0; private static final int LONG = 1; private static final int SHORT = 2; int lastOrder = NONE; public static final String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss"; //DEBUG boolean flipper=false; //debug public void onStart(IContext context) throws JFException { engine = context.getEngine(); history = context.getHistory(); indicators = context.getIndicators(); this.console = context.getConsole(); console.getOut().println("Started"); }
public void onStop() throws JFException { for (IOrder order : engine.getOrders()) { order.close(); } console.getOut().println("Stopped"); }
public void onTick(Instrument instrument, ITick tick) throws JFException { }
public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) {
if (period != Period.ONE_MIN) return; if (instrument != Instrument.EURJPY) return; try { macdResult = indicators.macd(instrument, Period.ONE_MIN, OfferSide.BID, IIndicators.AppliedPrice.CLOSE, 40, 8, 80, 1 ); } catch (JFException e) { // TODO Auto-generated catch block e.printStackTrace(); }
try{ lastTick = history.getLastTick(instrument); } catch(JFException e) { e.printStackTrace(console.getErr()); } //DEBUG //if (flipper== true) {macdResult [2] = 0.1; flipper= false;} else {macdResult [2] = -0.1; flipper= true;} //DEBUG System.out.println("Current: " + macdResult[2]); if (lastmacdResult!= null) { System.out.println("Last: " + lastmacdResult[2]); } System.out.println("----------------"); if (lastmacdResult !=null) { if (macdResult[2] >= 0.0000 && lastmacdResult[2]< 0.0000 && lastOrder != LONG) { stopLoss = lastTick.getBid() - 0.50; takeProfit = lastTick.getBid() + 1.20; try { if (openOrder != null) { if (openOrder.getState() != IOrder.State.CLOSED) { openOrder.close(); } } openOrder = engine.submitOrder(getLabel(instrument), instrument, IEngine.OrderCommand.BUY, 0.1, 0, 20, stopLoss, takeProfit); lastOrder = LONG; } catch (JFException e) { e.printStackTrace(); } } if (macdResult[2] <= 0.0000 && lastmacdResult[2] > 0.0000 && lastOrder != SHORT) { stopLoss = lastTick.getBid() + 0.50; takeProfit = lastTick.getBid() - 1.20; try { if (openOrder != null) { if (openOrder.getState() != IOrder.State.CLOSED) { openOrder.close(); } } openOrder = engine.submitOrder(getLabel(instrument), instrument, IEngine.OrderCommand.SELL, 0.1, 0, 20, stopLoss, takeProfit); lastOrder = SHORT; } catch (JFException e) { e.printStackTrace(); } } } lastmacdResult = macdResult; }
//count open positions protected int positionsTotal(Instrument instrument) throws JFException { int counter = 0; for (IOrder order : engine.getOrders(instrument)) { if (order.getState() == IOrder.State.FILLED) { counter++; } } return counter; }
protected String getLabel(Instrument instrument) { String label = instrument.name(); label = label.substring(0, 2) + label.substring(3, 5); label = label + (tagCounter++); label = label.toLowerCase(); return label; }
public void onMessage(IMessage message) throws JFException { }
public void onAccount(IAccount account) throws JFException { } } Is my code. it outputs as you can see in the overlay of my screenshot of the jforex client. as you can see. For the 13:55 minute MACD Hist on Jforex shows 0.0570678. My code shows 0.057202909204... for my strategy this is too big a difference. When I backtest this code, the orders are off (both ways, sometimes to early, sometimes too late). (minute 13:54 was 0.0553319 on the client, and 0.554979... from my code) The screenshot can be found at: https://www.forexfox.nl/extupl/macdproblem.pngThanks in advance, Johan Both indicators are set to 40,8,80. Close price, bid.
|
|
|
|
 |
API Support
|
Post subject: Re: IIndicator.macd giving different results then JF client |
Post rating: 0
|
Posted: Thu 30 Jun, 2011, 12:16
|
|
User rating: ∞
Joined: Fri 31 Aug, 2007, 09:17 Posts: 6139
|
Apparently the problem was that the timezone was not set to GMT. We adjusted your strategy to use the GMT, updated the print statements to include the time and added the indicator to the chart from the strategy. package jforex.bugtests;
import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.TimeZone;
import com.dukascopy.api.*;
public class MACDstrategy implements IStrategy { private IEngine engine = null; private IIndicators indicators = null; private int tagCounter = 0; private IConsole console; private IHistory history; private IChart chart;
double macdResult[]; double lastmacdResult[];
// macd specific params private int fastPeriod = 40; private int slowPeriod = 8; private int signalPeriod = 80; private int shift = 1;
// strategy specific params private Instrument instrument = Instrument.EURJPY; private Period period = Period.ONE_MIN;
double stopLoss; double takeProfit;
IOrder openOrder; ITick lastTick;
private static final int NONE = 0; private static final int LONG = 1; private static final int SHORT = 2;
int lastOrder = NONE;
@SuppressWarnings("serial") private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") {{setTimeZone(TimeZone.getTimeZone("GMT"));}};
// DEBUG boolean flipper = false;
// debug
public void onStart(IContext context) throws JFException { engine = context.getEngine(); history = context.getHistory(); indicators = context.getIndicators(); this.console = context.getConsole(); this.chart = context.getChart(instrument); console.getOut().println("Started");
/* uncomment to see the ordering of optional parameters IIndicator indicator = indicators.getIndicator("MACD"); for (int i = 0; i < indicator.getIndicatorInfo().getNumberOfOptionalInputs(); i++){ console.getOut().println( i + ": name = '"+ indicator.getOptInputParameterInfo(i).getName() + "' type = "+ indicator.getOptInputParameterInfo(i).getType()); } */ chart.addIndicator(indicators.getIndicator("MACD"), new Object[]{fastPeriod, slowPeriod, signalPeriod}); }
public void onStop() throws JFException { for (IOrder order : engine.getOrders()) { order.close(); } console.getOut().println("Stopped"); }
public void onTick(Instrument instrument, ITick tick) throws JFException {
}
public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
if (period != this.period || instrument != this.instrument) return;
macdResult = indicators.macd(instrument, period, OfferSide.BID, IIndicators.AppliedPrice.CLOSE, fastPeriod, slowPeriod, signalPeriod, shift);
lastTick = history.getLastTick(instrument); // DEBUG // if (flipper== true) {macdResult [2] = 0.1; flipper= false;} else {macdResult [2] = -0.1; flipper= true;} // DEBUG
print(sdf.format(bidBar.getTime()) + " Current: " + macdResult[2] + " whole array: " + arrayToString(macdResult));
if (lastmacdResult != null) { print(sdf.format(bidBar.getTime()) + " Last: " + lastmacdResult[2] + " whole array: " + arrayToString(macdResult)); } print("----------------");
if (lastmacdResult != null) { if (macdResult[2] >= 0.0000 && lastmacdResult[2] < 0.0000 && lastOrder != LONG) { stopLoss = lastTick.getBid() - 0.50; takeProfit = lastTick.getBid() + 1.20; if (openOrder != null) { if (openOrder.getState() != IOrder.State.CLOSED) { openOrder.close(); } } openOrder = engine .submitOrder(getLabel(instrument), instrument, IEngine.OrderCommand.BUY, 0.1, 0, 20, stopLoss, takeProfit); lastOrder = LONG; } if (macdResult[2] <= 0.0000 && lastmacdResult[2] > 0.0000 && lastOrder != SHORT) { stopLoss = lastTick.getBid() + 0.50; takeProfit = lastTick.getBid() - 1.20; if (openOrder != null) { if (openOrder.getState() != IOrder.State.CLOSED) { openOrder.close(); } } openOrder = engine.submitOrder(getLabel(instrument), instrument, IEngine.OrderCommand.SELL, 0.1, 0, 20, stopLoss, takeProfit); lastOrder = SHORT; } } lastmacdResult = macdResult; }
// print both on client and java consoles private void print(Object o) { console.getOut().println(o); System.out.println(o); } 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; }
// count open positions protected int positionsTotal(Instrument instrument) throws JFException { int counter = 0; for (IOrder order : engine.getOrders(instrument)) { if (order.getState() == IOrder.State.FILLED) { counter++; } } return counter; }
protected String getLabel(Instrument instrument) { return (instrument.getPrimaryCurrency().toString() + instrument.getSecondaryCurrency().toString() + (tagCounter++)).toLowerCase(); }
public void onMessage(IMessage message) throws JFException { }
public void onAccount(IAccount account) throws JFException { } }
|
|
|
|
 |
JohanRens
|
Post subject: Re: IIndicator.macd giving different results then JF client |
Post rating: 0
|
Posted: Thu 30 Jun, 2011, 12:35
|
|
User rating: -
|
Wow thanks for the effort. I'm having a little trouble compiling though. It's giving a nullPointerException at line 65. (java.lang.NullPointerException @ jforex.bugtests.MACDstrategy.onStart(MACDstrategy.java:65) null: java.lang.NullPointerException at jforex.bugtests.MACDstrategy.onStart(MACDstrategy.java:65) at com.dukascopy.api.impl.execution.t.call(Unknown Source) at com.dukascopy.api.impl.connect.ao.a(Unknown Source) at com.dukascopy.api.impl.connect.w.call(Unknown Source) at com.dukascopy.api.impl.connect.w.call(Unknown Source) at com.dukascopy.api.impl.execution.j.call(Unknown Source) at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) at java.util.concurrent.FutureTask.run(Unknown Source) at com.dukascopy.api.impl.execution.f$a.f(Unknown Source) at com.dukascopy.api.impl.execution.f$a.run(Unknown Source) at java.lang.Thread.run(Unknown Source) 2011-06-30 13:30:07.452 ERROR DCClientImpl$a - Exception thrown while running onStart method: null java.lang.NullPointerException at jforex.bugtests.MACDstrategy.onStart(MACDstrategy.java:65) at com.dukascopy.api.impl.execution.t.call(Unknown Source) at com.dukascopy.api.impl.connect.ao.a(Unknown Source) at com.dukascopy.api.impl.connect.w.call(Unknown Source) at com.dukascopy.api.impl.connect.w.call(Unknown Source) at com.dukascopy.api.impl.execution.j.call(Unknown Source) at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) at java.util.concurrent.FutureTask.run(Unknown Source) at com.dukascopy.api.impl.execution.f$a.f(Unknown Source) at com.dukascopy.api.impl.execution.f$a.run(Unknown Source) at java.lang.Thread.run(Unknown Source)) So, ALMOST there  ? Thanks again, Johan
|
|
|
|
 |
JohanRens
|
Post subject: Re: IIndicator.macd giving different results then JF client |
Post rating: 0
|
Posted: Thu 30 Jun, 2011, 13:49
|
|
User rating: -
|
Just found the obvious mistake in that line and testing now.
Thanks again,
J
|
|
|
|
 |
JohanRens
|
Post subject: Re: IIndicator.macd giving different results then JF client |
Post rating: 0
|
Posted: Thu 30 Jun, 2011, 14:22
|
|
User rating: -
|
Oh no, same nullpointerexception....
J
|
|
|
|
 |
JohanRens
|
Post subject: Re: IIndicator.macd giving different results then JF client |
Post rating: 0
|
Posted: Thu 30 Jun, 2011, 14:43
|
|
User rating: -
|
Also, wouldn't the wrong timezone result in the number begin out of synch (with a few bars in between, because of time difference)?
J
|
|
|
|
 |
API Support
|
Post subject: Re: IIndicator.macd giving different results then JF client |
Post rating: 0
|
Posted: Thu 30 Jun, 2011, 15:56
|
|
User rating: ∞
Joined: Fri 31 Aug, 2007, 09:17 Posts: 6139
|
JohanRens wrote: Also, wouldn't the wrong timezone result in the number begin out of synch (with a few bars in between, because of time difference)? No JForex always works with GMT, it's Java the one that needs the timezone adjustment. JohanRens wrote: Oh no, same nullpointerexception.... Presumably you figured out that EURJPY chart has to be open and EURJPY instrument has to be selected in Historical Tester settings.
|
|
|
|
 |
JohanRens
|
Post subject: Re: IIndicator.macd giving different results then JF client |
Post rating: 0
|
Posted: Mon 04 Jul, 2011, 12:19
|
|
User rating: -
|
Thanks for your help so far, but it doesn't seem to work (I'm starting the strategy in jforex now, whereas I was programming in eclipse beforehand). It still is off. The code should produce a long signal if the MACD hist is of another polarity then the last MACD hist. But it doesn't. I still think it's due to the Iindicator giving slightly different results. Any ideas? Thanks in advance, Johan Rensink Here is another screenshot (from a backtest): https://imageshack.us/photo/my-images/811/macdproblem3.png/
|
|
|
|
 |
API Support
|
Post subject: Re: IIndicator.macd giving different results then JF client |
Post rating: 0
|
Posted: Tue 05 Jul, 2011, 08:35
|
|
User rating: ∞
Joined: Fri 31 Aug, 2007, 09:17 Posts: 6139
|
JohanRens wrote: It still is off. The code should produce a long signal if the MACD hist is of another polarity then the last MACD hist. But it doesn't. I still think it's due to the Iindicator giving slightly different results. You can verify the results by comparing the print statements to the values of the drawn indicator. Moreover, after finalizing historical testing you can add to the chart another instance of MACD indicator and compare its values to the print statements and the values of MACD indicator added from your strategy. We noticed that the period in the chart was 30 mins, did you adjust the period in you strategy accordingly?
|
|
|
|
 |
JohanRens
|
Post subject: Re: IIndicator.macd giving different results then JF client |
Post rating: 0
|
Posted: Wed 06 Jul, 2011, 10:41
|
|
User rating: -
|
Hi,
Yes I did change it into 30 mins (that was how the strategy was meant originally), but still the results as in my last post. Can you do better over there with that code and make the strategy trade on an MACD cross?? Also, in jforex, where do I find the console/code output? I've been programming in eclipse and the numbers are still off there, but perhaps it's different in the client.
Regards,
Johan
|
|
|
|
 |
API Support
|
Post subject: Re: IIndicator.macd giving different results then JF client |
Post rating: 0
|
Posted: Thu 07 Jul, 2011, 08:15
|
|
User rating: ∞
Joined: Fri 31 Aug, 2007, 09:17 Posts: 6139
|
JohanRens wrote: Can you do better over there with that code and make the strategy trade on an MACD cross?? Consider the following strategy (note that the parameters are pulled out as @Configurable): package jforex.bugtests;
import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.TimeZone;
import com.dukascopy.api.*; import com.dukascopy.api.IEngine.OrderCommand;
public class MACDstrategy2 implements IStrategy { private IEngine engine = null; private IIndicators indicators = null; private int tagCounter = 0; private IConsole console; private IHistory history; private IChart chart;
// macd specific params private int fastPeriod = 40; private int slowPeriod = 8; private int signalPeriod = 80;
// strategy specific params @Configurable("Insturment") public Instrument instrument = Instrument.EURJPY; @Configurable("Period") public Period period = Period.ONE_MIN; @Configurable("Stop Loss") public double stopLoss = 0.50; @Configurable("Take Profit") public double takeProfit = 1.20; @Configurable("Order amount") public double amount = 0.1;
IOrder openOrder;
@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 { engine = context.getEngine(); history = context.getHistory(); indicators = context.getIndicators(); this.console = context.getConsole(); this.chart = context.getChart(instrument); console.getOut().println("Started");
chart.addIndicator(indicators.getIndicator("MACD"), new Object[] { fastPeriod, slowPeriod, signalPeriod }); }
public void onStop() throws JFException { for (IOrder order : engine.getOrders()) { order.close(); } console.getOut().println("Stopped"); }
public void onTick(Instrument instrument, ITick tick) throws JFException {}
public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
if (period != this.period || instrument != this.instrument) return;
double[] macdResult = indicators.macd(instrument, period, OfferSide.BID, IIndicators.AppliedPrice.CLOSE, fastPeriod, slowPeriod, signalPeriod, 1); double[] lastMacdResult = indicators.macd(instrument, period, OfferSide.BID, IIndicators.AppliedPrice.CLOSE, fastPeriod, slowPeriod, signalPeriod, 2);
print(sdf.format(bidBar.getTime()) + " Current: " + macdResult[2] + " Last: " + lastMacdResult[2]);
if (macdResult[2] >= 0 && lastMacdResult[2] < 0 && (openOrder == null || !openOrder.isLong())) { openOrder = submitOrder(OrderCommand.BUY); } else if (macdResult[2] <= 0 && lastMacdResult[2] > 0 && (openOrder == null || openOrder.isLong())) { openOrder = submitOrder(OrderCommand.SELL); } }
private IOrder submitOrder(OrderCommand orderCmd) throws JFException {
//close order and wait max 1 sec for the close to be finalized if(openOrder != null && engine.getOrders().contains(openOrder)){ openOrder.close(); openOrder.waitForUpdate(1000); } double stopLossPrice, takeProfitPrice; // Calculating stop loss and take profit prices if (orderCmd == OrderCommand.BUY) { stopLossPrice = history.getLastTick(this.instrument).getBid() - stopLoss; takeProfitPrice = history.getLastTick(this.instrument).getBid() + takeProfit; } else { stopLossPrice = history.getLastTick(this.instrument).getAsk() + stopLoss; takeProfitPrice = history.getLastTick(this.instrument).getAsk() - takeProfit; }
// Submitting an order for the specified instrument at the current market price return engine.submitOrder(getLabel(instrument), this.instrument, orderCmd, this.amount, 0, 20, stopLossPrice, takeProfitPrice); }
private void print(Object o) { console.getOut().println(o); }
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; }
protected String getLabel(Instrument instrument) { return (instrument.getPrimaryCurrency().toString() + instrument.getSecondaryCurrency().toString() + (tagCounter++)).toLowerCase(); }
public void onMessage(IMessage message) throws JFException { }
public void onAccount(IAccount account) throws JFException { } }
JohanRens wrote: Also, in jforex, where do I find the console/code output? If you are running strategy with live data, the IConsole.getOut().println() will print to the strategy-specific tab, if you are testing historical data you have to check Messages in Historical Tester tab in order to receive the messages. System.out.println() will print to the java console (if you have one turned on). See more about console here: https://www.dukascopy.com/wiki/index.php?title=IConsole
|
|
|
|
 |
JohanRens
|
Post subject: Re: IIndicator.macd giving different results then JF client |
Post rating: 0
|
Posted: Tue 12 Jul, 2011, 15:11
|
|
User rating: -
|
Hi,
The numbers are still not the same for longer periods (shorter ones seem to be ok), but also the backtester is giving me some trouble (hanging itself etc.). I'm going to switch to MT4 for this strategy for now.
Thanks for all the help.
Johan
|
|
|
|
 |
API Support
|
Post subject: Re: IIndicator.macd giving different results then JF client |
Post rating: 0
|
Posted: Wed 13 Jul, 2011, 14:05
|
|
User rating: ∞
Joined: Fri 31 Aug, 2007, 09:17 Posts: 6139
|
If the historical tester hangs, please post the exception you get in java console
|
|
|
|
 |
|
Pages: [
1
]
|
|
|
|
|