Simple Stochastic

The following strategy use the Stochastic indicator values as trading algorithm. The strategy creates a SHORT position when market if overbought(stochastic lines is more or equals 80) and LONG position when the market is oversold (stochastic lines is less or equals 20) Before create a position, the strategy closes opposite position. 
The picture below shows overbought and oversold examples on graph using red and blue points:

Let's describe the strategy source code:

import com.dukascopy.api.Configurable;
import com.dukascopy.api.IEngine;
import com.dukascopy.api.IAccount;
import com.dukascopy.api.IBar;
import com.dukascopy.api.IConsole;
import com.dukascopy.api.IContext;
import com.dukascopy.api.IIndicators;
import com.dukascopy.api.IMessage;
import com.dukascopy.api.IOrder;
import com.dukascopy.api.IStrategy;
import com.dukascopy.api.ITick;
import com.dukascopy.api.Instrument;
import com.dukascopy.api.JFException;
import com.dukascopy.api.OfferSide;
import com.dukascopy.api.Period;
import com.dukascopy.api.IEngine.OrderCommand;
import com.dukascopy.api.IIndicators.MaType;

public class Stochastic implements IStrategy{
        private IEngine engine;
        private IIndicators indicators;
        private IConsole console;

Initialize configurable and Stochastic indicator parameters.


        @Configurable("Amount")
        public double amount = 0.2;
        @Configurable("Period")
        public Period fixedPeriod = Period.ONE_MIN;
        @Configurable("Instrument")
        public Instrument selectedInstrument = Instrument.EURUSD;

        private OfferSide side = OfferSide.BID;
        private int fastKPeriod = 5;
        private MaType slowDMaType =  MaType.SMA;
        private int slowKPeriod = 3;
        private MaType slowKMaType =  MaType.SMA;
        private int slowDPeriod = 3;
        private int shift = 0;
        private int counter = 0;

The onStart method initialize interfaces and adds Stochastic indicator to the selected chart

        public void onStart(IContext context) throws JFException {
                engine = context.getEngine();
                indicators = context.getIndicators();
                console = context.getConsole();
                context.getChart(selectedInstrument).addIndicator(indicators.getIndicator("STOCH"));
        }

The onBar calculates stochastic indicator values, and calls the createOrderOnStochastic method.

        public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
                if (selectedInstrument.equals(instrument) && period.equals(fixedPeriod)) {
                        double[] stochastic = indicators.stoch(instrument, period, side, fastKPeriod, slowKPeriod , slowKMaType, 
                                        slowDPeriod, slowDMaType, shift );
                        createOrderOnStochastic(instrument, bidBar, stochastic);
                }
        }

The createOrderOnStochastic closes existing opposite position and create a new position if stochastic values is overbought (>=80) or oversold (<=20)

        private void createOrderOnStochastic(Instrument instrument, IBar bidBar, double[] stochastic) throws JFException {
                OrderCommand orderCommand;
                if ((stochastic[0] >= 80) && (stochastic[1] >= 80)) {
                        orderCommand = OrderCommand.SELL;
                        closeOppositeIfExist(orderCommand);
                        createOrder(instrument, bidBar, orderCommand);
                } else if ((stochastic[0] <= 20) && (stochastic[1] <= 20) ) {
                        orderCommand = OrderCommand.BUY;
                        closeOppositeIfExist(orderCommand);
                        createOrder(instrument, bidBar, orderCommand);
                }
        }

        private void closeOppositeIfExist(OrderCommand command) throws JFException {
                if (engine.getOrders().size() == 0) {
                        return;
                }
                for (IOrder order: engine.getOrders()) {
                        if (!order.getOrderCommand().equals(command)) {
                                order.close();
                        }
                }
        }

The createOrder method creates an order if no orders exist.

        private void createOrder(Instrument instrument, IBar bidBar, OrderCommand orderCommand) throws JFException {
            if (engine.getOrders().size() > 0) {
                return;
            }
            engine.submitOrder(getLabel(instrument), instrument, orderCommand, amount);
        }

        public void onAccount(IAccount account) throws JFException {
        }

        public void onMessage(IMessage message) throws JFException {

        }

The onStop method close all existing orders.

        public void onStop() throws JFException {
                for (IOrder order : engine.getOrders()) {
                        order.close();
                }
        }

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

        public void print(String string) {
                console.getOut().println(string);
        }

        protected String getLabel(Instrument instrument) {
                String label = instrument.name();
                label = label + (counter ++);
                label = label.toUpperCase();
                return label;
        }
}

Stochastic.java

The information on this web site is provided only as general information, which may be incomplete or outdated. Click here for full disclaimer.