Good evening,
I have been testing the jForex4 platform with some code I wrote in order to test the onFeedData for a Renko price feed (complete code supplied at the bottom). I wrote the strategy in regular JForex where it compiles and worked (i.e. it returned values for the MACD, Stoch and SMA indicators despite the MACD always being one brick behind due to this feedData problem) and I tested against regular JForex at the same time.
However from my tests I can see that there remain problems with the onFeedData in the new jForex4 as the same strategy now does not return values for Stoch OR SMA. It is stated earlier in this topic that for the new system it is now neccessary to define the period of the renko feed as a tick based period "Period.TICK" which I wrote as:
"public IFeedDescriptor feedDescriptor = new RenkoFeedDescriptor(Instrument.EURUSD,PriceRange.ONE_PIP,OfferSide.BID,Period.TICK);"
I took this from the second constructor detailed here:
https://www.dukascopy.com/client/javadoc/com/dukascopy/api/feed/util/RenkoFeedDescriptor.htmlHowever when you do this, the code fails to compile, (yet it compiles fine in regular JForex).
For it to compile in JForex4 I have found you need to remove the "Period.TICK". Can you please show me how to define a renko feed based on tick data in JForex4?
IMPORTANT!!: I have also noticed that there can be a VERY significant time delay in the output of messages from the strategy, sometimes in the order of a several minutes, and after a while the messages fail to come through at all. Whereas it's essentially instantaneous in regular JForex, always. This makes it impossible to check that the feedData is correct.
Have a lot of the indicator definitions changed for JForex4 or is it a bug that the indicators now do not work?
Thanks
package jforex;
import java.util.*;
//Dukascopy imports=========================
import com.dukascopy.api.*;
import com.dukascopy.api.feed.*;
import com.dukascopy.api.feed.util.*;
import com.dukascopy.api.IIndicators.AppliedPrice;
import com.dukascopy.api.feed.IFeedDescriptor;
import com.dukascopy.api.feed.IFeedListener;
import com.dukascopy.api.feed.util.RenkoFeedDescriptor;
import com.dukascopy.api.feed.util.TimePeriodAggregationFeedDescriptor;
import com.dukascopy.api.IEngine.OrderCommand;
import com.dukascopy.api.util.DateUtils;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
//============================================
public class RenkoFeedTester4 implements IStrategy, IFeedListener {
//================================
private IEngine engine;
private IConsole console;
private IHistory history;
private IContext context;
private IIndicators indicators;
private IUserInterface userInterface;
//=================================
//------FEED DESCRIPTORS---------------------
public IFeedDescriptor feedDescriptor = new RenkoFeedDescriptor(Instrument.EURUSD,PriceRange.ONE_PIP,OfferSide.BID);
//public IFeedDescriptor feedDescriptor = new RenkoFeedDescriptor(Instrument.EURUSD,PriceRange.ONE_PIP,OfferSide.BID,Period.TICK);
//---------------------------------------------
public static SimpleDateFormat MyDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS") {
{
setTimeZone(TimeZone.getTimeZone("GMT"));
}
};
//-----------------------------------------------
//---------PUBLIC DECLARATIONS-------------------
public Instrument selectedInstrument = Instrument.EURUSD;
//MACD constants
public int fastMaMACD = 12;
public int slowMaMACD = 26;
public int signalMaMACD = 9;
private int fastMaType = IIndicators.MaType.EMA.ordinal();
private int slowMaType = IIndicators.MaType.EMA.ordinal();
private int signalMaType = IIndicators.MaType.EMA.ordinal();
private double MACD_lvl;
//Stochastics constants
private int stochasticsPeriod = 10;
private int stochasticsSlowKPrd = 5;
private int stochasticsSlowDPrd = 5;
private IIndicators.MaType stochSlowKMAType = IIndicators.MaType.EMA;
private IIndicators.MaType stochSlowDMAType = IIndicators.MaType.EMA;
private static final int K = 0;
private static final int D = 1;
private Object[] params;
//------------------------------------------------
public void onStart(IContext context) throws JFException {
this.engine = context.getEngine();
this.console = context.getConsole();
this.history = context.getHistory();
this.context = context;
this.indicators = context.getIndicators();
this.userInterface = context.getUserInterface();
//--subscribe to renko feed
context.setSubscribedInstruments(java.util.Collections.singleton(feedDescriptor.getInstrument()), true);
context.subscribeToFeed(feedDescriptor, this);
//set trade counter to zero
params = new Object[] {stochasticsPeriod, stochasticsSlowKPrd, stochSlowKMAType.ordinal(),stochasticsSlowDPrd, stochSlowDMAType.ordinal()};
}
//@Override
public void onFeedData(IFeedDescriptor feedDescriptor, ITimedData feedData) {
Instrument myInstrument = feedDescriptor.getInstrument();
OfferSide myOfferSide = feedDescriptor.getOfferSide();
console.getOut().println("completed" + feedData);
try {
//------------RENKO MOVING AVERAGES------------------------
//wma 5----
Object[] smaFiveFeed = indicators.calculateIndicator(feedDescriptor, new OfferSide[] {OfferSide.BID},"SMA", new AppliedPrice[] {AppliedPrice.CLOSE},new Object[] {5},0);
//---------
double sma_five = (Double)smaFiveFeed[0];
//print wma values on each new brick
console.getOut().println(String.format("Renko2 SMA5 currently is: %.5f.", sma_five));
//---------------------------------------------------------
//-------------RENKO MACD--------------------------------------
Object[] renkoMACDEXT = indicators.calculateIndicator(feedDescriptor, new OfferSide[] { myOfferSide },"MACDEXT", new AppliedPrice[] { AppliedPrice.CLOSE }, new Object []{fastMaMACD,fastMaType,slowMaMACD,slowMaType,signalMaMACD,signalMaType},200,feedData.getTime(),0);
double[][] MACDFigures = {(double[]) renkoMACDEXT[0],(double[]) renkoMACDEXT[1],(double[]) renkoMACDEXT[2]};
console.getOut().println(String.format("Renko2 MACD line currently is: %.5f, signal line is: %.5f", MACDFigures[0][MACDFigures[0].length-1], MACDFigures[1][MACDFigures[1].length-1]));
//MACD_lvl = MACDFigures[0][MACDFigures[0].length-1];
//-------------------------------------------------------
//---------------RENKO STOCHASTICS--------------------------
Object[] stochUniversalShift = indicators.calculateIndicator(feedDescriptor, new OfferSide[] { OfferSide.BID }, "STOCH", new IIndicators.AppliedPrice[] { AppliedPrice.CLOSE }, params, 0);
double[] stochLast = { (Double) stochUniversalShift[0], (Double) stochUniversalShift[1] };
console.getOut().format("Last STOCH slow k=%.5f slow d=%.5f \n-------", stochLast[0], stochLast[1]).println();
//---------------------------------------------------------
} catch (JFException e) {
console.getErr().println(e);
e.printStackTrace();
}
}
public void onAccount(IAccount account) throws JFException {
}
public void onMessage(IMessage message) throws JFException {
}
public void onStop() throws JFException {
//for (IOrder order : engine.getOrders()) {
// engine.getOrder(order.getLabel()).close();
// }
}
public void onTick(Instrument instrument, ITick tick) throws JFException {
}
public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
}
}