【MQL5】 MT5のEA作成の勉強 その17 PositionModify が動かない?解決方法とは

【MQL5】 MT5のEA作成の勉強 その17 PositionModify が動かない?解決方法とは

まえがき

 前回の投稿で、インジケータ設定の方法を学びました。今回はEAの成績を向上する上で極めて重要な、損切の設定について勉強したいと思います。損切方法は一般的には逆指値とトレーリングストップの二つがあります。前者はあらかじめ決めた価格になると自動的に決済する、後者はあらかじめ決めた含み益が上がるたびに損切価格を繰り上げてゆきます。
 EAにおいて、トレーリングストップを設定する場合、ストラテジーモジュールにトレール注文のクラスが用意されていますが、今回はこれは使わずに、古典的にティックごとにポジションを更新するPositionModifyを使った方法を検討してゆきます。
 これを使って、ポジションオープン時のみ、広い幅で逆指値の損切設定を行い、利益が出ればそれ以降は小幅なトレーリングストップを行う方式を取ろうと思ったのですが、実装にどえらい苦労したので同じことを繰り返さないようにメモっておきます。

PositionModifyとは

  PositionModifyをとは、オープン済みのポジションの利食い / 損切の設定を変更することができる処理です。第一引数に通貨ペアを指定すると、その通貨ペアで持っているポジション全てを、チケットを指定すると、そのチケットと一致する単一ポジションを対象にすることができます。詳細はリンク先のリファイレンスをご覧ください。

Testerを確認

 まずはテスターのエラーメッセージを確認してみます。エラーメッセージは[Market closed]、即ち、市場が閉まっている時間の注文だから受け付けられない、ということです。実際、このメッセージのバーの時間は23:57分、市場が閉まっている時間です。これはシステムの動作として正常なので、 PositionModify 処理が動かない原因は他にあると思われます。
 しかし、出力されるエラーメッセージは確認した範囲では [Market closed] の起因するものばかりで、エラーメッセージから原因を特定することはできませんでした。

テスターのエラーメッセージ

ブレークポイントを PositionModify処理の直後に貼る

 次に、処理が終了した直後に、テスターにメッセージを出す部分にブレークポイントを貼ってテストを行いました。その結果、極めて稀(2年間のテストで3回ほど) PositionModify 処理が行われていないことが分かりました。

ブレークポイントを処理に入る判定部分に貼る

 次に、 PositionModify 処理の直前、 PositionModify 処理 を行うか否かの判定部分にブレークポイントを貼ってみたところ、何故か、以下の判定が、殆どの場合でFalseになっていることが分かりました。
 ちなみに、以下の判定では、「選択中のポジションが「BUY」(ロング)ポジションで、かつ、マジックナンバーが一致する(=このEAでオープンされたポジションである)」ことを確認しています。
 全く同じ判定をClose処理にも入れており、そちらは問題なく動いているので、コーディングミスやロジックミスは考えにくいのですが、謎です。

if(m_position.PositionType()==POSITION_TYPE_BUY && m_position.Magic()==InpMagic) 

PositionModify処理直前のClose処理をコメントアウト

 この段階では、一つのループ内で、まず、Close判定を行い、Close処理されなければ、 PositionModify 判定を行うという方式を取っていました。そこで、直前の Close判定をコメントアウトすると何故かうまく行きました。どうも、 Close判定 の条件を満たさない= PositionModify の条件を満たさないという状態になっていたようです。これを修正したところ、無事、Close PositionModify も処理されるようになりました。

ループを独立する

 上記の結果を受けて、やや非効率ではある者の、一度、全てのポジションに対して Close 判定を行った後、残ったのポジションに対して 別のループで PositionModify 処理 を行うようにしました。その結果、無事に Close 判定と PositionModify 処理が行われるようになりました。

結果

 試しに、トレーリングストップを1pipsにしてみると以下のようになりました。・・・時たま含み益を取り損ねている(緑のラインが青のラインの上に突き出ている)ので、ちょっと違和感があります。しかし、一応設定的には、1pips ×1.0Lot ≒ 100USDまでの含み益は取りこぼす可能性はあるので、有り得ない結果ではありません。オープン条件をもう少し検討すべきということでしょう。

オープン時の逆指値 :50pips トレーリングストップ:1pips
オープン時の逆指値 :50pips トレーリングストップ:1pips
オープン時の逆指値 :1pips トレーリングストップ:1pips
オープン時の逆指値 :1pips トレーリングストップ:1pips

まとめ

 何とか目指すものを作ることができました。結論としては原因は単なる凡ミス。教訓としてはClose、Modefiled、Openの条件はきちんと個別に判定しましょうということです。また、目指したものの成績は思いの外芳しくなかったので、今後さらに検討が必要だと思います。