変更箇所はたったの2行
トレイリングストップ関数とブレイクイーブン関数はどちらも自作ライブラリに包含されていますが、両方を併用するとトレイリングストップが打ち消されて、ブレイクイーブンが常に適用されてしまう問題があることが分かりました。
トレイリングストップとブレイクイーブンを併用したいという声が複数ありましたので、併用できるようにコードを変更します。
2 | if (NormalizeDouble(oStopLoss, digits) != NormalizeDouble(oPrice + stop, digits)){ |
3 | if (NormalizeDouble(oStopLoss, digits) != NormalizeDouble(oPrice - stop, digits)){ |
2 | if (oStopLoss == 0.0 || NormalizeDouble(oStopLoss, digits) < NormalizeDouble(oPrice + stop, digits)){ |
3 | if (oStopLoss == 0.0 || NormalizeDouble(oStopLoss, digits) > NormalizeDouble(oPrice - stop, digits)){ |
変更前のコードは、現在の損切り価格とブレイクイーブン後の損切り価格が不一致ならば、ブレイクイーブン後の損切り価格に変更するロジックになっています。
この場合、トレイリングストップで損切り価格を随時変更すると、上記条件が成立してしまうので、ブレイクイーブン後の損切り価格に戻っちゃうというわけです。
これを避けるために、変更後のコードでは、現在の損切り価格がブレイクイーブン後の損切り価格よりマイナス方向にあるか、そもそも損切り設定していない(oStopLoss == 0.0)場合のみ、ブレイクイーブン後の損切り価格に変更するようにしています。
これで併用できるようになります。アップロードしているライブラリも近いうちに最新化しますね。
なお、コードの抜粋だけだと分かりにくいでしょうから、変更前後の関数もそれぞれ載せておきます。
14 | void breakeven( int aMagic, double aMoveExecPips, double aMoveStopPips) |
16 | for ( int i = 0; i < OrdersTotal(); i++){ |
18 | if (OrderSelect(i, SELECT_BY_POS) == false ){ |
22 | string oSymbol = OrderSymbol(); |
25 | if (oSymbol != Symbol() || OrderMagicNumber() != aMagic){ |
29 | int oType = OrderType(); |
32 | if (oType != OP_BUY && oType != OP_SELL){ |
36 | int digits = ( int )MarketInfo(oSymbol, MODE_DIGITS); |
38 | double oPrice = NormalizeDouble(OrderOpenPrice(), digits); |
39 | double oStopLoss = NormalizeDouble(OrderStopLoss(), digits); |
40 | double oTakeProfit = NormalizeDouble(OrderTakeProfit(), digits); |
41 | int oTicket = OrderTicket(); |
43 | double exec = NormalizeDouble(aMoveExecPips * gPipsPoint, digits); |
44 | double stop = NormalizeDouble(aMoveStopPips * gPipsPoint, digits); |
49 | price = MarketInfo(oSymbol, MODE_BID); |
51 | if (price >= oPrice + exec){ |
53 | if (NormalizeDouble(oStopLoss, digits) != NormalizeDouble(oPrice + stop, digits)){ |
54 | PrintFormatLog(__FILE__, __FUNCTION__, " Attempted to change the stoploss price of the LONG opend order. " + DoubleToStr(oStopLoss, digits) + " -> " + DoubleToStr(oPrice + stop, digits)); |
55 | orderModifyReliable(oTicket, 0.0, NormalizeDouble(oPrice + stop, digits), oTakeProfit, 0, gArrowColor[oType]); |
58 | } else if (oType == OP_SELL){ |
59 | price = MarketInfo(oSymbol, MODE_ASK); |
61 | if (price <= oPrice - exec){ |
63 | if (NormalizeDouble(oStopLoss, digits) != NormalizeDouble(oPrice - stop, digits)){ |
64 | PrintFormatLog(__FILE__, __FUNCTION__, " Attempted to change the stoploss price of the SHORT opend order. " + DoubleToStr(oStopLoss, digits) + " -> " + DoubleToStr(oPrice - stop, digits)); |
65 | orderModifyReliable(oTicket, 0.0, NormalizeDouble(oPrice - stop, digits), oTakeProfit, 0, gArrowColor[oType]); |
14 | void breakeven2( int aMagic, double aMoveExecPips, double aMoveStopPips) |
16 | for ( int i = 0; i < OrdersTotal(); i++){ |
18 | if (OrderSelect(i, SELECT_BY_POS) == false ){ |
22 | string oSymbol = OrderSymbol(); |
25 | if (oSymbol != Symbol() || OrderMagicNumber() != aMagic){ |
29 | int oType = OrderType(); |
32 | if (oType != OP_BUY && oType != OP_SELL){ |
36 | int digits = ( int )MarketInfo(oSymbol, MODE_DIGITS); |
38 | double oPrice = NormalizeDouble(OrderOpenPrice(), digits); |
39 | double oStopLoss = NormalizeDouble(OrderStopLoss(), digits); |
40 | double oTakeProfit = NormalizeDouble(OrderTakeProfit(), digits); |
41 | int oTicket = OrderTicket(); |
43 | double exec = NormalizeDouble(aMoveExecPips * gPipsPoint, digits); |
44 | double stop = NormalizeDouble(aMoveStopPips * gPipsPoint, digits); |
49 | price = MarketInfo(oSymbol, MODE_BID); |
51 | if (price >= oPrice + exec){ |
53 | if (oStopLoss == 0.0 || NormalizeDouble(oStopLoss, digits) < NormalizeDouble(oPrice + stop, digits)){ |
54 | PrintFormatLog(__FILE__, __FUNCTION__, " Attempted to change the stoploss price of the LONG opend order. " + DoubleToStr(oStopLoss, digits) + " -> " + DoubleToStr(oPrice + stop, digits)); |
55 | orderModifyReliable(oTicket, 0.0, NormalizeDouble(oPrice + stop, digits), oTakeProfit, 0, gArrowColor[oType]); |
58 | } else if (oType == OP_SELL){ |
59 | price = MarketInfo(oSymbol, MODE_ASK); |
61 | if (price <= oPrice - exec){ |
63 | if (oStopLoss == 0.0 || NormalizeDouble(oStopLoss, digits) > NormalizeDouble(oPrice - stop, digits)){ |
64 | PrintFormatLog(__FILE__, __FUNCTION__, " Attempted to change the stoploss price of the SHORT opend order. " + DoubleToStr(oStopLoss, digits) + " -> " + DoubleToStr(oPrice - stop, digits)); |
65 | orderModifyReliable(oTicket, 0.0, NormalizeDouble(oPrice - stop, digits), oTakeProfit, 0, gArrowColor[oType]); |