二重指数関数移動平均トレンド 戦略に従う

作者: リン・ハーンチャオチャン,日付: 2024-02-02 17:11:29
タグ:

img

概要

ダブル指数関数移動平均トレンドフォロー戦略は,指数関数移動平均 (EMA) のクロスオーバーに基づくトレンドフォロー戦略である. 急速EMA線と遅いEMA線を計算して現在のトレンド方向を判断し,そのクロスオーバーに作用する. 急速EMA線が遅いEMA線を越えると,それは上昇信号として決定される. 急速EMA線が遅いEMA線を下回ると,それは下落信号として決定される. 特定されたトレンド方向に基づいて,この戦略はそれに応じて長行または短行することができます.

戦略の論理

この戦略の主な論理は,異なる期間の2つのEMAラインを計算することにある.一つは下落線として,もう一つは上昇線として機能する.具体的には,この戦略は,タリブ指標を使用して8期間の速いEMAラインを上昇線として計算する.そして21期間の遅いEMAラインを上昇線として計算する.その後,速いEMAラインと遅いEMAラインの間のクロスオーバー関係を判断する.速いラインがスローラインを超えると,それは長くなることを決定する.速いラインがスローラインを下回ると,それは短くなることを決定する.

実際の取引実行に関しては,この戦略は,高速線と遅い線の間にクロスオーバーが起こる場合,ロングのみ,ショートのみ,または両方向に行うことができます.また,ストップ・ロストとテイク・プロフィート価格が戦略で構成されています.ポジションを開設した後,価格が不利な方向に進んだ場合,ストップ・ロスは出口ポジションに触発されます.価格が期待される目標レベルに達した場合,テイク・プロフィートは実現し,ポジションを閉じます.

利点分析

ダブルEMAトレンドフォロー戦略の最大の利点は,移動平均クロスオーバーの強力なトレンド識別能力にある.トレンド分析のための一般的なツールとして,EMA線はクロスオーバーを通じてトレンドシフトとターニングポイントを特定し,短期的に市場の騒音に惑わされないようにし,主要なトレンド方向を把握することができます.

また,トレード方向の柔軟な設定により,戦略は一方的なトレンドと双方向の振動の両方に適応可能になり,戦略の適用性を高めます.設定されたストップ・ロストとテイク・プロフィートはリスクを制御し,部分利益をロックします.

リスク分析

この戦略の最大のリスクは,レンジ・バインド市場における頻繁な小さなクロスオーバーによって引き起こされる偽信号です.これは過剰なポジション開設と損失につながるでしょう.これに対処するために,クロスオーバー時間と偽信号の確率を減らすためにEMA期間を増加させることができます.

ストップ・ロスの設定が狭すぎると ストップ・アウトされる可能性も高まります.この場合は,ストップ・ロスの範囲を拡大し, 閉じ込められるリスクを慎重にバランスする必要があります.

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

この戦略は,次の側面でさらに最適化できます.

  1. 市場変動とバックテストの結果に基づいてEMA期間の適応調整,固定期間のオーバーフィットメントを回避する.

  2. 偽の信号をフィルタリングするためにフィルター条件を追加する.例えば,無意味なクロスオーバーをフィルタリングするために取引量と組み合わせる.または不確実性の信号を避けるためにMACDとKDJなどの他の指標を組み合わせる.

  3. ストップ・ロスの戦略を最適化し,利益を取ること,例えばATRを組み合わせてSL/TPのダイナミック・トラッキングを実現し,SLが過剰に緊迫し,TPが早すぎるのを防ぎます.

  4. 異なる保有期間をテストする. 持久期間が長すぎると事故の影響を受け,持久期間が短すぎると取引コストが高くなり,スライプコストが高くなります.最適な保持日を発見することで戦略の収益性が向上します.

概要

一般的には,ダブルEMAトレンドフォロー戦略は,堅牢で実用的なトレンドトレーディングシステムである.EMAクロスオーバーシステムを通じてトレンド方向を効果的に捕捉する.一方,トレード方向の柔軟な設定により適応性が高く,ストップ・ロスト・アンド・テイク・プロフィート・コントロールリスクが設定されている.さらなる最適化と強化により,この戦略は定量取引のための強力なツールになることができる.


/*backtest
start: 2024-01-02 00:00:00
end: 2024-02-01 00:00:00
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © TradersPostInc

//@version=5
strategy('TradersPost Example MOMO Strategy', overlay=true, default_qty_value=100, initial_capital=100000, default_qty_type=strategy.percent_of_equity, pyramiding=0)

startTime = input(defval = timestamp('01 Jan 2021 00:00 +0000'), title = 'Start Time', group = 'Date Range')
endTime = input(defval = timestamp('31 Dec 2023 23:59 +0000'), title = 'End Time', group = 'Date Range')
timeCondition = true
timeConditionEnd = timeCondition[1] and not timeCondition

fastEmaLength = input.int(defval = 8, title = 'Fast EMA Length')
slowEmaLength = input.int(defval = 21, title = 'Slow EMA Length')
sides = input.string(defval = 'Both', title = 'Sides', options = ['Long', 'Short', 'Both', 'None'])

fastEma = ta.ema(close, fastEmaLength)
slowEma = ta.ema(close, slowEmaLength)

isUptrend = fastEma >= slowEma
isDowntrend = fastEma <= slowEma
trendChanging = ta.cross(fastEma, slowEma)

ema105 = request.security(syminfo.tickerid, '30', ta.ema(close, 105)[1], barmerge.gaps_off, barmerge.lookahead_on)
ema205 = request.security(syminfo.tickerid, '30', ta.ema(close, 20)[1], barmerge.gaps_off, barmerge.lookahead_on)
plot(ema105, linewidth=4, color=color.new(color.purple, 0), editable=true)
plot(ema205, linewidth=2, color=color.new(color.purple, 0), editable=true)

aa = plot(fastEma, linewidth=3, color=color.new(color.green, 0), editable=true)
bb = plot(slowEma, linewidth=3, color=color.new(color.red, 0), editable=true)
fill(aa, bb, color=isUptrend ? color.green : color.red, transp=90)

tradersPostBuy = trendChanging and isUptrend and timeCondition
tradersPostSell = trendChanging and isDowntrend and timeCondition

pips = syminfo.pointvalue / syminfo.mintick

percentOrPipsInput = input.string('Percent', title='Percent or Pips', options=['Percent', 'Pips'])

stopLossLongInput = input.float(defval=0, step=0.01, title='Stop Loss Long', minval=0)
stopLossShortInput = input.float(defval=0, step=0.01, title='Stop Loss Short', minval=0)

takeProfitLongInput = input.float(defval=0, step=0.01, title='Target Profit Long', minval=0)
takeProfitShortInput = input.float(defval=0, step=0.01, title='Target Profit Short', minval=0)

stopLossPriceLong = ta.valuewhen(tradersPostBuy, close, 0) * (stopLossLongInput / 100) * pips
stopLossPriceShort = ta.valuewhen(tradersPostSell, close, 0) * (stopLossShortInput / 100) * pips

takeProfitPriceLong = ta.valuewhen(tradersPostBuy, close, 0) * (takeProfitLongInput / 100) * pips
takeProfitPriceShort = ta.valuewhen(tradersPostSell, close, 0) * (takeProfitShortInput / 100) * pips

takeProfitALong = takeProfitLongInput > 0 ? takeProfitLongInput : na
takeProfitBLong = takeProfitPriceLong > 0 ? takeProfitPriceLong : na

takeProfitAShort = takeProfitShortInput > 0 ? takeProfitShortInput : na
takeProfitBShort = takeProfitPriceShort > 0 ? takeProfitPriceShort : na

stopLossALong = stopLossLongInput > 0 ? stopLossLongInput : na
stopLossBLong = stopLossPriceLong > 0 ? stopLossPriceLong : na

stopLossAShort = stopLossShortInput > 0 ? stopLossShortInput : na
stopLossBShort = stopLossPriceShort > 0 ? stopLossPriceShort : na

takeProfitLong = percentOrPipsInput == 'Pips' ? takeProfitALong : takeProfitBLong
stopLossLong = percentOrPipsInput == 'Pips' ? stopLossALong : stopLossBLong
takeProfitShort = percentOrPipsInput == 'Pips' ? takeProfitAShort : takeProfitBShort
stopLossShort = percentOrPipsInput == 'Pips' ? stopLossAShort : stopLossBShort

buyAlertMessage = '{"ticker": "' + syminfo.ticker + '", "action": "buy", "price": ' + str.tostring(close) + '}'
sellAlertMessage = '{"ticker": "' + syminfo.ticker + '", "action": "sell", "price": ' + str.tostring(close) + '}'

exitLongAlertMessage = '{"ticker": "' + syminfo.ticker + '", "action": "exit", "price": ' + str.tostring(close) + '}'
exitShortAlertMessage = '{"ticker": "' + syminfo.ticker + '", "action": "exit", "price": ' + str.tostring(close) + '}'

if (sides != "None")
    if tradersPostBuy
        strategy.entry('Long', strategy.long, when = sides != 'Short', alert_message = buyAlertMessage)
        strategy.close('Short', when = sides == "Short" and timeCondition, alert_message = exitShortAlertMessage)

    if tradersPostSell
        strategy.entry('Short', strategy.short, when = sides != 'Long', alert_message = sellAlertMessage)
        strategy.close('Long', when = sides == 'Long', alert_message = exitLongAlertMessage)

exitAlertMessage = '{"ticker": "' + syminfo.ticker + '", "action": "exit"}'

strategy.exit('Exit Long', from_entry = "Long", profit = takeProfitLong, loss = stopLossLong, alert_message = exitAlertMessage)
strategy.exit('Exit Short', from_entry = "Short", profit = takeProfitShort, loss = stopLossShort, alert_message = exitAlertMessage)

strategy.close_all(when = timeConditionEnd)

もっと