Hull移動平均値とストカスティックRSIの組み合わせの取引戦略

作者: リン・ハーンチャオチャン, 日付: 2023年10月18日12時40分23秒
タグ:

img

概要

この戦略は,トレンド方向を決定するためにハル移動平均値を使用し,エントリーシグナルのためにストカスティックRSIと組み合わせます.HMAの中間線が下線を超えるとロングトレードが行われ,上線を下に突破するとショートトレードが行われます.また,ストカスティックRSIK線がオーバーバイトゾーンからD線を下に突破するとロングトレードが行われ,オーバーセールゾーンから上を突破するとショートトレードが行われます.

戦略の論理

この戦略の主要な構成要素は,トレンド方向を示すハル移動平均値と,タイミングのエントリー信号を示すストカスティックRSIである.

まず,ハルMA計算には,中間,上間,下間帯の式が含まれます.中間帯は重度の移動平均を使用し,上間帯と下間帯は中間線からオフセットされます.

中央帯と上下帯の関係によってトレンド方向が決定される.中央線の上向きクロスオーバーは購入圧力と上向きを示し,下向きクロスオーバーは販売圧力と下向きを示唆する.

ストカスティックRSIの計算も定義されており,スムーズ化されたKとD値は含まれています.K値はRSIのSMAスムーズ化を使用し,D値はKの第二のSMAスムーズ化です.

トレンド方向が決定された後,ストックRSIK線が上昇傾向中にオーバー買いゾーンからD線以下を横切るとロングトレードが行われます.ダウントレンド中にK線がオーバーセールゾーンからD線上を横切るとショートトレードが行われます.

HullのトレンドフィルターとStockのRSIの過剰購入/過剰売却分析を組み合わせることで,強固な多要素アプローチが得られます.

利点

この戦略の主要な利点は以下の通りです.

  1. Hull MAは,市場全体の傾向の方向性を効果的に特定します.

  2. ストックRSIは,時間エントリに過買い/過売りレベルを決定します.

  3. 両方を組み合わせると 誤った信号が減り 優位性が結合します

  4. 異なるシンボルと時間枠のパラメータを最適化するための柔軟性

  5. 船体帯は潜在的な動的サポートと抵抗を識別します

  6. ポジションのサイズとリスク管理の規則を含みます.

  7. 艦体データ辞書で 多種攻撃能力

  8. 収益性を向上させ,利用量を削減するために最適化可能な部品

リスク

考慮すべきいくつかのリスク:

  1. ハルフ・MAは遅れており 傾向の変化を見逃す可能性があります

  2. ストックRSIは,パラメータが最適化されていない場合,過剰な信号を生成する可能性があります.

  3. ハルとストックパラメータの不一致は 悪い信号を引き起こす可能性があります

  4. 太りすぎたり狭すぎたりすると 信号質が悪くなる

  5. 最近の不安定な市場は 中長期指標に課題を投げかけています

  6. ハルとストックとの間のデータ不一致が 誤った信号を引き起こした

  7. ハル船が把握できない急激な傾向の変化は損失を引き起こす可能性があります

  8. 複数のタイムフレームとシンボルで テストを拡大する必要がある

これ に 対処 する 方法:

  1. トレンドセンシビリティを高めるため,船体MA長さを短縮する.

  2. 偽のクロスをフィルタリングするためにストックRSIを最適化します.

  3. 最適なハルバンドチャネル幅を見つけます

  4. MACD のような追加的な確認指標を追加します.

  5. リスクをコントロールするためにストップ・ロスの戦略を組み込む.

最適化 の 機会

この戦略を改善するいくつかの方法:

  1. より多くのシンボルをテストして 安定性を確認します

  2. トレーリングストップや移動平均値のようなストップ・ロスのメカニズムを組み込む

  3. 入口規則を最適化し 誤った信号を減らすために 厳格なフィルターを設定します

  4. サポートと抵抗をより良く定義するために,ハルバンドを使用する探索.

  5. 信号の信頼性を向上させるため,追加の確認指標を評価する.

  6. 長さ,過剰購入/過剰販売等に関するパラメータ最適化

  7. ポジションのサイズ化とリスク管理の改善を導入する.

  8. リアルタイム取引に必要な 追加エントリー・ストップ・ロスト・テイク・プロフィートルール

  9. トレンド感度を高めるため,船体長を最適化します.

  10. シグナル品質を改善するためにフィルターや確認指標を追加します.

  11. 動的サポート/抵抗レベルを調査する

  12. ストックRSIのパラメータを最適化します 長さ,過買い/過売りなどです

  13. 先進的なポジションサイズ化とリスク管理を実施する.

結論

この戦略は,トレンドとモメンタムを組み合わせた効果的なアプローチである.しかし,固有の指標の弱点は,さらなる最適化とリスク制御なしに信号を盲目的に信頼すべきではないことを意味します.精製されたパラメータ,追加のフィルター,ストップ損失により,この戦略は可能性を持っています. 活気取引のために堅牢で収益性の高いものにするために,パラメータ,リスク管理,ポジションサイズ化についてより広範なテストが必要です.


/*backtest
start: 2023-10-16 00:00:00
end: 2023-10-17 00:00:00
period: 5m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
//Basic Hull Ma Pack tinkered by InSilico 
//Converted to Strategy by DashTrader
strategy("Hull Suite + Stoch RSI Strategy v1.1", overlay=true, pyramiding=1, initial_capital=100, default_qty_type= strategy.percent_of_equity, default_qty_value = 100, calc_on_order_fills=false, slippage=0,commission_type=strategy.commission.percent,commission_value=0.023)
strat_dir_input = input(title="Strategy Direction", defval="all", options=["long", "short", "all"])
strat_dir_value = strat_dir_input == "long" ? strategy.direction.long : strat_dir_input == "short" ? strategy.direction.short : strategy.direction.all
strategy.risk.allow_entry_in(strat_dir_value)
//////////////////////////////////////////////////////////////////////
// Testing Start dates
testStartYear = input(2016, "Backtest Start Year")
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,0,0)
//Stop date if you want to use a specific range of dates
testStopYear = input(2030, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(30, "Backtest Stop Day")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay,0,0)

stoch_upper_input = input(88, "Stoch Upper Threshold", type=input.float)
stoch_lower_input = input(5, "Stoch Lower Threshold", type=input.float)
sl = input(0.7, "SL %", type=input.float, step=0.1)
tp = input(2.1, "TP %", type=input.float, step=0.1)
// slowEMA = ema(close, slowEMA_input)

// vwap = vwap(close)
// rsi = rsi(close, rsi_input)


// stoch rsi
smoothK = 3
smoothD = 3
lengthRSI = 14
lengthStoch = 14
rsi1 = rsi(close, 14)
k = sma(stoch(rsi1, rsi1, rsi1, lengthStoch), smoothK)
d = sma(k, smoothD)

testPeriod() =>
    time >= testPeriodStart and time <= testPeriodStop ? true : false
// Component Code Stop
//////////////////////////////////////////////////////////////////////
//INPUT
src = input(close, title="Source")
modeSwitch = input("Hma", title="Hull Variation", options=["Hma", "Thma", "Ehma"])
length = input(180, title="Length(180-200 for floating S/R , 55 for swing entry)")
switchColor = input(true, "Color Hull according to trend?")
candleCol = input(false,title="Color candles based on Hull's Trend?")
visualSwitch  = input(true, title="Show as a Band?")
thicknesSwitch = input(1, title="Line Thickness")
transpSwitch = input(40, title="Band Transparency",step=5)

//FUNCTIONS
//HMA
HMA(_src, _length) =>  wma(2 * wma(_src, _length / 2) - wma(_src, _length), round(sqrt(_length)))
//EHMA    
EHMA(_src, _length) =>  ema(2 * ema(_src, _length / 2) - ema(_src, _length), round(sqrt(_length)))
//THMA    
THMA(_src, _length) =>  wma(wma(_src,_length / 3) * 3 - wma(_src, _length / 2) - wma(_src, _length), _length)
    
//SWITCH
Mode(modeSwitch, src, len) =>
      modeSwitch == "Hma"  ? HMA(src, len) :
      modeSwitch == "Ehma" ? EHMA(src, len) : 
      modeSwitch == "Thma" ? THMA(src, len/2) : na
      
//OUT
HULL = Mode(modeSwitch, src, length)
MHULL = HULL[0]
SHULL = HULL[2]

//COLOR
hullColor = switchColor ? (HULL > HULL[2] ? #00ff00 : #ff0000) : #ff9800

//PLOT
///< Frame
Fi1 = plot(MHULL, title="MHULL", color=hullColor, linewidth=thicknesSwitch, transp=50)
Fi2 = plot(visualSwitch ? SHULL : na, title="SHULL", color=hullColor, linewidth=thicknesSwitch, transp=50)
///< Ending Filler
fill(Fi1, Fi2, title="Band Filler", color=hullColor, transp=transpSwitch)
///BARCOLOR
barcolor(color = candleCol ? (switchColor ? hullColor : na) : na)

bgcolor(color = k < stoch_lower_input  and crossover(k, d) ? color.green : na)
bgcolor(color = d > stoch_upper_input and crossover(d, k) ? color.red : na)

notInTrade = strategy.position_size == 0

if notInTrade and HULL[0] > HULL[2] and testPeriod() and k < stoch_lower_input and crossover(k, d)
// if HULL[0] > HULL[2] and testPeriod()
    stopLoss = close * (1 - sl / 100) 
    profit25 = close * (1 + (tp / 100) * 0.25)
    profit50 = close * (1 + (tp / 100) * 0.5)
    takeProfit = close * (1 + tp / 100)
    
    
    strategy.entry("long", strategy.long, alert_message="buy")
    strategy.exit("exit long 25%", "long", stop=stopLoss, limit=profit25, qty_percent=25, alert_message="profit_25")
    strategy.exit("exit long 50%", "long", stop=stopLoss, limit=profit50, qty_percent=25, alert_message="profit_50")
    strategy.exit("exit long", "long", stop=stopLoss, limit=takeProfit)
    
    // line.new(bar_index, profit25, bar_index + 4, profit25, color=color.green)
    // line.new(bar_index, profit50, bar_index + 4, profit50, color=color.green)
    // box.new(bar_index, stopLoss, bar_index + 4, close, border_color=color.red, bgcolor=color.new(color.red, 80))
    // box.new(bar_index, close, bar_index + 4, takeProfit, border_color=color.green, bgcolor=color.new(color.green, 80))

    
if notInTrade and HULL[0] < HULL[2] and testPeriod() and d > stoch_upper_input and crossover(d, k)
// if HULL[0] < HULL[2] and testPeriod()
    stopLoss = close * (1 + sl / 100)
    profit25 = close * (1 - (tp / 100) * 0.25)
    profit50 = close * (1 - (tp / 100) * 0.5)
    takeProfit = close * (1 - tp / 100)
    
    

    strategy.entry("short", strategy.short, alert_message="sell")
    strategy.exit("exit short 25%", "short", stop=stopLoss, limit=profit25, qty_percent=25, alert_message="profit_25")
    strategy.exit("exit short 50%", "short", stop=stopLoss, limit=profit50, qty_percent=25, alert_message="profit_50")
    strategy.exit("exit short", "short", stop=stopLoss, limit=takeProfit)
    
    // line.new(bar_index, profit25, bar_index + 4, profit25, color=color.green)
    // line.new(bar_index, profit50, bar_index + 4, profit50, color=color.green)
    // box.new(bar_index, stopLoss, bar_index + 4, close, border_color=color.red, bgcolor=color.new(color.red, 80))
    // box.new(bar_index, close, bar_index + 4, takeProfit, border_color=color.green, bgcolor=color.new(color.green, 80))

// var table winrateDisplay = table.new(position.bottom_right, 1, 1)
// table.cell(winrateDisplay, 0, 0, "Winrate: " + tostring(strategy.wintrades / strategy.closedtrades * 100, '#.##')+" %", text_color=color.white)

もっと