// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © calibrated89 //___________________________________________________________________________________________________________ // When to enter a position? // Bar turned Green -> CVD MA turned bullish -> LONG -> exit when CVD turns bearish // Bar turned Red -> SHORT -> exit when CVD MA turned bullish //___________________________________________________________________________________________________________ //@version=5 indicator("~CVD") //----Normalization Function n(s,l) => hi = ta.highest(s, l) lo = ta.lowest(s, l) n = (s - lo) / (hi - lo)+1 n // This source code is adapted from "Cummulative Volume Delta" by footlz lookback = input(72, title="CVD lookback [colored candles]") v = volume o = open c = close vbuy = 0.0 vsell = 0.0 if c > o vbuy := v * math.abs(o / c - 1) if c < o vsell := v * math.abs(o / c - 1) delta = ta.cum(vbuy - vsell) ema = ta.ema( delta, lookback) ema_ltf = ta.ema( delta, lookback/3) // The following gives very good result at 30 minutes tf //barcolor( delta >= cvd ? c12 : c01 ) //_________________ colors c11 = color.rgb(248,248,255), c01 = color.rgb(132,132,130) c12 = color.rgb( 7, 236, 247 ), c02 = color.rgb(153,50,204) c13 = color.rgb(105, 247, 7), c03 = color.rgb(220,20,60) //_____________________________________________________________________ Tested plots. GOOD results !!! alma_ltf_2 = ta.alma(delta, 12, 0.90, 6) bgcolor( delta > alma_ltf_2 ? color.rgb(0,116,116, 75) : color.rgb(101,0,11,65) ) // gives faster signals than ema(18) alma_ltf = ta.alma(delta, 24, 0.90, 6) barcolor( color = delta > alma_ltf ? c11 : delta < alma_ltf_2 ? color.rgb(65,105,225) : color.rgb(105,105,105) ) // Tested. GOOD result!!! alma = ta.alma( delta, 50, .90, 6) alma_rma = ta.rma( alma, 2 ) plot( alma, color = alma > alma_rma ? c11 : c01, style = plot.style_stepline, linewidth = 2 ) ema_ltf_2 = ta.ema( delta, 18) ema_rma_2 = ta.rma( ema_ltf_2, 3) //plot(ema_ltf_2, color= ema_ltf_2 > ema_rma_2 ? c11 : c01, linewidth = 1, style = plot.style_stepline ) //____________________________________________________________________________________________________ //plot(delta, color = color.rgb( 247, 240, 7 ) ) //plot(ema_ltf, color=delta > ema_ltf ? c11 : color.rgb(132,132,130), linewidth = 1, style = plot.style_stepline ) // Very GOOD result!!! //plot( alma, color=delta > alma ? c11 : c01, linewidth = 4, style=plot.style_stepline ) // Late but GOOD for over-confirmation!!! //_________________________________________________________ LTF calculations ltf_delta() => vb=0.0, vs=0.0 if open > close vs := volume * math.abs(open/close -1) if close > open vb := volume * math.abs(open/close -1) delta_ltf_1 = ta.cum(vb-vs) [vb,vs] [vb,vs] = request.security_lower_tf( syminfo.tickerid, '10', ltf_delta(), false ) vb_t = nz( array.sum(vb)) vs_t = nz( array.sum(vs)) delta_ltf = vb_t - vs_t ltf_alma = ta.alma(delta_ltf, 24, 0.95, 6) //plot(ltf_alma) //_________________________________________________________ Experiments //======= Alert //========================================================================= //----Trigger Rotation (Adjusted from "30minutes rotations") v000 = volume b000 = 0.0, s000 = 0.0 if close > open b000 := v000 * math.abs(open / close - 1) b000 if close < open s000 := v000 * math.abs(open / close - 1) s000 d000 = ta.cum(b000 - s000) //nd00 = (n(d00,l00) -1.5)*2.0 nd000 = ta.alma(d000, 48,0.95,6) nd000_ = ta.rma(nd000,2) //plot( nd000, color = nd000 > nd000_ ? #ffffff : c02 ) //=========================================================================== //=========================================================================== // This source code is adapted from "Cummulative Volume Delta" by Ankit_1618 //=========================================================================== cumulation_length = input(36, "CVD MA Lookback") upper_wick = close>open ? high-close : high-open lower_wick = close>open ? open-low : close-low spread = high-low body_length = spread - (upper_wick + lower_wick) percent_upper_wick = upper_wick/spread percent_lower_wick = lower_wick/spread percent_body_length = body_length/spread //=== Normalize volume vol_norm = volume buying_volume = 0.0 selling_volume = 0.0 buying_volume := close>open ? (percent_body_length + (percent_upper_wick + percent_lower_wick)/2)*vol_norm : ((percent_upper_wick + percent_lower_wick)/2) * vol_norm selling_volume := close cumulative_selling_volume ? cumulative_buying_volume : cumulative_selling_volume ema_volume_strength_wave = ta.alma(volume_strength_wave, cumulation_length, .90, 6) // Following plot is less effective!!! //plot(ema_volume_strength_wave, color=cumulative_buying_volume > cumulative_selling_volume ? c13 : c01, style= plot.style_area) cumulative_volume_delta = cumulative_buying_volume - cumulative_selling_volume cvd_ma = ta.alma(cumulative_volume_delta, cumulation_length, .85, 6) cvd_ma_ltf = ta.alma(cumulative_volume_delta, cumulation_length/3, 0.90, 6) // Following plot is LESS effective !!! //plot(cvd_ma, color= cvd_ma_ltf > cvd_ma ? c13 : c02, linewidth = 2, style = plot.style_area ) //========================================================================= // Following code is adapted from "30min Rotations" by PeckerPonzi //========================================================================= l00 = input(24,'Lookback'),l01 = l00*3,l02 = l00*6,l03 = l00*9,l04 = l00*12 //----Step Function step(nd) => step = nd >0 and nd <0.25 ? 0 : nd > 0.25 and nd < 0.5 ? 0.25 : nd > 0.5 and nd <0.75 ? 0.5 : nd > 0.75 and nd < 0.875 ? 0.75 : nd > 0.875 ? 1 : nd <0 and nd >-0.25 ? 0 : nd < -0.25 and nd > -0.5 ? -0.25 : nd < -0.5 and nd > -0.75 ? -0.5 : nd < -0.75 and nd > -0.875 ? -0.75 : nd < -0.875 ? -1 : nd step //----Trigger Rotation v00 = n(volume,l00) b00 = 0.0, s00 = 0.0 if close > open b00 := v00 * math.abs(open / close - 1) b00 if close < open s00 := v00 * math.abs(open / close - 1) s00 d00 = ta.cum(b00 - s00) nd00 = (n(d00,l00) -1.5)*2.0 nd00 := ta.alma(nd00,l00,0.95,6) nd10 = ta.rma(nd00,2) //----Fast Rotation v01 = n(volume,l01) b01 = 0.0, s01 = 0.0 if close > open b01 := v01 * math.abs(open / close - 1) b01 if close < open s01 := v01 * math.abs(open / close - 1) s01 d01 = ta.cum(b01 - s01) nd01 = (n(d01,l01) -1.5)*2.0 nd01 := ta.alma(nd01,l01,0.90,6) nd11 = ta.rma(nd01,3) //----Medium Rotation //----Slow Rotation //----Trend Rotation //----Plots //fill(plot(nd01,'Fast Rotation',c01),plot(nd11,'Smooth Fast Rotation',c01),color=c01) //fill(z,plot(nd02,'Slow Rotation',c02,style=plot.style_stepline),color=c12) //fill(z,plot(nd03,'Medium Rotation',c03,style=plot.style_stepline),color=c13) //fill(z,plot(nd04,'Trend Rotation',c04,style=plot.style_stepline),color=c14) //hl_1 = hline(1,'1',#FF52528F,linestyle=hline.style_solid) //hl_2 = hline(0.75,'0.75',#FF52528F,linestyle=hline.style_dotted) //bgcolor(nd00 > 0.75 and nd00 < nd10 ? color.rgb(206, 32, 41, 75) : nd00 < -0.75 and nd00 > nd10 ? color.rgb(64, 224, 208, 70) : #0000002f) //hline(0,'0',#FFFFFF8F,linestyle=hline.style_solid) //fill(hline(-0.75,'-0.75',#00BCD48F,linestyle=hline.style_dotted),hline(-1,'-1',#00BCD48F,linestyle=hline.style_solid),color= nd00 < -0.75 and nd00 > nd10 ? #00BCD4CF : #00BCD42F) //----Basic Single Alert bool vis_alert = input(true, 'Show Alert?') threshold = input(0.75,'Alert Threshold') long = ta.crossover(nd01,nd11) and nd01 <= - threshold and nd00 > nd10 short = ta.crossunder (nd01,nd11) and nd01 >= threshold and nd00 < nd10 cond = long or short bgcol = long ? c12 : short ? c01 : na //bgcolor(vis_alert ? bgcol : na ,title='Alert Trigger') //alertcondition(cond, title='Rotations X', message='Rotations X')