含み益が発生する前から動くトレーリングストップの作り方

知人から依頼されて作成したトレーリングストップ機能が、普通とは違っていて面白かったので紹介します。

通常のトレーリングストップ

MT4のトレーリングストップの場合、設定が10pipsだとすると、10pipsの含み益が発生するまでは何も起きません。
10pips以上の含み益が発生すると、現在価格の10pips下にストップロスを設定します。
その後、含み益が更新されるごとにストップロスも更新され、最大含み益から10pips逆行した時点で決済となります。

このため、MT4のトレーリングストップが発動すると、確実にプラスで決済することができます。 (大幅に滑った場合などは除きます)

今回作成したトレーリングストップ

今回依頼があったのは、含み益が出るのを待たずにトレーリングストップを開始する処理でした。
設定が10pipsだとすると、エントリー時点で10pips下にストップロスが設定されます。
その後、少しでも含み益が更新されるとストップロスも更新されていきます。

この方式ですと、+10pipsの含み益が出る前に逆行して決済されると損切りになる場合があります。

作り方

処理は普通のトレーリングストップと似ています。
普通のトレーリングストップでは、OrderModifyを実行する条件に、「新しいストップロスがOrderOpenPriceよりも有利な価格になること」を加えますが、今回作成するトレーリングストップでは不要です。

コードはこんな感じになります。

void TrailingStop(int magic, int point_value)
{
    double sl;

    for (int i = OrdersTotal() - 1; i >= 0; i--) {
        if (OrderSelect(i, SELECT_BY_POS) == false) continue;
        if (OrderMagicNumber() != magic) continue;

        if (OrderType() == OP_BUY) {
             sl = Bid - point_value * Point;
             if (OrderStopLoss() == 0 || OrderStopLoss() < sl) {
                 if (OrderModify(OrderTicket(), OrderOpenPrice(), sl, OrderTakeProfit(), 0) == false) {
                     // エラー処理
                 }
             }
        }
        if (OrderType() == OP_SELL) {
            sl = Ask + value * Point;
            if (OrderStopLoss() == 0 || OrderStopLoss() < sl) {
                if (OrderModify(OrderTicket(), OrderOpenPrice(), sl, OrderTakeProfit(), 0) == false) {
                     // エラー処理
                 }
            }
        }
    }
}

第一引数magicには注文を変更したいポジションのマジックナンバーを指定します。
第二引数point_valueにはトレーリングストップの幅を入力します。
今回は簡略化のためpoint単位で値を受け取っていますが、pips単位で受け取ったほうが使いやすいかもしれません。
その場合はslを計算する処理を修正してください。

あとはこの関数をOnTick関数内で実行してあげれば完成です。

arrow_upward