package jforex.orders.merge;
import com.dukascopy.api.*;
import com.dukascopy.api.util.DateUtils;
import static com.dukascopy.api.IEngine.OrderCommand.*;
@RequiresFullAccess
public class MergeWithSlAdjustment implements IStrategy {
@Configurable("通貨ペア")
public Instrument instrument = Instrument.EURUSD;
@Configurable("order1 をロングでエントリー?")
public boolean order1IsLong = true;
@Configurable("order1 の取引量")
public double order1Amount = 0.001;
@Configurable("order1 のストップロス[Pips]")
public int order1SlPips = 30;
@Configurable("order2 をロングでエントリー?")
public boolean order2IsLong = false;
@Configurable("order2 の取引量")
public double order2Amount = 0.002;
@Configurable("order2 のストップロス[Pips]")
public int order2SlPips = 10;
@Configurable("order3 をロングでエントリー?")
public boolean order3IsLong = true;
@Configurable("order3 の取引量")
public double order3Amount = 0.003;
@Configurable("order3 のストップロス[Pips]")
public int order3SlPips = 10;
private IConsole console;
private IEngine engine;
private IHistory history;
@Override
public void onStart(IContext context) throws JFException {
engine = context.getEngine();
console = context.getConsole();
history = context.getHistory();
context.setSubscribedInstruments(java.util.Collections.singleton(Instrument.EURUSD), true);
console.getOut().println("開始");
double price = history.getLastTick(instrument).getBid();
double pip = instrument.getPipValue();
IOrder order1 = engine.submitOrder("order1", instrument, order1IsLong ? BUY : SELL, order1Amount, 0, 20,
order1IsLong ? price - order1SlPips * pip : price + order1SlPips * pip, 0);
IOrder order2 = engine.submitOrder("order2", instrument, order2IsLong ? BUY : SELL, order2Amount, 0, 20,
order2IsLong ? price - order2SlPips * pip : price + order2SlPips * pip, 0);
IOrder order3 = engine.submitOrder("order3", instrument, order3IsLong ? BUY : SELL, order3Amount, 0, 20,
order3IsLong ? price - order3SlPips * pip : price + order3SlPips * pip, 0);
order1.waitForUpdate(2000);
order1.waitForUpdate(2000);
if(order2.getState() != IOrder.State.FILLED)
order2.waitForUpdate(2000);
if(order2.getState() != IOrder.State.FILLED)
order2.waitForUpdate(2000);
if(order3.getState() != IOrder.State.FILLED)
order3.waitForUpdate(2000);
if(order3.getState() != IOrder.State.FILLED)
order3.waitForUpdate(2000);
try {
mergeWithSlAndTp(order1, order2, order3);
} catch (JFException e) {
printErr("マージ失敗: " + e.getMessage());
}
}
@Override
public void onTick(Instrument instrument, ITick tick) throws JFException {
}
private void mergeWithSlAndTp(IOrder... orders) throws JFException{
ITick tick = history.getLastTick(instrument);
double slAmountWeightedTotal = 0;
double slAmountWeighted;
int slCount = 0;
for(IOrder o: orders){
double price = o.isLong() ? tick.getBid() : tick.getAsk();
if(Double.compare(o.getStopLossPrice(),0) != 0){
slAmountWeighted = Math.abs(price - o.getStopLossPrice()) * o.getAmount();
slAmountWeightedTotal += slAmountWeighted;
print( String.format(
"%s のストップロス削除。" +
"取引数量で加重したストップロス=%.8f, 加重ストップロスサマリー=%.8f",
o.getLabel(), slAmountWeighted, slAmountWeightedTotal));
o.setStopLossPrice(0);
o.waitForUpdate(2000);
slCount++;
}
}
double slAmountWeightedAverage = slAmountWeightedTotal / slCount;
IOrder mergedOrder = engine.mergeOrders("mergedOrder", orders);
mergedOrder.waitForUpdate(2000);
if(mergedOrder.getState() != IOrder.State.FILLED){
return;
}
double slPriceDelta = slAmountWeightedAverage / mergedOrder.getAmount();
double slPrice = mergedOrder.isLong()
? tick.getBid() - slPriceDelta
: tick.getAsk() + slPriceDelta;
mergedOrder.setStopLossPrice(slPrice);
mergedOrder.waitForUpdate(2000);
print(String.format("マージされたオーダーのストップロス=%.5f", mergedOrder.getStopLossPrice()));
}
@Override
public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
}
@Override
public void onMessage(IMessage message) throws JFException {
if (message.getOrder() != null)
print("<html><font color=\"gray\">"+ DateUtils.format(System.currentTimeMillis()) + " " + message+"</font>");
}
private void printErr(Object o){
console.getErr().println(o);
}
private void print(Object o) {
console.getOut().println(o);
}
@Override
public void onAccount(IAccount account) throws JFException {
}
@Override
public void onStop() throws JFException {
for (IOrder o : engine.getOrders())
o.close();
}
}