Triple Exponential Moving Average Convergence Divergence und Relative Strength Index kombiniert 1-Minuten-Diagramm Kryptowährungen Quantitative Handelsstrategie

Schriftsteller:ChaoZhang, Datum: 2024-03-29 11:16:10
Tags:

img

Übersicht

Diese Strategie kombiniert die Triple Exponential Moving Average Convergence Divergence (Triple MACD) und den Relative Strength Index (RSI) Methoden, die speziell für den quantitativen Handel auf dem Kryptowährungsmarkt in einem 1-minütigen Zeitrahmen entwickelt wurden. Die Hauptidee hinter der Strategie besteht darin, Veränderungen in der bullischen und bärischen Dynamik mit MACD-Indikatoren mit verschiedenen Periodenparametern zu erfassen, während der RSI-Indikator zur Bestätigung der Trendstärke verwendet wird. Durch Durchschnitt der drei MACD-Signale kann das Rauschen effektiv ausgeglichen werden, wodurch die Zuverlässigkeit der Handelssignale verbessert wird. Darüber hinaus nutzt die Strategie lineare Regressionstechniken, um Konsolidierungsphasen auf dem Markt zu identifizieren und häufige Trades während der preisaktion zu vermeiden.

Strategieprinzipien

Die Strategie verwendet drei MACD-Indikatoren mit unterschiedlichen Parametern: schnelle Linieperioden von 5/13/34 und langsame Linieperioden von 8/21/144. Es berechnet die Differenz zwischen ihnen, um die MACD-Werte zu erhalten. Diese drei MACD-Werte werden dann durchschnittlich berechnet, und das endgültige MACD-Histogramm wird durch Subtrahieren des Signalwerts (N-Periode EMA des MACD) vom durchschnittlichen MACD abgeleitet. Gleichzeitig wird ein 14-Perioden-RSI-Indikator berechnet, um die Trendstärke zu bestimmen. Ein langes Signal wird erzeugt, wenn das durchschnittliche MACD-Histogramm von negativ zu positiv verschiebt, der RSI unter 55 liegt und eine bullische Ausrichtung besteht. Umgekehrt wird ein schließendes Signal ausgelöst, wenn das durchschnittliche MACD-Histogramm von positiv zu negativ ändert, der RSI über 45 liegt und eine Ausrichtung besteht.

Analyse der Vorteile

  1. Die Kombination von MACD-Indikatoren für mehrere Perioden spiegelt trendige Veränderungen auf dem Markt in verschiedenen Zeiträumen objektiv wider und verbessert so die Genauigkeit der Trendenkennung.
  2. Durch die Integration des MACD mit dem RSI-Indikator werden strenge Ein- und Ausstiegsbedingungen geschaffen, die zu einer verbesserten Strategieprofitabilität und einer besseren Kontrolle der Auslastung beitragen.
  3. Durch Durchschnittswerte der MACD-Signale eliminieren effektiv falsche Signale, die durch häufige Schwankungen der Indikatoren verursacht werden, was die Handelssignale zuverlässiger macht.
  4. Die Verwendung von linearer Regression zur Bestimmung von Schwankungsmärkten hilft, Trades während oszillierender Märkte zu vermeiden, wenn der Trend unklar ist, wodurch Verlustgeschäfte reduziert werden.
  5. Auf dem sich rasch verändernden Kryptowährungsmarkt ist eine quantitative Handelsstrategie auf der Ebene von 1 Minute besser positioniert, um Handelschancen, die sich aus Marktschwankungen ergeben, rechtzeitig zu erfassen.

Risikoanalyse

  1. Wenn der Markt für einen längeren Zeitraum in einem weitreichenden Schwingungszustand bleibt, können Handelssignale häufig ungültig werden.
  2. Aufgrund der hohen Volatilität des Kryptowährungsmarktes können extreme abnormale Schwankungen kurzfristig zu erheblichen Rückgängen führen.
  3. Die Auswahl der Strategieparameter hat einen deutlichen Einfluss auf die Gesamtrentabilität. Falsche Parameter-Einstellungen können dazu führen, dass die Strategie fehlschlägt. Daher sind vor dem Live-Handel ausreichende Parameteroptimierung und Backtesting-Verifizierung für verschiedene Handelsinstrumente erforderlich.

Optimierungsrichtlinien

  1. Es sollte in Erwägung gezogen werden, Indikatoren für die Preisvolatilität, wie z. B. ATR, einzuführen, um Einstiegssignale zu filtern und potenzielle Verluste durch abnormale Marktschwankungen zu reduzieren.
  2. Zusätzlich zur linearen Regression können andere Methoden wie Unterstützungs- und Widerstandsniveaus, Bollinger-Band-Kanäle usw. untersucht werden, um die Genauigkeit der Identifizierung von Marktbereichen weiter zu verbessern.
  3. In Trendmärkten, führen Sie Trailing-Stop-Loss ein, um Exit-Punkte zu optimieren und den Gewinn jedes Handels zu maximieren.
  4. Unter Berücksichtigung der charakteristischen Unterschiede zwischen verschiedenen Handelsinstrumenten sollten für verschiedene Instrumente verschiedene Strategieparameter festgelegt werden, um die Anpassungsfähigkeit und Stabilität der Gesamtstrategie zu verbessern.

Zusammenfassung

Diese Strategie kombiniert klug den Triple MACD mit dem RSI-Indikator und nutzt lineare Regressionstechniken, um Range-Märkte zu identifizieren, um einen kompletten Satz von hochfrequenten quantitativen Handelsstrategien zu bilden. Die strengen Einstiegs- und Ausstiegsbedingungen und die Anwendung von durchschnittlichen MACD-Signalen tragen zu einer verbesserten Handelsgenauigkeit und Drawdown-Kontrolle bei. Obwohl die Strategie in einseitigen Trendmärkten besser abschneidet, können Maßnahmen wie die Einführung von Volatilitätsfiltern, die Optimierung von Range-Marktidentifikationsmethoden, die Festlegung von Trailing-Stop-Losses und die Festlegung unabhängiger Parameter für verschiedene Instrumente die Anpassungsfähigkeit und Robustheit der Strategie weiter verbessern. Insgesamt ist dies eine sehr vielversprechende quantitative Kryptowährungshandelsstrategie, die eine weitere Optimierung und Live-Handelsanwendung verdient.


/*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)

Mehr