Hi,
We have slightly modified the above strategy to make it more self explanatory:
package jforex.misc;
import java.util.concurrent.TimeUnit;
import com.dukascopy.api.*;
import com.dukascopy.api.IEngine.OrderCommand;
public class TrailingStepTest implements IStrategy {
private boolean trailSet = false;
private IEngine engine;
private IOrder order;
private IConsole console;
@Configurable("Instrument") public Instrument instr = Instrument.EURUSD;
@Configurable("Amount") public double amount = 1;
@Configurable("stopLossDistanceInQC") public double stopLossDistanceInQC = 0.0100;
@Configurable("trailingStep") public double trailingStep = 10.0;
private double currentStopLossPrice = 0;
public void onStart(IContext context) throws JFException {
this.engine = context.getEngine();
this.console = context.getConsole();
//placing an order as soon as the strategy starts
if (engine.getOrder("MyOrder") == null) order = engine.submitOrder("MyOrder", instr, OrderCommand.BUY, amount);
}
public void onAccount(IAccount account) throws JFException {
}
//============================================================================================================================================================
public void onMessage(IMessage message) throws JFException {
if (message.getType().equals(IMessage.Type.ORDER_FILL_OK)) {
IOrder order = message.getOrder();
console.getOut().println(
"Order state = " + order.getState() +
", Open Price = " + order.getOpenPrice()
);
}
if (message.getType().equals(IMessage.Type.ORDER_CLOSE_OK)) {
IOrder order = message.getOrder();
console.getOut().println(
"Order state = " + order.getState() +
", Close Price = " + order.getClosePrice()
);
}
}
public void onStop() throws JFException {
}
public void onTick(Instrument instrument, ITick tick) throws JFException {
if (order != null && instrument.equals(instr) && !trailSet) {
if (order.getTrailingStep() < 1 && order.getState() == IOrder.State.FILLED) {
double newSlPrice = stopLossDistanceInQC == 0 ? 0 : tick.getAsk() - stopLossDistanceInQC;
order.setStopLossPrice(newSlPrice, OfferSide.BID, trailingStep);
order.waitForUpdate(2, TimeUnit.SECONDS);
trailSet = true;
console.getOut().println(
"Just after trail set: Bid = " + tick.getBid() +
", new Sl Price = " + order.getStopLossPrice()
);
this.currentStopLossPrice = order.getStopLossPrice();
}
} else {
}
}
public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
if (period == Period.ONE_HOUR && this.currentStopLossPrice != order.getStopLossPrice()){
console.getOut().println(
"Ticks after trail set: Bid = " + bidBar.getClose() +
", Sl Price = " + order.getStopLossPrice());
this.currentStopLossPrice = order.getStopLossPrice();
}
}
}
Here's the output:
Order state = CLOSED, Close Price = 1.33937
Ticks after trail set: Bid = 1.34963, Sl Price = 1.33944
Ticks after trail set: Bid = 1.3437, Sl Price = 1.33726
Ticks after trail set: Bid = 1.34542, Sl Price = 1.33619
Ticks after trail set: Bid = 1.34164, Sl Price = 1.33311
Ticks after trail set: Bid = 1.33857, Sl Price = 1.32905
Ticks after trail set: Bid = 1.33184, Sl Price = 1.32199
Ticks after trail set: Bid = 1.3297, Sl Price = 1.31997
Ticks after trail set: Bid = 1.32775, Sl Price = 1.31797
Ticks after trail set: Bid = 1.32232, Sl Price = 1.31287
Ticks after trail set: Bid = 1.31999, Sl Price = 1.31187
Just after trail set: Bid = 1.31966, new Sl Price = 1.30983
Order state = FILLED, Open Price = 1.31979
Also, you may want to enable the visual mode in historical tester - it's easier to make sure the stop loss price of your order is updated accordingly.