True Strength Index Indicator for ThinkorSwim

TSI Dashboard For ThinkOrSwim
Here is my TSI Dashboard.
You should be able to amend it to meet your needs.

This version is superior to the Tradestation code you listed. Your code only looks at above and below zero. This takes all the conditions into account.

I use the True Strength dashboard to weed out the false signals of other studies.
7xPzgeb.png

Ruby:
###########################################################################
#TSItsiTSI
#Settings
#standard = 25,13,8
#quicker = 13,7,8
#daily, weekly & monthly = 40,20,8

#A quick review of the BUY signals:
#1. TSI crosses above zero.
#2. TSI crosses above moving average.
#3. TSI makes higher low (below zero) while price makes a lower low

#And the SELL signals:
#1. TSI crosses below zero
#2. TSI crosses below moving average
#3. TSI makes a lower high (above zero) while price makes a higher high
#4. Trend of TSI breaks down
declare lower;
input longLength = 25;
input shortLength = 13;
input signalLength = 8;
input averageType = AverageType.EXPONENTIAL;

def diff = close - close[1];
def doubleSmoothedAbsDiff = MovingAverage(averageType, MovingAverage(averageType, AbsValue(diff), longLength), shortLength);

def TSI = if doubleSmoothedAbsDiff == 0 then 0
      else 100 * (MovingAverage(averageType, MovingAverage(averageType, diff, longLength), shortLength)) / doubleSmoothedAbsDiff;

def Signal = MovingAverage(averageType, TSI, signalLength);
##########################################################################
#TSI Short Term

input longLengths = 8;
input shortLengths = 8;
input signalLengths = 3;

def diffs = close - close[1];
def doubleSmoothedAbsDiffs = MovingAverage(averageType, MovingAverage(averageType, AbsValue(diffs), longLengths), shortLengths);

def TSIs;
TSIs = if doubleSmoothedAbsDiffs == 0 then 0
      else 100 * (MovingAverage(averageType, MovingAverage(averageType, diffs, longLengths), shortLengths)) / doubleSmoothedAbsDiffs;
##########################################################################
#TSI Long Term
input longLengthl = 40;
input shortLengthl = 20;
input signalLengthl = 8;

def diffl = close - close[1];
def doubleSmoothedAbsDiffl = MovingAverage(averageType, MovingAverage(averageType, AbsValue(diffl), longLengthl), shortLengthl);

def TSIl;
TSIl = if doubleSmoothedAbsDiffl == 0 then 0
      else 100 * (MovingAverage(averageType, MovingAverage(averageType, diffl, longLengthl), shortLengthl)) / doubleSmoothedAbsDiffl;
######################################################################
#TSI Horizontal Line
def bullish = TSIl > TSIl[1] and TSIs > TSIs[1] and TSI > TSI[1];
def bearish = TSIl < TSIl[1] and TSIs < TSIs[1] and TSI < TSI[1];
def bar = barNumber();

plot TSI_Dashboard = 0.00;
TSI_Dashboard.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
TSI_Dashboard.SetLineWeight(2);
TSI_Dashboard.AssignValueColor(if bullish then Color.cyan else if bearish then Color.dark_orange else Color.GRAY);
@MerryDay
Another question is about the time axis. When "Expansion area" is used (shown as in the picture below):
The TSI dashboard cannot have the "expansion area" automatically (shown in the picture below):

How can I make this work?
Thanks!
 
I have the following code updated with divergence line. Can anyone help with adding paint bar color according to HISTOGRAM COLORS.

Thank you.

Here is the code.
Code:
# True Strength Index Bladeof300

declare lower;

input longLength = 25;
input shortLength = 13;
input signalLength = 8;
input averageType = AverageType.EXPONENTIAL;

def diff = close - close[1];
def doubleSmoothedAbsDiff = MovingAverage(averageType, MovingAverage(averageType, AbsValue(diff), longLength), shortLength);

plot TSI;
plot Signal;

TSI = if doubleSmoothedAbsDiff == 0 then 0
else 100 * (MovingAverage(averageType, MovingAverage(averageType, diff, longLength), shortLength)) / doubleSmoothedAbsDiff;
Signal = MovingAverage(averageType, TSI, signalLength);

plot ZeroLine = 0;

TSI.SetDefaultColor(GetColor(1));
Signal.SetDefaultColor(GetColor(8));
Signal.Hide();
ZeroLine.SetDefaultColor(GetColor(5));



TSI.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
TSI.SetLineWeight(3);
TSI.DefineColor("Positive and Up", Color.GREEN);
TSI.DefineColor("Positive and Down",(CreateColor(153, 0, 242)));
TSI.DefineColor("Negative and Down", Color.RED);
TSI.DefineColor("Negative and Up", Color.YELLOW);
TSI.AssignValueColor(if TSI >= 0 then if TSI > TSI[1] then TSI.Color("Positive and Up") else TSI.Color("Positive and Down") else if TSI < TSI[1] then TSI.Color("Negative and Down") else TSI.Color("Negative and Up"));

input n = 20;
def bar = BarNumber();
def Currh = if tsi > zeroline
then fold i = 1 to Floor(n / 2)
with p = 1
while p
do tsi > getValue(tsi, -i)
else 0;
def CurrPivotH = if (bar > n and
tsi == highest(tsi, Floor(n/2)) and
Currh)
then tsi
else double.NaN;
def Currl = if tsi < zeroline
then fold j = 1 to Floor(n / 2)
with q = 1
while q
do tsi < getValue(tsi, -j)
else 0;
def CurrPivotL = if (bar > n and
tsi == lowest(tsi, Floor(n/2)) and
Currl)
then tsi
else double.NaN;
def CurrPHBar = if !isNaN(CurrPivotH)
then bar
else CurrPHBar[1];
def CurrPLBar = if !isNaN(CurrPivotL)
then bar
else CurrPLBar[1];
def PHpoint = if !isNaN(CurrPivotH)
then CurrPivotH
else PHpoint[1];
def priorPHBar = if PHpoint != PHpoint[1]
then CurrPHBar[1]
else priorPHBar[1];
def PLpoint = if !isNaN(CurrPivotL)
then CurrPivotL
else PLpoint[1];
def priorPLBar = if PLpoint != PLpoint[1]
then CurrPLBar[1]
else priorPLBar[1];
def HighPivots = bar >= highestAll(priorPHBar);
def LowPivots = bar >= highestAll(priorPLBar);
def pivotHigh = if HighPivots
then CurrPivotH
else double.NaN;
plot PlotHline = pivotHigh;
PlotHline.enableApproximation();
PlotHline.SetDefaultColor(GetColor(5));
PlotHline.SetStyle(Curve.LONG_DASH);
PlotHline.SetLineWeight(5);
plot pivotLow = if LowPivots
then CurrPivotL
else double.NaN;
pivotLow.enableApproximation();
pivotLow.SetDefaultColor(GetColor(6));
pivotLow.SetStyle(Curve.LONG_DASH);
pivotLow.SetLineWeight(3);
plot PivotDot = if !isNaN(pivotHigh)
then pivotHigh
else if !isNaN(pivotLow)
then pivotLow
else double.NaN;
pivotDot.SetDefaultColor(GetColor(3));
pivotDot.SetPaintingStrategy(PaintingStrategy.POINTS);
pivotDot.SetLineWeight(3);

Thank you.
 
Last edited by a moderator:
Painting Candles:
d6cKDiW.png

Ruby:
# True Strength Index

declare lower;

input longLength = 25;
input shortLength = 13;
input signalLength = 8;
input averageType = AverageType.EXPONENTIAL;

def diff = close - close[1];
def doubleSmoothedAbsDiff = MovingAverage(averageType, MovingAverage(averageType, AbsValue(diff), longLength), shortLength);

plot TSI;
plot Signal;

TSI = if doubleSmoothedAbsDiff == 0 then 0
else 100 * (MovingAverage(averageType, MovingAverage(averageType, diff, longLength), shortLength)) / doubleSmoothedAbsDiff;
Signal = MovingAverage(averageType, TSI, signalLength);

plot ZeroLine = 0;

TSI.SetDefaultColor(GetColor(1));
Signal.SetDefaultColor(GetColor(8));
Signal.Hide();
ZeroLine.SetDefaultColor(GetColor(5));



TSI.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
TSI.SetLineWeight(3);
TSI.DefineColor("Positive and Up", Color.GREEN);
TSI.DefineColor("Positive and Down",(CreateColor(153, 0, 242)));
TSI.DefineColor("Negative and Down", Color.RED);
TSI.DefineColor("Negative and Up", Color.YELLOW);
TSI.AssignValueColor(if TSI >= 0 then if TSI > TSI[1] then TSI.Color("Positive and Up") else TSI.Color("Positive and Down") else if TSI < TSI[1] then TSI.Color("Negative and Down") else TSI.Color("Negative and Up"));


AssignPriceColor(
if TSI >= 0 then if TSI > TSI[1] then TSI.Color("Positive and Up") else TSI.Color("Positive and Down") else
if TSI < TSI[1] then TSI.Color("Negative and Down") else TSI.Color("Negative and Up"));

input n = 20;
def bar = BarNumber();
def Currh = if tsi > zeroline
then fold i = 1 to Floor(n / 2)
with p = 1
while p
do tsi > getValue(tsi, -i)
else 0;
def CurrPivotH = if (bar > n and
tsi == highest(tsi, Floor(n/2)) and
Currh)
then tsi
else double.NaN;
def Currl = if tsi < zeroline
then fold j = 1 to Floor(n / 2)
with q = 1
while q
do tsi < getValue(tsi, -j)
else 0;
def CurrPivotL = if (bar > n and
tsi == lowest(tsi, Floor(n/2)) and
Currl)
then tsi
else double.NaN;
def CurrPHBar = if !isNaN(CurrPivotH)
then bar
else CurrPHBar[1];
def CurrPLBar = if !isNaN(CurrPivotL)
then bar
else CurrPLBar[1];
def PHpoint = if !isNaN(CurrPivotH)
then CurrPivotH
else PHpoint[1];
def priorPHBar = if PHpoint != PHpoint[1]
then CurrPHBar[1]
else priorPHBar[1];
def PLpoint = if !isNaN(CurrPivotL)
then CurrPivotL
else PLpoint[1];
def priorPLBar = if PLpoint != PLpoint[1]
then CurrPLBar[1]
else priorPLBar[1];
def HighPivots = bar >= highestAll(priorPHBar);
def LowPivots = bar >= highestAll(priorPLBar);
def pivotHigh = if HighPivots
then CurrPivotH
else double.NaN;
plot PlotHline = pivotHigh;
PlotHline.enableApproximation();
PlotHline.SetDefaultColor(GetColor(5));
PlotHline.SetStyle(Curve.LONG_DASH);
PlotHline.SetLineWeight(5);
plot pivotLow = if LowPivots
then CurrPivotL
else double.NaN;
pivotLow.enableApproximation();
pivotLow.SetDefaultColor(GetColor(6));
pivotLow.SetStyle(Curve.LONG_DASH);
pivotLow.SetLineWeight(3);
plot PivotDot = if !isNaN(pivotHigh)
then pivotHigh
else if !isNaN(pivotLow)
then pivotLow
else double.NaN;
pivotDot.SetDefaultColor(GetColor(3));
pivotDot.SetPaintingStrategy(PaintingStrategy.POINTS);
pivotDot.SetLineWeight(3);
@APOT7 @majidg
 
I modified the TOS standard code to add labels and clouds. This accents the relationship of the TSI line to the zero line, which is an important interpretation of the TSI indicator. . Modify it further as you need....Scott

Code:
# SD_TOS_TSI
# TD Ameritrade IP Company, Inc. (c) 2007-2021
# Altered TOS version to add labels and clouds showing relationship to the zero line
# The signal line is "commented" out

declare lower;

input longLength = 25;
input shortLength = 13;
# input signalLength = 8;
input averageType = AverageType.EXPONENTIAL;
input TSI_Labels = yes;
input TSI_Clouds = yes;

def diff = close - close[1];
def doubleSmoothedAbsDiff = MovingAverage(averageType, MovingAverage(averageType, AbsValue(diff), longLength), shortLength);

plot TSI;
# plot Signal;

TSI = if doubleSmoothedAbsDiff == 0 then 0
else 100 * (MovingAverage(averageType, MovingAverage(averageType, diff, longLength), shortLength)) / doubleSmoothedAbsDiff;

# Signal = MovingAverage(averageType, TSI, signalLength);

plot ZeroLine = 0;

TSI.SetDefaultColor(GetColor(1));
# Signal.SetDefaultColor(GetColor(8));
# Signal.Hide();
ZeroLine.SetDefaultColor(GetColor(5));

AddLabel(TSI_Labels, if TSI < ZeroLine and TSI > TSI[1] then "  BELOW & UP  " else "", Color.CYAN);

AddLabel(TSI_Labels, if TSI > ZeroLine and TSI > TSI[1] then "  ABOVE & UP  " else "", Color.GREEN);

AddLabel(TSI_Labels, if TSI > ZeroLine and TSI < TSI[1] then "  ABOVE & DOWN  " else "", Color.MAGENTA);

AddLabel(TSI_Labels, if TSI < ZeroLine and TSI < TSI[1] then "  BELOW & DOWN  " else "", Color.RED);

AddCloud(if TSI_Clouds == yes and TSI > TSI[1] and TSI > ZeroLine then TSI else double.nan, ZeroLine, Color.GREEN, Color.GREEN);

AddCloud(if TSI_Clouds == yes and TSI < TSI[1] and TSI < ZeroLine then ZeroLine else double.nan, TSI, Color.RED, Color.RED);


### END ###
 
Last edited by a moderator:
I have the following code updated with divergence line. Can anyone help with adding paint bar color according to HISTOGRAM COLORS.

Thank you.

Here is the code.
Code:
# True Strength Index Bladeof300

declare lower;

input longLength = 25;
input shortLength = 13;
input signalLength = 8;
input averageType = AverageType.EXPONENTIAL;

def diff = close - close[1];
def doubleSmoothedAbsDiff = MovingAverage(averageType, MovingAverage(averageType, AbsValue(diff), longLength), shortLength);

plot TSI;
plot Signal;

TSI = if doubleSmoothedAbsDiff == 0 then 0
else 100 * (MovingAverage(averageType, MovingAverage(averageType, diff, longLength), shortLength)) / doubleSmoothedAbsDiff;
Signal = MovingAverage(averageType, TSI, signalLength);

plot ZeroLine = 0;

TSI.SetDefaultColor(GetColor(1));
Signal.SetDefaultColor(GetColor(8));
Signal.Hide();
ZeroLine.SetDefaultColor(GetColor(5));



TSI.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
TSI.SetLineWeight(3);
TSI.DefineColor("Positive and Up", Color.GREEN);
TSI.DefineColor("Positive and Down",(CreateColor(153, 0, 242)));
TSI.DefineColor("Negative and Down", Color.RED);
TSI.DefineColor("Negative and Up", Color.YELLOW);
TSI.AssignValueColor(if TSI >= 0 then if TSI > TSI[1] then TSI.Color("Positive and Up") else TSI.Color("Positive and Down") else if TSI < TSI[1] then TSI.Color("Negative and Down") else TSI.Color("Negative and Up"));

input n = 20;
def bar = BarNumber();
def Currh = if tsi > zeroline
then fold i = 1 to Floor(n / 2)
with p = 1
while p
do tsi > getValue(tsi, -i)
else 0;
def CurrPivotH = if (bar > n and
tsi == highest(tsi, Floor(n/2)) and
Currh)
then tsi
else double.NaN;
def Currl = if tsi < zeroline
then fold j = 1 to Floor(n / 2)
with q = 1
while q
do tsi < getValue(tsi, -j)
else 0;
def CurrPivotL = if (bar > n and
tsi == lowest(tsi, Floor(n/2)) and
Currl)
then tsi
else double.NaN;
def CurrPHBar = if !isNaN(CurrPivotH)
then bar
else CurrPHBar[1];
def CurrPLBar = if !isNaN(CurrPivotL)
then bar
else CurrPLBar[1];
def PHpoint = if !isNaN(CurrPivotH)
then CurrPivotH
else PHpoint[1];
def priorPHBar = if PHpoint != PHpoint[1]
then CurrPHBar[1]
else priorPHBar[1];
def PLpoint = if !isNaN(CurrPivotL)
then CurrPivotL
else PLpoint[1];
def priorPLBar = if PLpoint != PLpoint[1]
then CurrPLBar[1]
else priorPLBar[1];
def HighPivots = bar >= highestAll(priorPHBar);
def LowPivots = bar >= highestAll(priorPLBar);
def pivotHigh = if HighPivots
then CurrPivotH
else double.NaN;
plot PlotHline = pivotHigh;
PlotHline.enableApproximation();
PlotHline.SetDefaultColor(GetColor(5));
PlotHline.SetStyle(Curve.LONG_DASH);
PlotHline.SetLineWeight(5);
plot pivotLow = if LowPivots
then CurrPivotL
else double.NaN;
pivotLow.enableApproximation();
pivotLow.SetDefaultColor(GetColor(6));
pivotLow.SetStyle(Curve.LONG_DASH);
pivotLow.SetLineWeight(3);
plot PivotDot = if !isNaN(pivotHigh)
then pivotHigh
else if !isNaN(pivotLow)
then pivotLow
else double.NaN;
pivotDot.SetDefaultColor(GetColor(3));
pivotDot.SetPaintingStrategy(PaintingStrategy.POINTS);
pivotDot.SetLineWeight(3);
Great Job! I really like this indicator for the pivot points!
 
Last edited by a moderator:
Great Job! I really like this indicator. If I wanted to keep the Pivot Points plotted (I realize they are for divergence purposes now), what would I need to do to modify the above code? I want to put a solid vertical line when there is a high or low pivot point.
Can you please help to provide the code for scanning the pivodot?
 
Can you please help to provide the code for scanning the pivodot?
Here is the portion that creates the pivot dot. I tried plotting the pivotDot and also tried the PivotLow and PivotHi but they disappear when new plots are made. I'm just not sure which part of the code to change to keep the previous pivot dots plotted.

Code:
input n = 20;
def bar = BarNumber();
def Currh = if tsi > zeroline
then fold i = 1 to Floor(n / 2)
with p = 1
while p
do tsi > getValue(tsi, -i)
else 0;
def CurrPivotH = if (bar > n and
tsi == highest(tsi, Floor(n/2)) and
Currh)
then tsi
else double.NaN;
def Currl = if tsi < zeroline
then fold j = 1 to Floor(n / 2)
with q = 1
while q
do tsi < getValue(tsi, -j)
else 0;
def CurrPivotL = if (bar > n and
tsi == lowest(tsi, Floor(n/2)) and
Currl)
then tsi
else double.NaN;
def CurrPHBar = if !isNaN(CurrPivotH)
then bar
else CurrPHBar[1];
def CurrPLBar = if !isNaN(CurrPivotL)
then bar
else CurrPLBar[1];
def PHpoint = if !isNaN(CurrPivotH)
then CurrPivotH
else PHpoint[1];
def priorPHBar = if PHpoint != PHpoint[1]
then CurrPHBar[1]
else priorPHBar[1];
def PLpoint = if !isNaN(CurrPivotL)
then CurrPivotL
else PLpoint[1];
def priorPLBar = if PLpoint != PLpoint[1]
then CurrPLBar[1]
else priorPLBar[1];
def HighPivots = bar >= highestAll(priorPHBar);
def LowPivots = bar >= highestAll(priorPLBar);
def pivotHigh = if HighPivots
then CurrPivotH
else double.NaN;
plot PlotHline = pivotHigh;
PlotHline.enableApproximation();
PlotHline.SetDefaultColor(GetColor(5));
PlotHline.SetStyle(Curve.LONG_DASH);
PlotHline.SetLineWeight(1);
plot pivotLow = if LowPivots
then CurrPivotL
else double.NaN;
pivotLow.enableApproximation();
pivotLow.SetDefaultColor(GetColor(6));
pivotLow.SetStyle(Curve.LONG_DASH);
pivotLow.SetLineWeight(1);
plot PivotDot = if !isNaN(pivotHigh)
then pivotHigh
else if !isNaN(pivotLow)
then pivotLow
else double.NaN;
pivotDot.SetDefaultColor(GetColor(3));
pivotDot.SetPaintingStrategy(PaintingStrategy.POINTS);
pivotDot.SetLineWeight(3);

addVerticalLine(pivotDot, " ", color.white,curve.short_dash);
 
Here is the portion that creates the pivot dot. I tried plotting the pivotDot and also tried the PivotLow and PivotHi but they disappear when new plots are made. I'm just not sure which part of the code to change to keep the previous pivot dots plotted.
It is not possible to keep the previous pivot dots plotted. As this indicator repaints, it deletes the previous plots and there is no record of their existence in this code.
 
TSI Dashboard For ThinkOrSwim
Here is my TSI Dashboard.
You should be able to amend it to meet your needs.

This version is superior to the Tradestation code you listed. Your code only looks at above and below zero. This takes all the conditions into account.

I use the True Strength dashboard to weed out the false signals of other studies.
7xPzgeb.png

Ruby:
###########################################################################
#TSItsiTSI
#Settings
#standard = 25,13,8
#quicker = 13,7,8
#daily, weekly & monthly = 40,20,8

#A quick review of the BUY signals:
#1. TSI crosses above zero.
#2. TSI crosses above moving average.
#3. TSI makes higher low (below zero) while price makes a lower low

#And the SELL signals:
#1. TSI crosses below zero
#2. TSI crosses below moving average
#3. TSI makes a lower high (above zero) while price makes a higher high
#4. Trend of TSI breaks down
declare lower;
input longLength = 25;
input shortLength = 13;
input signalLength = 8;
input averageType = AverageType.EXPONENTIAL;

def diff = close - close[1];
def doubleSmoothedAbsDiff = MovingAverage(averageType, MovingAverage(averageType, AbsValue(diff), longLength), shortLength);

def TSI = if doubleSmoothedAbsDiff == 0 then 0
      else 100 * (MovingAverage(averageType, MovingAverage(averageType, diff, longLength), shortLength)) / doubleSmoothedAbsDiff;

def Signal = MovingAverage(averageType, TSI, signalLength);
##########################################################################
#TSI Short Term

input longLengths = 8;
input shortLengths = 8;
input signalLengths = 3;

def diffs = close - close[1];
def doubleSmoothedAbsDiffs = MovingAverage(averageType, MovingAverage(averageType, AbsValue(diffs), longLengths), shortLengths);

def TSIs;
TSIs = if doubleSmoothedAbsDiffs == 0 then 0
      else 100 * (MovingAverage(averageType, MovingAverage(averageType, diffs, longLengths), shortLengths)) / doubleSmoothedAbsDiffs;
##########################################################################
#TSI Long Term
input longLengthl = 40;
input shortLengthl = 20;
input signalLengthl = 8;

def diffl = close - close[1];
def doubleSmoothedAbsDiffl = MovingAverage(averageType, MovingAverage(averageType, AbsValue(diffl), longLengthl), shortLengthl);

def TSIl;
TSIl = if doubleSmoothedAbsDiffl == 0 then 0
      else 100 * (MovingAverage(averageType, MovingAverage(averageType, diffl, longLengthl), shortLengthl)) / doubleSmoothedAbsDiffl;
######################################################################
#TSI Horizontal Line
def bullish = TSIl > TSIl[1] and TSIs > TSIs[1] and TSI > TSI[1];
def bearish = TSIl < TSIl[1] and TSIs < TSIs[1] and TSI < TSI[1];
def bar = barNumber();

plot TSI_Dashboard = 0.00;
TSI_Dashboard.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
TSI_Dashboard.SetLineWeight(2);
TSI_Dashboard.AssignValueColor(if bullish then Color.cyan else if bearish then Color.dark_orange else Color.GRAY);
@MerryDay , looks to be a great addition, Thanks! Does this indicator repaint?

I just have the horizontal bar in the lower study, using the above code. So not sure about these comments on the code:
----
#A quick review of the BUY signals:
#1. TSI crosses above zero.
#2. TSI crosses above moving average.
#3. TSI makes higher low (below zero) while price makes a lower low

#And the SELL signals:
#1. TSI crosses below zero
#2. TSI crosses below moving average
#3. TSI makes a lower high (above zero) while price makes a higher high
#4. Trend of TSI breaks down
---
These buy/sell signals, moving average crossovers etc.. are part of a different study?


I guess thats what my question is...Can you point me to the TSI histogram study pls? The study just plots the horizontal bar. But the comments in the code talk about TSI crossing Zero line,MA etc. Or is this just the horizontal bar(which is fine, but want to confirm)
I've plotted this on my Stochastic Oscillator..great idea to overlay this on any oscillator to save space..!
( Think am well aware of oscillator signals/definitions - been doing this for over two decades :))

Thanks!
 
Last edited by a moderator:
@MerryDay I guess thats what my question is...Can you point me to the TSI histogram study pls? The study just plots the horizontal bar. But the comments in the code talk about TSI crossing Zero line,MA etc. Or is this just the horizontal bar(which is fine, but want to confirm)
I've plotted this on my Stochastic Oscillator..great idea to overlay this on any oscillator to save space..!
( Think am well aware of oscillator signals/definitions - been doing this for over two decades :))

Thanks!
There are several modified TSI scripts in this thread. The original is a built-in ToS study: TrueStrengthIndex

The horizontal line was created to save real estate. But should probably only be used when you have watched and understand the
TSI histogram action.

The line can be overlaid on any oscillator on your chart(defaults to overlaying the zero line; must be modified if oscillator has a different midpoint).
It can be used as a traffic light to confirm your other indicators.

The buy/sell signals, moving average crossovers etc.. are not part of a different study.
These are the common definitions of oscillator buy / sells.
Read more here: https://usethinkscript.com/threads/how-to-read-an-oscillator-in-thinkorswim.11497/#post-99858
 
@MerryDay , looks to be a great addition, Thanks! Does this indicator repaint?

I just have the horizontal bar in the lower study, using the above code. So not sure about these comments on the code:
----
#A quick review of the BUY signals:
#1. TSI crosses above zero.
#2. TSI crosses above moving average.
#3. TSI makes higher low (below zero) while price makes a lower low

#And the SELL signals:
#1. TSI crosses below zero
#2. TSI crosses below moving average
#3. TSI makes a lower high (above zero) while price makes a higher high
#4. Trend of TSI breaks down
---
These buy/sell signals, moving average crossovers etc.. are part of a different study?


I guess thats what my question is...Can you point me to the TSI histogram study pls? The study just plots the horizontal bar. But the comments in the code talk about TSI crossing Zero line,MA etc. Or is this just the horizontal bar(which is fine, but want to confirm)
I've plotted this on my Stochastic Oscillator..great idea to overlay this on any oscillator to save space..!
( Think am well aware of oscillator signals/definitions - been doing this for over two decades :))

Thanks!
try BJ TSI converted from TV. pls test.

#//@Bjorgum on Stocktwits
#//@version=5
#indicator ( "Bjorgum TSI", "BJ TSI" )
#https://www.tradingview.com/script/VX852ekB-Bjorgum-TSI/
# Converted by SAM4COk - Not Exact Convert :)
# ================================== //
# ---------> User Input <----------- //
# ================================== //
declare lower;

def Na = Double.NaN;
def RTH = SecondsFromTime(0930) >= 0 and SecondsTillTime(1600) >= 0;

input strat = {default Fast, Slow};

#// TSI Colors //
DefineGlobalColor("tsiBull", CreateColor( 23, 255, 0 ));
DefineGlobalColor("tsiMid", CreateColor(149, 152, 161));
DefineGlobalColor("tsiBear", CreateColor(243, 255, 0 ));
DefineGlobalColor("tslBull", CreateColor(100, 181, 246));
DefineGlobalColor("tslBear", CreateColor(211, 47 , 47 ));
DefineGlobalColor("fillBull", CreateColor(100, 181, 246));
DefineGlobalColor("fillBear", CreateColor(211, 47 , 47 ));
DefineGlobalColor("oBot", CreateColor(255, 0 , 0 ));
DefineGlobalColor("oSold", CreateColor(100, 181, 246));
DefineGlobalColor("oZero", CreateColor(178, 181, 190));
DefineGlobalColor("obBar", CreateColor(255, 0 , 0 ));
DefineGlobalColor("neBar", CreateColor(255, 255, 255));
DefineGlobalColor("osBar", CreateColor( 23, 255, 0 ));

input FastLong = 25; # "Long Length"
input FastShort = 5; # "Short Length"
input FastSignal = 14; # "Signal Length"

input SlowLong = 25; # "Long Length"
input Slowshort = 13; # "Short Length"
input Slowsignal = 13; # "Signal Length"

input OBValue = 30; # "Ob Value"
input OSValue = -30; # "Os Value"
input OBOSLines = yes; # "Show Ob/Os Lines"
input ZeroLine = yes; # "Show Zero Line"
input BarColor = no; # "Ob/Os Curl Color"

# ================================== //,
# ---> Functional Declarations <---- //
# ================================== //

#// TSI Scripts //
script nz
{
input data1 = 0;
input data2 = close;
def ret_val = if IsNaN(data1) then data1 else data2;
plot return = ret_val;
}

script _doubleSmooth {
input src = 0;
input longvar = 0;
input shortvar = 0;
def fist_smooth = ExpAverage(src, longvar);
def smooth = ExpAverage(fist_smooth, shortvar);
plot return = smooth;
}
# ================================== //
# ----> Variable Calculations <----- //
# ================================== //

def tsifast = strat == strat.Fast;
def tsislow = strat == strat.Slow;

def shortvar = if tsifast then FastShort else if tsislow then Slowshort else Na;
def longvar = if tsifast then FastLong else if tsislow then SlowLong else Na;
def signalvar = if tsifast then FastSignal else if tsislow then Slowsignal else Na;

def pc = close - close[1];
def dSmoothPc = _doubleSmooth(pc, longvar, shortvar);
def dSmoothAbs = _doubleSmooth(AbsValue(pc), longvar, shortvar);
def tsi = 100 * (dSmoothPc / dSmoothAbs);
def tsl = ExpAverage(tsi, signalvar);

# ================================== //
# ----> Conditional Parameters <---- //
# ================================== //

def data = tsi > tsi[1] and tsi < tsl;
def dtat = tsi < tsi[1] and tsi > tsl;

def lot1 = tsl >= tsl[1];
def lot2 = tsl < tsl[1];

def data1 = tsi >= tsl;
def data2 = tsi < tsl;

def obcol = tsi > OBValue and tsi < tsi[1] and tsi[1] > tsl[1];
def oscol = tsi < OSValue and tsi > tsi[1] and tsi[1] < tsl[1];

Plot obcol1 = if RTH and obcol then tsl else na;
obcol1.SetPaintingStrategy(PaintingStrategy.POINTS);
obcol1.AssignValueColor(GlobalColor("tslBear"));
obcol1.SetLineWeight(3);

Plot oscol1 = if RTH and oscol then tsl else na;
oscol1.SetPaintingStrategy(PaintingStrategy.POINTS);
oscol1.AssignValueColor(GlobalColor("tsiBull"));
oscol1.SetLineWeight(3);

def buy = Crosses (tsi, tsl , CrossingDirection.ABOVE);
def sell = Crosses (tsi, tsl , CrossingDirection.BELOW);
def cross = Crosses (tsi, tsl , CrossingDirection.ANY);

def tsixup = Crosses (tsi, OBValue, CrossingDirection.ABOVE);
def tsixdwn = Crosses (tsi, OSValue, CrossingDirection.BELOW);

# ================================== //
# ------> Graphical Display <------- //
# ================================== //

plot p1 = tsi; # "TSI Value Line"
p1.AssignValueColor(if data then GlobalColor("tsiBull") else
if dtat then GlobalColor("tsiBear") else GlobalColor("tsiMid"));

plot p2 = tsl; # "TSI Signal Line"
p2.AssignValueColor(if lot1 then GlobalColor("tslBull") else
if lot2 then GlobalColor("tslBear") else color.current);

plot p3 = if OBOSLines then OBValue else Na; # "Overbought"
P3.SetPaintingStrategy(PaintingStrategy.DASHES);
p3.AssignValueColor(GlobalColor("oBot"));

plot p4 = if OBOSLines then OSValue else Na; # "Oversold"
P4.SetPaintingStrategy(PaintingStrategy.DASHES);
p4.AssignValueColor(GlobalColor("oSold"));

plot p5 = if ZeroLine then 0 else Na; # "Zero"
P5.SetPaintingStrategy(PaintingStrategy.DASHES);
p5.AssignValueColor(GlobalColor("oZero"));

Def jercol = if obcol then -1 else if oscol then 1 else 0;

AssignPriceColor ( if BarColor then if jercol > 0 then GlobalColor("osBar") else
if jercol < 0 then GlobalColor("obBar") else
GlobalColor("neBar")else Color.CURRENT);

AddCloud(p1, p2, GlobalColor("fillBull") , GlobalColor("fillBear"));
 
Here is another version with histogram.
1727821140201.png

Code:
#TSI
declare lower;

input longLength = 25;
input shortLength = 13;
input signalLength = 8;
input averageType = AverageType.EXPONENTIAL;

def diff = close - close[1];
def doubleSmoothedAbsDiff = MovingAverage(averageType, MovingAverage(averageType, AbsValue(diff), longLength), shortLength);

plot Signal;
plot TSI;

plot up = 20;
plot dn = -20;
up.setdefaultColor(color.red);
dn.setdefaultColor(color.green);

TSI = if doubleSmoothedAbsDiff == 0 then 0
      else 100 * (MovingAverage(averageType, MovingAverage(averageType, diff, longLength), shortLength)) / doubleSmoothedAbsDiff;
Signal = MovingAverage(averageType, TSI, signalLength);

plot ZeroLine = 0;

TSI.SetDefaultColor(GetColor(1));
#Signal.SetDefaultColor(GetColor(8));
Signal.AssignValueColor(if Signal < TSI then Color.green else Color.red);
#Signal.hide();
ZeroLine.SetDefaultColor(GetColor(5));

TSI.SetPaintingStrategy( PaintingStrategy.HISTOGRAM );
TSI.setlineWeight(4);
#SwingTrd2.SetDefaultColor( Color.MAGENTA );


TSI.AssignValueColor(if TSI > TSI[1] and TSI > 20 then Color.magenta
else if TSI > TSI[1] and TSI > 10 and TSI < 20 then color.red
else if TSI > TSI[1] and TSI > 0 then Color.yellow
else if TSI > 0 and TSI < TSI[1] and TSI < Signal then color.downtick
else if TSI > 0 and TSI < TSI[1] then color.dark_red
else if TSI < -20 and TSI < TSI[1] then Color.cyan
else if TSI > -20 and TSI < -10 and TSI < TSI[1] then Color.dark_green
else if TSI < 0 and TSI < TSI[1] then createColor(51,102,255)
else if TSI < 0 and TSI > TSI[1] and TSI > signal then color.light_green
else color.green);
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
416 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top