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

この記事の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行を最小部品までほどく¶
原典の最初の式は、概念として次の処理です。
内側から読むと意味が見えてきます。
Ref(H, -1)は1本前の高値です。H > Ref(H, -1)は、高値を更新したバーなら1、そうでなければ0です。- その値を2本分足し、合計が2なら「2回連続で高値を更新した」と判断します。
BarsSinceは、その条件が最後に成立してから何本経過したかを数えます。
安値側のDsは上下を反転した同じ構造です。
短い式を関数名のまま眺めると難しく見えますが、「比較 → 2本集計 → 経過本数」という3段階に分ければ追いやすくなります。
最高値・最安値を記憶する¶
次の2行は、起点から現在までの価格極値を保持します。
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版では同じ役割を、次の状態遷移へ置き換えています。
このため、表示は+1 → -1 → +1のように必ず交互に切り替わります。水色の上矢印と黄色の下矢印は、状態が実際に反転したバーだけに表示されます。
MQL5版の表示¶
サブウィンドウでは、次の要素を確認できます。
| 表示 | 意味 |
|---|---|
| 緑のヒストグラム | 最後に確定した方向が+1 |
| 赤のヒストグラム | 最後に確定した方向が-1 |
| 水色の上矢印 | -1から+1へ転換 |
| 黄色の下矢印 | +1から-1へ転換 |
| 左上パネル | 最新方向、転換時刻、Us/Ds、分解手順 |
計算ロジックの外部パラメータは設けていません。これは、原典のGann Swing Oscillatorにも計算用の外部入力がなかったためです。入力欄にあるのは、説明パネルを表示するInpShowPanelだけです。
専用MT5での照合結果¶
今回は、配布インジケーターと同じ式を呼び出すだけのテストにはしていません。検証側でEURUSDのH1データを別に取得し、CTSLの分解手順を独立実装して比較しました。
| 確認項目 | 結果 |
|---|---|
| 対象 | EURUSD・H1 |
| 参照データ | 直近1,000本 |
| 詳細比較 | 直近300本 |
| 比較した計算系列 | 9系列 |
| 300本内の方向転換 | 42回 |
| 転換方向の交互性 | 一致 |
| 最新状態 | DOWN -1 |
| 最新転換シフト | 1本前 |
| 公開バッファ | 12本 |
| コンパイル | 0エラー・0警告 |
| 売買注文 | なし |
| 実画面キャプチャー | 成功 |
比較対象は、最終状態だけではありません。TD1、色番号、上下の転換矢印、Us、Ds、Hc、Lc、Sd1まで、直近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を逐語変換したものではなく、
Sd2とValueWhenの役割を明示的な状態遷移へ置き換えた再構成版です。
ロジック評価の結論¶
今回の主役は、Gannという名前より「知らない式をどう読むか」です。
複雑な式を見つけたとき、最初から完成形を理解しようとすると手が止まりやすいですよね。比較式だけを表示し、次に集計を足し、さらに経過本数を重ねる。この順番なら、別言語や難解なMQLでも、各配列が何を記憶しているのかを確かめられます。
短いコードが簡単とは限りません。省略されたループと状態を見つけ、検証できる中間値へ戻すこと。それが、古いインジケーターを現在のMQL5へ移すときの一番再利用しやすい技術でした。
前後の記事¶
前: 【移植#33】確定足と予報を分けるメール通知 — MACDゼロクロスを同一バー1回だけ送る