# Lane's Stochastic Divergence Indicator for ThinkorSwim
# BenTen 3/19/19
declare lower;
input over_bought = 80.0;
input over_sold = 20.0;
input percentDLength = 3;
input percentKLength = 14;
input AudibleAlert = yes;
def min_low = Lowest(low, percentKLength);
def max_high = Highest(high, percentKLength);
def rel_diff = close - (max_high + min_low) / 2;
def diff = max_high - min_low;
def avgrel = Average(Average(rel_diff, percentDLength), percentDLength);
def avgdiff = Average(Average(diff, percentDLength), percentDLength);
def SMIData = (avgrel / (avgdiff / 2) + 1) * 50;
def isLow = If (SMIData < SMIData[-1] and SMIData < SMIData[1], 1, 0);
def isHigh = If (SMIData > SMIData[-1] and SMIData > SMIData[1], 1, 0);
rec prevLowSMI = CompoundValue(1, If(isLow[1], SMIData[1], prevLowSMI[1]), 0);
rec prevHighSMI = CompoundValue(1, If(isHigh[1], SMIData[1], prevHighSMI[1]), 0);
rec prevLow = CompoundValue(1, If(isLow[1], low, prevLow[1]), low);
rec prevHigh = CompoundValue(1, If(isHigh[1], high, prevHigh[1]), high);
def positiveDivergenceReg = If (SMIData > prevLowSMI and low < prevLow, 1,0);
def positiveDivergenceHid = If (SMIData < prevLowSMI and low > prevLow, 1,0);
DefineGlobalColor("ArrowUp", CreateColor(0, 200, 255)) ;
DefineGlobalColor("ArrowDn", CreateColor(225, 0, 0)) ;
DefineGlobalColor("neutral", color.gray) ;
plot posDiv = If(isLow and (positiveDivergenceReg or positiveDivergenceHid), SMIData, Double.NaN);
posDiv.AssignValueColor(if positiveDivergenceReg then GlobalColor("ArrowUp") else
GlobalColor("neutral"));
posDiv.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
posDiv.SetLineWeight(2);
def negativeDivergenceReg = If (SMIData < prevHighSMI and high > prevHigh,1, 0);
def negativeDivergenceHid = If (SMIData > prevHighSMI and high < prevHigh,1, 0);
plot negDiv = If(isHigh and ( negativeDivergenceReg or negativeDivergenceHid), SMIData, Double.NaN);
negDiv.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
negDiv.AssignValueColor(if negativeDivergenceReg then GlobalColor("ArrowDn") else
GlobalColor("neutral"));
negDiv.SetLineWeight(2);
plot AvgSMI = Average(SMIData, percentDLength);
AvgSMI.SetDefaultColor(Color.GRAY);
plot overbought = over_bought;
overbought.SetDefaultColor(Color.WHITE);
overbought.SetStyle(Curve.SHORT_DASH);
plot oversold = over_sold;
oversold.SetDefaultColor(Color.WHITE);
oversold.SetStyle(Curve.SHORT_DASH);
plot SMI = SMIData;
SMI.AssignValueColor(if SMI > SMI[1] then Color.GREEN else Color.RED);
SMI.SetLineWeight(2);