

Code written in the episode one of signal school.
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © TheTradingParrot
//@version=5
indicator("TTP PSAR VOL MA signal v0.1", overlay = false)
toSignal(val) =>
val ? 1 : 0
toColor(val) =>
val ? color.new( color.green, 18) : color.new(color.red, 18)
shorts = input.bool(false,"Short signals", group = "Settings")
volumeConfluence = input.int(2, "Vol confluence", group = "Settings", tooltip = "How many volume indicators must be in green to open a new deal.")
backtestable = input.bool(true,"Backtestable",group = "Settings", tooltip = "Prints 1 for deal open, 2 for deal close.")
// PSAR
Pstart = input.float(title="Start", step=0.001, defval=0.02)
Pincrement = input.float(title="Increment", step=0.001, defval=0.02)
Pmaximum = input.float(title="Maximum", step=0.01, defval=0.2)
Pwidth = input.float(title="Point Width", minval=1, defval=2)
Ppsar = ta.sar(Pstart, Pincrement, Pmaximum)
Pdir = Ppsar < close ? 1 : -1
buySignal = Pdir == 1 and Pdir[1] == -1
sellSignal = Pdir == -1 and Pdir[1] == 1
pCondition = shorts ? sellSignal : buySignal
pExitCondition = shorts ? buySignal : sellSignal
plot(1.2, title="PSAR", style=plot.style_circles, color=toColor(pCondition), linewidth=2)
// MA
maLength = input.int(60,"ma length",minval = 1, group = "MA")
ma = ta.sma(close, maLength)
maBuyCondition = close > ma
maSellCondition = close < ma
maCondition = shorts ? maSellCondition : maBuyCondition
maColor = toColor(maCondition)
plot(1, title="MA", style=plot.style_circles, color=maColor, linewidth=2)
// VSA
vsaEnabled = input.bool(true,"Enabled", group = "VSA vol")
vsaVolMAlength = input.int(200,"MA length", group = "VSA vol")
vsaVolmult1 = input.float(0.5, "MA mult 1", group = "VSA vol")
vsaVolmult2 = input.float(1.0, "MA mult 2", group = "VSA vol")
vsaVolmult3 = input.float(2.0, "MA mult 3", group = "VSA vol")
volMa = ta.sma(volume, vsaVolMAlength)
vsaYellow = volume > vsaVolmult2 * volMa
vsaOrange = volume > vsaVolmult3 * volMa
vsaBuySellCondition = vsaOrange or vsaYellow
vsaColor = vsaEnabled ? toColor(vsaBuySellCondition) : color.gray
plot(0.8, title="VSA", style=plot.style_circles, color=vsaColor, linewidth=2)
// Volume heatmap
VHEnabled = input.bool(true,"Enabled", group = "Volume Heatmap")
VHlength = input.int(610, title="MA Length", minval=2, group = "Volume Heatmap")
VHslength = input.int(610, title='Std Length', minval=2, group = "Volume Heatmap")
VHthresholdExtraHigh = input.float(4, title="Extra High Volume Threshold", group = "Volume Heatmap")
VHthresholdHigh = input.float(2.5, title="High Volume Threshold", group = "Volume Heatmap")
VHthresholdMedium = input.float(1, title="Medium Volume Threshold", group = "Volume Heatmap")
VHthresholdNormal = input.float(-0.5, title="Normal Volume Threshold", group = "Volume Heatmap")
VHlength := VHlength > bar_index + 1 ? bar_index + 1 : VHlength
VHslength := VHslength > bar_index + 1 ? bar_index + 1 : VHslength
pstdev(Series, Period) =>
mean = math.sum(Series, Period) / Period
summation = 0.0
for i=0 to Period-1
sampleMinusMean = nz(Series[i]) - mean
summation := summation + sampleMinusMean * sampleMinusMean
math.sqrt(summation / Period)
VHmean = ta.sma(volume, VHlength)
VHstd = pstdev(volume, VHslength)
VHstdbar = (volume - VHmean) / VHstd
VHdir = close > open
VHv = volume
VHmosc = VHmean
VHExtrahigh = VHstdbar > VHthresholdExtraHigh
VHhigh = VHstdbar > VHthresholdHigh
VHmid = VHstdbar > VHthresholdMedium
VHBuySellCondition = VHExtrahigh or VHhigh or VHmid
VHColor = VHEnabled ? toColor(VHBuySellCondition) : color.gray
plot(0.6, title="Vol heatmap", style=plot.style_circles, color=VHColor, linewidth=2)
// vol fight
VFEnabled = input.bool(true,"Enabled", group = "Volume fight")
VFma = input.int(24, 'Search_range', minval=1,group = "Volume fight")
VFdelta = input.float(15, 'Smoothing_for_flat,%', step=0.5, minval=0,group = "Volume fight")
VFbgshow = false
VFall_signal_show = false
VFbull_vol = open<close ? volume : volume*(high-open)/(high-low) //determine the share of bullish volume
VFbear_vol = open>close ? volume : volume*(open-low)/(high-low) //determine the share of bearish volume
VFavg_bull_vol = ta.vwma(VFbull_vol,VFma), VFavg_bear_vol = ta.vwma(VFbear_vol,VFma) //determine vwma
VFdiff_vol = ta.sma((VFavg_bull_vol/volume-1)-(VFavg_bear_vol/volume-1),VFma) //normalize and smooth the values
VFvol_flat = math.abs(VFavg_bull_vol+VFavg_bear_vol)/2 //determine average value for calculation flat-filter
VFside = VFavg_bull_vol>VFavg_bear_vol and VFvol_flat/VFavg_bull_vol<(1-VFdelta/100) ? 1 : VFavg_bull_vol<VFavg_bear_vol and VFvol_flat/VFavg_bear_vol<(1-VFdelta/100) ? 2 : 0
VFBuySignal = VFside == 1
VFSellSignal = VFside == 2
// plot(toSignal(VFEnabled and shorts and VFSellSignal), "VFSellSignal")
// plot(toSignal(VFEnabled and not shorts and VFBuySignal), "VFBuySignal")
vfColorPre = shorts ? toColor(VFSellSignal) : toColor(VFBuySignal)
vfColor = vsaEnabled ? vfColorPre : color.gray
plot(0.4, title="Vol fight", style=plot.style_circles, color=vfColor, linewidth=2)
vfCondition = shorts ? VFSellSignal : VFBuySignal
// signal
volumeSum = (vsaEnabled? toSignal(vsaBuySellCondition) : 0) + (VHEnabled ? toSignal(VHBuySellCondition):0 ) + (VFEnabled ? toSignal(vfCondition) : 0)
volumeConditions = volumeSum >= volumeConfluence
condition = pCondition and maCondition and volumeConditions
signalC = shorts ? color.red : color.lime
exitC = color.new(color.yellow,60)
plot(2 , title="Deal oppen", style=plot.style_circles, color=condition ? signalC : color.black, linewidth=6)
plot(1.6 , title="Deal close", style=plot.style_circles, color=pExitCondition ? exitC : color.black, linewidth=6)
plot(backtestable ? condition ? 1 : pExitCondition ? 2 : 0 : na, "PVol signal", color = na)