逆転捕獲戦略

作者: リン・ハーンチャオチャン,日付: 2023-11-24 16:43:25
タグ:

img

概要

リバース・キャッチャー戦略は,波動性指標ボリンジャーバンドとモメント指標RSIを利用したリバース・トレーディング戦略である.トレンド方向の変化時に逆転機会を見つけるために,ボリンジャーバンドチャネルとRSIオーバーバイト/オーバーセールドラインをシグナルとして設定する.

戦略の論理

この戦略は,主要技術指標としてボリンジャー帯を使用し,RSIおよび他のモメント指標と組み合わせて取引信号を確認します. 具体的な論理は:

  1. 長期または短期のポジションを決定するために主要なトレンド方向を判断します.トレンドを決定するために50日間のEMAと21日間のEMAの黄金十字/死十字を使用します.
  2. ダウントレンドでは,価格がボリンジャー・ローナー・バンドを突破し,RSIが過売れ地域から反発し,黄金十字を形成すると,過売れエリアが既に底を下り,購入信号を与えることを示します.
  3. 上昇傾向では,価格がボリンジャー上部帯を下回り,RSIが過買いエリアから戻り,死十字を形成すると,過買いエリアが引き下げ始めると示し,売り信号を出す.
  4. 上記の買いと売るシグナルは,偽のシグナルを避けるために同時に起動する必要があります.

利点分析

この戦略の利点は以下の通りである.

  1. 波動性と勢力の指標を組み合わせることで 信号はより信頼性が高まります
  2. リバース取引はリスクが低く,短期取引に適しています.
  3. トレーディングルールは自動取引のためにプログラムできます
  4. トレンドトレードと組み合わせると,市場の整合中に混乱が起こるのを避ける.

リスク分析

この戦略のリスクには以下のものがある:

  1. ボリンジャー・バンドは誤った信号のリスクを突破し RSIフィルターが必要です
  2. 失敗した逆転リスクは,間に合うストップ損失が必要です.
  3. タイムリングの逆転リスクは 早く入るかもしれないし 最適なエントリーポイントを逃すかもしれない

リスクをコントロールするために ストップ・ロスのレベルを設定し リスクの曝露を制限し ボリンジャー・バンド・ピリオドや RSI のようなパラメータを最適化して システムのパフォーマンスを向上させることができます

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

主な最適化方向は以下の通りである.

  1. ボリンジャー・バンドのパラメータを最適化し 期間の長さと標準偏差を調整して 最適な設定を見つけます
  2. トレンド判断のための最適な期間を決定するために移動平均の期間を最適化します.
  3. RSIのパラメータを調整して 最良の超買/超売範囲を把握します
  4. KDJ,MACDなどの指標を追加して 参入シグナルを多様化します
  5. 機械学習モデルを導入して最適化されたパラメータを見つけます

結論

リバース・キャッチャー戦略は,全体として効果的な短期取引戦略である.トレンドフィルタリングとリバース・シグナルを組み合わせることで,市場の統合中に誤った信号を回避し,トレンドと戦うことを避けることができる.継続的なパラメータとモデル最適化により,より良い戦略パフォーマンスを達成することができる.


/*backtest
start: 2023-10-24 00:00:00
end: 2023-11-23 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This is an Open source work. Please do acknowledge in case you want to reuse whole or part of this code.
// Please see the documentation to know the details about this.

//@version=5
strategy('Strategy:Reversal-Catcher', shorttitle="Reversal-Catcher", overlay=true , currency=currency.NONE, initial_capital=100000)

// Inputs
src = input(close, title="Source (close, high, low, open etc.")

BBlength = input.int(defval=20, minval=1,title="Bollinger Period Length, default 20")
BBmult = input.float(defval=1.5, minval=1.0, maxval=4, step=0.1, title="Bollinger Bands Standard Deviation, default is 1.5")

fastMovingAvg = input.int(defval=21, minval=5,title="Fast Exponential Moving Average, default 21", group = "Trends")
slowMovingAvg = input.int(defval=50, minval=8,title="Slow Exponential Moving Average, default 50", group = "Trends")

rsiLenght = input.int(defval=14, title="RSI Lenght, default 14", group = "Momentum")
overbought = input.int(defval=70, title="Overbought limit (RSI), default 70", group = "Momentum")
oversold = input.int(defval=30, title="Oversold limit (RSI), default 30", group = "Momentum")

hide = input.bool(defval=true, title="Hide all plots and legends from the chart (default: true)")


// Trade related
tradeType = input.string(defval='Both', group="Trade settings", title="Trade Type", options=['Both', 'TrendFollowing', 'Reversal'], tooltip="Consider all types of trades? Or only Trend Following or only Reversal? (default: Both).")
endOfDay = input.int(defval=1500, title="Close all trades, default is 3:00 PM, 1500 hours (integer)", group="Trade settings")
mktAlwaysOn = input.bool(defval=false, title="Markets that never closed (Crypto, Forex, Commodity)", tooltip="Some markers never closes. For those cases, make this checked. (Default: off)", group="Trade settings")


// Utils
annotatePlots(txt, val, hide) => 
    if (not hide)
        var l1 = label.new(bar_index, val, txt, style=label.style_label_left, size = size.tiny, textcolor = color.white, tooltip = txt)
        label.set_xy(l1, bar_index, val)

/////////////////////////////// Indicators /////////////////////
vwap = ta.vwap(src)
plot(hide ? na : vwap, color=color.purple, title="VWAP", style = plot.style_line)
annotatePlots('VWAP', vwap, hide)

// Bollinger Band of present time frame
[BBbasis, BBupper, BBlower] = ta.bb(src, BBlength, BBmult)
p1 = plot(hide ? na : BBupper, color=color.blue,title="Bollinger Bands Upper Line")
p2 = plot(hide ? na : BBlower, color=color.blue,title="Bollinger Bands Lower Line")
p3 = plot(hide ? na : BBbasis, color=color.maroon,title="Bollinger Bands Width", style=plot.style_circles, linewidth = 1)
annotatePlots('BB-Upper', BBupper, hide)
annotatePlots('BB-Lower', BBlower, hide)
annotatePlots('BB-Base(20-SMA)', BBbasis, hide)

// RSI
rsi = ta.rsi(src, rsiLenght)

// Trend following
ema50 = ta.ema(src, slowMovingAvg)
ema21 = ta.ema(src, fastMovingAvg)
annotatePlots('21-EMA', ema21, hide)
annotatePlots('50-EMA', ema50, hide)


// Trend conditions
upTrend = ema21 > ema50 
downTrend = ema21 < ema50


// Condition to check Special Entry: HH_LL
// Long side:
hhLLong = barstate.isconfirmed and (low > low[1]) and (high > high[1]) and (close > high[1])
hhLLShort = barstate.isconfirmed and (low < low[1]) and (high < high[1]) and (close < low[1])

longCond =  barstate.isconfirmed and (high[1] < BBlower[1]) and (close > BBlower) and (close < BBupper) and hhLLong and ta.crossover(rsi, oversold) and downTrend
shortCond = barstate.isconfirmed and (low[1] > BBupper[1]) and (close < BBupper) and (close > BBlower) and hhLLShort and ta.crossunder(rsi, overbought) and upTrend

// Trade execute
h = hour(time('1'), syminfo.timezone)
m = minute(time('1'), syminfo.timezone)
hourVal = h * 100 + m
totalTrades = strategy.opentrades + strategy.closedtrades
if (mktAlwaysOn or (hourVal < endOfDay))
    // Entry
    var float sl = na
    var float target = na
    if (longCond)
        strategy.entry("enter long", strategy.long, 1, limit=na, stop=na, comment="Long[E]")
        sl := low[1]
        target := high >= BBbasis ? BBupper : BBbasis
        alert('Buy:' + syminfo.ticker + ' ,SL:' + str.tostring(math.floor(sl)) + ', Target:' + str.tostring(target), alert.freq_once_per_bar)
    if (shortCond)
        strategy.entry("enter short", strategy.short, 1, limit=na, stop=na, comment="Short[E]")
        sl := high[1]
        target := low <= BBbasis ? BBlower : BBbasis
        alert('Sell:' + syminfo.ticker + ' ,SL:' + str.tostring(math.floor(sl)) + ', Target:' + str.tostring(target), alert.freq_once_per_bar)

    // Exit: target or SL
    if ((close >= target) or (close <= sl))
        strategy.close("enter long", comment=close < sl ? "Long[SL]" : "Long[T]")
    if ((close <= target) or (close >= sl))
        strategy.close("enter short", comment=close > sl ? "Short[SL]" : "Short[T]")
else if (not mktAlwaysOn)
    // Close all open position at the end if Day
    strategy.close_all(comment = "EoD[Exit]", alert_message = "EoD Exit", immediately = true)


もっと