Joke's on us: JForex DEMO 2.13.6 is out of whack

I hope this is a April Fool's joke but it isn't. As shown, the Dukascopy JForex DEMO platform version 2.13.6 released this week is causing havoc to my strategy. I tested my contest strategy, which has been running fine for almost a year, but is now failing left and right. Even though this is only happening with the DEMO platform (the LIVE platform is a stable release and is running fine at the moment), the fact that they published a buggy version for us developers as guinea pigs is upsetting. JForex developers are clients too, after all. [caption id="attachment_4974" align="aligncenter" width="580" caption="Dukascopy JForex DEMO 2.13.6"][/caption]

Posted 01 April 2011 in journal.

More trouble with JForex IIndicators

JFUtil offers [an elegant way of requesting indicators from the JForex IIndicators interface][]. But the new design for JForex IIndicators through JFUtil is only fixing one side of the problem. There is still the question of what to do with the multiple return types from the calculations. In JForex, indicators like RSI returns a one-dimensional array. Other indicators like Stochastic Oscillator returns a two-dimensional array. And some other ones return three or more dimensional arrays. Java doesn't allow overloading a method with multiple return types, as the program wouldn't know what to expect. So how can we get rid of coding mess like this in our JForex strategy? [java] Stochastic stochBean = IndicatorBeanFactory.getStochastic(); Object[] objs = Indicating.calculateMultiDimension(instrument, Period.ONE_MIN, stochBean, 1); double[][] sto = new double[2][]; sto[0] = (double[])objs[0]; // %K values sto[1] = (double[])objs[1]; // %D values [/java] The default calculation method in JForex returns a generic Object array. It's up to the programmer to know what to expect from the call and cast the Object into something useful. Obviously, this is a recipe for programming headaches and runtime errors. Having said this, one of the biggest benefits of JForex is that it uses a standard programming language like Java. So if there's something that you don't like about the API, you can probably change it (e.g. Facade pattern). This is the purpose of JFUtil to some extent, to simplify the JForex API behaviour. In any case, I'm sure other Java programmers have faced this problem before and have come up with good solutions for it. A search on stackoverflow.com doesn't yield a quick fix solution at first glimpse. My guess is that this require leveraging the knowledge about the program structure. We know in advance what dimension of the calculation result we can expect based on the indicator itself, perhaps I can use something like a Command pattern to choose a calculation sub-routine and then return a Map object with named values? I have yet to try implementing this. I am open to design suggestions to encapsulate multiple return values through a single interface. So that any indicator bean can use the same calculation interface with an easy to use output. In the mean time, getting multi-dimensional indicators results through JFUtil 2.1.2 isn't pretty.

[an elegant way of requesting indicators from the JForex IIndicators interface]: http://www.quantisan.com/conjuring-beans-to-simplify-jforex-iindicators/

Conjuring beans to simplify JForex IIndicators

The JForex API is not perfect. Like any application programming interface (API), some parts of the JForex API is better designed than others. One of the most gripping problems with JForex is its use of technical analysis (TA) indicators. Here's an example of using an exponential moving average, one of the most simplest indicators. ema(instrument, Period.TEN_SECS, OfferSide.BID, IIndicators.AppliedPrice.MEDIAN_PRICE, 14, 0); And the corresponding javadoc explaining the parameters, Parameters: instrument instrument of the bar period period of the bar side bid or ask side of the bar appliedPrice type of input data timePeriod time period value shift number of candle back in time staring from current bar. 0 - current bar (currently generated from ticks), 1 - previous bar (last formed bar), 2 - current bar minus 2 bars and so on It's not intuitive but it's usable. Recall that in my JForex programming tutorial, I suggested using the JForex API javadoc to find out information about the API. However, for the case of IIndicators, if you take a look at its javadoc, you will only be led to more confusion by the hundred or so mysterious indicator methods with cryptic parameter names. In JForex API, if you want to calculate an indicator, you need to look through a long list of abbreviated method names in the javadoc. Many of which are not easy to decipher. Secondly, you need to figure out the generic parameters and set them correctly, which is different for almost every indicator. Lastly, as there is no standard interface for indicators, you need to hardcode these into your strategy with little flexibility. In contrast, here's the same call using JFUtil 2.1.0 to get an EMA value. It has notably more lines of code. It is designed deliberately so using an object oriented approach by encapsulating the indicator parameters into a bean object and abstracting the calculation into a single generic function call. [java] // get an EMA indicator value by building an indicator bean MovingAverage maBean = IndicatorBeanFactory.getMovingAverage(); // then sets its parameters with obvious method names maBean.setAppliedPrice(IIndicators.AppliedPrice.MEDIAN_PRICE) .setMAType(IIndicators.MaType.EMA) .setWidth(14); // all of these are optional parameters // feed the bean into a generic calculation method to get the result double ema = Indicating.calculate(instrument, Period.ONE_MIN, maBean); [/java] With JFUtil, to calculate an indicator, you create an indicator bean with the intuitive bean name that corresponds with the full name of an indicator. For example, a moving average will be MovingAverage. Then you set the indicator-specific parameters using clearly defined methods with useful javadoc descriptions. One method for one parameter. Lastly, you feed this indicator bean into a generic calculation function to get your value. It took some thinking to abstract and generalize such a rigidly structured API. I am quite pleased with this new design as the current JFUtil opens up a lot of design flexibility. Such as dynamic indicator selection with genetic algorithm and interchangeable indicators use for runtime adaptive algorithms.

JFUtil 2.0 alpha demonstration

Rather than talk about how much better JFUtil 2.0 is and all, I'll just show you a demonstration strategy illustrating the features of this JForex utilities library. Download the latest JFUtil from the project page. As this is an alpha release, I need your help in finding bugs and look for improvements. Leave me a message if you have any comment or suggestion please. It's best if you copy and paste the following demo strategy source code into your IDE or text editor for viewing. [java] import java.util.*; import com.dukascopy.api.*; import com.quantisan.JFUtil.*; @Library("JFQuantisan.jar") // place this file in your ../JForex/Strategy/files folder public class jfutilDemo implements IStrategy { private int counter = new Random().nextInt(100); // notice the lack of fields to manage JForex objects @Override public void onStart(IContext context) throws JFException { // ** Essential steps ** // must initialize objects once and for all JForexContext.setContext(context); JForexAccount.setAccount(context.getAccount()); Set\<Instrument> set = new HashSet\<Instrument>(context.getSubscribedInstruments()); set = context.getSubscribedInstruments(); // get list of subscribed instruments // subscribe to transitional instruments for currency conversion calculations Pairer.subscribeTransitionalInstruments(set); // ** End of essential steps ** Printer.println("-- Quantisan.com JFUtil v2.0 alpha: Usage demo --"); Printer.println(""); } @Override public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException { if (period != Period.TEN_SECS) return; // only run every 10 sec. // *** 1. access IContext and IAccount from anywhere *** Printer.println("Account equity = " + JForexAccount.getEquity()); // get an EMA indicator value double ema = JForexContext.getIndicators().ema(instrument, Period.TEN_SECS, OfferSide.BID, IIndicators.AppliedPrice.MEDIAN_PRICE, 14, 1); Printer.println(instrument.toString() + " EMA = " + ema); // printing the EMA value // *** 2. Profit/loss calculation to account currency before placing your order *** // Demonstrating currency conversion double risk = 100 * Pairer.convertPipToAccountCurrency(instrument); String symbol = JForexAccount.getAccountCurrency().getSymbol(); Printer.println(symbol + risk + " risked in for 1,000 units and 100 pips move in " + instrument.toString()); // ** 3. Simplify order parameters with order ticket builder *** // Demonstrating trade ordering String label = instrument.toString().substring(0,2) + ++counter; OrderTicket mktBuyTicket = new OrderTicket // order ticket .Builder(label, // setting required ticket info instrument, IEngine.OrderCommand.BUY, 0.1) .build(); // build ticket Orderer.placeOrder(mktBuyTicket); // placing order // market buy order with a 100 pips stop and 100 pips target double stopPrice = JForexContext.getPrice(instrument) - (100 * instrument.getPipValue()); double targetPrice = JForexContext.getPrice(instrument) + (100 * instrument.getPipValue()); label = instrument.toString().substring(0,2) + ++counter; OrderTicket buySpTicket = new OrderTicket .Builder(label, instrument, IEngine.OrderCommand.BUY, 0.1) .setStopLossPrice(stopPrice) // set stop price to ticket .setTakeProfitPrice(targetPrice) // set target .build(); // ** 4. Single method to placing orders for all order types and parameters *** Orderer.placeOrder(buySpTicket); } @Override public void onAccount(IAccount account) throws JFException { JForexAccount.setAccount(account); // update IAccount to latest } @Override public void onStop() throws JFException { for (IOrder order : Orderer.getOrders()) // close all orders Orderer.close(order); } } [/java]

Dissecting a JForex strategy -- MA_Play.java

Having studied the anatomy of an empty JForex strategy (Part 1 and Part 2), it's time to dissect a working one. MA_Play is the strategy that is included with every JForex API download as a demonstration. You can find the complete source code of this strategy in /src/singlejartest/ in the JForex API zipped package. Recall that the first Interface method which runs at the start of the strategy is onStart. The onStart method of MA_Play is reproduced below.

public void onStart(IContext context) throws JFException { 
    engine = context.getEngine(); 
    indicators = context.getIndicators();
    this.console = context.getConsole();
    console.getOut().println("Started"); 
}

The variables engine, indicators, and console are fields of the MA_Play class. They are global variables within the class. What lines 42--44 do is to save the IEngine, IIndicators, and IConsole objects for later use.

The last line of onStart, line 45, is merely to print a message on your JForex program console to notify the user that the strategy has started.

Once onStart is finished processing, the server is likely to call onTick if a market tick arrives. If it's not during market hours, then there's no tick and some other event might happen instead of onTick. Think of the methods as events rather than a linear process. You program your JForex strategy according to what you want to do with each of the six IStrategy Interface event.

For this particular strategy, the programmer decides to implement their strategy at the tick level. As such, much of the trading algorithm resides in onTick for MA_Play. Note that this is a design choice, you can use onBar if you want your strategy to process at the bar level (or you can use both onTick and onBar).

Here's the source code for onTick in MA_Play.

public void onTick(Instrument instrument, ITick tick) throws JFException {
    if (ma1[instrument.ordinal()] == -1) {
        ma1[instrument.ordinal()] = indicators.ema(instrument, 
            Period.TEN_SECS, 
            OfferSide.BID, 
            IIndicators.AppliedPrice.MEDIAN_PRICE, 
            14, 1);
    }
    double ma0 = indicators.ema(instrument, Period.TEN_SECS, OfferSide.BID, IIndicators.AppliedPrice.MEDIAN_PRICE, 14, 0);
    if (ma0 == 0 || ma1[instrument.ordinal()] == 0) {
        ma1[instrument.ordinal()] = ma0;
        return;
    }

    double diff = (ma1[instrument.ordinal()] - ma0) / (instrument.getPipValue());

    if (positionsTotal(instrument) == 0) {
        if (diff > 1) {
            engine.submitOrder(getLabel(instrument), instrument, IEngine.OrderCommand.SELL, 0.001, 0, 0, tick.getAsk()
                    + instrument.getPipValue() * 10, tick.getAsk() - instrument.getPipValue() * 15);
        }
        if (diff < -1) {
            engine.submitOrder(getLabel(instrument), instrument, IEngine.OrderCommand.BUY, 0.001, 0, 0, tick.getBid()
                    - instrument.getPipValue() * 10, tick.getBid() + instrument.getPipValue() * 15);
        }
    }
    ma1[instrument.ordinal()] = ma0;
}

At a glance, you may notice that the variables ma0 and ma1 play a key role in determining the setup. Hint: To reverse engineer a strategy, it may be easier to work backward from when the order is placed, which is done by engine.submitOrder in this case.

ma0 and ma1 hold results from exponential moving averages (EMA). ma0 is the current value. ma1 is the previous bar's value. Lines 56--63 check using IF tests (lines 56 and 60) to see if either of the variables hold invalid data. If the data is invalid, the indicator is calculated and the rest of the onTick is skipped with the return statement on line 62.

Note: Indicator values can sometimes be invalid (zero, negative, or Double.NaN, depending on the particular indicator implementation) if there is insufficient data to calculate it or an error occurred, for examples.

The EMAs are fetched in lines 57 and 59 using the IIndicators object (which was initialized in onStart). The JForex Wiki provides an explanation of its use.

Notice that ma1 is an array, which was declared in line 38 with a size equivalent to the number of all available JForex instruments. In particular, it is used with a special index value as in ma1[instrument.ordinal()]. In other words, it is asking for the current instrument's slot in the ma1 array. The current instrument is the one that is passed into the method in line 55.

Moving down the code, another point of interest is line 65, showing the use of instrument.getPipValue(). Line 67 checks if the current total number of position is zero. If it is, meaning no opened position, then the strategy proceeds to check the entry signal to enter a trade (lines 68--76).

positionsTotal() is a custom method defined in lines 84--92. It uses a FOR loop to cycle through all the orders obtained from [engine.getOrders(instrument)][]

Once either of the long or short condition, lines 68 and 72, respectively, is met, the strategy submits an order in lines 69 for a short and line 73 for a long. The particulars of submitting market orders is described in the JForex Wiki.

When you stop this strategy, onStop (lines 48--53) is called. For this strategy, the programmer loops through all the orders again using engine.getOrders() and closes each of the position with an [order.close()][] command in line 50.

That is it for this trivial strategy. If there is one point that you should remember. Note my use of the many links to the JForex javadoc and JForex Wiki throughout this post. You are likely to find many of your answers from those two sources. If not, there's always the JForex Support Board. Now that you've had an idea of how MA_Play.java works, it's time to test it. In the next post in January, we will discuss the JForex Historical Tester and what to watch for when running a strategy live.

Anatomy of a JForex strategy, Part 2

We looked at four of the six methods in the IStrategy Interface in a previous post. The last two methods, onTick and onBar, is where your strategy connect with market data. Either one, or both, of these methods is where you put your trading algorithm in. Your strategy would then be able to process the market data as they arrive one tick/bar at a time. Recall that IStrategy Interface is the skeleton of your strategy. And that IContext object is the heart of your strategy. onTick/onBar is the head of your strategy, which contains your trading algorithm, which is the brain.

onTick

Here's the method definition of onTick.

onTick(Instrument instrument, ITick tick) throws JFException { }

Important:onTick is called for each and every instrument that your JForex platform is subscribed to (the instrument list in your workspace box). Let me say that again, onTick is called for each and every instrument that your JForex platform is subscribed to. The standard practice is to filter out ticks for instruments that you don't want with a simple IF-return statement. if (instrument != myInstrument) return; Actual tick data is passed to your strategy using the ITick object from the onTick method's parameter. Take a look at the ITick javadoc entry to see what it offers.

onBar

public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException { }

onBar works in a similar manner to onTick. In which onBar is called for each and every subsribed instrument and period known to JForex. Similarly, you have to filter out all the unwanted instruments and periods or else there will be expected results from your strategy. Another point to note is that onBar provides both a IBar askBar and IBar bidBar, representing the ask and bid bars. Question: What happens when two or more periods overlap as in 13:45? 1, 5, and 15-minutes bars are all arriving at the same time (not to mention the periods in seconds too). Answer: According to Dukascopy Support in the forum, "They come in a strict order, for example (1min 1min 1min 1min 1min 5min 1min 1min 1min 1min 1min 5min ..) They come in cycles, where smaller periods comes first."

JForex Support Forum

As you program your strategy with JForex, you will no doubt come up with questions of your own. The best place to ask is at the official JForex Support Forum. This is the last of the three essential JForex resources that I alluded to earlier. Even if you don't have any specific question, there are sample codes, coding discussion, and hundreds of existing Q&A from other JForex developers posted in the forum.

Summary

The discussion so far has been very high level. To show you what you can actually do in an IStrategy, we will dissect a working strategy in the next post. And what else better to examine than the most popular JForex strategy of them all -- MA_Play.java.

continue   →