資源の読み込みに... 荷物...

クロスオーバー移動平均値に基づいた適応型予想値評価戦略の傾向

作者: リン・ハーンチャオチャン,日付: 2024-06-17 16:29:02
タグ:SMAエイマ

img

概要

この戦略は,異なる期間の2つの単純な移動平均値のクロスオーバーを使用して,トレンド方向を決定し,トレンドが現れたときに取引を開始する.同時に,この戦略は,異なる時間スケールで戦略の期待回報を計算し,表示するための期待値パネルも導入し,ユーザーが戦略のパフォーマンスをよりよく評価できるようにする.期待値パネルは,戦略の勝利率,平均利益,歴史的期間の平均損失などの主要な指標を考慮し,異なる市場条件下で戦略のパフォーマンスを直感的に提示する.

戦略原則

この戦略の核心は,異なる期間の2つの単純な移動平均値 (この例では14日と28日) のクロスオーバーを使用して市場動向を決定することです.短期平均値が下から長期平均値を超えると,市場は上昇傾向に入ると考えられ,戦略はロングポジションを開きます.逆に,短期平均値が上から長期平均値を下に突破すると,市場は下向き傾向に入ると考えられ,戦略はショートポジションを開きます.この方法で,戦略は異なる市場動向に適応し,トレンドがもたらす利益を捉えるように見えたときにタイミングでポジションを確立することができます.

基本的トレンド決定と取引論理に加えて,戦略は,異なる時間スケール (月間および年次) で戦略の期待回報を計算し表示するための期待値パネルも導入しています.期待値の計算は,歴史的な期間中の戦略の主要な統計指標に基づいています.

  1. WIN RATE: 期間中の収益性の高い取引の比率と取引総数
  2. 平均利益: 期間中のすべての収益性の高い取引の平均利益額
  3. 平均損失: 期間中のすべての失敗する取引の平均損失額

これらの指標を用いて,その期間の戦略の期待値が計算できます. 期待値 = 利益率 × 平均利益 - (1 - 利益率) × 平均損失

グラフに異なる時間間の予想値をヒートマップの形で表示することで,ユーザーは異なる市場条件下で戦略の期待されるパフォーマンスを一目で確認し,戦略の適用性とリスクをよりよく把握できます.

利点分析

  1. トレンドに適応する能力: 動向平均のクロスオーバーを使用してトレンドを決定することで,戦略は市場の変化に適応するために異なる市場のトレンドの下でポジションを適時に調整することができます. これにより,戦略はトレンド市場で良い収益を達成することができます.

  2. 直感的なパフォーマンス評価:内蔵された期待値パネルは,異なる時間帯における戦略の期待回報をヒートマップの形で表示し,ユーザーが異なる市場条件下で戦略のパフォーマンスを一目で評価できるようにします.この視覚化されたパフォーマンスプレゼンテーションは,ユーザーにより多くの意思決定参照を提供します.

  3. 主要な統計指標の考慮: 期待値の計算では,戦略の勝利率だけでなく,平均利益と平均損失の影響を統合します.この計算方法により,戦略の実際のパフォーマンスをより包括的かつ正確に反映し,ユーザーにより信頼できる参照を提供します.

  4. フレキシブルなパラメータ設定:ユーザーは,自分のニーズに応じて,期待値パネルとその透明性を表示するかどうかを柔軟に設定できます. これにより,ユーザーは自分の好みに応じてチャートの表示効果を調整し,ユーザー体験を改善できます.

リスク分析

  1. レンジ・バインド市場での不良業績:戦略は主に利益を生むために動向に依存しているため,レンジ・バインドまたはトレンド不明な市場条件で頻繁な取引は,戦略の全体的な業績に影響を与える重大なスライドと取引コストを引き起こす可能性があります.

  2. 期待値計算の限界: 予想値パネルは戦略の業績を評価するための直感的な方法を提供しているが,計算のために歴史的データに基づいている.市場に大きな変化が発生するか,極端な状況が発生した場合,歴史的なデータは戦略の実際のパフォーマンスを十分に反映していない可能性があり,期待値の基準値は低下する可能性があります.

  3. パラメータ選択の大きな影響: 戦略のパフォーマンスは,移動平均期間の選択に大きく依存する.異なる期間の組み合わせは,まったく異なる取引結果をもたらす可能性があります. 選択されたパラメータが市場の特徴にうまく適応できない場合,戦略の実際のパフォーマンスは期待値から大幅に逸脱する可能性があります.

最適化方向

  1. より多くの技術指標を導入する.既存の移動平均値に基づいて,MACDやRSIなどの他の技術指標を考慮し,トレンドの強さと持続性をより良く決定し,戦略のエントリーとアウトリーのタイミングを改善することができます.

  2. ポジション管理の最適化:現在,戦略は,取引信号が表示されたときに固定ポジションアプローチを採用している.市場変動やトレンド強度などの要因に基づいてポジションを動的に調整することを検討し,リスクをより良く制御し,収益を上げることができる.

  3. ストップ・プロフィートとストップ・ロストメカニズムを追加: 戦略に合理的なストップ・プロフィートとストップ・ロストメカニズムを追加することで,戦略が潜在的な損失を制限しながら,既存の利益を間に合うようにすることができます. これにより,戦略のリスク・報酬比を改善し,さまざまな市場環境で比較的安定したパフォーマンスを維持することができます.

  4. 期待値の計算を最適化: 期待値の計算方法は,取引コストを考慮し,期待値指標の有効性と実用性を向上させるために移動窓を導入するなど,さらに最適化することができる. さらに,他の戦略パフォーマンス評価指標を調査し,ユーザーにより包括的な参照を提供することができる.

概要

この戦略は,移動平均クロスオーバーを使用して市場動向を決定し,トレンドがトレンドによってもたらされた利益を把握しているように見えるときにタイミングでポジションを確立する.同時に,戦略は,異なる時間スケールで戦略の期待回報を表示するための直感的な期待値パネルも導入し,ユーザーにより多くの意思決定参照を提供します. 戦略は範囲限定市場では不良なパフォーマンスを発揮し,期待値の計算には一定の制限があるが,より多くの技術指標を導入し,ポジション管理を最適化し,ストップ・プロフィートとストップ・ロストメカニズムを追加し,その他の措置により,戦略のリスク・リワート比をさらに改善し,変化する市場環境により良く適応できるようにすることができます.


/*backtest
start: 2023-06-11 00:00:00
end: 2024-06-16 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © ir0nantc2

//@version=5
strategy("Expected Value Panel", overlay=true)

// ロングエントリー条件 / Long entry condition
longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
if (longCondition)
    strategy.entry("My Long Entry Id", strategy.long)

// ショートエントリー条件 / Short entry condition
shortCondition = ta.crossunder(ta.sma(close, 14), ta.sma(close, 28))
if (shortCondition)
    strategy.entry("My Short Entry Id", strategy.short)



// ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
// Please copy the code below and paste it into the strategy where you want to display the expected value.
// 以下のコードをコピーして期待値を表示させたいストラテジーに貼り付けて下さい。
// ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

// 表示選択 / Display selection
show_performance = input.bool(true, '期待値ON/OFF (Show Expected Value)', group='Expected Value / ©ir0nantc2')
transparency = input.int(50, '透過度 (Transparency)', minval=0, maxval=100, group='Expected Value / ©ir0nantc2')
prec = 2

// 背景色 / Background color
bg_color(value) =>
    na(value) ? color.new(color.gray, transparency) : value > 0.0 ? color.new(color.green, transparency) :
   value < 0.0 ? color.new(color.red, transparency) :color.new(color.gray, transparency)

// 利益と損失の追跡 / Track profits and losses
var float total_monthly_profit = 0.0
var float total_yearly_profit = 0.0

if show_performance
    new_month = month(time) != month(time[1])
    new_year  = year(time)  != year(time[1])
    cur_month_pnl = 0.0, cur_year_pnl  = 0.0
    eq = strategy.equity
    bar_pnl = eq / eq[1] - 1

    // 月次・年次 期待値 / Monthly & Yearly Expected Value
    cur_month_pnl := new_month ? 0.0 : (1 + cur_month_pnl[1]) * (1 + bar_pnl) - 1 
    cur_year_pnl := new_year ? 0.0 : (1 + cur_year_pnl[1]) * (1 + bar_pnl) - 1  
    
    // 年次および月次期待値を格納 / Store monthly and yearly expected values
    var month_pnl  = array.new_float(), var month_time = array.new_int()
    var year_pnl  = array.new_float(), var year_time = array.new_int()
    
    // 期待値計算の変数 / Variables for expected value calculation
    var month_wins = array.new_int(), var month_losses = array.new_int()
    var month_avg_win = array.new_float(), var month_avg_loss = array.new_float()
    var year_wins = array.new_int(), var year_losses = array.new_int()
    var year_avg_win = array.new_float(), var year_avg_loss = array.new_float()

    // 月次および年次期待値の配列更新 / Update arrays for monthly and yearly expected values
    bool last_computed = false
    if (not na(cur_month_pnl[1]) and (new_month or barstate.islastconfirmedhistory))
        if (last_computed and array.size(month_pnl) > 0)
            array.pop(month_pnl), array.pop(month_time)
            array.pop(month_wins), array.pop(month_losses)
            array.pop(month_avg_win), array.pop(month_avg_loss)

        array.push(month_pnl, cur_month_pnl[1]), array.push(month_time, time[1])
        array.push(month_wins, 0), array.push(month_losses, 0)
        array.push(month_avg_win, 0.0), array.push(month_avg_loss, 0.0)
    
    if (not na(cur_year_pnl[1]) and (new_year or barstate.islastconfirmedhistory))
        if (last_computed and array.size(year_pnl) > 0)
            array.pop(year_pnl), array.pop(year_time)
            array.pop(year_wins), array.pop(year_losses)
            array.pop(year_avg_win), array.pop(year_avg_loss)

        array.push(year_pnl, cur_year_pnl[1]), array.push(year_time, time[1])
        array.push(year_wins, 0), array.push(year_losses, 0)
        array.push(year_avg_win, 0.0), array.push(year_avg_loss, 0.0)

    last_computed := barstate.islastconfirmedhistory ? true : last_computed

    // 勝ち取引と負け取引を追跡 / Track winning and losing trades
    if (strategy.closedtrades > 0 and na(strategy.closedtrades[1]) == false)
        closed_profit = strategy.netprofit - strategy.netprofit[1]
        if closed_profit > 0
            if array.size(month_wins) > 0
                wins = array.get(month_wins, array.size(month_wins) - 1) + 1
                avg_win = (array.get(month_avg_win, array.size(month_avg_win) - 1) * (wins - 1) + closed_profit) / wins
                array.set(month_wins, array.size(month_wins) - 1, wins)
                array.set(month_avg_win, array.size(month_avg_win) - 1, avg_win)
            if array.size(year_wins) > 0
                wins = array.get(year_wins, array.size(year_wins) - 1) + 1
                avg_win = (array.get(year_avg_win, array.size(year_avg_win) - 1) * (wins - 1) + closed_profit) / wins
                array.set(year_wins, array.size(year_wins) - 1, wins)
                array.set(year_avg_win, array.size(year_avg_win) - 1, avg_win)
        else
            if array.size(month_losses) > 0
                losses = array.get(month_losses, array.size(month_losses) - 1) + 1
                avg_loss = (array.get(month_avg_loss, array.size(month_avg_loss) - 1) * (losses - 1) + closed_profit) / losses
                array.set(month_losses, array.size(month_losses) - 1, losses)
                array.set(month_avg_loss, array.size(month_avg_loss) - 1, avg_loss)
            if array.size(year_losses) > 0
                losses = array.get(year_losses, array.size(year_losses) - 1) + 1
                avg_loss = (array.get(year_avg_loss, array.size(year_avg_loss) - 1) * (losses - 1) + closed_profit) / losses
                array.set(year_losses, array.size(year_losses) - 1, losses)
                array.set(year_avg_loss, array.size(year_avg_loss) - 1, avg_loss)

    // 月次テーブル / Monthly table
    var monthly_table = table(na)
    if (barstate.islastconfirmedhistory)
        monthly_table := table.new(position.bottom_right, columns = 14, rows = array.size(year_time) + 1, border_width = 1)
        table.cell(monthly_table, 0,  0, "",     bgcolor = #bbbbbb00)
        table.cell(monthly_table, 1,  0, "Jan",  bgcolor = #bbbbbb)
        table.cell(monthly_table, 2,  0, "Feb",  bgcolor = #bbbbbb)
        table.cell(monthly_table, 3,  0, "Mar",  bgcolor = #bbbbbb)
        table.cell(monthly_table, 4,  0, "Apr",  bgcolor = #bbbbbb)
        table.cell(monthly_table, 5,  0, "May",  bgcolor = #bbbbbb)
        table.cell(monthly_table, 6,  0, "Jun",  bgcolor = #bbbbbb)
        table.cell(monthly_table, 7,  0, "Jul",  bgcolor = #bbbbbb)
        table.cell(monthly_table, 8,  0, "Aug",  bgcolor = #bbbbbb)
        table.cell(monthly_table, 9,  0, "Sep",  bgcolor = #bbbbbb)
        table.cell(monthly_table, 10, 0, "Oct",  bgcolor = #bbbbbb)
        table.cell(monthly_table, 11, 0, "Nov",  bgcolor = #bbbbbb)
        table.cell(monthly_table, 12, 0, "Dec",  bgcolor = #bbbbbb)
        table.cell(monthly_table, 13, 0, "Year", bgcolor = #bbbbbb)
    
        // 年次データの集計 / Collecting yearly data
        var year_total_pnl = array.new_float()
        var year_exp_val = array.new_float()
        
        for yt = 0 to array.size(year_time) - 1
            total_year_wins = 0, total_year_losses = 0
            total_year_avg_win = 0.0, total_year_avg_loss = 0.0
            total_year_pnl = 0.0

            for mt = 1 to 12
                idx = -1
                for j = 0 to array.size(month_time) - 1
                    if year(array.get(month_time, j)) == year(array.get(year_time, yt)) and month(array.get(month_time, j)) == mt
                        idx := j
                        break
                if idx != -1
                    total_year_pnl := total_year_pnl + array.get(month_pnl, idx)
                    total_year_wins := total_year_wins + array.get(month_wins, idx)
                    total_year_losses := total_year_losses + array.get(month_losses, idx)
                    total_year_avg_win := total_year_avg_win + (array.get(month_avg_win, idx) * array.get(month_wins, idx))
                    total_year_avg_loss := total_year_avg_loss + (array.get(month_avg_loss, idx) * array.get(month_losses, idx))
            
            total_year_avg_win := total_year_wins > 0 ? total_year_avg_win / total_year_wins : 0.0
            total_year_avg_loss := total_year_losses > 0 ? total_year_avg_loss / total_year_losses : 0.0
            win_rate = total_year_wins + total_year_losses > 0 ? total_year_wins / (total_year_wins + total_year_losses) : na
            exp_val = win_rate ? (win_rate * total_year_avg_win) - ((1 - win_rate) * math.abs(total_year_avg_loss)) : na
            array.push(year_total_pnl, total_year_pnl)
            array.push(year_exp_val, exp_val)
            
        for yt = 0 to array.size(year_time) - 1
            table.cell(monthly_table, 0,  yt + 1, str.tostring(year(array.get(year_time, yt))), bgcolor = #bbbbbb)
            
            y_color = bg_color(array.get(year_exp_val, yt))
            value_to_display = na(array.get(year_exp_val, yt)) ? "" : str.tostring(math.round(array.get(year_exp_val, yt) * 100, prec))
            table.cell(monthly_table, 13, yt + 1, value_to_display, bgcolor = y_color, text_color=color.new(color.white, 0))
            
        for mt = 0 to array.size(month_time) - 1
            m_row = year(array.get(month_time, mt)) - year(array.get(year_time, 0)) + 1
            m_col = month(array.get(month_time, mt))
            
            if array.size(month_wins) > mt and array.size(month_losses) > mt and array.size(month_avg_win) > mt and array.size(month_avg_loss) > mt
                win_rate = array.get(month_wins, mt) / (array.get(month_wins, mt) + array.get(month_losses, mt))
                exp_val = (win_rate * array.get(month_avg_win, mt)) - ((1 - win_rate) * math.abs(array.get(month_avg_loss, mt)))
                m_color = bg_color(exp_val)
                value_to_display = na(exp_val) ? "" : str.tostring(math.round(exp_val * 100, prec))
                table.cell(monthly_table, m_col, m_row, value_to_display, bgcolor = m_color, text_color=color.new(color.white, 0))
            else
                table.cell(monthly_table, m_col, m_row, "", bgcolor = color.new(color.gray, transparency), text_color=color.new(color.white, 0))
// [EOF]


関連性

もっと