stochastic + tsv
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © goonerholic

//@version=5
indicator("stochastic + tsv", overlay=true)

// ========================================================================================================
// ========================================================================================================
// EMA ====================================================================================================
useEma = input.bool(true, title="Ema 사용여부", tooltip="지표의 계산에 ema 조건을 포함시킬지 결정합니다", group="EMA")
emaPeriod = input.int(200, title="EMA Period", group="EMA")
ema = ta.ema(close, emaPeriod)

emaLongCond = useEma ? close > ema : true
emaShortCond = useEma ? close < ema : true

plot(ema, "ema")


// ========================================================================================================
// ========================================================================================================
// Stochastic =============================================================================================
periodK = input.int(7, title="%K Length", minval=1, group="Stochastic")
smoothK = input.int(3, title="%K Smoothing", minval=1, group="Stochastic")

k = ta.sma(ta.stoch(close, high, low, periodK), smoothK)

stochUpper = 80
stochLower = 20
stochMiddle = 50

var int direction = na

if (ta.crossunder(k, stochLower))
    direction := 1

if (ta.crossover(k, stochUpper))
    direction := -1

if (ta.cross(k, stochMiddle))
    direction := 0

stochLongCond = direction == 1 and k <= stochMiddle
stochShortCond = direction == -1 and k >= stochMiddle

// ========================================================================================================
// ========================================================================================================
// Stochastic RSI =========================================================================================
lengthStoch = input.int(14, "%K Length", minval=1, group="Stochastic RSI")
smoothKRSI = input.int(3, "%K Smoothing", minval=1, group="Stochastic RSI")
lengthRSI = input.int(14, "RSI Length", minval=1, group="Stochastic RSI")
src = input(close, title="RSI Source", group="Stochastic RSI")
rsi1 = ta.rsi(src, lengthRSI)
rsik = ta.sma(ta.stoch(rsi1, rsi1, rsi1, lengthStoch), smoothKRSI)

var int stochRsiDirection = na

if (ta.crossunder(rsik, stochLower))
    stochRsiDirection := 1
if (ta.crossover(rsik, stochUpper))
    stochRsiDirection := -1
if (ta.cross(rsik, stochMiddle))
    stochRsiDirection := 0

stochRsiLongCond = stochRsiDirection == 1 and rsik <= stochMiddle
stochRsiShortCond = stochRsiDirection == -1 and rsik >= stochMiddle

plotchar(direction, "direction", display=display.data_window)
plotchar(stochRsiDirection, "RSI direction", display=display.data_window)
// ========================================================================================================
// ========================================================================================================
// Supertrend 3n1 =========================================================================================

PeriodsA = input.int(title="ATR Period", defval=12)
srcA = input.source(hl2, title="Source")
MultiplierA = input.float(title="ATR Multiplier", step=0.1, defval=3.0)
changeATRA= input.bool(title="Change ATR Calculation Method ?", defval=true)
// showsignalsA = input.bool(title="Show Buy/Sell Signals ?", defval=true)
// highlightingA = input.bool(title="Highlighter On/Off ?", defval=true)
atr2A = ta.sma(ta.tr, PeriodsA)
atrA= changeATRA ? ta.atr(PeriodsA) : atr2A
upA=srcA-(MultiplierA*atrA)
up1A = nz(upA[1],upA)
upA := close[1] > up1A ? math.max(upA,up1A) : upA
dnA=srcA+(MultiplierA*atrA)
dn1A = nz(dnA[1], dnA)
dnA := close[1] < dn1A ? math.min(dnA, dn1A) : dnA
trendA = 1
trendA := nz(trendA[1], trendA)
trendA := trendA == -1 and close > dn1A ? 1 : trendA == 1 and close < up1A ? -1 : trendA

PeriodsB = input.int(title="ATR Period", defval=11)
srcB = input.source(hl2, title="Source")
MultiplierB = input.float(title="ATR Multiplier", step=0.1, defval=2.0)
changeATRB= input.bool(title="Change ATR Calculation Method ?", defval=true)
// showsignalsB = input.bool(title="Show Buy/Sell Signals ?", defval=true)
// highlightingB = input.bool(title="Highlighter On/Off ?", defval=true)
atr2B = ta.sma(ta.tr, PeriodsB)
atrB= changeATRB ? ta.atr(PeriodsB) : atr2B
upB=srcB-(MultiplierB*atrB)
up1B = nz(upB[1],upB)
upB := close[1] > up1B ? math.max(upB,up1B) : upB
dnB=srcB+(MultiplierB*atrB)
dn1B = nz(dnB[1], dnB)
dnB := close[1] < dn1B ? math.min(dnB, dn1B) : dnB
trendB = 1
trendB := nz(trendB[1], trendB)
trendB := trendB == -1 and close > dn1B ? 1 : trendB == 1 and close < up1B ? -1 : trendB

PeriodsC = input.int(title="ATR Period", defval=10)
srcC = input.source(hl2, title="Source")
MultiplierC = input.float(title="ATR Multiplier", step=0.1, defval=1.0)
changeATRC= input.bool(title="Change ATR Calculation Method ?", defval=true)
atr2C = ta.sma(ta.tr, PeriodsC)
atrC= changeATRC ? ta.atr(PeriodsC) : atr2C
upC=srcC-(MultiplierC*atrC)
up1C = nz(upC[1],upC)
upC := close[1] > up1C ? math.max(upC,up1C) : upC
dnC=srcC+(MultiplierC*atrC)
dn1C = nz(dnC[1], dnC)
dnC := close[1] < dn1C ? math.min(dnC, dn1C) : dnC
trendC = 1
trendC := nz(trendC[1], trendC)
trendC := trendC == -1 and close > dn1C ? 1 : trendC == 1 and close < up1C ? -1 : trendC

supertrendCount = trendA + trendB + trendC

// plotchar(trendA, "trendA", display=display.data_window)
// plotchar(trendB, "trendB", display=display.data_window)
// plotchar(trendC, "trendC", display=display.data_window)

supertrendLongCond = supertrendCount >= 1
supertrendShortCond = supertrendCount <= -1

// ========================================================================================================
// ========================================================================================================
// TSV ====================================================================================================

tsv_length = input.int(13, "TSV Length")
tsv = math.sum(close > close[1] or close < close[1] ? volume * (close - close[1]) : 0, tsv_length)

tsvLongCond = tsv > 0
tsvShortCond = tsv < 0

longAlertCond = emaLongCond and (stochLongCond or stochRsiLongCond) and supertrendLongCond and tsvLongCond
shortAlertCond = emaShortCond and (stochShortCond or stochRsiShortCond) and supertrendShortCond and tsvShortCond

plotshape(longAlertCond, "Long", style=shape.labelup, location=location.belowbar, color=color.green)
plotshape(shortAlertCond, "Short", style=shape.labeldown, location=location.abovebar, color=color.red)

alertcondition(longAlertCond, "Long", "Long")
alertcondition(shortAlertCond, "Short", "Short")