コンテンツにスキップ

【移植#34】7行のCTSLをほどいて再構成する — Gann Swing OscillatorをMQL5へ

EURUSDの1時間足でGann Swing Oscillatorのプラス・マイナス状態、転換矢印、CTSL分解パネルを表示したMT5画面

この記事の3行まとめ

  • VisualTraderの短いCTSL式を、高値・安値の連続更新から順番に分解します
  • 最後の非ゼロ信号を保持する処理を、MQL5では明示的な±1の状態遷移として再構成しました
  • 専用MT5で直近300本・9系列・42回の転換を独立計算と照合し、12バッファを確認しました

今回の原典は「知らない言語を分解して読む」

投稿日順で次に当たる2010年1月21日の記事では、VisualTrader/ChartTraderで使われていたCTSLという言語のGannSwingOscillatorを、MQL4へ移植する考え方が解説されていました。

元記事「VTのGannSwingOscillatorをMT4に移植する術。」を読む

CTSL側の式はわずか7行です。しかし、MQLユーザーが普段見るforループ、入力宣言、バッファ接続が式の中に現れません。そこで原典は、式を一気に翻訳せず、途中の配列を1本ずつ表示して意味を推理していました。

今回もこの方針を引き継ぎます。完成形だけを似せるのではなく、次の中間値をMQL5のバッファとして残しました。

  • 高値更新が2回続いてからの経過本数Us
  • 安値更新が2回続いてからの経過本数Ds
  • 直近の上方向条件からの最高値Hc
  • 直近の下方向条件からの最安値Lc
  • 方向転換の候補Sd1
  • 最後の方向を保持するTD1

まず1行を最小部品までほどく

原典の最初の式は、概念として次の処理です。

Text Only
Us = BarsSince(Sum(H > Ref(H, -1), 2) == 2)

内側から読むと意味が見えてきます。

  1. Ref(H, -1)は1本前の高値です。
  2. H > Ref(H, -1)は、高値を更新したバーなら1、そうでなければ0です。
  3. その値を2本分足し、合計が2なら「2回連続で高値を更新した」と判断します。
  4. BarsSinceは、その条件が最後に成立してから何本経過したかを数えます。

安値側のDsは上下を反転した同じ構造です。

Text Only
Ds = BarsSince(Sum(L < Ref(L, -1), 2) == 2)

短い式を関数名のまま眺めると難しく見えますが、「比較 → 2本集計 → 経過本数」という3段階に分ければ追いやすくなります。


最高値・最安値を記憶する

次の2行は、起点から現在までの価格極値を保持します。

Text Only
Hc = HighestSince(Us == 0, High)
Lc = LowestSince(Ds == 0, Low)

Us == 0は、2回連続の高値更新が起きたバーです。そこから現在までの最高値がHcになります。Lcは、2回連続の安値更新が起きたバーからの最安値です。

MQL5版では、バーを古い方から新しい方へ進みながら、条件成立時に極値をリセットし、その後はMathMaxまたはMathMinで更新しました。

この「古いバーから状態を引き継ぐ」順序が大切です。MQL5の指標バッファは接続後の添字方向を明示できるため、配布版では通常配列の向きへ統一してから計算しています。詳しい仕様は、公式のSetIndexBuffer配列・バッファの添字方向で確認できます。


Sd1の候補を、交互の転換へ変える

原典の入れ子になったIfは、Us == 0またはDs == 0のタイミングで、現在と1本前の高値・安値が記憶した極値と異なるかを確認します。条件を満たすと、上方向候補は+1、下方向候補は-1です。

ただし、候補は同じ方向で続けて発生することがあります。そのまま出力すると、同方向の転換を何度も数えてしまいます。

CTSL版はSd2で最初の1回だけをパルス化し、ValueWhenで最後の非ゼロ値を保持していました。MQL5版では同じ役割を、次の状態遷移へ置き換えています。

Text Only
候補が +1 かつ現在状態が +1 ではない → +1へ転換
候補が -1 かつ現在状態が -1 ではない → -1へ転換
それ以外                              → 現在状態を保持

このため、表示は+1 → -1 → +1のように必ず交互に切り替わります。水色の上矢印と黄色の下矢印は、状態が実際に反転したバーだけに表示されます。


MQL5版の表示

サブウィンドウでは、次の要素を確認できます。

表示 意味
緑のヒストグラム 最後に確定した方向が+1
赤のヒストグラム 最後に確定した方向が-1
水色の上矢印 -1から+1へ転換
黄色の下矢印 +1から-1へ転換
左上パネル 最新方向、転換時刻、UsDs、分解手順

計算ロジックの外部パラメータは設けていません。これは、原典のGann Swing Oscillatorにも計算用の外部入力がなかったためです。入力欄にあるのは、説明パネルを表示するInpShowPanelだけです。


専用MT5での照合結果

今回は、配布インジケーターと同じ式を呼び出すだけのテストにはしていません。検証側でEURUSDのH1データを別に取得し、CTSLの分解手順を独立実装して比較しました。

確認項目 結果
対象 EURUSD・H1
参照データ 直近1,000本
詳細比較 直近300本
比較した計算系列 9系列
300本内の方向転換 42回
転換方向の交互性 一致
最新状態 DOWN -1
最新転換シフト 1本前
公開バッファ 12本
コンパイル 0エラー・0警告
売買注文 なし
実画面キャプチャー 成功

比較対象は、最終状態だけではありません。TD1、色番号、上下の転換矢印、UsDsHcLcSd1まで、直近300本をバー単位で照合しています。

MQL5のOnCalculate()は、利用可能なバー数rates_totalと前回処理数prev_calculatedを受け取ります。履歴が追加・修正された場合はprev_calculatedが0へ戻ることがあるため、配布版は履歴全体から状態を再構築する設計です。これは速度より、途中状態を含む再現性を優先した判断です。公式仕様はOnCalculateで確認できます。


ダウンロードと使い方

34_Gann_Swing_Oscillator_v1_00.mq5 をダウンロード

MT5のIndicatorsへ保存してコンパイルし、確認したいチャートへ適用してください。パラメータ変更は不要です。説明パネルが不要ならInpShowPanelを無効にできます。

このインジケーターは表示だけを行い、注文の送信・変更・決済は行いません。


使えないこと・注意点

  • +1-1は直近のスイング状態であり、利益や次の値動きを保証する売買信号ではありません。
  • 2回の高値・安値更新を待つため、転換の認識には遅れがあります。
  • 現在形成中のバーも計算対象なので、最新バーの候補は足確定まで変化する場合があります。確定情報として使う場合は1本前を参照してください。
  • 同値の高値・安値は「更新」に含めず、厳密な大小比較で判定します。
  • 履歴全体を再計算するため、極端に多い表示バーでは軽量な単純指標より処理量が増えます。
  • 原典のCTSLを逐語変換したものではなく、Sd2ValueWhenの役割を明示的な状態遷移へ置き換えた再構成版です。

ロジック評価の結論

今回の主役は、Gannという名前より「知らない式をどう読むか」です。

複雑な式を見つけたとき、最初から完成形を理解しようとすると手が止まりやすいですよね。比較式だけを表示し、次に集計を足し、さらに経過本数を重ねる。この順番なら、別言語や難解なMQLでも、各配列が何を記憶しているのかを確かめられます。

短いコードが簡単とは限りません。省略されたループと状態を見つけ、検証できる中間値へ戻すこと。それが、古いインジケーターを現在のMQL5へ移すときの一番再利用しやすい技術でした。


前後の記事

前: 【移植#33】確定足と予報を分けるメール通知 — MACDゼロクロスを同一バー1回だけ送る

— SPONSORED —