指値オーダーの一つが約定されると、もう一方のオーダーを削除し、OCO(One Cancels Other)オーダーのような動作をします。
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.TimeZone;
import com.dukascopy.api.*;
import com.dukascopy.api.IEngine.OrderCommand;
public class SimulateOCOStrategy implements IStrategy {
private IEngine engine = null;
private IHistory history;
private int counter = 0;
private SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm");
@Configurable("トレード時間[GMT]")
public String startTradeTime = "07:10";
@Configurable("バーの時間軸")
public Period selectedPeriod = Period.FIVE_MINS;
@Configurable("ロング指値")
public double longPrice = 1.3425;
@Configurable("ショート指値")
public double shortPrice = 1.3435;
private HashMap<String, IOrder> createdOrders = new HashMap <String, IOrder>();
private String parsedStartTime ;
public void onStart(IContext context) throws JFException {
engine = context.getEngine();
this.history = context.getHistory();
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
parsedStartTime = startTradeTime.replace(":", "");
}
public void onStop() throws JFException {
}
public void onTick(Instrument instrument, ITick tick) throws JFException {
}
public void onBar(Instrument instrument, Period period, IBar askbar, IBar bidbar) throws JFException {
if (instrument.equals(Instrument.EURUSD) && period.equals(selectedPeriod) &&
(isValidOrderTime(history.getNextBarStart(period, askbar.getTime())))) {
createdOrders.put("long" , engine.submitOrder(getLabel(instrument), instrument, OrderCommand.BUYLIMIT, 0.01, longPrice, 0,
askbar.getLow() - (5 * instrument.getPipValue()), askbar.getHigh() + (5 * instrument.getPipValue())));
createdOrders.put("short", engine.submitOrder(getLabel(instrument), instrument, OrderCommand.SELLLIMIT, 0.01, shortPrice, 0,
askbar.getHigh() + (5 * instrument.getPipValue()), askbar.getLow() - (5 * instrument.getPipValue())));
}
}
private boolean isValidOrderTime(long tickTime) {
String formattedTickTime = dateFormat.format(tickTime);
formattedTickTime = formattedTickTime.replace(":", "");
int tickTimeValue = Integer.parseInt(formattedTickTime);
int startTimeValue = Integer.parseInt(parsedStartTime);
return tickTimeValue == startTimeValue;
}
protected String getLabel(Instrument instrument) {
String label = instrument.name();
label = label + (counter ++);
label = label.toUpperCase();
return label;
}
もしロングオーダーが約定されていたらonMessageメソッドはショートオーダーをクローズします。逆も同様です。
public void onMessage(IMessage message) throws JFException {
if (message.getType().equals(IMessage.Type.ORDER_FILL_OK)) {
IOrder order = message.getOrder();
if (order.isLong()) {
createdOrders.get("short").close();
} else {
createdOrders.get("long").close();
}
}
}
public void onAccount(IAccount account) throws JFException {
}
}