Quantitative Handelsstrategie für CVD Divergenz

Schriftsteller:ChaoZhang, Datum: 2024-03-15 16.47:47
Tags:

img

Strategieübersicht: Die CVD Divergence Quantitative Trading Strategy nutzt Divergenzen zwischen dem CVD-Indikator und dem Preis, um mögliche Trendumkehrsignale zu erfassen. Die Strategie berechnet den CVD-Indikator und vergleicht ihn mit dem Preis, um festzustellen, ob sich bullische oder bärische Divergenzen bilden. Wenn ein Divergenzsignal erkannt wird, eröffnet die Strategie eine Long- oder Short-Position. Sie verwendet auch einen Trailing Stop Loss und einen festen Prozentsatz, um das Risiko zu kontrollieren und Gewinne zu erzielen.

Strategieprinzipien:

  1. Berechnung des CVD-Indikators: Berechnung des CVD-Indikators und seines gleitenden Durchschnitts auf der Grundlage eines bullischen und eines bearishen Volumens.
  2. Identifizieren von Abweichungen: Vergleichen Sie die Höhen und Tiefen des CVD-Indikators mit den Höhen und Tiefen des Preises, um festzustellen, ob Abweichungen entstehen.
    • Regelmäßige bullische Divergenz: Der Preis macht ein niedrigeres Tief, aber CVD bildet ein höheres Tief.
    • Versteckte bullische Divergenz: Preis macht ein höheres Tief, aber CVD bildet ein niedrigeres Tief.
    • Regelmäßige bärische Divergenz: Der Preis macht ein höheres Hoch, aber CVD bildet ein niedrigeres Hoch.
    • Verborgene bearish Divergenz: Preis macht ein niedrigeres Höchststand, aber CVD bildet ein höheres Höchststand.
  3. Offene Positionen: Wenn ein Abweichungssignal erkannt wird, wird je nach Art der Abweichung eine Long- oder Short-Position eröffnet.
  4. Stop-Loss und Take-Profit: Verwenden Sie Trailing-Stop-Loss und Fixed-Percentage-Take-Profit. Der Stop-Loss-Preis wird berechnet, indem der Einstiegspreis mit dem Stop-Loss-Prozent multipliziert wird, und der Take-Profit-Preis wird berechnet, indem der Einstiegspreis mit dem Take-Profit-Prozent multipliziert wird.
  5. Pyramiden: Die Strategie erlaubt maximal 3 Positionen für Pyramiden.

Strategische Vorteile:

  1. Trendumkehrsignale: Die CVD-Divergenz ist ein wirksames Trendumkehrsignal, das dazu beitragen kann, Trendumkehrchancen zu erfassen.
  2. Trendfortsetzungssignale: Verborgene Abweichungen können als Trendfortsetzungssignale dienen und der Strategie helfen, während der Trends die richtige Richtung zu halten.
  3. Risikokontrolle: Durch den Einsatz von Trailing Stop Loss und einem festen Prozentsatz des Gewinns wird das Risiko effektiv verwaltet.
  4. Pyramiden: Die Bereitstellung mehrerer Positionen für Pyramiden ermöglicht eine bessere Kapitalisierung auf Trendmärkten.

Strategische Risiken:

  1. Signalwirksamkeit: Divergenzsignale sind nicht vollständig zuverlässig und es können manchmal falsche Signale auftreten.
  2. Parameterkonfiguration: Die Strategieergebnisse sind an die Parameter-Einstellungen angepasst und verschiedene Parameter können zu unterschiedlichen Ergebnissen führen.
  3. Stop-Loss-Slip: Auf volatilen Märkten werden Stop-Loss-Orders möglicherweise nicht zum vorgegebenen Preis ausgeführt, was zusätzliche Risiken mit sich bringt.
  4. Transaktionskosten: Häufiges Öffnen und Schließen von Positionen kann zu hohen Transaktionskosten führen, die sich auf die Rentabilität der Strategie auswirken.

Optimierungsrichtlinien:

  1. Dynamische Parameteroptimierung: Anpassungsparameter für verschiedene Marktbedingungen verwenden, um die Signalgültigkeit zu verbessern.
  2. Kombination mit anderen Indikatoren: Integration mit anderen technischen Indikatoren wie RSI, MACD usw. zur Verbesserung der Signalzuverlässigkeit.
  3. Verbesserte Stop-Loss- und Take-Profit-Strategien: Ergreifen Sie fortschrittlichere Stop-Loss- und Take-Profit-Strategien, wie zum Beispiel Trailing Stop-Loss oder Volatilitätsbasierte Stop-Loss-Strategien.
  4. Positionsgröße: Dynamische Anpassung der Positionsgrößen anhand der Marktvolatilität, des Eigenkapitals usw.

Schlussfolgerung: Die CVD Divergence Quantitative Trading Strategie zielt darauf ab, potenzielle Trendumkehrchancen zu identifizieren, indem Abweichungen zwischen dem CVD-Indikator und dem Preis erfasst werden. Sie verwendet Trailing Stop Loss und festen Prozentsatz Gewinn zu machen, um das Risiko zu managen. Die Hauptvorteile der Strategie liegen in ihrer Fähigkeit, Trendumkehr- und Fortführungssignale effektiv zu erfassen und Trendmärkte durch Pyramiden besser zu nutzen. Die Strategie ist jedoch auch mit Risiken wie Signalgültigkeit, Parameterkonfiguration, Stop Loss Slippage und Transaktionskosten konfrontiert. Zukünftige Verbesserungen können durch dynamische Parameteroptimierung, Kombination mit anderen Indikatoren, verbesserte Stop-Loss- und Take-Profit-Mechanismen und Positionsgrößenmanagement erzielt werden. Insgesamt ist die CVD Divergence Quantitative Trading Strategie eine effektive und optimierbare Trendfolgestrategie für Trader, die sich für die Erfassung von quantitativen Risiken


/*backtest
start: 2023-03-09 00:00:00
end: 2024-03-14 00:00:00
period: 1d
basePeriod: 1h
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/

//@version=5
//@ mmattman

//Thank you to @ contrerae and Tradingview each for parts of the code to make 
//this indicator and matching strategy and also theCrypster for the clean concise TP/SL code.

// indicator(title="CVD Divergence Indicator 1", shorttitle='CVD Div1', format=format.price, timeframe="", timeframe_gaps=true)

strategy("CVD Divergence Strategy.1.mm", shorttitle = 'CVD Div Str 1', overlay=false)


//..................................................................................................................
// Inputs
periodMa = input.int(title='MA Length', minval=1, defval=20)
plotMa = input(title='Plot MA?', defval=false)

// Calculations (Bull & Bear Balance Indicator by Vadim Gimelfarb)
iff_1 = close[1] < open ? math.max(high - close[1], close - low) : math.max(high - open, close - low)
iff_2 = close[1] > open ? high - low : math.max(open - close[1], high - low)
iff_3 = close[1] < open ? math.max(high - close[1], close - low) : high - open
iff_4 = close[1] > open ? high - low : math.max(open - close[1], high - low)
iff_5 = close[1] < open ? math.max(open - close[1], high - low) : high - low
iff_6 = close[1] > open ? math.max(high - open, close - low) : iff_5
iff_7 = high - close < close - low ? iff_4 : iff_6
iff_8 = high - close > close - low ? iff_3 : iff_7
iff_9 = close > open ? iff_2 : iff_8
bullPower = close < open ? iff_1 : iff_9
iff_10 = close[1] > open ? math.max(close[1] - open, high - low) : high - low
iff_11 = close[1] > open ? math.max(close[1] - low, high - close) : math.max(open - low, high - close)
iff_12 = close[1] > open ? math.max(close[1] - open, high - low) : high - low
iff_13 = close[1] > open ? math.max(close[1] - low, high - close) : open - low
iff_14 = close[1] < open ? math.max(open - low, high - close) : high - low
iff_15 = close[1] > open ? math.max(close[1] - open, high - low) : iff_14
iff_16 = high - close < close - low ? iff_13 : iff_15
iff_17 = high - close > close - low ? iff_12 : iff_16
iff_18 = close > open ? iff_11 : iff_17
bearPower = close < open ? iff_10 : iff_18

// Calculations (Bull & Bear Pressure Volume)
bullVolume = bullPower / (bullPower + bearPower) * volume
bearVolume = bearPower / (bullPower + bearPower) * volume

// Calculations Delta
delta = bullVolume - bearVolume
cvd = ta.cum(delta)
cvdMa = ta.sma(cvd, periodMa)

// Plotting
customColor = cvd > cvdMa ? color.new(color.teal, 50) : color.new(color.red, 50)
plotRef1 = plot(cvd, style=plot.style_line, linewidth=1, color=color.new(color.yellow, 0), title='CVD')
plotRef2 = plot(plotMa ? cvdMa : na, style=plot.style_line, linewidth=1, color=color.new(color.white, 0), title='CVD MA')
fill(plotRef1, plotRef2, color=customColor)
//..................................................................................................................


// len = input.int(title="RSI Period", minval=1, defval=14)
// src = input(title="RSI Source", defval=close)
lbR = input(title="Pivot Lookback Right", defval=3)
lbL = input(title="Pivot Lookback Left", defval=7)
rangeUpper = input(title="Max of Lookback Range", defval=60)
rangeLower = input(title="Min of Lookback Range", defval=5)
plotBull = input(title="Plot Bullish", defval=true)
plotHiddenBull = input(title="Plot Hidden Bullish", defval=true)
plotBear = input(title="Plot Bearish", defval=true)
plotHiddenBear = input(title="Plot Hidden Bearish", defval=true)
bearColor = color.red
bullColor = color.green
hiddenBullColor = color.new(color.green, 80)
hiddenBearColor = color.new(color.red, 80)
textColor = color.white
noneColor = color.new(color.white, 100)
osc = cvd

// plot(osc, title="CVD", linewidth=2, color=#2962FF)
// hline(50, title="Middle Line", color=#787B86, linestyle=hline.style_dotted)
// obLevel = hline(70, title="Overbought", color=#787B86, linestyle=hline.style_dotted)
// osLevel = hline(30, title="Oversold", color=#787B86, linestyle=hline.style_dotted)
// fill(obLevel, osLevel, title="Background", color=color.rgb(33, 150, 243, 90))

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

//------------------------------------------------------------------------------
// Regular Bullish
// Osc: Higher Low

oscHL = osc[lbR] > ta.valuewhen(plFound, osc[lbR], 1) and _inRange(plFound[1])

// Price: Lower Low

priceLL = low[lbR] < ta.valuewhen(plFound, low[lbR], 1)
bullCondAlert = priceLL and oscHL and plFound
bullCond = plotBull and bullCondAlert

plot(
     plFound ? osc[lbR] : na,
     offset=-lbR,
     title="Regular Bullish",
     linewidth=2,
     color=(bullCond ? bullColor : noneColor)
     )

plotshape(
	 bullCond ? osc[lbR] : na,
	 offset=-lbR,
	 title="Regular Bullish Label",
	 text=" Bull ",
	 style=shape.labelup,
	 location=location.absolute,
	 color=bullColor,
	 textcolor=textColor
	 )

//------------------------------------------------------------------------------
// Hidden Bullish
// Osc: Lower Low

oscLL = osc[lbR] < ta.valuewhen(plFound, osc[lbR], 1) and _inRange(plFound[1])

// Price: Higher Low

priceHL = low[lbR] > ta.valuewhen(plFound, low[lbR], 1)
hiddenBullCondAlert = priceHL and oscLL and plFound
hiddenBullCond = plotHiddenBull and hiddenBullCondAlert

plot(
	 plFound ? osc[lbR] : na,
	 offset=-lbR,
	 title="Hidden Bullish",
	 linewidth=2,
	 color=(hiddenBullCond ? hiddenBullColor : noneColor)
	 )

plotshape(
	 hiddenBullCond ? osc[lbR] : na,
	 offset=-lbR,
	 title="Hidden Bullish Label",
	 text=" H Bull ",
	 style=shape.labelup,
	 location=location.absolute,
	 color=bullColor,
	 textcolor=textColor
	 )

//------------------------------------------------------------------------------
// Regular Bearish
// Osc: Lower High

oscLH = osc[lbR] < ta.valuewhen(phFound, osc[lbR], 1) and _inRange(phFound[1])

// Price: Higher High

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

bearCondAlert = priceHH and oscLH and phFound
bearCond = plotBear and bearCondAlert

plot(
	 phFound ? osc[lbR] : na,
	 offset=-lbR,
	 title="Regular Bearish",
	 linewidth=2,
	 color=(bearCond ? bearColor : noneColor)
	 )

plotshape(
	 bearCond ? osc[lbR] : na,
	 offset=-lbR,
	 title="Regular Bearish Label",
	 text=" Bear ",
	 style=shape.labeldown,
	 location=location.absolute,
	 color=bearColor,
	 textcolor=textColor
	 )

//------------------------------------------------------------------------------
// Hidden Bearish
// Osc: Higher High

oscHH = osc[lbR] > ta.valuewhen(phFound, osc[lbR], 1) and _inRange(phFound[1])

// Price: Lower High

priceLH = high[lbR] < ta.valuewhen(phFound, high[lbR], 1)

hiddenBearCondAlert = priceLH and oscHH and phFound
hiddenBearCond = plotHiddenBear and hiddenBearCondAlert

plot(
	 phFound ? osc[lbR] : na,
	 offset=-lbR,
	 title="Hidden Bearish",
	 linewidth=2,
	 color=(hiddenBearCond ? hiddenBearColor : noneColor)
	 )

plotshape(
	 hiddenBearCond ? osc[lbR] : na,
	 offset=-lbR,
	 title="Hidden Bearish Label",
	 text=" H Bear ",
	 style=shape.labeldown,
	 location=location.absolute,
	 color=bearColor,
	 textcolor=textColor
	 )

// alertcondition(bullCondAlert, title='Regular Bullish CVD Divergence', message="Found a new Regular Bullish Divergence, `Pivot Lookback Right` number of bars to the left of the current bar")
// alertcondition(hiddenBullCondAlert, title='Hidden Bullish CVD Divergence', message='Found a new Hidden Bullish Divergence, `Pivot Lookback Right` number of bars to the left of the current bar')
// alertcondition(bearCondAlert, title='Regular Bearish CVD Divergence', message='Found a new Regular Bearish Divergence, `Pivot Lookback Right` number of bars to the left of the current bar')
// alertcondition(hiddenBearCondAlert, title='Hidden Bearisn CVD Divergence', message='Found a new Hidden Bearisn Divergence, `Pivot Lookback Right` number of bars to the left of the current bar')

le = bullCondAlert or hiddenBullCondAlert

se = bearCondAlert or hiddenBearCondAlert

ltp = se

stp = le

// Check if the entry conditions for a long position are met
if (le) //and (close > ema200)
    strategy.entry("Long", strategy.long, comment="EL")

 // Check if the entry conditions for a short position are met
if (se) //and (close < ema200)
    strategy.entry("Short", strategy.short, comment="ES")

// Close long position if exit condition is met
if (ltp) // or (close < ema200)
    strategy.close("Long", comment="XL")

    // Close short position if exit condition is met
if (stp) //or (close > ema200)
    strategy.close("Short", comment="XS")


// The Fixed Percent Stop Loss Code
// User Options to Change Inputs (%)
stopPer = input.float(5.0, title='Stop Loss %') / 100
takePer = input.float(10.0, title='Take Profit %') / 100

// Determine where you've entered and in what direction
longStop = strategy.position_avg_price * (1 - stopPer)
shortStop = strategy.position_avg_price * (1 + stopPer)
shortTake = strategy.position_avg_price * (1 - takePer)
longTake = strategy.position_avg_price * (1 + takePer)

if strategy.position_size > 0 
    strategy.exit("Close Long", "Long", stop=longStop, limit=longTake)
if strategy.position_size < 0 
    strategy.exit("Close Short", "Short", stop=shortStop, limit=shortTake)









Mehr