コンテンツにスキップ

【移植#27】OCO両建て注文の状態遷移を可視化する — 実注文なしでキャンセル順序を検証

EURUSD 1時間足でOCO買い逆指値の到達と売り側キャンセルを表示したMT5画面

この記事の3行まとめ

  • 基準価格の上に買い逆指値、下に売り逆指値を置いたOCO状態をチャートで再現します
  • 片側へ到達したら反対側ラインを消し、同一バーで両方へ到達した場合は曖昧状態として分けます
  • 実注文を一切送らないため、注文削除事故を起こさずにロジックと時系列を確認できます

今回の原典は「片方が成立したら、もう片方を取り消す」

投稿日順で次に当たる2010年1月14日の記事では、買い逆指値と売り逆指値を手動で置き、片方が成立したらEAが残った注文を削除する半裁量キットが紹介されていました。

元記事「MT4で OCOオーダー機能を実現する?半裁量指標トレードキット」を読む

OCOは“One Cancels the Other”の略です。レンジ上側の買い注文と下側の売り注文をペアにし、一方が成立したら他方を取り消します。

原典では、現在価格より25pips上へ買い逆指値、25pips下へ売り逆指値を置く例も示されています。MQL5の注文種別では、それぞれORDER_TYPE_BUY_STOPORDER_TYPE_SELL_STOPに当たります。

ただし、注文削除を行うEAには誤操作時の影響があります。原典の実装も、EAを先に有効にすると1件だけ置いた注文が直ちに削除される注意点を明記していました。

そこで今回の公開版は、実注文を監視・削除するEAにはしません。OCOの状態遷移を価格履歴上で再現し、どちらをキャンセルすべきか、OHLCだけでは判定できない場面はどこかを確認する非取引インジケーターへ再構成します。


OCOを4つの状態へ分ける

基準価格を開始バーの終値とし、その上下へ同じ距離だけラインを置きます。

Text Only
Buy Stop  = Reference + Distance
Sell Stop = Reference - Distance

状態は次の4種類です。

状態値 状態 判定・表示
0 ARMED 青の買いラインと赤の売りラインを両方表示
1 BUY TRIGGERED 高値が買いラインへ到達。以後は売りラインを消す
-1 SELL TRIGGERED 安値が売りラインへ到達。以後は買いラインを消す
2 AMBIGUOUS SAME BAR 同じバーで上下両ラインへ到達。順序は判定不能

画像では緑の上矢印が買い側への到達です。到達後も青い買いラインは残り、ペアだった赤い売りラインは終了しています。これは「買いが成立したので、売り逆指値をキャンセルした」という状態を表します。


同一バー両到達を曖昧にする理由

1本のローソク足から分かるのは始値・高値・安値・終値です。高値が買いライン以上、安値が売りライン以下でも、どちらへ先に到達したかはOHLCだけでは分かりません。

この場合に「必ず買いが先」「必ず売りが先」と決めると、バックテストへ都合のよい約定順序を持ち込むことになります。今回のインジケーターは状態2として止め、ティック履歴が必要なケースとして明示します。

実際のOCO注文では、急変や価格ギャップによって反対側のキャンセルがサーバーへ届く前に、両方が成立する可能性もゼロではありません。OCOは損失を消す仕組みではなく、待機注文を管理する仕組みです。


なぜ公開版では注文削除を行わないのか

「待機注文が2件から1件になったら、残った1件を削除する」だけでは、別の裁量注文まで巻き込む恐れがあります。また、EA起動前から1件しか存在しなかった場合、それがOCOの残りなのか、独立した注文なのかを区別できません。

実運用向けにするなら、少なくとも次の情報でペアを限定する必要があります。

  1. 買い注文と売り注文の正確なチケット番号
  2. 同じ銘柄であること
  3. Buy StopとSell Stopの組み合わせであること
  4. 同じEA識別番号と注文コメントを持つこと
  5. 2件が同時に確認できた後でのみARMEDへ移ること
  6. 削除結果のリターンコードを検査すること

さらにMQL5では、手動操作、待機注文の成立、注文削除などがOnTradeTransactionへ複数段階で通知されます。公式資料も、関連イベントの到着順は保証されないと説明しています。1回の通知だけで口座状態を決めつけず、対象チケットの現状を再照合する設計が必要です。

今回の配布ファイルにはOrderSend()、注文作成、注文削除、ポジション変更を入れていません。まず危険のない環境で状態設計を確認するための教材です。


MQL5実装で確認したポイント

開始価格を固定する

初期値では72本前の確定足終値を基準価格にします。現在価格を毎ティック基準にすると上下ラインまで一緒に動き、永遠に到達しないためです。

InpReferencePriceへ価格を指定すれば、任意の固定価格を基準にもできます。0の場合だけ開始バー終値を使います。

確定足を古い順に走査する

開始バーの次から直近確定足までを古い順に確認し、最初に起きたイベントで状態を固定します。あとから起きた逆方向の値動きで、最初のOCO結果を書き換えません。

形成中バーをトリガーにしない

最新バーは高値・安値が変わるため、状態判定から外します。形成中バーにマーカーが出ないことも検証EAで確認しています。

反対側ラインだけを終了する

買い到達後は売りライン、売り到達後は買いラインをEMPTY_VALUEにします。同一バー両到達では両方を終了し、確定できない状態を残します。


専用MT5での動作確認

売買無効の専用テストMT5で、本体と検証EAをコンパイルしました。検証時は状態遷移を確実に観察できるよう、72本前の終値から上下10pipsを使っています。配布版の初期距離は原典の例に合わせた25pipsです。

項目 設定・結果
通貨ペア・時間足 EURUSD・1時間足
開始位置 72本前
検証時の上下距離 10pips
最初の到達 買い側
最終状態 BUY TRIGGERED
トリガー位置 70本前
買い/売りマーカー 1件/0件
ライン位置の最大誤差 0.0000ポイント
マーカー位置の最大誤差 0.0000ポイント
形成中バー マーカーなし
注文送信 0件
本体コンパイル 0 errors / 0 warnings
検証用コンパイル 0 errors / 0 warnings
キャプチャ 成功、エラー0

実MT5のOHLCから独立に状態を再計算し、買い到達後に売りラインだけが消えることを照合しました。


パラメータ

パラメータ 初期値 説明
InpLookbackBars 72 何本前からシミュレーションするか
InpEntryDistancePips 25.0 基準価格から上下ラインまでの距離
InpReferencePrice 0.0 固定基準価格。0なら開始バー終値
InpMarkerOffsetPips 4.0 到達マーカーを足から離す距離

3桁・5桁のFX銘柄では1pipを_Point × 10、2桁・4桁では_Pointとして換算します。


ダウンロード

27_OCO_Breakout_State_Simulator_v1_00.mq5 をダウンロード

MT5のIndicatorsへ保存してコンパイルし、チャートへ適用してください。このファイルはシミュレーターであり、注文は作成・取消しません。


ロジック評価の結論

原典の重要な発想は、EAを完全自動売買だけでなく、裁量注文の管理補助にも使うことでした。片側が成立した後の取消忘れを自動化するOCOは、その代表例です。

一方、MQL5へ移すときは「注文数が奇数なら削除」のような広い条件ではなく、どの2件をペアとして管理するかを明示しなければなりません。イベント順序、部分約定、両側成立、期限切れ、手動取消しも別々に扱う必要があります。

今回の非取引版は、買い・売り・同一バー両到達の分岐を安全に観察できます。これで確認できるのは状態ロジックであり、サーバー遅延、スリッページ、実際の約定順序ではありません。実注文へ発展させる場合は、必ずデモ口座で正確なチケット管理と全リターンコードを検証する必要があります。


前後の記事

前: 【移植#26】バッドティック候補を異常ヒゲから探す — 中央値TRで要確認バーを絞る

次: 【移植#28】シフトの違うMAの間へ雲を描く — 表示時刻をそろえてから塗りつぶす

— SPONSORED —