見出し画像

フィボナッチエクスパンションを使ったEA開発3つの極意

みなさん、メリークリスマス🎄 今回はEAにフィボナッチエクスパンションを組み込みたいけれど、具体的な実装方法が分からない…という方に向けて記事を書きました!

実は、フィボナッチエクスパンションの実装は、正しい手順を踏めば決して難しくありません。

フィボナッチエクスパンションの実装に必要な計算式

フィボナッチエクスパンションをシステムに組み込む第一歩は、計算式の理解と実装です。

基本となる計算式は、以下の3つのステップで構成されています。

  • 価格の取得
    始値、高値、安値、終値の時系列データを配列として取得します。特に、トレンドの転換点となる高値・安値の特定が重要です。

  • フィボナッチレベルの算出
    トレンドの転換点から、0%、61.8%、100%、161.8%のレベルを計算します。これらの水準が、次の値動きの目標値となります。

  • 実装のポイント
    計算式をコードに落とし込む際は、小数点以下の端数処理に注意が必要です。有効桁数は銘柄の価格帯に応じて適切に設定しましょう。

//+------------------------------------------------------------------+
//| インディケータの初期化関数                                      |
//+------------------------------------------------------------------+
#property strict

// 入力パラメータ
input int Period = 14; // ピボットポイントの期間
input int Lookback = 100; // 過去何本のローソク足を解析するか

// 結果の記録用
double PivotPointsHigh[];
double PivotPointsLow[];
string TrendDirection[];

//+------------------------------------------------------------------+
//| カスタムインディケータ初期化                                      |
//+------------------------------------------------------------------+
int OnInit()
{
    // バッファのセットアップ
    SetIndexBuffer(0, PivotPointsHigh);
    SetIndexStyle(0, DRAW_ARROW, EMPTY, 2, clrBlue);
    SetIndexArrow(0, 233); // 上矢印

    SetIndexBuffer(1, PivotPointsLow);
    SetIndexStyle(1, DRAW_ARROW, EMPTY, 2, clrRed);
    SetIndexArrow(1, 234); // 下矢印

    ArraySetAsSeries(PivotPointsHigh, true);
    ArraySetAsSeries(PivotPointsLow, true);

    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| インディケータ計算                                                |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
    // データ不足のチェック
    if (rates_total < Period * 2) return 0;

    int start = MathMax(Period, prev_calculated - 1);

    for (int i = start; i < rates_total - Period; i++)
    {
        // 高値のピボット判定
        bool isHighPivot = true;
        for (int j = i - Period; j <= i + Period; j++)
        {
            if (j != i && high[j] > high[i])
            {
                isHighPivot = false;
                break;
            }
        }

        // 安値のピボット判定
        bool isLowPivot = true;
        for (int j = i - Period; j <= i + Period; j++)
        {
            if (j != i && low[j] < low[i])
            {
                isLowPivot = false;
                break;
            }
        }

        // 結果をバッファに格納
        if (isHighPivot)
            PivotPointsHigh[i] = high[i];
        else
            PivotPointsHigh[i] = EMPTY_VALUE;

        if (isLowPivot)
            PivotPointsLow[i] = low[i];
        else
            PivotPointsLow[i] = EMPTY_VALUE;

        // トレンド判定
        if (i >= 2 * Period)
        {
            string trend = DetermineTrend(i);
            TrendDirection[i] = trend;
            Comment("Trend at ", TimeToString(time[i]), ": ", trend);
        }
    }

    return rates_total;
}

//+------------------------------------------------------------------+
//| トレンド判定関数                                                 |
//+------------------------------------------------------------------+
string DetermineTrend(int index)
{
    double currentHigh = PivotPointsHigh[index];
    double prevHigh = PivotPointsHigh[index - Period];
    double prevPrevHigh = PivotPointsHigh[index - 2 * Period];

    double currentLow = PivotPointsLow[index];
    double prevLow = PivotPointsLow[index - Period];
    double prevPrevLow = PivotPointsLow[index - 2 * Period];

    // 上昇トレンド判定
    if (currentHigh > prevHigh && prevHigh > prevPrevHigh)
        return "Uptrend";

    // 下降トレンド判定
    if (currentLow < prevLow && prevLow < prevPrevLow)
        return "Downtrend";

    // 横ばい
    return "Sideways";
}

//+------------------------------------------------------------------+

このコードについて、以下重要なポイントです。

  1. 価格データの構造

    • 時系列データは、タイムスタンプと4本値(始値・高値・安値・終値)を持つオブジェクトの配列として管理します

    • データは時系列順に並んでいることが前提です

  2. 転換点の特定方法

    • 指定された期間(デフォルト14期間)の範囲で、局所的な高値・安値を探します

    • 高値の転換点:その期間内で最も高い価格

    • 安値の転換点:その期間内で最も低い価格

    • これらの点がフィボナッチエクスパンションの計算の基準点となります

  3. トレンドの判定

    • 3つの連続する転換点を使用してトレンドを判定します

    • 上昇トレンド:高値が連続して上昇

    • 下降トレンド:安値が連続して下降

    • 横ばい:明確なトレンドが確認できない場合

  4. 実装上の注意点

    • ノイズを減らすため、適切な期間設定が重要です

    • 価格のボラティリティに応じて、判定期間を調整する必要があります

    • 市場の流動性が低い時間帯のデータは、誤った転換点を生む可能性があるため注意が必要です

バックテストで検証すべき3つの重要ポイント

システムの信頼性を高めるために、以下の3つの観点でバックテストを行います。

  • フィボナッチレベルのヒット率
    各レベルに対する価格の到達確率を検証します。特に161.8%レベルは、利益確定の重要な指標となります。

  • トレンド環境での成功率
    上昇トレンド・下降トレンドそれぞれの環境で、システムの有効性を確認します。相場環境ごとの勝率の違いを把握することで、より適切な運用が可能になりました。

  • 誤シグナルの検証
    レンジ相場での誤シグナルを排除するため、トレンド判定の閾値を適切に設定します。ATRなどのボラティリティ指標との組み合わせが効果的でした。

システムの最適化テクニック

システムの性能を最大限に引き出すために、以下の3つの最適化を行います。

  • パラメータの最適化
    フィボナッチレベルの判定幅や、トレンド判定の期間など、重要なパラメータを最適化します。過去データで検証した結果、判定幅は価格帯の0.1%程度が最も安定していました。

  • 動的パラメータ調整
    相場のボラティリティに応じて、パラメータを動的に調整する仕組みを導入します。市場環境の変化に柔軟に対応することで、システムの安定性が向上します。

  • リスク管理の実装
    1トレードあたりの損失を一定範囲に抑えるストップロス設定や、ポジションサイズの自動調整機能を実装します。これにより、長期的な収益の安定性が確保できました。

まとめ

フィボナッチエクスパンションをシステムトレードに実装する際は、計算式の正確な実装、綿密なバックテスト、そして適切な最適化が重要です。

これらのステップを丁寧に踏むことで、より精度の高いトレードシステムを構築できるはずです。


ブログランキングに参加中です🐣

こちらを押して応援していただけると嬉しいです🩵

筆者のおすすめ

以下は、筆者がおすすめする取引サービスです。
※アフィリエイトリンクではありません。

取引ツール
インジケーターなどおすすめ取引ツールです。

アフィリエイト
筆者おすすめのFXアフィリエイトです。


いいなと思ったら応援しよう!