損益価格を変更するOrderModify()関数ですが、、、よくエラーがでます。まぁ私が悪いのかもしれませんが、よう出るのがModifyエラー1です。既に変更済みもしくは既知の値と同じ値で変更しようとしているです。
これを防ぐには例えばBreakEvenだと、
int ticket; OrderSelect(ticket,SELECT_BY_TICKET); //約定価格と損切り価格が同じではない場合 if(OrderStopLoss()!=OrderOpenPrice()){OrderModify(ticket,...);}
ブレイクイーブンとは利益がある程度出てきたら損切り価格を約定価格に変更することを言います。なので、約定価格とストップロスの価格が同じであればBreakEvenに変更済みだ、ということになります。
つまり同じではない場合となります。
このブレイクイーブンでもう一つエラーが出ることがあります。それがエラー4108の無効なチケットです。
これは既に決済済みのチケットをOrderModify()で変更しようとした際に起こります。
例えば、利益確定価格で決済済みのやつにOrderModify()でProfit価格に変更を加えようとするとエラー4108の無効なチケットだよと注意されますね。
これを防ぐには
int ticket; OrderSelect(ticket,SELECT_BY_TICKET); //約定価格と損切り価格が同じではない場合 if(OrderStopLoss()!=OrderOpenPrice() //決済されていない=決済時間が0(初期値) && OrderCloseTime()==0 ){ OrderModify(ticket,...); }
又はブレイクイーブンではなく普通に後からProfitを付け足す場合
int ticket; OrderSelect(ticket,SELECT_BY_TICKET); //損切り価格と利益確定価格が初期値の場合 if(OrderStopLoss()==0 && OrderTakeProfit()==0 //決済されていない=決済時間が0(初期値) && OrderCloseTime()==0 ){ OrderModify(ticket,...); }
まぁ条件式さえ合っていればOrderModify()はエラーは出ません。ただ一度エラーが出るとこのOrderModify()のエラーは解決しづらいと思います。
たまに注文価格でエラー130が出ることがあります。その場合はNormalizeDoubleを条件式につけてやりましょう。
例えば、
if(NormalizeDouble(OrderStopLoss(),_Digits)!=NormalizeDouble(OrderOpenPrice(),_Digits) //決済されていない=決済時間が0(初期値) && OrderCloseTime()==0 ){ OrderModify(ticket,...); }
上記のようにレート価格にレート最小変動の桁数を返す定義済み変数_DigitsをNomalizeDouble関数に使って最小レートの少数の位で正規化をしてあげましょう。そうするとエラー130がでなくなります。
このModifyエラー130はハマってしまうと解決するのが本当に大変です。
なので確実にModify関数を使う際は条件式に
NormalizeDouble(レート価格,_Digits) //少数の位の正規化 OrderCloseTime==0 //ポジションのクローズ時間が0(初期値)つまり決済がなされていない状態 OrderModify(ticket,OrderOpenPrice(),OrderStopLoss,OrderTakeProfit(),expiration )
を使いましょう。
トレーリングストップなどを実装する際は”<=",">=”の条件式が役にたちます。
今回は以上となります。お読みいただきありがとうございました。