動的取引理論の指数移動平均と累積出来高サイクルクロスオーバー戦略

EMA CVP AVWP TOD
作成日: 2025-01-06 11:45:38 最終変更日: 2025-01-06 11:45:38
コピー: 1 クリック数: 346
1
フォロー
1617
フォロワー

動的取引理論の指数移動平均と累積出来高サイクルクロスオーバー戦略

概要

この戦略は、指数移動平均 (EMA) と累積出来高期間 (CVP) を組み合わせた取引システムです。価格の指数移動平均と累積出来高加重価格のクロスオーバーを分析することで、市場トレンドの転換点を捉えます。この戦略には、取引時間を制限し、取引期間の終了時にポジションを自動的にクローズする機能をサポートする時間フィルターが組み込まれています。この戦略では、リバース クロス エグジットとカスタム CVP エグジットの 2 つの異なるエグジット方法が提供され、より柔軟で適応性の高いものになっています。

戦略原則

戦略のコアロジックは、次の主要な計算に基づいています。

  1. 平均価格 (AVWP) を計算します。最高値、最低値、終値の算術平均に取引量を掛けます。
  2. 累積取引量期間値を計算します。設定期間の取引量加重価格を加算し、累積取引量で割ります。
  3. 終値のEMAとCVPのEMAを別々に計算します。
  4. 価格 EMA が CVP EMA を上向きに交差するとロング シグナルが生成され、価格 EMA が CVP EMA を下向きに交差するとショート シグナルが生成されます。
  5. 終了信号は、逆クロスオーバー信号またはカスタム CVP サイクルに基づくクロスオーバー信号にすることができます。

戦略的優位性

  1. シグナル システムは堅牢で、価格動向と取引量情報を組み合わせて、市場の動向をより正確に判断します。
  2. 強力な適応性: EMA 期間と CVP 期間は、さまざまな市場環境に適応するように調整できます。
  3. 完璧なリスク管理: 組み込みの時間フィルターにより、取引に適さない期間中の操作を回避できます。
  4. 柔軟な終了メカニズム: 2 つの異なる終了方法が提供されており、市場特性に応じて適切な終了方法を選択できます。
  5. 優れた視覚化: この戦略は、シグナル マーカーやトレンド領域の塗りつぶしなど、明確なグラフィカル インターフェイスを提供します。

戦略リスク

  1. ヒステリシスリスク: EMA 自体には一定のヒステリシスがあり、エントリーとエグジットのタイミングに若干の遅れが生じる可能性があります。
  2. 不安定な市場のリスク: 横ばいで不安定な市場では誤ったシグナルが生成される可能性があります。
  3. パラメータの感度: パラメータの組み合わせが異なると、戦略のパフォーマンスに大きな違いが生じる可能性があります。
  4. 流動性リスク: 流動性の低い市場では、CVP 計算の精度が十分でない可能性があります。
  5. タイムゾーン依存性: この戦略では、時間フィルターとしてニューヨーク時間を使用するため、異なる市場の取引時間の違いに注意する必要があります。

戦略最適化の方向性

  1. ボラティリティ フィルターの導入: 戦略パラメータを市場のボラティリティに応じて調整し、戦略の適応性を向上させることができます。
  2. 最適化された時間フィルター: 複数の時間ウィンドウを追加して、取引セッションをより細かく制御できます。
  3. ボリューム品質評価の向上: 低品質のボリューム信号を除外するためのボリューム分析インジケーターを導入します。
  4. 動的パラメータ調整: 市場の状況に応じて EMA および CVP 期間を自動的に調整する適応型パラメータ システムを開発します。
  5. 市場センチメント指標を追加: 他のテクニカル指標と組み合わせて、取引シグナルを確認します。

要約する

これは、完全な構造と明確なロジックを備えた定量的な取引戦略です。 EMAとCVPの利点を組み合わせることで、リスク管理を重視しながらトレンドを捉えることができる取引システムが構築されます。この戦略は高度にカスタマイズ可能で、さまざまな市場環境での使用に適しています。最適化の提案を実装することで、戦略のパフォーマンスをさらに向上させる余地があります。

ストラテジーソースコード
/*backtest
start: 2019-12-23 08:00:00
end: 2025-01-04 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
// © sapphire_edge 

// # ========================================================================= #
// #                  
// #        _____                   __    _              ______    __         
// #      / ___/____ _____  ____  / /_  (_)_______     / ____/___/ /___ ____ 
// #      \__ \/ __ `/ __ \/ __ \/ __ \/ / ___/ _ \   / __/ / __  / __ `/ _ \
// #     ___/ / /_/ / /_/ / /_/ / / / / / /  /  __/  / /___/ /_/ / /_/ /  __/
// #    /____/\__,_/ .___/ .___/_/ /_/_/_/   \___/  /_____/\__,_/\__, /\___/ 
// #              /_/   /_/                                     /____/       
// #                                      
// # ========================================================================= #

strategy(shorttitle="⟡Sapphire⟡ EMA/CVP", title="[Sapphire] EMA/CVP Strategy", initial_capital= 50000, currency= currency.USD,default_qty_value = 1,commission_type= strategy.commission.cash_per_contract,overlay= true )

// # ========================================================================= #
// #                       // Settings Menu //
// # ========================================================================= #

// --------------------    Main Settings    -------------------- //
groupEMACVP = "EMA / Cumulative Volume Period"
tradeDirection = input.string(title='Trade Direction', defval='LONG', options=['LONG', 'SHORT'], group=groupEMACVP)
emaLength = input.int(25, title='EMA Length', minval=1, maxval=200, group=groupEMACVP)
cumulativePeriod = input.int(100, title='Cumulative Volume Period', minval=1, maxval=200, step=5, group=groupEMACVP)
exitType = input.string(title="Exit Type", defval="Crossover", options=["Crossover", "Custom CVP" ], group=groupEMACVP)
cumulativePeriodForClose = input.int(50, title='Cumulative Period for Close Signal', minval=1, maxval=200, step=5, group=groupEMACVP)
showSignals = input.bool(true, title="Show Signals", group=groupEMACVP)
signalOffset = input.int(5, title="Signal Vertical Offset", group=groupEMACVP)

// --------------------    Time Filter Inputs    -------------------- //
groupTimeOfDayFilter = "Time of Day Filter"
useTimeFilter1  = input.bool(false, title="Enable Time Filter 1", group=groupTimeOfDayFilter)
startHour1      = input.int(0, title="Start Hour (24-hour format)", minval=0, maxval=23, group=groupTimeOfDayFilter)
startMinute1    = input.int(0, title="Start Minute", minval=0, maxval=59, group=groupTimeOfDayFilter)
endHour1        = input.int(23, title="End Hour (24-hour format)", minval=0, maxval=23, group=groupTimeOfDayFilter)
endMinute1      = input.int(45, title="End Minute", minval=0, maxval=59, group=groupTimeOfDayFilter)
closeAtEndTimeWindow = input.bool(false, title="Close Trades at End of Time Window", group=groupTimeOfDayFilter)

// --------------------    Trading Window    -------------------- //
isWithinTradingWindow(startHour, startMinute, endHour, endMinute) =>
    nyTime            = timestamp("America/New_York", year, month, dayofmonth, hour, minute)
    nyHour            = hour(nyTime)
    nyMinute          = minute(nyTime)
    timeInMinutes     = nyHour * 60 + nyMinute
    startInMinutes    = startHour * 60 + startMinute
    endInMinutes      = endHour * 60 + endMinute
    timeInMinutes    >= startInMinutes and timeInMinutes <= endInMinutes

timeCondition =  (useTimeFilter1 ? isWithinTradingWindow(startHour1, startMinute1, endHour1, endMinute1) : true)

// Check if the current bar is the last one within the specified time window
isEndOfTimeWindow() =>
    nyTime            = timestamp("America/New_York", year, month, dayofmonth, hour, minute)
    nyHour            = hour(nyTime)
    nyMinute          = minute(nyTime)
    timeInMinutes     = nyHour * 60 + nyMinute
    endInMinutes      = endHour1 * 60 + endMinute1
    timeInMinutes == endInMinutes

// Logic to close trades if the time window ends
if timeCondition and closeAtEndTimeWindow and isEndOfTimeWindow()
    strategy.close_all(comment="Closing trades at end of time window")

// # ========================================================================= #
// #                       // Calculations //
// # ========================================================================= #

avgPrice = (high + low + close) / 3
avgPriceVolume = avgPrice * volume

cumulPriceVolume = math.sum(avgPriceVolume, cumulativePeriod)
cumulVolume = math.sum(volume, cumulativePeriod)
cumValue = cumulPriceVolume / cumulVolume

cumulPriceVolumeClose = math.sum(avgPriceVolume, cumulativePeriodForClose)
cumulVolumeClose = math.sum(volume, cumulativePeriodForClose)
cumValueClose = cumulPriceVolumeClose / cumulVolumeClose

emaVal = ta.ema(close, emaLength)
emaCumValue = ta.ema(cumValue, emaLength)

// # ========================================================================= #
// #                       // Signal Logic //
// # ========================================================================= #

// Strategy Entry Conditions
longEntryCondition = ta.crossover(emaVal, emaCumValue) and tradeDirection == 'LONG'
shortEntryCondition = ta.crossunder(emaVal, emaCumValue) and tradeDirection == 'SHORT'

// User-Defined Exit Conditions
longExitCondition = false
shortExitCondition = false

if exitType == "Crossover"
    longExitCondition := ta.crossunder(emaVal, emaCumValue)
    shortExitCondition := ta.crossover(emaVal, emaCumValue)

if exitType == "Custom CVP"
    emaCumValueClose = ta.ema(cumValueClose, emaLength)
    longExitCondition := ta.crossunder(emaVal, emaCumValueClose)
    shortExitCondition := ta.crossover(emaVal, emaCumValueClose)

// # ========================================================================= #
// #                       // Strategy Management //
// # ========================================================================= #

// Strategy Execution
if longEntryCondition and timeCondition
    strategy.entry('Long', strategy.long)
    label.new(bar_index, high - signalOffset, "◭", style=label.style_label_up, color = color.rgb(119, 0, 255, 20), textcolor=color.white)

if shortEntryCondition and timeCondition
    strategy.entry('Short', strategy.short)
    label.new(bar_index, low + signalOffset, "⧩", style=label.style_label_down, color = color.rgb(255, 85, 0, 20), textcolor=color.white)

if strategy.position_size > 0 and longExitCondition
    strategy.close('Long')

if strategy.position_size < 0 and shortExitCondition
    strategy.close('Short')

// # ========================================================================= #
// #                         // Plots and Charts //
// # ========================================================================= #

plot(emaVal, title='EMA', color=color.new(color.green, 25))
plot(emaCumValue, title='Cumulative EMA', color=color.new(color.purple, 35))
fill(plot(emaVal), plot(emaCumValue), color=emaVal > emaCumValue ? #008ee6 : #d436a285, title='EMA and Cumulative Area', transp=70)