トップ  >  リファレンス  >  ストラテジーAPI  >  オーダーとポジション  >  ポジションのマージ
ポジションのマージ


ポジションはIEngine.mergeOrdersメソッドでマージする事が出来ます。
マージ可能なオーダーリストとマージ後のラベルを指定する必要があります。



マージの前提条件

2つのオーダーをマージするには、以下条件を満たす必要があります。
  1. 両方のオーダーが同じ通貨ペアである事
  2. 両方のオーダーのオーダー状態がIOrder.State.FILLEDである事
  3. 両方のオーダーにリミットやストップロスの設定がされていない事


マージの実行

オーダーマージの実行と結果については、以下のような特徴があります。
  1. マージ後のオーダー方向・取引量・オーダー状態・メッセージは、オーダーマージ状態ダイアグラムによって指定されます。
  2. マージされたオーダーのオープン価格(IOrder.getOpenPrice)は、マージ可能なオーダーのオープン価格の加重平均になります。
  3. マージ操作による手数料はありませんが、since technically no orders get neither filled nor closed (except the case when resulting order amount is 0, see diagram in 1). Hence one may reduce commission on order close by merging opposite direction orders before their close.
  4. マージによってスリップページが発生する事はありません。






サンプル(シンプルなマージ)

2つのオーダーをマージします。


IEngine engine      = context.getEngine();
IOrder  firstOrder  = engine.getOrder(   "firstOrder");
IOrder  secondOrder = engine.getOrder(   "secondOrder");
IOrder  mergedOrder = engine.mergeOrders("mergedOrder", firstOrder, secondOrder);


In a case of normal execution both orders get closed and the appropriate onMessage events get triggered.


サンプル(ストップロス・リミット設定のオーダーをマージ)

ストップロスかリミット設定された3つのオーダーをマージする場合、
ストップロスかリミット設定されているとマージする事が出来ない為、ストップロスとリミットの両方を削除しなければなりません。
マージ完了後に、マージされたオーダーに新たにストップとリミットを設定する必要があります。

以下例では、異なるストップロス・リミット設定を持つ3つのオーダーを作成します。


double price = history.getLastTick(Instrument.EURUSD).getBid();
//order1 1千通貨で成行買い(ストップロスとリミットをそれぞれ10pips設定)
IOrder order1 = engine.submitOrder("order1", Instrument.EURUSD, OrderCommand.BUY , 0.001, 0, 20, price - 0.0010, price + 0.0010);
//order2 2千通貨で成行売り(ストップロスとリミットの設定は無し)
IOrder order2 = engine.submitOrder("order2", Instrument.EURUSD, OrderCommand.SELL, 0.002, 0, 20, 0             , 0             );
//order3 2千通貨で成行買い(ストップロス10pips設定)
IOrder order3 = engine.submitOrder("order3", Instrument.EURUSD, OrderCommand.BUY , 0.002, 0, 20, price - 0.0010, 0             );


以下例では、ストップロスとリミットの設定があったら削除します。


// オーダーにストップロスとリミットが設定されていたら、設定を削除する
for(IOrder o: orders){
    if(Double.compare(o.getStopLossPrice(),0) != 0){
        o.setStopLossPrice(0);
        print(o.getLabel() + " のストップロスを削除しました。");
        o.waitForUpdate(2000);                
    }
    if(Double.compare(o.getTakeProfitPrice(),0) != 0){
        o.setTakeProfitPrice(0);
        print(o.getLabel() + " のリミットを削除しました。");
        o.waitForUpdate(2000);                
    }
}        


以下例は、3つのオーダーをマージし、マージしたオーダーにストップロス設定を行います。


IOrder mergedOrder = engine.mergeOrders("mergedOrder" + ++mergeCount, order1, order2, order3);
IMessage message = mergedOrder.waitForUpdate(2, TimeUnit.SECONDS);
// MESSAGE_MERGE_OK か MESSAGE_MERGE_REJECTED のいずれかを受信した。
print("ポジションマージされました: " + message.getType() + " - " + message);
// マージ完了したオーダーのオーダー状態がFILLEDだったら(マージした取引量が0以外である事)
if(mergedOrder.getState() == IOrder.State.FILLED){
    double slPrice = mergedOrder.isLong() ? price - 0.0010 : price + 0.0010;
    mergedOrder.setStopLossPrice(slPrice);
}



サンプルソースコード:MergeRemoveSlTp.java







サンプル(マージして加重平均ストップロスで更新)

マージ可能なオーダーのストップロスの加重平均を算出し、マージしたオーダーに算出したストップロスを設定します
(ストップロスの比重はマージ可能なオーダーの取引数量に依存します)。



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()));
    
}



サンプルソースコード:MergeWithSlAdjustment.java







サンプル(ポジション毎のマージ回数制限)

異なるポジションを4回以上マージされないようにする例です



private Map<IOrder, Integer> mergeCounts = new HashMap<IOrder, Integer>();  
@Override
public void onStart(IContext context) throws JFException {
    engine = context.getEngine();
    console = context.getConsole();
    context.setSubscribedInstruments(java.util.Collections.singleton(instrument), true);
    console.getOut().println("Start");

    // 4つの買いオーダーと、4つの売りオーダーを行います
    for (int i = 0; i < 8; i++) {
        IOrder order = engine.submitOrder('o' + String.valueOf((char)((int)'A' + i))
                                          , instrument, i % 2 == 1 ? OrderCommand.BUY : OrderCommand.SELL, 0.001 * (i + 1));
        order.waitForUpdate(IOrder.State.FILLED);
    }

    while (engine.getOrders().size() > 1){
        int previousMergeCountTotal = 0;
        String label = "";
        List<IOrder> mergeableOrders = Arrays.asList(engine.getOrders().get(0), engine.getOrders().get(1));
        for(IOrder mergeableOrder : mergeableOrders){
            Integer previousMergeCount = mergeCounts.get(mergeableOrder);
            if(previousMergeCount != null){
                previousMergeCountTotal += previousMergeCount;
            }
            label += mergeableOrder.getLabel();
        }
        if(previousMergeCountTotal >= 4){
            console.getWarn().println("マージ回数は4回を超えて実施する事は出来ません!");
            break;
        } else {
            IOrder mergedOrder = engine.mergeOrders(label,mergeableOrders.toArray(new IOrder[]{}));
            IMessage message = mergedOrder.waitForUpdate(2, TimeUnit.SECONDS);
            if(message.getType() == IMessage.Type.ORDERS_MERGE_OK){
                mergeCounts.put(mergedOrder, previousMergeCountTotal+1);
            }
            console.getInfo().println(mergeCounts);
        }
        
    }
}



サンプルソースコード:Merge10WLimit.java





スポンサーリンク

スポンサーリンク
検索
リファレンスツリー


Copyright ©2016 JForexAPIで自動売買させ隊! All Rights Reserved.


Top

inserted by FC2 system