CVD ディバージェンスの量的な取引戦略

作者: リン・ハーンチャオチャン開催日:2024年3月15日 16時47分47秒
タグ:

img

戦略概要 CVDダイバージェンス定量取引戦略は,CVD指標と価格の間のダイバージェンスを利用し,潜在的なトレンド逆転信号を捕捉する.この戦略は,CVD指標を計算し,価格と比較して,上昇または下落のダイバージェンスが形成されるかどうかを決定する.ダイバージェンス信号が検出されると,戦略はロングまたはショートポジションを開く.また,リスクを制御し,利益をロックするために,トライリングストップ損失と固定パーセントの利益を取ることを使用する.この戦略は複数のポジションでピラミディングをサポートする.

戦略の原則

  1. CVD指標の計算:CVD指標とその移動平均を,上昇と下落のボリュームに基づいて計算する.
  2. 差異を特定する:CVD指標の高値と低値を価格の高値と低値と比較して,差異が形成されているかどうかを判断する.
    • 定期的な上昇差:価格が低い低値を上げますが,CVDは高い低値を上げます.
    • 隠された上昇差:価格が低い値に上昇するが,CVDは低い値に上昇する.
    • 定期的な下落差:価格が高い高値を上げますが,CVDは低い高値を上げます.
    • 隠された下落差:価格が低値に上昇するが,CVDは高値に上昇する.
  3. オープン・ポジション: 差異信号が検出された場合,差異の種類に応じて,ロング・またはショート・ポジションを開く.
  4. ストップ・ロストとテイク・プロフィート: トレイリング・ストップ・ロストと固定・パーセント・テイク・プロフィートを使用する.ストップ・ロスト価格はエントリー価格をストップ・ロストパーセントで掛け,テイク・プロフィート価格はエントリー価格をテイク・プロフィートパーセントで掛け算する.
  5. ピラミダリング:この戦略ではピラミダリングに3つのポジションを最大限使用できます.

戦略上の利点

  1. トレンド逆転信号:CVDディバージェンスは,トレンド逆転の機会を把握するのに役立つ効果的なトレンド逆転信号です.
  2. トレンド継続シグナル: 隠された差異はトレンド継続シグナルとして機能し,トレンド中に戦略が正しい方向を維持するのに役立ちます.
  3. リスク管理: トレイリング・ストップ・ロスの利用と固定・割引の取上げにより,リスクは効果的に管理されます.
  4. ピラミディング:ピラミディングの複数のポジションを許可することで,トレンド市場でのより良い資本化が可能になります.

戦略リスク:

  1. 信号の有効性: 差異信号は完全に信頼性がないため,時には誤った信号が発生することがあります.
  2. パラメータ設定: 戦略結果はパラメータ設定に敏感で,異なるパラメータが異なる結果をもたらす可能性があります.
  3. ストップ・ロッド・スリップ: 変動性の高い市場では,ストップ・ロッド・オーダーは,事前に定義された価格で実行されない可能性があり,追加のリスクが伴う.
  4. 取引コスト: ポジションの頻繁な開閉は,高い取引コストをもたらし,戦略の収益性に影響を与えます.

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

  1. ダイナミックパラメータ最適化:信号の有効性を向上させるために,異なる市場条件に適応可能なパラメータを使用する.
  2. 他の指標との組み合わせ:信号の信頼性を高めるため,RSI,MACDなどの他の技術指標と統合します.
  3. 改善されたストップ損失と利益を引き出す: より高度なストップ損失と利益を引き出す戦略を採用する.例えば,ストップ損失を後押しする,または変動に基づくストップ損失.
  4. ポジションサイズ: 市場の変動,口座資本などに基づいてポジションサイズを動的に調整する.

結論: CVDダイバージェンツ量的な取引戦略は,CVD指標と価格の間のダイバージェンツを捕捉することによって潜在的なトレンド逆転機会を特定することを目的としている.リスクを管理するために,ストップ損失を追及し,固定パーセントの利益を得ることを採用している.戦略の主な利点は,トレンド逆転と継続のシグナルを効果的に捕捉し,ピラミダイジングを通じてトレンド市場をより良い活用する能力にある.しかし,この戦略は,シグナル有効性,パラメータ構成,ストップ損失の滑り,取引コストなどのリスクにも直面している.将来の改善は,ダイナミックなパラメータ最適化,他の指標との組み合わせ,改善されたストップ損失と利益の取りメカニズム,およびポジションサイジング管理を通じて行なわれる.全体として,CVDダイバージェンツ量的な取引戦略は,トレンドチャンスを管理しながらリスクを捕捉することを目指すトレーダーに適した効果的な最適化可能なトレンドフォロー戦略である.


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









もっと