EMAのクロスADR戦略 - 厳格なリスク管理を伴う多次元的な技術指標に基づく取引方法

作者: リン・ハーンチャオチャン, 日付: 2024-03-28 16:46:29
タグ:

img

概要

EMAクロスADR戦略は,TradingViewプラットフォームをベースとした定量的な取引戦略である.トレンドを決定し,フィルタ信号をフィルターし,ストップ・ロストとテイク・プロフィートレベルを設定するために複数の技術指標を組み合わせ,主要トレンドを特定するために異なる期間の2つの指数関数移動平均 (EMA) を採用し,波動性フィルターとして平均日間範囲 (ADR) を使用し,リスク・リターン比率に基づいてストップ・ロストとテイク・プロフィートレベルを動的に設定する.また,戦略には,取引時間窓,ブレイク・イブンストップ,最大日間の損失制限などのリスク管理措置が含まれ,ダウンサイドリスクを厳格に制御しながらトレンド機会を把握することを目的としている.

戦略の原則

  1. ダブルEMAクロスオーバー: この戦略は,トレンドを決定するために異なる期間の2つのEMAを使用する.短期EMAが長期EMAを超越したとき,それは上昇傾向とみなされ,長い信号を生成する.逆に,短期EMAが長期EMAを下回るとき,それは下降傾向とみなされ,短い信号を生成する.

  2. ADR波動性フィルター:低波動性環境で取引信号を生成しないために,戦略は波動性フィルターとしてADR指標を導入する.ADR値が事前に設定された最低限値を超えるとのみポジションを開設することが許される.

  3. トレーディングタイムウィンドウ:この戦略は,ユーザーが日々の取引の開始および終了時間を設定できるようにします.取引は指定された時間ウィンドウ内でのみ実行され,不流動または非常に不安定な期間を避けるのに役立ちます.

  4. ダイナミックストップ・ロスとテイク・プロフィート:この戦略は,先行設定されたリスク・リターン比と組み合わせて,最新のNキャンドルストイックの平均最高値と最低値に基づいて,ストップ・ロスとテイク・プロフィートの価格を動的に計算します. これにより,各取引のリスク・リターンは制御可能になります.

  5. ブレイク・イブンストップ:ポジションが一定の利益レベル (ユーザーによって定義されたリスク・リターン比率) に達すると,ストップ・ロスはブレイク・イブンポイント (エントリー価格) に移動します.これは既に稼いだ利益を保護するのに役立ちます.

  6. 最大日々の損失制限: 1 日あたりの最大損失を制御するために,戦略は日々の損失制限を設定します.日々の損失がこの制限に達すると,戦略は次の日の開業まで取引を停止します.

  7. 日末にすべてのポジションを閉じる: ポジションがメリットを取るかストップ・ロスを取るかに関わらず,戦略は毎日の取引日 (例えば16:00) の固定時間 (固定時間) にすべてのポジションを閉じる.

利点分析

  1. 強いトレンドフォロー能力:トレンドを決定するために二重EMAクロスオーバーを使用することで,戦略は主要な市場トレンドを効果的に把握し,それによって勝利率と利益の可能性を向上させることができます.

  2. 変動に適した適応性:ADR指標を変動フィルターとして導入することで,変動が低い環境での頻繁な取引を回避し,無効信号や誤ったブレイクによる損失を減らすことができます.

  3. 厳格なリスク管理: 戦略は,ダイナミックストップ・ロストとテイク・プロフィート,ブレイク・イブン・ストップ,最大日当たりの損失制限を含む複数の次元からリスク管理措置を設定し,ダウンサイドリスクを効果的に制御し,リスク調整収益を向上させる.

  4. 柔軟なパラメータ設定: EMA期間,ADR長さ,リスク・リターン比,取引時間窓など,戦略のパフォーマンスを最適化するために,ユーザーの好みや市場特性に合わせて,戦略のさまざまなパラメータを柔軟に設定できます.

  5. 高度な自動化: 戦略はTradingViewプラットフォームに基づい,取引論理は完全にプログラムによって実行され,人間の感情と主観的な判断の干渉を軽減し,戦略の長期的安定な運用を促進します.

リスク分析

  1. パラメータ最適化リスク: 戦略のパラメータは柔軟に調整できるが,過剰な最適化は過剰なフィットメントとサンプル外でのパフォーマンスが低下する可能性があります. したがって,パラメータを設定する際に,戦略の堅牢性を確保するために十分なバックテストと分析が必要です.

  2. 突発的な出来事のリスク: 戦略は主に技術指標に基づいて取引され,政策の変化や経済データの大幅な変動などの突発的な主要な根本的な出来事に対して十分に反応しない可能性があります.

  3. トレンド逆転リスク: トレンド逆転の重要な期間中,ダブルEMAクロスオーバー信号が遅れて,戦略がポジションを確立するための最適なタイミングを逃したり,トレンド逆転の開始時に損失を被る可能性があります.

  4. 流動性リスク: 戦略は取引期間を設定しているが,取引される商品の流動性が低い場合,戦略の業績に影響を与えるスライドや取引遅延などのリスクに直面する可能性がある.

  5. 技術指標の失敗リスク:戦略は技術指標に大きく依存する.市場状況が大きく変化し,指標が元の意味を失ってしまう場合,戦略の有効性は低下する可能性があります.

オプティマイゼーションの方向性

  1. より多次元的な指標を導入する.既存の二重EMAとADRに基づいて,より効果的な技術指標,MACDとRSIを導入することを検討し,信号の信頼性と強度を向上させる.

  2. ダイナミックパラメータ最適化: 市場の変化に適応するために,異なる市場状態 (トレンドや振動など) に基づいて,主要な戦略パラメータを動的に調整するパラメータ最適化メカニズムを確立する.

  3. 基本的要素を組み込む: 経済データや政策の方向性などの重要な基本的指標を適切に考慮し,市場動向をよりよく把握し,システムリスクを間に合うようにする戦略を支援する.

  4. ストップ・ロストとテイク・プロフィートのメカニズムを改善する: ストップ・ロストとテイク・プロフィートの論理を,既存のダイナミックなストップ・ロストとテイク・プロフィートの基礎でさらに最適化し,利益をより良く保護し,リスクを制御するために,トラッキング・ストップと部分的なテイク・プロフィートを導入する.

  5. 複数の取引手段と時間枠: 戦略を複数の取引手段と時間枠に拡張し,投資の多様化と時間枠の最適化によって戦略の適応性と安定性を向上させる.

概要

EMAクロスADR戦略は,技術分析に基づく定量的な取引戦略である. 双 EMAクロスオーバーを通じてトレンドを決定し,波動性フィルタリングのためにADR指標を使用する. 戦略はまた,動的ストップ損失とテイク・プロフィート,ブレイク・イブンストップ,最大日損失制限を含む厳格なリスク管理措置を設定し,ダウンサイドリスクを制御する. 戦略の利点は,傾向を追跡する能力,良質な波動性適応性,厳格なリスク制御,柔軟なパラメータ設定,および高度な自動化にある. しかし,パラメータ最適化リスク,突然のイベントリスク,トレンド逆転リスク,流動性リスク,技術指標失敗リスクなどのいくつかのリスクもあります. 将来,戦略は,より実用的な指標を導入し,動的最適化,基本的なリスクと利益の要素を組み込み,ストップ損失のメカニズムを拡張し,取引モデルに適正に適正に調整することができます. 戦略の全体的な利益と利益の拡大は,EMAの独自の戦略に適しています. 戦略は,取引モデルに適正に適正


/*backtest
start: 2024-02-26 00:00:00
end: 2024-03-27 00:00:00
period: 2h
basePeriod: 15m
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/
// © Sameh_Hussein

//@version=5
strategy('EMA Cross ADR Strategy with Stats', overlay=true)

// Adjustable Parameters
shortEmaLength = input(10, title='Short EMA Length')
longEmaLength = input(50, title='Long EMA Length')
adrLength = input(14, title='ADR Length')
riskRewardRatio = input(2.0, title='Risk/Reward Ratio')
lookbackCandles = input(10, title='Lookback Candles for Stop Loss')
startTime = input(0900, title='Start Time')
endTime = input(1600, title='End Time')
minAdrValue = input(10, title='Minimum ADR Value for Entry')
breakEvenProfit = input.float(1.0, title='Break-Even Profit', minval=0.0)
breakEvenRR = input.float(1.0, title='Break-Even Risk-Reward Ratio', minval=0.0)
dailyLossLimit = input(-2000.0, title='Daily Loss Limit')

// Exponential Moving Averages
shortEma = ta.ema(close, shortEmaLength)
longEma = ta.ema(close, longEmaLength)

// Average Daily Range
adr = ta.sma(ta.tr, adrLength)

// Time Filter Function
timeFilter() => true

// Entry Conditions with ADR filter
longCondition = ta.crossover(shortEma, longEma) and timeFilter() and adr > minAdrValue
shortCondition = ta.crossunder(shortEma, longEma) and timeFilter() and adr > minAdrValue

// Calculate the average low and average high of the previous 'lookbackCandles' candles
averageLow = ta.sma(low, lookbackCandles)
averageHigh = ta.sma(high, lookbackCandles)

// Risk and Reward Calculation
stopLossLong = averageLow
takeProfitLong = close + (close - averageLow) * riskRewardRatio
stopLossShort = averageHigh
takeProfitShort = close - (averageHigh - close) * riskRewardRatio

// Entry Control Variables
var longEntryAllowed = true
var shortEntryAllowed = true

// Update entry price on trade execution
var float entryPriceLong = na
var float entryPriceShort = na

if (strategy.position_size > 0)
    if (strategy.position_size[1] <= 0)
        entryPriceLong := strategy.opentrades.entry_price(strategy.opentrades - 1)
    else
        entryPriceLong := entryPriceLong
else
    entryPriceLong := na

if (strategy.position_size < 0)
    if (strategy.position_size[1] >= 0)
        entryPriceShort := strategy.opentrades.entry_price(strategy.opentrades - 1)
    else
        entryPriceShort := entryPriceShort
else
    entryPriceShort := na

// Adjust stop loss to break-even plus the defined profit when the specified risk-reward ratio is reached
breakEvenTriggerLong = entryPriceLong + (entryPriceLong - stopLossLong) * breakEvenRR
breakEvenTriggerShort = entryPriceShort - (stopLossShort - entryPriceShort) * breakEvenRR

if (longEntryAllowed and close >= breakEvenTriggerLong)
    stopLossLong := entryPriceLong + breakEvenProfit

if (shortEntryAllowed and close <= breakEvenTriggerShort)
    stopLossShort := entryPriceShort - breakEvenProfit

// Close all trades at 1600
if (hour == 15 and minute == 59)
    strategy.close_all(comment='Close at 1600')

// Define the daily loss variable and last trade day
var float[] dailyLossArray = array.new_float(1, 0.0)
var int[] lastTradeDayArray = array.new_int(1, na)

// Function to update the daily loss
updateDailyLoss() =>
    _dailyLoss = array.get(dailyLossArray, 0)
    _lastTradeDay = array.get(lastTradeDayArray, 0)
    if na(_lastTradeDay) or dayofmonth != _lastTradeDay
        _dailyLoss := 0.0
        array.set(lastTradeDayArray, 0, dayofmonth)
    if not na(strategy.closedtrades.entry_bar_index(strategy.closedtrades - 1))
        _dailyLoss += strategy.closedtrades.profit(strategy.closedtrades - 1)
    array.set(dailyLossArray, 0, _dailyLoss)

// Call the function to update the daily loss
updateDailyLoss()

// Execute Strategy
if longCondition and longEntryAllowed
    strategy.entry('Long', strategy.long)
    strategy.exit('Take Profit/Stop Loss', 'Long', stop=stopLossLong, limit=takeProfitLong)
    longEntryAllowed := false

if shortCondition and shortEntryAllowed
    strategy.entry('Short', strategy.short)
    strategy.exit('Take Profit/Stop Loss', 'Short', stop=stopLossShort, limit=takeProfitShort)
    shortEntryAllowed := false

// Reset entry control variables on position close
if strategy.position_size == 0
    longEntryAllowed := true
    shortEntryAllowed := true

// // Statistics
// winRate = strategy.wintrades / strategy.closedtrades * 100
// totalTrades = strategy.closedtrades
// averageProfit = strategy.grossprofit / strategy.wintrades
// averageLoss = strategy.grossloss / strategy.losstrades

// // Plotting
// plot(shortEma, color=color.new(color.red, 0), title='Short EMA')
// plot(longEma, color=color.new(color.blue, 0), title='Long EMA')

// // Display Table
// table statsTable = table.new(position=position.top_right, columns=2, rows=4, bgcolor=color.gray, border_width=1)
// table.cell(statsTable, column=0, row=0, text='Win Rate (%)', bgcolor=color.blue)
// table.cell(statsTable, column=1, row=0, text=str.tostring(winRate), bgcolor=color.blue)
// table.cell(statsTable, column=0, row=1, text='Total Trades', bgcolor=color.blue)
// table.cell(statsTable, column=1, row=1, text=str.tostring(totalTrades), bgcolor=color.blue)
// table.cell(statsTable, column=0, row=2, text='Average Profit', bgcolor=color.blue)
// table.cell(statsTable, column=1, row=2, text=str.tostring(averageProfit), bgcolor=color.blue)
// table.cell(statsTable, column=0, row=3, text='Average Loss', bgcolor=color.blue)
// table.cell(statsTable, column=1, row=3, text=str.tostring(averageLoss), bgcolor=color.blue)


もっと