コンテンツにスキップ

【移植#77】5日ごとのランダム方向を検証する — 固定seedの読み取り専用ベースライン

EURUSD H1で5日ごとのランダム方向54区間を表示し、独立計算54件一致・同seed一致・別seed33件差を示したMT5実画面

この記事の3行まとめ

  • 旧EAのランダム売買を、注文を出さない5暦日区間の比較器へ置き換えました
  • 固定seedの54区間は独立計算と全件一致し、別seedでは33/54区間の方向が変わりました
  • 月曜開始から5日後は週末だったため、今回の実データでは全区間が7日間隔になりました

原典は「週に1度ランダムにトレードするEA」

今回採用したのは、2010年4月2日の「週に1度ランダムにトレードするEA」です。

元記事を読む

原典の短いMT4コードは、起動時にMathSrand(GetTickCount())で乱数列を初期化します。前回の処理から5 * 24時間以上が経過した最初のtickで既存注文を閉じ、BUYかSELLをランダムに1ロット開く仕組みでした。

題名は「週に1度」ですが、コードに曜日や暦週の判定はありません。実際の条件は前回処理から5暦日後です。価格更新のない週末をまたげば、次の実行は5日ちょうどより後ろへずれます。

また、旧コードは選択できた最初の注文を閉じるため、銘柄や識別番号で対象を限定していません。そのまま現行環境へ持ち込むのではなく、今回はランダム方向を比較基準として使う部分だけを残します。

前日の4月1日「レンジ相場大好き♪」は、最後にエイプリルフールと明かす随筆で、独立したMQL実装仕様がありません。そのため番号を使わず、次の技術記事へ進めました。

注文を出さない比較器へ再設計

配布版はEURUSD H1の確定履歴だけを読み、次の手順で仮想区間を作ります。

  1. InpStartTime以降で最初に存在する確定H1を入口にする
  2. 入口から5暦日後を出口の目標時刻にする
  3. 目標時刻以降で最初に存在する確定H1を出口にする
  4. 固定seedからBUYまたはSELLの方向を1つ決める
  5. 出口を次の入口として繰り返す

BUYなら出口始値 - 入口始値、SELLなら符号を逆にし、_Pointで割った値をgross pointsとします。そこから1区間ごとの仮定コストを差し引いたものがcost-adjusted pointsです。

Text Only
gross points = direction × (出口H1始値 - 入口H1始値) ÷ _Point
cost-adjusted points = gross points - 仮定コストpoints
direction = BUYなら+1、SELLなら-1

売買関数は使っていません。水色の上向き三角と赤の下向き三角は、履歴上の比較方向です。注文やポジションを表すマーカーではありません。

固定seedは「答え合わせ」のため

MQL5公式資料では、MathSrand()へ同じ初期値を渡すと同じ疑似乱数列を作れます。一方、原典で使われたGetTickCount()はOS起動後の経過ミリ秒なので、起動ごとに方向列が変わります。

配布版はプログラム内に独立した32bitの状態を持ち、固定seedから方向列を作ります。同じ履歴・開始時刻・seedなら、再装着しても同じ方向になります。これは将来成績の再現性ではなく、同じ入力から同じ計算結果を得て検証できるようにするための再現性です。

乱数生成器の品質比較は、【検証#18】MathRandの乱数は偏っている?XorShiftとの比較で扱っています。今回は生成器の優劣ではなく、ランダム方向を戦略評価の基準線として固定できるかを調べます。

月曜から5日後でも、実測は7日間隔になった

初期設定の開始時刻は2025年9月1日00:00です。この日は月曜日なので、5暦日後の目標は土曜日になります。しかし、今回のEURUSD履歴には土曜日のH1がありません。比較器は次に存在するH1まで待つため、出口は翌週の取引時間へ進みました。

その出口を次の入口にするので、同じ並びが繰り返されます。結果として、完了した54区間はすべて次の状態でした。

項目 実測
指定した保有間隔 5暦日
完了区間 54
目標より遅い出口 54
最短の実測間隔 7.00日
最長の実測間隔 7.00日

「5日を指定したから5日足相当」とは限りません。時刻差の条件は、実際に存在するバーへどう着地したかまで記録して初めて意味が分かります。

EURUSD H1の54区間を独立照合

専用MT5 Build 6182で、配布インジケーターと独立検証EAをコンパイルしました。どちらも0エラー・0警告です。

検証EAは配布版の集計値を信じず、確定H1を別に取得して、入口、出口、方向、区間points、累積値を作り直しました。同じseedの別インスタンスと、seedを1だけ変えた別インスタンスも同時に比較しています。

検査項目 結果
対象 EURUSD H1
固定seed 20100402
完了区間 54
BUY / SELL 24 / 30
独立再計算との不一致 0
同じseedの再実行差 0
別seedの実装不一致 0
別seedで方向が変わった区間 33 / 54
コスト控除後のプラス区間 24 / 54(44.4%)
gross合計 -3,506.0 points
20 points/区間控除後 -4,586.0 points
控除後の最大ドローダウン 7,854.0 points
注文数・ポジション数 開始前後で変化なし

このseedの結果はマイナスでした。別seedでは33区間の方向が変わっています。1つの乱数列で良い成績が出ても、予測力や売買優位性の証拠にはなりません。

パラメーター

パラメーター 初期値 役割
InpStartTime 2025-09-01 00:00 最初の入口を探し始める時刻
InpHoldDays 5 出口の目標までの暦日数
InpSeed 20100402 方向列を再現する初期値
InpRoundTripCostPoints 20.0 1区間ごとに差し引く仮定コスト
InpMaxVisibleEvents 18 直近に表示する矢印の最大数
InpShowPanel true 集計パネルの表示

77_Five_Day_Random_Baseline_Auditor_v1_00.mq5 をダウンロード

使い方

  1. MQ5をMT5のデータフォルダー内のMQL5/Indicatorsへ置き、MetaEditorでコンパイルします。
  2. 調べたい銘柄のH1チャートへ適用します。
  3. 水色と赤の三角で、固定seedが割り当てた方向を確認します。
  4. パネルで完了区間、BUY/SELL数、gross、コスト控除後、最大ドローダウンを確認します。
  5. InpSeedを変え、単一の方向列だけで結論が変わっていないか見比べます。

今回の数値が測っていないもの

  • H1内部で価格が動いた順序
  • 原典の500 pointsストップへ途中で到達したか
  • 実際のスプレッド、手数料、スワップ、スリッページ
  • ロット数、証拠金、通貨換算を含む口座損益
  • 未確定H1での途中経過

原典の500 pointsストップは再現していません。旧環境では銘柄の桁数によって価格幅の意味が変わり、H1 OHLCだけではストップ到達時の約定やギャップを厳密に再現できないためです。

InpRoundTripCostPointsも実コストではありません。一定pointsを全区間から引き、結果がコストにどれだけ敏感かを見るための入力です。今回の履歴は後から補正される可能性があり、同じ期間でも接続先が違えば結果は変わり得ます。

まとめ

ランダム売買は、何も考えずに注文を出す道具として使うより、戦略の成績を比べる基準線として使う方が安全です。そのためには、方向列を固定し、別seedでも見て、実価格のどこを入口と出口にしたかを明示する必要があります。

今回の54区間は独立計算と全件一致し、同じseedは完全一致、別seedは33区間で方向が変わりました。そして「5日ごと」というコード上の指定は、週末をはさんだ実データでは全件7日間隔になりました。

乱数を使うほど、再現条件と測定限界を先に固定する。旧EAの短いアイデアを、注文を出さずに答え合わせできる形へ移した回です。

あわせて読みたい記事


前後の記事

前: 【移植#76】H1の5分ずれを壊さず調べる — M1再集計でOHLCを照合

次: 【移植#78】M1のTick VolumeをOHLC経路で見積もる — 履歴を書き換えないwhat-if監査

— SPONSORED —