3倍指数関数移動平均収束差異と相対強度指数 組み合わせた1分チャート 仮想通貨量的な取引戦略

作者: リン・ハーンチャオチャン, 開催日:2024年3月29日 11:16:10
タグ:

img

概要

この戦略は,1分間のタイムフレームで暗号通貨市場で定量的な取引のために特別に設計されたトリプル指数関数移動平均収束差 (Triple MACD) と相対強度指数 (RSI) 方法を組み合わせています.この戦略の背後にある主なアイデアは,異なる期間のパラメータを持つMACD指標を使用して,トレンド強さを確認するためにRSI指標を使用しながら,上昇と下落の勢力の変化を把握することです.3つのMACD信号を平均することによって,ノイズは効果的に滑らかにされ,取引信号の信頼性が向上します.さらに,この戦略は,市場における統合段階を特定するために線形回帰技術を使用し,激動的な価格アクション中に頻繁な取引を避けます.この戦略はグリッド取引に適しており,暗号通貨市場の急速な変動の中で安定したリターンを生成することができます.

戦略の原則

この戦略は,異なるパラメータを持つ3つのMACDインジケーターを使用する. 5/13/34の速いライン期と8/21/144のスローライン期.MACD値を入手するために,それらの間の差を計算する.これらの3つのMACD値は平均され,最終MACDヒストグラムは,平均MACDからシグナル値 (MACDのN期EMA) を減算することによって得られる.同時に,トレンド強度を決定するのに役立つ14期RSIインジケーターが計算される.平均MACDヒストグラムがマイナスからポジティブに変化し,RSIが55未満で,バリーシグネーションがあるとき,長い信号が生成される.逆に,平均MACDヒストグラムがマイナスからポジティブに変化し,RSIが45を超え,ベアシグネーション戦略があるとき,近い信号が誘発される.さらに,11期レグネーションラインは,キャンドルスタイヤの長さと市場比率によって変動する,レグネーション・シグネーションを識別するために適用される.

利点分析

  1. 多期MACD指標の組み合わせにより,異なる時間スケールで市場の動向変化を客観的に反映し,動向の識別の精度を向上させる.
  2. MACDをRSI指標と統合することで,厳格な入出条件が形成され,戦略の収益性と引き下げ制御が向上します.
  3. MACD信号を平均化することで,指標の頻繁な振動によって引き起こされる誤った信号が効果的に排除され,取引信号がより信頼性が高まります.
  4. 線形回帰を活用して市場を測ると,トレンドが不明確であるときの振動市場中に取引を避けるのに役立ち,損する取引を減らす.
  5. 急速に変化する仮想通貨市場において,1分間のレベルでの定量的な取引戦略は,市場の変動から生じる取引機会を迅速に把握するのに適しています.

リスク分析

  1. この戦略は,単方向のトレンド市場ではよりうまく機能する.市場が長期間にわたって広範な振動状態のままであれば,取引信号はしばしば無効になる可能性があります.
  2. 仮想通貨市場の高い変動性により,短期的に異常な変動が起こり,大幅な引き下げにつながる可能性があります.
  3. 戦略パラメータの選択は,全体的な収益性に明確な影響を与える.パラメータの設定が正しくない場合,戦略が失敗する可能性があります.したがって,ライブ取引の前に,さまざまな取引機器のための十分なパラメータ最適化とバックテスト検証が必要です.

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

  1. 価格変動に関する指標,例えばATRを導入することを検討し,エントリーシグナルをフィルタリングし,異常な市場変動による潜在的な損失を削減する.
  2. 線形回帰に加えて,サポートレベルやレジスタンスレベル,ボリンジャー帯のチャネルなど,他の方法も検討され,範囲市場を特定する精度をさらに向上させることができます.
  3. トレンド市場では,出口ポイントを最適化して,各取引の利益を最大化するために,ストップロスを導入します.
  4. 各取引手段の特徴的な違いを考慮し,全体的な戦略の適応性と安定性を高めるために,異なる手段の戦略パラメータを設定する.

概要

この戦略は,トリプルMACDとRSIインジケーターを巧みに組み合わせ,線形回帰技術を使用してレンジング市場を特定し,高周波定量的な取引戦略の完全なセットを形成する.厳格なエントリーと出口条件,平均的なMACD信号の適用は,取引精度と引き下げ制御の向上に貢献する. 戦略は片方向のトレンド市場でより良いパフォーマンスを発揮しているが,波動性フィルターを導入し,レンジング市場識別方法を最適化し,トレーリングストップ・ロスを設定し,さまざまなツールの独立したパラメータを確立するなどの措置は,戦略の適応性と堅牢性をさらに高めることができます. 全体的に,これは,さらなる最適化とライブ取引アプリケーションに値する非常に有望な仮想通貨定量的な取引戦略です.


/*backtest
start: 2023-03-23 00:00:00
end: 2024-03-28 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
strategy(title="TrippleMACD", shorttitle="TrippleMACD + RSI strategy", format=format.price, precision=4, overlay=true)

// RSI 
ma(source, length, type) =>
    switch type
        "SMA" => ta.sma(source, length)
        "Bollinger Bands" => ta.sma(source, length)
        "EMA" => ta.ema(source, length)
        "SMMA (RMA)" => ta.rma(source, length)
        "WMA" => ta.wma(source, length)
        "VWMA" => ta.vwma(source, length)

rsiLengthInput = input.int(14, minval=1, title="RSI Length", group="RSI Settings")
rsiSourceInput = input.source(close, "Source", group="RSI Settings")
maTypeInput = input.string("SMA", title="MA Type", options=["SMA", "Bollinger Bands", "EMA", "SMMA (RMA)", "WMA", "VWMA"], group="MA Settings")
maLengthInput = input.int(14, title="MA Length", group="MA Settings")
bbMultInput = input.float(2.0, minval=0.001, maxval=50, title="BB StdDev", group="MA Settings")
showDivergence = input.bool(false, title="Show Divergence", group="RSI Settings")

up = ta.rma(math.max(ta.change(rsiSourceInput), 0), rsiLengthInput)
down = ta.rma(-math.min(ta.change(rsiSourceInput), 0), rsiLengthInput)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))
rsiMA = ma(rsi, maLengthInput, maTypeInput)
isBB = maTypeInput == "Bollinger Bands"

bbUpperBand = plot(isBB ? rsiMA + ta.stdev(rsi, maLengthInput) * bbMultInput : na, title = "Upper Bollinger Band", color=color.green)
bbLowerBand = plot(isBB ? rsiMA - ta.stdev(rsi, maLengthInput) * bbMultInput : na, title = "Lower Bollinger Band", color=color.green)

// Divergence
lookbackRight = 5
lookbackLeft = 5
rangeUpper = 60
rangeLower = 5
bearColor = color.red
bullColor = color.green
textColor = color.white
noneColor = color.new(color.white, 100)

plFound = na(ta.pivotlow(rsi, lookbackLeft, lookbackRight)) ? false : true
phFound = na(ta.pivothigh(rsi, lookbackLeft, lookbackRight)) ? false : true
_inRange(cond) =>
	bars = ta.barssince(cond == true)
	rangeLower <= bars and bars <= rangeUpper

//------------------------------------------------------------------------------
// Regular Bullish
// rsi: Higher Low

rsiHL = rsi[lookbackRight] > ta.valuewhen(plFound, rsi[lookbackRight], 1) and _inRange(plFound[1])

// Price: Lower Low

priceLL = low[lookbackRight] < ta.valuewhen(plFound, low[lookbackRight], 1)
bullCondAlert = priceLL and rsiHL and plFound
bullCond = showDivergence and bullCondAlert

// rsi: Lower High

rsiLH = rsi[lookbackRight] < ta.valuewhen(phFound, rsi[lookbackRight], 1) and _inRange(phFound[1])

// Price: Higher High

priceHH = high[lookbackRight] > ta.valuewhen(phFound, high[lookbackRight], 1)

bearCondAlert = priceHH and rsiLH and phFound
bearCond = showDivergence and bearCondAlert

// Getting inputs
stopLuse          = input(1.040)
fast_length = input(title = "Fast Length", defval = 5)
slow_length = input(title = "Slow Length", defval = 8)
fast_length2 = input(title = "Fast Length2", defval = 13)
slow_length2 = input(title = "Slow Length2", defval = 21)
fast_length3 = input(title = "Fast Length3", defval = 34)
slow_length3 = input(title = "Slow Length3", defval = 144)
fast_length4 = input(title = "Fast Length3", defval = 68)
slow_length4 = input(title = "Slow Length3", defval = 288)
src = input(title = "Source", defval = close)
signal_length2 = input.int(title="Signal Smoothing", minval = 1, maxval = 200, defval = 11)
signal_length = input.int(title = "Signal Smoothing",  minval = 1, maxval = 50, defval = 9)
sma_source = input.string(title = "Oscillator MA Type",  defval = "EMA", options = ["SMA", "EMA"])
sma_signal = input.string(title = "Signal Line MA Type", defval = "EMA", options = ["SMA", "EMA"])
// Calculating
fast_ma = sma_source == "SMA" ? ta.sma(src, fast_length) : ta.ema(src, fast_length)
slow_ma = sma_source == "SMA" ? ta.sma(src, slow_length) : ta.ema(src, slow_length)

fast_ma2 = sma_source == "SMA2" ? ta.sma(src, fast_length2) : ta.ema(src, fast_length2)
slow_ma2 = sma_source == "SMA2" ? ta.sma(src, slow_length2) : ta.ema(src, slow_length2)

fast_ma3 = sma_source == "SMA3" ? ta.sma(src, fast_length3) : ta.ema(src, fast_length3)
slow_ma3 = sma_source == "SMA3" ? ta.sma(src, slow_length3) : ta.ema(src, slow_length3)

fast_ma4 = sma_source == "SMA3" ? ta.sma(src, fast_length3) : ta.ema(src, fast_length3)
slow_ma4 = sma_source == "SMA3" ? ta.sma(src, slow_length3) : ta.ema(src, slow_length3)

macd = fast_ma - slow_ma
macd2 = fast_ma2 - slow_ma2
macd3 = fast_ma3 - slow_ma3
macd4 = fast_ma4 - slow_ma4

signal = sma_signal == "SMA" ? ta.sma(macd, signal_length) : ta.ema(macd, signal_length)
signal2 = sma_signal == "SMA" ? ta.sma(macd2, signal_length) : ta.ema(macd2, signal_length)
signal3 = sma_signal == "SMA" ? ta.sma(macd3, signal_length) : ta.ema(macd3, signal_length)
signal4 = sma_signal == "SMA" ? ta.sma(macd4, signal_length) : ta.ema(macd4, signal_length)
//hist = (macd + macd2 + macd3)/1 - (signal + signal2 + signal3)/1
hist = (macd + macd2 + macd3 + macd4)/4 - (signal + signal2 + signal3 + signal4)/4
signal5 = (signal + signal2 + signal3)/3

sma_signal2 = input.bool(title="Simple MA (Signal Line)", defval=true)

lin_reg = input.bool(title="Lin Reg", defval=true)
linreg_length = input.int(title="Linear Regression Length", minval = 1, maxval = 200, defval = 11)

bopen = lin_reg ? ta.linreg(open, linreg_length, 0) : open
bhigh = lin_reg ? ta.linreg(high, linreg_length, 0) : high
blow = lin_reg ? ta.linreg(low, linreg_length, 0) : low
bclose = lin_reg ? ta.linreg(close, linreg_length, 0) : close

shadow = (bhigh - bclose) + (bopen - blow)
body = bclose - bopen
perc = (shadow/body)
cond2 = perc >=2 and bclose+bclose[1]/2 > bopen+bopen[1]/2

r = bopen < bclose

//signal5 = sma_signal2 ? ta.sma(bclose, signal_length) : ta.ema(bclose, signal_length)
plotcandle(r ? bopen : na, r ? bhigh : na, r ? blow: na, r ? bclose : na, title="LinReg Candles", color= color.green, wickcolor=color.green, bordercolor=color.green, editable= true)
plotcandle(r ? na : bopen, r ? na : bhigh, r ? na : blow, r ? na : bclose, title="LinReg Candles", color=color.red, wickcolor=color.red, bordercolor=color.red, editable= true)
//alertcondition(hist[1] >= 0 and hist < 0, title = 'Rising to falling', message = 'The MACD histogram switched from a rising to falling state')
//alertcondition(hist[1] <= 0 and hist > 0, title = 'Falling to rising', message = 'The MACD histogram switched from a falling to rising state')

green = hist >= 0 ? (hist[1] < hist ? "G" : "GL") : (hist[1] < hist ? "RL" : "R")
Buy = green == "G" and green[1] != "G" and green[1] != "GL" and bopen < bclose and rsi < 55.0 //and not cond2
//StopBuy = (green == "R" or green == "RL" or green == "RL") and bopen > bclose and bopen[1] < bclose[1]
StopBuy = bopen > bclose and bopen[1] < bclose[1] and (green == "G" or green == "GL" or green == "R") and bopen[2] < bclose[2] and bopen[3] < bclose[3]
hists = close[3] < close[2] and close[2] < close[1]
//Buy = green == "RL" and hist[0] > -0.07 and hist[0] < 0.00 and rsi < 55.0 and hists
//StopBuy = green == "GL" or green == "R"
alertcondition(Buy, "Long","Покупка в лонг")
alertcondition(StopBuy, "StopLong","Закрытие сделки")

//hline(0, "Zero Line", color = color.new(#787B86, 50))
plot(hist + (close - (close * 0.03)), title = "Histogram", style = plot.style_line, color = (hist >= 0 ? (hist[1] < hist ? #26A69A : #B2DFDB) : (hist[1] < hist ? #FFCDD2 : #FF5252)))
plotshape(Buy ? low : na, 'Buy', shape.labelup, location.belowbar , color=color.new(#0abe40, 50), size=size.small, offset=0)
plotshape(StopBuy ? low : na, 'Buy', shape.cross, location.abovebar , color=color.new(#be0a0a, 50), size=size.small, offset=0)
plot(macd4  + (close - (close * 0.01)),   title = "MACD",   color = #2962FF)
plot(signal5 + (close - (close * 0.01)), title = "Signal", color = #FF6D00)

plotchar(cond2 , char='↓', color = color.rgb(0, 230, 119), text = "-")

if (Buy)
    strategy.entry("long", strategy.long)

// if (startShortTrade)
//     strategy.entry("short", strategy.short)

profitTarget = strategy.position_avg_price * stopLuse
strategy.exit("Take Profit", "long", limit=profitTarget)
// strategy.exit("Take Profit", "short", limit=profitTarget)

もっと