取引戦略の開発:バタフライオシレーター法
はじめに
インジケーターとは、市場データを視覚的な形式で表現するために設計された数学的ツールです。これらはトレーダーが市場のトレンド、ボラティリティ、モメンタムを分析するのに役立ちます。代表的な例として、相対力指数(RSI)、ATR、移動平均(MA)、相対活力指数(RVI)などがあります。それぞれが異なる役割を持ち、取引チャート上でのエントリーおよびエグジットポイントの特定に貢献します。
本記事では、新しいテクニカル指標である「バタフライオシレーター」を紹介します。この指標は、1989年にTemple H. Fayによって発見された有名な数学曲線「バタフライ曲線」に基づいています。この曲線は、グラフに描画した際に翼のような独特の形状を示すことから、その名が付けられました。本記事の目的は、この数学的基盤を用いてバタフライオシレーターを構築し、それに対応する取引戦略を開発することです。
バタフライカーブ:数学的基盤
バタフライ曲線は、その特徴的な翼のような形状を生成するパラメトリック方程式によって定義されます。

ここでパラメータtの範囲は[0,12π]です。
図1はバタフライ曲線を示しています。

図1:バタフライ曲線
特筆すべき点:
- x軸の値は対称性を示す一方、y軸の値は非対称です。
- 全体構造は非線形かつ周期的であり、一定のパターンを繰り返します。
- このパラメトリック方程式は単一の入力(t)から対応するxおよびyの値を出力します。
バタフライ曲線を構築するためのコード構造
ここでは、スクリプトファイルを使用してチャート上にバタフライ曲線を描画する方法を示します。
#include <Canvas\Canvas.mqh>
最初のステップは、上記の行を用いてMQL5にCanvasライブラリをインクルードすることです。このライブラリは、バタフライ曲線をチャート上に描画および可視化するために必要なクラスおよび関数を提供します。
// Create canvas for drawing int width = 800; // Canvas width int height = 600; // Canvas height string canvas_name = "ButterflyCurve"; // Create canvas object CCanvas canvas; if(!canvas.CreateBitmapLabel(canvas_name, 200, 50, width, height, COLOR_FORMAT_XRGB_NOALPHA)) { Print("Error creating canvas: ", GetLastError()); return; }
まず、キャンバスのサイズを定義します。幅は800ピクセル、高さは600ピクセルとし、キャンバス名を「ButterflyCurve」に設定します。これらのパラメータは、チャート上に表示される描画領域のサイズとラベルを決定します。
次に、CCanvasオブジェクトを宣言します。これは、線、図形、テキストなどの視覚要素を描画するためのグラフィカルな描画面として機能します。CreateBitmapLabel()関数を使用して、チャート上の特定の位置(左から200ピクセル、上から50ピクセル)にキャンバスを生成します。また、COLOR_FORMAT_XRGB_NOALPHAを指定することで、色と透明度の処理方法を定義します。
最後に、エラーハンドリングを実装しています。キャンバス作成に失敗した場合、GetLastError()で取得したエラーコードを表示し、処理を停止します。これにより、キャンバスが正常に生成された場合のみ描画処理が実行されます。
// Set up drawing parameters int points = 1000; // Number of points double t_start = 0; // Start angle double t_end = 12 * M_PI; // End angle double step = (t_end - t_start) / (points - 1); // Calculate curve points double x[], y[]; ArrayResize(x, points); ArrayResize(y, points); for(int i = 0; i < points; i++) { double t = t_start + i * step; double expr = MathExp(MathCos(t)) - 2 * MathCos(4 * t) - MathPow(MathSin(t/12), 5); x[i] = MathSin(t) * expr; y[i] = MathCos(t) * expr; }
このコード部分では、キャンバスに描画する前段階として、バタフライ曲線を生成するための数学的設定とデータ構造を定義しています。
まず描画パラメータを設定します。
- pointsは曲線を描くためのデータ点数(1000点)を指定し、滑らかな曲線を実現します。
- t_startとt_endはパラメータtの範囲(0から12π)を定義します。
- stepは各データ点間の増分を計算し、均等な分布を保証します。
次に、x[]とy[]の動的配列を作成し、すべての計算された座標を格納できるようにサイズを調整します。これらの配列の各要素は、曲線上の1つの点に対応しています。
forループ内では、各tの値に対してバタフライ曲線の式を計算し、対応する幾何学的座標(x, y)を求めます。 これらの値は後にスケーリングおよび描画に使用されます。
// Find coordinate bounds for scaling double x_min = x[ArrayMinimum(x)]; double x_max = x[ArrayMaximum(x)]; double y_min = y[ArrayMinimum(y)]; double y_max = y[ArrayMaximum(y)]; // Scale points to canvas coordinates int x_px[], y_px[]; ArrayResize(x_px, points); ArrayResize(y_px, points); double x_scale = (width - 40) / (x_max - x_min); double y_scale = (height - 40) / (y_max - y_min); double scale = MathMin(x_scale, y_scale); // Maintain aspect ratio for(int i = 0; i < points; i++) { x_px[i] = (int)((x[i] - x_min) * scale) + 20; y_px[i] = height - (int)((y[i] - y_min) * scale) - 20; // Flip Y-axis for canvas coordinates }
このコード部分では、計算されたバタフライ曲線のデータ点をキャンバス領域内に適切に収めるためのスケーリングおよび座標変換をおこないます。
まず、プログラムはx配列およびy配列の最小値と最大値を求めることで、曲線の座標範囲(境界)を特定します。これらの値は、バタフライ曲線の水平方向および垂直方向の全体的な範囲を定義するものであり、データを画面上へ正確にマッピングするために不可欠です。
次に、新たに2つの整数配列(x_pxとy_px)を作成し、データ点の数に合わせてサイズを調整します。これらの配列には、スケーリング後の曲線に対応するピクセルベースの座標が格納されます。
続いて、スケーリング係数を計算します。
- x_scaleは、左右それぞれに20ピクセルの余白を残しながら、x値の範囲をキャンバスの利用可能な幅へ変換します。
- y_scaleは、同様に余白を確保しながら、y値の範囲をキャンバスの利用可能な高さへ変換します。曲線の縦横比を維持し、引き伸ばしや歪みを防ぐために、これら2つのスケーリング係数のうち小さい方が最終的なスケール値として選択されます。
最後に、各データ点をキャンバス座標に変換します。
この変換式は、余白を考慮しながら数学的なx–y座標を画面上の位置へと変換し、さらにY軸を反転させます(キャンバス座標系は左上が原点であるため)。この処理が完了すると、すべてのバタフライ曲線のデータ点は適切にスケーリングされ、可視キャンバス領域内に正しく配置され、描画の準備が整います。
// Draw the curve canvas.Erase(ColorToARGB(clrWhite, 255)); // White background // Set line color - we'll pass this directly to Line() method uint line_color = ColorToARGB(clrBlue, 255); // Draw the polyline for(int i = 1; i < points; i++) { canvas.Line(x_px[i-1], y_px[i-1], x_px[i], y_px[i], line_color); } // Title canvas.FontSet("Arial", 20, FW_BOLD); canvas.TextOut(300, 20, "Butterfly Curve", ColorToARGB(clrBlack, 255)); // Update display canvas.Update();
このコード部分では、キャンバス上に最終的なバタフライ曲線を描画し、表示スタイルの設定について説明します。 まず、キャンバスの背景色を白に設定し、データ線の色を青に指定することで、プロットの視覚スタイルを設定します。次に、x_pxおよびy_pxのデータ点を線として描画します。最後に、タイトルのフォントを黒色の20ポイントArialに設定し、キャンバスを更新して最終的なビジュアライゼーションを表示します。
バタフライオシレーターの開発
バタフライオシレーターを構築するにあたり、対称性という特性を持つバタフライ曲線のx成分を使用します。x成分は概ね[-3, +3]の範囲に収まるため、オシレーターを構成するのに適しています。
取引用途に適応させるため、入力パラメータtを単純に経過した価格バーの数として定義します。 tはバー数を表すため、曲線の形状はすべての時間足において同一になります。基礎となる方程式は周期的であるため、オシレーターは1サイクルごとに繰り返される波状パターンを形成します。
基礎となるバタフライ曲線の完全な1周期はt = 24πであり、約75.4本のバーに相当します。オシレーターの感度を調整するために、スケーリング係数としてステップサイズ(Δt)を導入します。完全な1サイクルに必要なバー数(N)は次の式で計算されます。 N = 24π / Δt
例
- ステップサイズ = 1: N=24π/1=76バー(完全なサイクル)
- ステップサイズ = 0.5: N=24π/0.5=151バー
- ステップサイズ = 5: N=24π/5=15バー
ステップサイズはオシレーターの挙動に直接影響を与えます。
- ステップサイズが小さいほど、波形はより滑らかで緩やかになります。
- ステップサイズが大きいほど、振動がより速く、頻繁になります。
オシレーターを価格反応型にする
このオシレーターはバー数のみに基づいて動作させることも可能ですが、価格変動に反応するよう設計することもできます。そのために、ローソク足の終値と始値の差を組み込みます。この調整により、オシレーターは時間経過のみに依存するのではなく、価格ダイナミクスの変化に反応するようになります。
このハイブリッド設計(周期構造と価格反応性の組み合わせ)により、バタフライオシレーターは構造的なタイミング指標とモメンタム確認の両方を提供することが可能になります。
オシレーターが実際にどのように動作するかを示す前に、それを実装するために使用されるコード構造の概要を簡単に説明しましょう。
//--- plot Butterfly #property indicator_label1 "Butterfly Oscillator" #property indicator_type1 DRAW_LINE #property indicator_color1 DodgerBlue #property indicator_width1 2 #property indicator_style1 STYLE_SOLID //--- indicator levels #property indicator_level1 2.5 #property indicator_level2 -2.5 #property indicator_level3 0.0
このコード部分では、バタフライオシレーターの視覚的および構造的な特性を設定します。インジケーターがチャート上でどのように表示されるかを定義しており、デフォルトでは「Butterfly Oscillator」というラベル付きの実線のDodgerBlueカラーで表示され、視認性を高めるために線の太さは2に設定されています。さらに、2.5、-2.5、0.0という重要な基準レベルも設定されています。これらの設定により、オシレーターは視覚的に明確であるだけでなく、市場サイクルを識別するための分析ツールとしても有用なものとなります。
//--- input parameters input bool UsePriceStep = false; // Use ClosePrice as Step size for t increment input double tmStep = 0.05; // Step size for t increment
このコード部分では、バタフライオシレーターが時間増分をどのように計算するかを制御するユーザー入力パラメータを定義します。
- UsePriceStep:Boolean型のオプションで、ステップサイズをバー数ではなく価格変動に基づいて決定するかどうかをユーザーが選択できます。
- tmStep:変数tを増分するための固定ステップサイズを設定する数値入力です。
これらの入力により、トレーダーはオシレーターが市場の変化に対してどの程度滑らかに、または敏感に反応するかを調整できます。選択したステップサイズは、オシレーターの挙動や全体的なダイナミクスに大きな影響を与えます。
double CalButterflyValue(int bar_index, double bar_close, double bar_open) { double tStep = UsePriceStep ? MathMod((bar_close - bar_open) / _Point, tmStep) : tmStep; double t = bar_index * tStep; // Butterfly curve formula double x = MathSin(t) * (MathExp(MathCos(t)) - 2.0 * MathCos(4.0 * t) - MathPow(MathSin(t / 12.0), 5)); return (x); }
このコード部分では、チャート上の各バーに対してオシレーターの値を計算するバタフライ関数を定義しています。
CalButterflyValue()関数は3つのパラメータを受け取ります。
- bar_index:現在のバーのチャート上での位置
- bar_close:そのバーの終値
- bar_open:そのバーの始値
関数内では、まずステップサイズ(tStep)を計算します。UsePriceStepが有効な場合は価格変動に応じて動的に調整され、無効な場合は固定値tmStepが使用されます。その後、バーインデックスとステップサイズから変数tが求められます。
最後に、バタフライ曲線の式を適用してxを計算します。この値がそのバーにおけるオシレーターの値を表し、チャート上で描画するために返されます。
int pStart = prev_calculated == 0 ? 0 : prev_calculated - 1; for(int i = pStart; i < rates_total; i++) { double bar_close = close[i]; double bar_open = open[i]; ButterflyBuffer[i] = CalButterflyValue(i, bar_close, bar_open); }
この部分では、チャート描画用に計算された値をバタフライオシレーターのバッファに初期化し、格納します。
変数pStartは計算を開始する位置を決定します。初回実行時は0から開始し、それ以降の更新時は、前回計算済みバーの直前から開始して効率を向上します。各計算結果はButterflyBuffer配列に格納され、後でインジケーターウィンドウ上にオシレーターラインとして描画されます。
バタフライオシレーターのデモンストレーション
バタフライオシレーターのデモでは、バー数のみを使った場合とバー数と価格変動を組み合わせた場合の2つの条件下での挙動を比較します。この比較により、オシレーターが各シナリオでどのように反応するかを観察できます。
ケース1:ステップサイズの影響(バー数のみ)
図2は、バー数のみで動作するオシレーターを示しています。この場合、パラメータUsePriceStepはfalseに設定されており、オシレーターの進行はバー数のみに依存します。波形への影響を調べるために、異なる3つのステップサイズ0.05、0.5、5を使用しています。

図2:価格変動なしのバタフライオシレーター
グラフから以下のことが観察できます。
- ステップサイズが小さい場合(例:0.05)、オシレーターは1サイクルを完了するまで時間がかかり、波形はより滑らかで緩やかになります。
- ステップサイズが大きい場合(例:5)、オシレーターはサイクルを非常に速く完了し、波形はより鋭く不規則になります。
これにより、ステップサイズがオシレーターの滑らかさと周波数を直接制御することがわかります。小さいステップは長期的な周期的変動を強調し、大きいステップは短期的な変動を強調します。
ケース2:ステップサイズの影響(価格変動あり)
図3は、価格変動によって駆動されるオシレーターのパターンを示しています。この場合、オシレーターの挙動はステップサイズだけでなく、市場価格の変動にも影響されます。バー数のみのモードと同様に、ステップサイズが大きいとオシレーターは速く動き、小さいと遅く動きます。しかし、価格変動を組み込むことで、曲線には変動性が加わります。

図3:価格変動によるバタフライオシレーター
価格変動はカオス的かつ非線形な挙動を示す傾向があるため、その変動はオシレーターの波形にも反映されます。その結果、バタフライオシレーターはよりダイナミックな挙動を示し、純粋に数学的なリズムに従うのではなく、基礎となる市場のボラティリティに応じて波形を適応させます。
バタフライオシレーター取引戦略
バタフライオシレーターインジケーターを開発したので、次にこの指標をエントリー条件として使用する簡単なバタフライエキスパートアドバイザー(EA)を構築できます。この取引戦略は、オシレーターの周期的な転換点を検出し、移動平均(MA)で示される市場全体のトレンドと整合させることを目的としています。
このアプローチでは、市場エントリーのための2つの戦略を定義します。
戦略1
- 買いシグナル: MAが上昇トレンドを示し、バタフライオシレーターが+2.5を上抜けしたときに買いポジションを開く
- 売りシグナル: MAが下降トレンドを示し、バタフライオシレーターが+2.5を上抜けしたときに売りポジションを開く
戦略2
- 買いシグナル: MAが上昇トレンドを示し、バタフライオシレーターが-2.5を下抜けしたときに買いポジションを開く
- 売りシグナル: MAが下降トレンドを示し、バタフライオシレーターが-2.5を下抜けしたときに売りポジションを開く
両戦略において、MAトレンド方向がトレンドフィルタとなり、バタフライオシレーターがエントリートリガーの役割を果たします。
- 戦略1は上限閾値(+2.5)を基準にしたシグナルに注目し、オシレーターサイクルのピークを特定します。
- 戦略2は下限閾値(-2.5)を基準にしたシグナルに注目し、サイクルのボトムを捕捉します。
バタフライEAは、トレーダーが戦略1または戦略2を選択する、あるいは両方を順次実行する柔軟性を提供します。また、EAにはバタフライオシレーターを価格変動に反応させるか、バー数の進行のみで動作させるかを選択するオプションも含まれています。
関連する入力パラメータは次のように定義されます。//--- Strategy Selection input bool UsePriceStep = false; // Use ClosePrice input bool EnableStrategy1 = true; // Enable Strategy 1 Peak input bool EnableStrategy2 = false; // Enable Strategy 2 Trough
UsePriceStep:価格変動モードの有効/無効を切り替えます。
- trueの場合、EAはオシレーターに価格変動(終値-始値の差)を組み込み、市場ダイナミクスに応答する
- falseの場合、オシレーターはバー数のみを基準に固定周期で動作する
戦略の選択:
- 戦略1:オシレーターのピーク形成に基づくシグナル生成
- 戦略2:オシレーターのボトム形成に基づくシグナル生成
両方有効な場合は、リアルタイム運用時には、先に満たされた閾値条件を優先します。
取引管理を厳格におこなうため、EAは同時に1つのポジションしか保有できないように設計されています。これにより、相反する取引が同時に実行されることを防ぎ、戦略パフォーマンスの評価を明確に保つことができます。
バタフライEAのコア取引ロジックは次のように実装されています。//--- Strategy 1: Peak if(EnableStrategy1 && prevValue < 2.5 && currValue > 2.5) { if(maFast > maSlow) OpenBuy(); else if(maFast < maSlow) OpenSell(); } //--- Strategy 2: Trough if(EnableStrategy2 && prevValue > -2.5 && currValue < -2.5) { if(maFast > maSlow) OpenBuy(); else if(maFast < maSlow) OpenSell(); }
戦略1(ピーク)
前回のバタフライオシレーターの値が+2.5未満で、今回の値が+2.5を上抜けしたときにシグナルが発生します。
- 高速(短期)MAが低速(長期)MAを上回る場合、上昇トレンドと判断し、買い注文を実行します。
- 高速(短期)MAが低速(長期)MAを下回る場合、下降トレンドと判断し、売り注文を実行します。
戦略2(谷間)
前回のバタフライオシレーターの値が-2.5を上回り、今回の値が-2.5を下抜けしたときにシグナルが発生します。
- 高速(短期)MAが低速(長期)MAを上回る場合、上昇トレンドと判断し、買い注文を出します。
- 高速MAが低速MAを下回って下降トレンドを示している場合は、売り注文を出します。
バタフライオシレーターEAのテスト
EAを個々の取引スタイルやリスク管理ルールに合わせるために、多様な入力パラメータが用意されています。これらの設定はカテゴリごとに整理されており、ユーザーは取引管理、インジケーター挙動、戦略選択を自由に制御できます。

図4:EA入力パラメータ
戦略テストとエントリーシグナルのデモンストレーション
- ステップサイズ:0.3
バタフライEAが生成するエントリーシグナルを示すため、戦略1をステップサイズ0.3でテストしました。
図5は、この設定で生成された買いおよび売りシグナルを示しています。ステップサイズが大きい場合、バタフライオシレーターはより少ないバーでサイクルを完了するため、ピークやボトムに早く到達します。その結果、EAは短期間でより頻繁にエントリーシグナルを生成します。

図5:戦略1(ステップサイズ=0.3)
- ステップサイズ:0.03
次に、ステップサイズ0.03で戦略1におけるバタフライEAの挙動を確認しました。
図6は、この小さいステップサイズで生成された買いおよび売りシグナルを示しています。ステップサイズが小さい場合、バタフライオシレーターは完全なサイクルを完了するのにより多くのバーを必要とします。そのため、ピークやボトムに到達するのが遅くなり、同じ期間で生成されるエントリーシグナルは少なくなります。

図6:戦略1(ステップサイズ=0.03)
この挙動は、ステップサイズが売買シグナルの頻度に直接影響することを示しています。大きいステップサイズでは、オシレーションが速く、取引が増加し、小さいステップサイズでは、オシレーションが遅く滑らかになり、シグナルは少ないがより安定します。
結論
本記事では、バタフライ曲線の概念を用いてオシレーターと取引戦略を構築しました。バタフライオシレーターは、数学的パターンが市場のダイナミクスにどのように適応できるかを示し、価格変動に関するユニークな洞察を提供しました。ステップサイズを変化させることで、オシレーターの滑らかさやシグナルの頻度がどのように変わるか、またこれらの特性が移動平均トレンドと組み合わせた場合の取引エントリーにどのように影響するかを観察しました。
開発したバタフライEAは、オシレーターをエントリー基準としてうまく適用し、ピーク用の戦略とボトム用の戦略という2つの異なる戦略を提供しました。各戦略は、市場の方向性とオシレーターの閾値の両方に応じて動作します。
次回の記事では、さまざまな金融商品でこの概念の強みと弱みを検証する予定です。また、他のオシレーターと組み合わせることで、この新しいオシレーターを使ったエントリー戦略の最適化をさらに試みます。バタフライ取引システムのエントリー戦略の改善点についても解説する予定です。
| ファイル | 説明 |
|---|---|
| ButterflyPlot.mq5 | このスクリプトファイルは、定義された数学関数を使用してアクティブなチャート上にバタフライ曲線を生成および表示します。スクリプトを実行すると、チャート上に曲線が視覚的に描画されます。一度描画されたバタフライ曲線は、チャートテンプレートを変更または更新しない限り、チャート上に残ります。このスクリプトによって生成された曲線は、チャートのテンプレートが変更されるか新しいテンプレートに更新された場合にのみクリアまたは削除できます。 |
| ButterflyOscillator.mq5 | バタフライインジケーターを定義するファイルで、メインの価格チャート下のサブウィンドウに表示されるよう設計されています。 |
| ButterflyOscillatorEA.mq5 | バタフライオシレーターを利用して、自動的に取引ポジションを開閉および管理するEAを定義するファイルです。 |
MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/20113
警告: これらの資料についてのすべての権利はMetaQuotes Ltd.が保有しています。これらの資料の全部または一部の複製や再プリントは禁じられています。
この記事はサイトのユーザーによって執筆されたものであり、著者の個人的な見解を反映しています。MetaQuotes Ltdは、提示された情報の正確性や、記載されているソリューション、戦略、または推奨事項の使用によって生じたいかなる結果についても責任を負いません。
オンチャートUIを使用したリスクベースの取引執行EA(第1回):ユーザーインターフェースの設計
エラー 146 (「トレードコンテキスト ビジー」) と、その対処方法
共和分株式による統計的裁定取引(第7回):スコアリングシステム2
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索