• Get $30 off VIP with code SUMMER30. Ends July 27. Happy trading!

Swing High/Low Indicator for ThinkorSwim


New member
Trying to extract the high and low price for the 2nd highest volume bar. Finding it for the highest is easy enough. I'm using a fold statement to iterate thought the range comparing the volume bars to each other. If there is a better way I'm all ears. Appreciate the help.

declare lower;
input length = 100;

# highest volume bar used to help compare for 2nd highest volume bar
def vol = highest(volume, length);

#2nd highest volume bar need to extract the high and low values. 
def vol2 = fold i = 0 to length with v do if volume[ i ] < vol and volume[ i ] > v then volume[ i ]  else v;

# get the high and low values for the highest volume bar. 
def highPriceVolhigh = GetValue(high, GetMaxValueOffset(volume, length), length);
def lowPriceVolhigh = GetValue(low, GetMaxValueOffset(volume, length), length);


I've searched around the forum and found code that leverages highestall and barnumber to get the highest/lowest values. My ask is bit more complex i'm tying to find the 2nd and 3rd highest volume values x bar before and after the swing high of the volume bar.

I leveraged the swing high swing low code to get the bar number and volume of the first highest volume but now I'll looking from that point to look to find the 2nd highest swing high in that same range. I'm assuming the using the barNumber of the highest volume is the key but i'm not sure how you pass that to HighestAll but not sure how you make a range of it. Any help would be appreciated. Link to image below showing the highest and second highest volume with the price highs and lows for a 5 period lookback and lookforward swing high.


### taken for Robert Paynes swing high low code.
input length = 10;
def bn = BarNumber();
def lastBar = HighestAll(if IsNaN(close) then 0 else bn);
def offset = Min(length - 1, lastBar - bn);

# i get this defines the swing high looking back 10 and foward  10 periods  changed it for volume
def swingHigh = volume > Highest(volume[1], length - 1) and high == GetValue(Highest(volume, length), -offset);
# identify the very last swing high point
def highPointOneBarNumber = HighestAll(if swingHigh then bn else 0);

So i gave it a shot and was able to get the next highest value prior to the swing high but not the highest value after the swing high. Instead I get some weird number I think it has to do with the -offset calculation but can't seem to figure why it give a weird number for vol2 plot. Any help would be greatly appreciated.

input length = 10;

def bn = BarNumber();
def lastBar = HighestAll(if IsNaN(close) then 0 else bn);
def offset = Min(length - 1, lastBar - bn);
def swingHigh = volume > Highest(volume[1], length - 1) and volume == GetValue(Highest(volume, length), -offset);
def volHighBefore = volume > Highest(volume[1], length - 1);
def volHighAfter = volume == GetValue(Highest(volume, length), -offset);

# identify the very last swing high point
def volHighBarNum = HighestAll(if swingHigh then bn else 0);
def volHighValue = if bn == volHighBarNum then high else volHighValue[1];
plot volHighPrior = if bn < volHighBarNum then Double.NaN else volHighValue;

# identify the  highest volume for the last X periods before the last swing high point
def volHighBeforeBarNum = HighestAll(if volHighBefore and bn < volHighBarNum then bn else 0);
def volHighBeforeValue = if bn ==  volHighBeforeBarNum then high else volHighBeforeValue[1];
plot vol1 = if bn < volHighBeforeBarNum then Double.NaN else volHighBeforeValue;

# identify the  highest volume for the last X periods after the last swing high point
def volHighAfterBarNum = HighestAll(if volHighAfter and bn > volHighBarNum then bn else 0);
def volHighAfterValue = if bn ==  volHighAfterBarNum then high else volHighAfterValue[1];
plot vol2 = if bn < volHighAfterBarNum then Double.NaN else volHighAfterValue;
Last edited by a moderator:


New member
This is fairly new to me, so I might not know the appropriate terminology, please bear with me. I am not sure even if I picked the proper category, thank you.

Everyone needs to start somewhere, I might not know what I am doing now, but when I am accomplished, I will surely pass it along. I am requesting help for code that will provide the 3 desired results that could possibly help me.
  • First, Code that will define 5 (swings or waves).
  • Second, code to identify that the 5th (swing or wave) is complete.
  • Third, code that will authenticate that the 5th (swing or wave) is longer than the 3rd swing.
Is this complicated? Whatever you can do for me will be deeply appreciated.

What I was trying to do was. I wanted the highest SWING at the top of the screen. Next have the 2 black candles right after the swing HIGH. And lastly I wanted the 2 black candles to be as close as possible to be Last 2 candles on this chart

def peak =  ( close < close[1] and close[1] < close[2] and close[2] > close[3] and close[3] > close[4]) ;
plot scan = peak;
plot scan highestall (high);
input length = 20;
def = islongblack = islongblack(length);
plot twolongblack = islongblack[1] and islongblack;

My objective is to place a down arrow over close[4] the highest point in the pivot

def peak = ( close < close[1] and close[1] < close[2] and close[2] < close[3] and close[3] < close[4]) and close[4] > close[5] and close [5] > close[6];
plot arrowdown = close[4];

Would like to utilize this script I retrieved from funwiththinkscript but I don't know what is missing to plot this to the chart. I was hoping that Robert or someone was available to help me make this happen. I am new and do not understand the switch concept.

input xyz = {"major", default "minor"};

def R3;
def R2;
def R1;
def PP;
def S1;
def S2;
def S3;
switch (xyz) {
case "major":
PP = MajorCalculation;
R1 = MajorCalculation;
R2 = MajorCalculation;
R3 = MajorCalculation;
S1 = MajorCalculation;
S2 = MajorCalculation;
S3 = MajorCalculation;
case "minor":
PP = MinorCalculation;
R1 = MinorCalculation;
R2 = MinorCalculation;
R3 = MinorCalculation;
S1 = MinorCalculation;
S2 = MinorCalculation;
S3 = MinorCalculation;

plot PP = if Switch == 1 then MinorCalculation else MajorCalculation;


Well-known member
@lee-I-O=coke-A Hi Bernie, and welcome to useThinkScript.com. I am a senior citizen living with brain injury as well.
I do not mean this to be short or snippy:

Please migrate to the tutorial section and look at the Universe of ThinkScript. If one has been created, you'll find it in there.

There is also this post https://usethinkscript.com/threads/wolf-waves-trendline-breakouts-indicator-for-thinkorswim.66/

Google "SyracusePro Thinkscript". I believe that Victor has worked with Elliot, Kondriedtiff and Wolf Waves among others.

Questions: Have you scheduled a platform tour? You are entitled to one. Please contact ThinkorSwim support and ask for one to be scheduled.
Be sure to write down 10 questions to ask that are of interest to you so that your time is well spent.

Why are you starting with such an extremely difficult study to start with? I'd suggest starting smaller.

As far as your last line above, VIP status can be searched for in the Box above.


Is this related to Elliott wave by any chance? See if this can be any help to ya (but I doubt it)

## Mobius' swing high/low script.
## Added Fib retracements and extensions

# The number of bars to look back.
input n = 20;

# Set minDollarRange > 0 to turn off 0.382 and 0.618 Fibs,
# when dollar value of HighLine - LowLine range is less than
# chosen minDollarRange. Set to zero to ignore setting.
input minDollarRange = 200.0;

# Allow lines to be drawn in expansion area (Yes).
input rightExt = Yes;

def H = high;
def L = low;
def cBar = barNumber();
def PH;
def PL;

def isH = fold i = 1 to n + 1 with p = 1
while p do H > getValue(H, -i);

PH = if (cBar > n and H == Highest(H, n) and isH) then H
else double.NaN;

def isL = fold j = 1 to n + 1 with q = 1
while q do L < getValue(L, -j);

PL = if (cBar > n and L == Lowest(L, n) and isL) then l
else double.NaN;

rec PHL = if !IsNaN(PH) then PH else PHL[1];
rec PLL = if !IsNaN(PL) then PL else PLL[1];

def bOk = !IsNaN(h) or rightExt;

plot HighLine = if bOk and PHL > 0 then PHL else double.NaN;

plot LowLine = if bOk and PLL > 0 then PLL else double.NaN;

## Fib Retracements

def Ext0_382 = 0.382;
def Ext0_618 = 0.618;
def Ext0_2 = 0.2;
def Ext0_8 = 0.8;

def rHi = HighLine;
def rLo = LowLine;

def tmidP = (rHi + rLo) / 2;
def range = rHi - rLo;
def F0_382 = rHi - (range * Ext0_382);
def F0_618 = rHi - (range * Ext0_618);
def F0_2 = rHi - (range * Ext0_2);
def F0_8 = rHi - (range * Ext0_8);

def rangeValue = (AbsValue(range) / tickSize()) * tickValue();

def rangeValueOK = minDollarRange <= rangeValue;

plot FibMid = tmidP;
plot Fib0_382 = if !rangeValueOK then Double.NaN else F0_382;
plot Fib0_618 = if !rangeValueOK then Double.NaN else F0_618;
plot Fib0_2 = F0_2;
plot Fib0_8 = F0_8;






## Fib Extensions

def FH_382 = range + if !IsNaN(h) then F0_382 else F0_382[1];

plot FibH_382 = FH_382;


def FL_618 = (if !IsNaN(h) then F0_618 else F0_618[1]) - range;

plot FibL_618 = FL_618;



Active member
Is there an Indicator somewhere that draws a dot on the swing highs and lows ? I did some searching in here and havent found anything . Thanks



New member
I have this indicator which was provided as part of a training course I took , long time back. I cant find the documentation for it and haven't received response from its authors. Any chance someone can help summarize what it might be doing? It plots some good resistance/support lines, but don't understand how its being calculated.

# Trading Analysis Swing Waves - Trader
# Version 1.0
# 6/13/2016
# Authors: Brian Strong - Micro Quant ([email protected]) SwingWave detection
#          Daniel Sinnig - Biiuse Trading ([email protected]) Ideal entry detection

input MajorSwingPeriod = 13;
input MinorSwingPeriod = 5;
input AlertsOn = yes;
input ExpansionFactor = 1.0;
input LookBackPeriod = 200;
input ADXPeriod = 21;
input ShowCounterTrendEntries = no;

def powerStopsOff = no;

def signalOffsetFactor = 0.20;
def offset = Average(TrueRange(high, close, low), 9) * signalOffsetFactor;

#Calculate Major Swings
def majorPivotH = if high > Highest(high[1], MajorSwingPeriod) and high >
Highest(high[-MajorSwingPeriod], MajorSwingPeriod) then 1 else 0;
def majorH = if majorPivotH then high+offset else Double.NaN;
def majorPivotL = if low < Lowest(low[1], MajorSwingPeriod) and low <
Lowest(low[-MajorSwingPeriod], MajorSwingPeriod) then 1 else 0;
def majorL = if majorPivotL then low-offset else Double.NaN;

#Calculate Minor Swings
def minorPivotH = if high > Highest(high[1], MinorSwingPeriod) and high >
Highest(high[-MinorSwingPeriod], MinorSwingPeriod) then 1 else 0;
def minorH = if minorPivotH then high+offset else Double.NaN;
def minorPivotL = if low < Lowest(low[1], MinorSwingPeriod) and low <
Lowest(low[-MinorSwingPeriod], MinorSwingPeriod) then 1 else 0;
def minorL = if minorPivotL then low-offset else Double.NaN;

#Ideal entry detection
#Find last minor and major High and Lows
def indexOfLastMinorHigh = fold minorHighIndex = -MajorSwingPeriod to lookBackPeriod - MajorSwingPeriod  while IsNaN(GetValue(minorH, minorHighIndex)) do minorHighIndex + 1;
def indexOfLastMinorLow = fold minorLowIndex = -MajorSwingPeriod to lookBackPeriod - MajorSwingPeriod while IsNaN(GetValue(minorL, minorLowIndex)) do minorLowIndex + 1;
def indexOfLastMajorHigh = fold majorHighIndex = -MajorSwingPeriod to lookBackPeriod - MajorSwingPeriod while IsNaN(GetValue(majorH, majorHighIndex)) do majorHighIndex + 1;
def indexOfLastMajorLow = fold majorLowIndex = -MajorSwingPeriod to lookBackPeriod - MajorSwingPeriod while IsNaN(GetValue(majorL, majorLowIndex)) do majorLowIndex + 1;

#Find High / Low between current bar and last minor low / high (check that it should only minor for major stops as well)/
def indexOfLastHigh_sinceMinorHigh = fold i20 = -MajorSwingPeriod to indexOfLastMinorHigh + 1 with _tempHigh = Double.NEGATIVE_INFINITY do if GetValue(high, i20) > _tempHigh then GetValue(high, i20) else _tempHigh;
def indexOfLastLow_sinceMinorLow = fold i21 = -MajorSwingPeriod to indexOfLastMinorLow + 1 with _tempLow = Double.POSITIVE_INFINITY do if GetValue(low, i21) < _tempLow then GetValue(low, i21) else _tempLow;

def DiPlusDiMinusDiff = DIPlus(ADXPeriod) - DIMinus(ADXPeriod);

#Calculate and set individual differences

# (1) Major High to major Low
def differenceMajorH_to_MajorL = if IsNaN(majorL)
                                    then 0 #if we are not at a major low then it's 0
                                    else #otherwise find the corresponding major High and calculate the difference
                                        fold i1 = 1 to lookBackPeriod
                                             with diffMajorHighToMajorLow = 0
                                             while (diffMajorHighToMajorLow == 0) do
                                               if (!IsNaN(GetValue(majorL, i1))) then Double.NaN else #if another major low is found then cancel
                                                if (!IsNaN(GetValue(majorH, i1)) and (GetValue(DiPlusDiMinusDiff, i1) < 0)) then Double.NaN #if DI+ is less than DI- then flag as NaN so that loop will stop and it'll be ignored later on
                                                else if (!IsNaN(GetValue(majorH, i1))) then high[i1] - low
                                                                                                  else 0;
def sum_AllDifferences_MajorH_to_MajorL = fold i5 = -MajorSwingPeriod to lookBackPeriod - MajorSwingPeriod
                                            with _tempSum_MajorH_to_MajorL = 0 do
                                            if !IsNaN(differenceMajorH_to_MajorL[i5]) then _tempSum_MajorH_to_MajorL + differenceMajorH_to_MajorL[i5] else _tempSum_MajorH_to_MajorL;
def count_AllDifferences_MajorH_to_MajorL = fold i9 = -MajorSwingPeriod to lookBackPeriod - MajorSwingPeriod with _tempCount_MajorH_to_MajorL = 0 do if
!IsNaN(differenceMajorH_to_MajorL[i9]) then
    if (differenceMajorH_to_MajorL[i9] <> 0) then _tempCount_MajorH_to_MajorL + 1 else _tempCount_MajorH_to_MajorL
else _tempCount_MajorH_to_MajorL;                                                                                               

def average_MajorH_to_MajorL = if (count_AllDifferences_MajorH_to_MajorL <> 0) then sum_AllDifferences_MajorH_to_MajorL / count_AllDifferences_MajorH_to_MajorL else 0;

plot majorLongEntryLine = HighestAll(if IsNaN(close[-MajorSwingPeriod - 1]) and !IsNaN(close) then
    if (!powerStopsOff and (ShowCounterTrendEntries or GetValue(DiPlusDiMinusDiff, -MajorSwingPeriod) >= 0)) then indexOfLastHigh_sinceMinorHigh - average_MajorH_to_MajorL * ExpansionFactor else Double.NaN
else Double.NaN);


# (2) Major Low to major High

def differenceMajorL_to_MajorH = if IsNaN(majorH)
                                    then 0 #if we are not at a minor high then it's 0
                                    else #otherwise find the corresponding major Low and calculate the difference
                                        fold i2 = 1 to lookBackPeriod
                                             with diffMajorLowToMajorHigh = 0
                                             while (diffMajorLowToMajorHigh == 0) do
                                                if (!IsNaN(GetValue(majorH, i2))) then Double.NaN else #if another major high is found then cancel
                                                if (!IsNaN(GetValue(majorL, i2)) and (GetValue(DiPlusDiMinusDiff, i2) > 0)) then Double.NaN #if DI+ is greater than DI- then flag as NaN so that loop will stop and it'll be ignored later on
                                                else if (!IsNaN(GetValue(majorL, i2))) then high - low[i2]
                                                                                                  else 0;
def sum_AllDifferences_MajorL_to_MajorH = fold i6 = -MajorSwingPeriod to lookBackPeriod - MajorSwingPeriod
                                            with _tempSum_MajorL_to_MajorH = 0 do
                                            if !IsNaN(differenceMajorL_to_MajorH[i6]) then _tempSum_MajorL_to_MajorH + differenceMajorL_to_MajorH[i6] else _tempSum_MajorL_to_MajorH;
def count_AllDifferences_MajorL_to_Major_H = fold i10 = -MajorSwingPeriod to lookBackPeriod - MajorSwingPeriod with _tempCount_MajorL_to_MajorH = 0 do if
!IsNaN(differenceMajorL_to_MajorH[i10]) then
    if (differenceMajorL_to_MajorH[i10] <> 0) then _tempCount_MajorL_to_MajorH + 1 else _tempCount_MajorL_to_MajorH
else _tempCount_MajorL_to_MajorH;                                                                                           

def average_MajorL_to_MajorH = if (count_AllDifferences_MajorL_to_Major_H <> 0) then sum_AllDifferences_MajorL_to_MajorH / count_AllDifferences_MajorL_to_Major_H else 0;

plot majorShortEntryLine = HighestAll(if IsNaN(close[-MajorSwingPeriod - 1]) and !IsNaN(close) then
     if (!powerStopsOff and (ShowCounterTrendEntries or GetValue(DiPlusDiMinusDiff, -MajorSwingPeriod) <= 0)) then indexOfLastLow_sinceMinorLow + average_MajorL_to_MajorH * ExpansionFactor else Double.NaN
else Double.NaN);


# (3) Any high to any low (except major to major)

def differenceMinorH_to_MinorL = if IsNaN(minorL)
                                    then 0 #if we are not at a minor low (that is not also a major low)  then it's 0
                                    else #otherwise find the corresponding major High and calculate the difference
                                        fold i3 = 1 to lookBackPeriod
                                             with diffMinorHighToMinorLow = 0
                                             while (diffMinorHighToMinorLow == 0) do
                                               if (!IsNaN(GetValue(minorL, i3))) then Double.NaN else #if another low is found then cancel
                                               if !IsNaN(majorL) and !IsNaN(GetValue(majorH, i3)) then Double.NaN else #exclude major to major
                                               if (!IsNaN(GetValue(minorH, i3)) and (GetValue(DiPlusDiMinusDiff, i3) < 0)) then Double.NaN #if DI+ is less than DI- then flag as NaN so that loop will stop and it'll be ignored later on
                                                else if (!IsNaN(GetValue(minorH, i3))) then high[i3] - low
                                                else 0;

def sum_AllDifferences_MinorH_to_Minor_L = fold i7 = -MajorSwingPeriod to lookBackPeriod - MajorSwingPeriod
                                            with _tempSum_MinorH_to_MinorL = 0 do
                                            if !IsNaN(differenceMinorH_to_MinorL[i7]) then _tempSum_MinorH_to_MinorL + differenceMinorH_to_MinorL[i7] else _tempSum_MinorH_to_MinorL;
def count_AllDifferences_MinorH_to_MinorL = fold i11 = -MajorSwingPeriod to lookBackPeriod - MajorSwingPeriod with _tempCount_MinorH_to_MinorL = 0 do if
!IsNaN(differenceMinorH_to_MinorL[i11]) then
    if (differenceMinorH_to_MinorL[i11] <> 0) then _tempCount_MinorH_to_MinorL + 1 else _tempCount_MinorH_to_MinorL
else _tempCount_MinorH_to_MinorL;                                                                                                

def average_MinorH_to_MinorL = if (count_AllDifferences_MinorH_to_MinorL <> 0) then sum_AllDifferences_MinorH_to_Minor_L / count_AllDifferences_MinorH_to_MinorL else 0;

plot minorLongEntryLine = HighestAll(if IsNaN(close[-MajorSwingPeriod - 1]) and !IsNaN(close) then
if (!powerStopsOff and (ShowCounterTrendEntries or GetValue(DiPlusDiMinusDiff, -MajorSwingPeriod) >= 0)) then indexOfLastHigh_sinceMinorHigh - average_MinorH_to_MinorL * ExpansionFactor else Double.NaN
else Double.NaN);


# (4) Minor Low (not major) to Minor High (not major)

def differenceMinorL_to_MinorH = if IsNaN(minorH)
                                    then 0 #if we are not at a minor low (that is not also a major low)  then it's 0
                                    else #otherwise find the corresponding major High and calculate the difference
                                        fold i4 = 1 to lookBackPeriod
                                             with diffMinorLowToMinorHigh = 0
                                             while (diffMinorLowToMinorHigh == 0) do
                                                if (!IsNaN(GetValue(minorH, i4))) then Double.NaN else #if another high is found then cancel
                                                if !IsNaN(majorH) and !IsNaN(GetValue(majorL, i4)) then Double.NaN else #exclude major to major
                                                if (!IsNaN(GetValue(minorL, i4)) and (GetValue(DiPlusDiMinusDiff, i4) > 0)) then Double.NaN #if DI+ is greater than DI- then flag as NaN so that loop will stop and it'll be ignored later on
                                                    else if (!IsNaN(GetValue(minorL, i4))) then high - low [i4]
                                                    else 0;

def sum_AllDifferences_MinorL_to_MinorH = fold i8 = -MajorSwingPeriod to lookBackPeriod - MajorSwingPeriod
                                            with _tempSum_MinorL_to_MinorH = 0 do
                                            if !IsNaN(differenceMinorL_to_MinorH[i8]) then _tempSum_MinorL_to_MinorH + differenceMinorL_to_MinorH[i8] else _tempSum_MinorL_to_MinorH;
def count_AllDifferences_MinorL_to_MinorH = fold i12 = -MajorSwingPeriod to lookBackPeriod - MajorSwingPeriod with _tempCount_MinorL_to_MinorH = 0 do if
!IsNaN(differenceMinorL_to_MinorH[i12]) then
    if (differenceMinorL_to_MinorH[i12] <> 0) then _tempCount_MinorL_to_MinorH + 1 else _tempCount_MinorL_to_MinorH
else _tempCount_MinorL_to_MinorH;                                                                                             

def average_MinorL_to_MinorH = if (count_AllDifferences_MinorL_to_MinorH <> 0) then sum_AllDifferences_MinorL_to_MinorH / count_AllDifferences_MinorL_to_MinorH else 0;

plot minorShortEntryLine = HighestAll(if IsNaN(close[-MajorSwingPeriod - 1]) and !IsNaN(close) then
if  (!powerStopsOff and (ShowCounterTrendEntries or GetValue(DiPlusDiMinusDiff, -MajorSwingPeriod) <= 0)) then indexOfLastLow_sinceMinorLow + average_MinorL_to_MinorH * ExpansionFactor else Double.NaN
else Double.NaN);


Here is another indicator that plots the swing highs and swing lows in ThinkorSwim. You set the length period to identify the highest price point and lowest price point within the lookback period.

# HINT: this code is a TOS  Mr Scripts Chart study
# that plots an Exponential moving average line
# and also finds and counts swing high/swing low points

input length = 50;
input price = close;
input averageType = AverageType.EXPONENTIAL;

plot avg = MovingAverage(averageType, price, length);
def height = avg - avg[length];
def AngleDeg = ATan(height / length) * 180 / Double.Pi;
def up = AngleDeg >= 0.0;
avg.AssignValueColor(if up then Color.RED else Color.BLUE);

input swing_back = 8;
input swing_forward = 2;
input maxbars = 30;
input showlevels = Yes;
def na = Double.NaN;
def lfor = Lowest(low, swing_forward)[-swing_forward];
def lback = Lowest(low, swing_back)[1];
def swinglow = if low < lfor and low <= lback then 1 else 0;
plot sl = if swinglow then low else na;
def hfor = Highest(high, swing_forward)[-swing_forward];
def hback = Highest(high, swing_back)[1];
def swinghigh = if high > hfor and high >= hback then 1 else 0;
plot sh = if swinghigh then high else na;

rec countd = CompoundValue(2, if !up and (swinglow or swinghigh) then countd[1] + 1 else if up and (swinglow or swinghigh)  then 0 else countd[1], 1);

rec count = CompoundValue(2, if up and (swinglow or swinghigh) then count[1] + 1 else if !up and (swinglow or swinghigh)  then 0 else count[1], 1);

plot x = if (swinglow or swinghigh) and count != 0 then count else Double.NaN;

plot y = if (swinglow or swinghigh) and countd != 0 then countd else Double.NaN;


Well-known member
2019 Donor
Can we create a script that shows the confluence of the major and minor wave lines at tops and bottoms.... garleys whatever that shows on all time frames with an audible alert when these points converge and preferably an upper indicator.


Last edited by a moderator:


I'm using the below code to create previous high and low levels. seems to work well.

How can i get this to allow me to store the 2nd previous swing high or 2nd previous swing low?

My goal is to compare the the 2nd previous high to the current previous high to determine up or down trend.

I have tried using the simple Support[1] > Support[2] but it doesn't seem to work. When i add these to a label, it only gives me to current high or low no matter what value i put into the [ ].

Please help.

input LookbackPeriod = 3;
input HideCurrentTF = no;

def _highInPeriod1 = Highest(high, LookbackPeriod);
def _lowInPeriod1 = Lowest(low, LookbackPeriod);
def marketLow1 = if _lowInPeriod1 < _lowInPeriod1[-LookbackPeriod] then _lowInPeriod1 else _lowInPeriod1[-LookbackPeriod];
def _markedLow1 = low == marketLow1;

rec _lastMarkedLow1 = CompoundValue(1, if IsNaN(_markedLow1) then _lastMarkedLow1[1] else if _markedLow1 then low else _lastMarkedLow1[1], low);
def marketHigh1 = if _highInPeriod1 > _highInPeriod1[-LookbackPeriod] then _highInPeriod1 else _highInPeriod1[-LookbackPeriod];
def _markedHigh1 = high == marketHigh1;

rec _lastMarkedHigh1 = CompoundValue(1, if IsNaN(_markedHigh1) then _lastMarkedHigh1[1] else if _markedHigh1 then high else _lastMarkedHigh1[1], high);
plot Resistance1 = _lastMarkedHigh1;
plot Support1 = _lastMarkedLow1 ;


I'm struggling with this. I feel like this should be something relatively easy to figure out but i can't seem to crack the logic on this. Simply doubling the lookback period doesn't help.

For example - I just want to record the previous 2 highs of 82.94 and 82.90 as well as the 2 previous lows of 82.25 and 82.33. Once i can do that, i can use them for comparison.

Last edited by a moderator:


New member
Hi team, I'm looking to code up an indicator that tells me if the current high takes out a previous swing high.

Wo far I've got this with my poor thinkscript skills.

#returns a list of local tops - aka highest pivot high with 10 bars to the left and 10 to the right
def isMinorHigh = fold i = -10 to 10 with isHigh = high do (if GetValue(high, i) > high then 0 else isHigh);

#returns the last value of the high that's not NaN
def getPreviousHigh = fold j = 0 to 99 while GetValue(isMinorHigh, j)<0.1 do GetValue(isMinorHigh, j+1);

#this should return if the current high of the bar is higher than the previous high
plot scan = high > getPreviousHigh[1];

For some reason, this code works as a label on a chart quite well (ex: high>getPreviousHigh[1]) but it doesn't work in the scanner - i think the scan query kinda defaults to 'true' and I am not sure how to debug what causes it and the limitations of the scanner etc.

Anybody got any ideas?



Well-known member
2019 Donor
I posted an older study using the above techniques so I thought I would throw out an update. I have not used TOS for a while and decided to pick it up again after using trade view... well I'm back toTOS.

Primarily the strategy consists of using a script that will plot market wave highs and lows posting a label at each high and low showing the price change amount this is the core of my strategy.

The lines plotted for major and minor waves continue until the major and minor lines will converge for at some point at a market high/low and when they do these are the best odds for a successful trade, they form triangles at tops and bottoms of price channels.

The indicators I use: market moves 2.0, 8/15 exponential moving averages, Laguerre upper study https://tos.mx/X0hJEUz with a Laguerre MTF lower study https://tos.mx/eTzkKBu, can use harmonic patterns the script https://tos.mx/2LfTtet basically that's it.


Personally I do not use harmonics but its the closest thing to my script that is not available to share and I trade a 2 min chart I primarily scalp but extend those lines out on higher time frames and follow for gains.

Can also think of using the wave lines as a heads up to change in price direction and probably the best way to confirm buy sell signals is by using the lower RSI in Laguerre Time MTF Option_v3 script and watch for the cross below 8 and above 2 shown on the 1 hr chart. https://tos.mx/DEBxarm


I've combined some studies that help to validate my wave the wave theory I'm using the CCI/ATR, moving average crossover upper, and a harmonics study I came across. I split the charts so the left chart shows the above cross over and the right shows the below crossover with all else being the same indicators just be sure to change that under the crossover script.



I'm watching AMD running a 4-hour chart and only using minor waves. We finished out a minor yesterday and the price still dropping so I wait for the next minor wave to draw to ending a 4h drawdown before I consider buying back in, always keep an eye on the daily for lines to be drawn.

Last edited by a moderator:


Active member
I feel your pain. I'm trying to write a script to connect a high to the next highest high and a low to the next lowest low, but no dice


Well-known member
2019 Donor
Wonder if it is possible to create a scan from the swing waves script?
Last edited by a moderator:


New member
Here is my attempt/compiled code for a Broadening Pattern. I am new to thinkscript but not new to programming. Please see if this can help you. Also, I would appreciate it if you can review/test and provide comments. Reminded me of middle school/high school math :)

Rich (BB code):
#Broadening Pattern
#Multiple Sources
# Fun with thinkscript: https://researchtrade.com/forum/read.php?7,2258,page=31
# UseThinkScript: https://usethinkscript.com/threads/create-column-based-on-peak-and-valley-indicator.901/
# https://funwiththinkscript.com/count-the-number-of-bars-between-successive-highs/
# Idea source: https://www.patternsmart.com/cart/index.php?route=product/product&product_id=430&search=broadening

# 20201019 Raj B, initial code upto calculating peaks/valleys, getting barNumbers , checking if broadening pattern conditions exist
# 20201020 Raj B. Added ability for separate left/right threshold to allow indepedent values
# 20201020 Raj B. Added initial column/watchlist alerts, needs testing
# TODO complete alert part

# Inputs

input LeftBarsThreshold = 5;
input RightBarsThreshold = 5;
input isAlertSetup = no;
input debug = yes;

# Setup
def bn = BarNumber();

# Calculate values for peaks
def peak = high > Highest(high[1], LeftBarsThreshold) and high >= Highest(high[-RightBarsThreshold], RightBarsThreshold);
plot peakBoolean = peak;

def peakValue = if peak then high else peakValue[1];
def peakBar = if peak then BarNumber() else Double.NaN;

# Calculate barNumbers for previous 2 peaks

def lastPeakBarNumber = HighestAll(if peak then bn else 0);
def prevPeakBarNumber = HighestAll(if peak and bn < lastPeakBarNumber then bn else 0);

# Get values for previous 2 peaks
def lastPeakValue = GetValue(high, bn - HighestAll(peakBar));
def prevPeakValue = GetValue(peakValue[1], bn - HighestAll(peakBar));

#  Calculate values for valleys/low points
def valley = low < Lowest(low[1], LeftBarsThreshold) and low <= Lowest(low[-RightBarsThreshold], RightBarsThreshold);
plot valleyBoolean = valley;

def valleyValue = if valley then low else valleyValue[1];
def valleyBar = if valley then BarNumber() else Double.NaN;

# Get barNumbers for previous 2 valleys
def lastValleyBarNumber = HighestAll(if valley then bn else 0);
def prevValleyBarNumber = HighestAll(if valley and bn < lastValleyBarNumber then bn else 0);

# Get values for previous 2 valleys
def lastValleyValue = GetValue(low, bn - HighestAll(valleyBar));
def prevValleyValue = GetValue(valleyValue[1], bn - HighestAll(valleyBar));

# Do we have valid values for peaks/valleys and
# are they  increasing peaks and decreasing valleys
def areLast2PeaksIncreasing =  !IsNaN(lastPeakValue) and !IsNaN(prevPeakValue) and lastPeakValue > prevPeakValue;
def areLast2ValleysDecreasing = !IsNaN(lastValleyValue) and !IsNaN(prevValleyValue) and lastValleyValue < prevValleyValue;

# Do we have interlaced peaks/valleys
def peaksValleysInterlaced = (prevValleyBarNumber > prevPeakBarNumber and prevValleyBarNumber < lastPeakBarNumber)
                              (prevPeakBarNumber > prevValleyBarNumber and prevPeakBarNumber < lastValleyBarNumber);

def  inBroadeningPattern = areLast2PeaksIncreasing and areLast2ValleysDecreasing and peaksValleysInterlaced;

# if we have a broadening pattern, get last 2 values and draw a line with extension

# get scaling factor for high side, low side
# initial line is drawn using last 2 peaks/valleys
# However, after those 2 points, we need to use scaling factors to extend the line y=mx+c
# Thank you to my middle school math teachers in India :)
# Expect valleyScalePerBar to be negative number

def peakScalePerBar = (lastPeakValue - prevPeakValue) / (lastPeakBarNumber - prevPeakBarNumber );
def valleyScalePerBar = (lastValleyValue - prevValleyValue) / (lastValleyBarNumber - prevValleyBarNumber );

def peakExtendedValue = lastPeakValue + (bn - lastPeakBarNumber) * peakScalePerBar;
def valleyExtendedValue = lastValleyValue + (bn - lastValleyBarNumber) * valleyScalePerBar;

#Draw UpperLine, initial with 2 points, then extend with scaling factor
plot upperLine = if !isAlertSetup and inBroadeningPattern and bn > lastPeakBarNumber
                 then peakExtendedValue
                 else if inBroadeningPattern and peak and bn >= prevPeakBarNumber
                 then high
                 else Double.NaN;

plot lowerLine = if !isAlertSetup and inBroadeningPattern and bn > lastValleyBarNumber
                 then valleyExtendedValue
                 else if inBroadeningPattern and valley and bn >= prevValleyBarNumber
                 then low
                 else Double.NaN;


# alert when crosses over/above line?

#get highestPrice after last peak

#def highValueAfterLastPeak = Highest(high[-(bn-lastPeakBarNumber)], RightBarsThreshold);

# scantype=1; for price cross above upper line
#def scantype_1 = inBroadeningPattern and high >

# scantype=2; for price cross below lower line
# scantype=3; for price is below lower line
def scantype_3 = inBroadeningPattern and high > peakExtendedValue;
# scantype=4; for price is above upper line
def scantype_4 = inBroadeningPattern and low < valleyExtendedValue;
# scantype=5; for price is inside two lines.
def scantype_5 = inBroadeningPattern and high < peakExtendedValue
                                     and low  > valleyExtendedValue;

# getDisplayValue for alerts/scans

AddLabel(scantype_3, "Above BF", Color.CYAN);
AddLabel(scantype_4, "Below BF", Color.CYAN);
AddLabel(scantype_5, "Between BF", Color.CYAN);

AddLabel(debug, "BarNumber:" + bn, Color.WHITE);
AddLabel(debug, "lastpeakbar:" + lastPeakBarNumber, Color.WHITE);
AddLabel(debug, "prevPeakGetValue:" + prevPeakBarNumber, Color.WHITE);
AddLabel(debug, "lastpeakvalue:" + lastPeakValue, Color.WHITE);
AddLabel(debug, "previouspeakvalue:" + prevPeakValue, Color.WHITE);

AddLabel(debug, "lastvalleybar:" + lastValleyBarNumber, Color.YELLOW);
AddLabel(debug, "prevValleyGetValue:" + prevValleyBarNumber, Color.YELLOW);
AddLabel(debug, "lastvalleyvalue:" + lastValleyValue, Color.YELLOW);
AddLabel(debug, "previousvalleyvalue:" + prevValleyValue, Color.YELLOW);

AddLabel(debug, "IncPeaks?:" + areLast2PeaksIncreasing, Color.WHITE);
AddLabel(debug, "DecPeaks?:" + areLast2ValleysDecreasing, Color.WHITE);
AddLabel(debug, "ValuesInterlaced?:" + peaksValleysInterlaced, Color.WHITE);
AddLabel(debug, "BroadPattern?:" + inBroadeningPattern, if inBroadeningPattern then Color.LIGHT_GREEN else Color.LIGHT_RED);

AddLabel(debug, "peakSideScaleFactor:" + peakScalePerBar, Color.YELLOW);
AddLabel(debug, "valleySideScaleFactor:" + valleyScalePerBar, Color.YELLOW);

AddLabel(debug, "peakExtendedValue:" + peakExtendedValue, Color.YELLOW);
AddLabel(debug, "valleyExtendedValue:" + valleyExtendedValue, Color.YELLOW);

#AddLabel(debug, "LastPrice:" + last, Color.YELLOW);
Last edited:


New member
Hey @RajB. Thank you so much for the formula. I'm having trouble seeing the yellow and purple lines on my chart. Is there something I need to fix in the settings of the formula or does it only work on certain time frames? Any help would be appreciated. Thanks


New member
@Slydog482 Hi, The script works on all different timeframes. However, it will ONLY draw the lines when conditions for broadening formation are valid. It needs 2 higher/increasing peaks and two lower decreasing valleys and the highs/lows interlaced.

If you edit the settings for the script and set debug=yes, then it will show you the values for highs/lows and its overall assessment. If you find a bug, do let me know and I will attempt to fix it. What does it say for the value of BroadPattern? 0 or 1?



New member
:) Thank you. If you find any issues, please let me know. It would be great if you like the post with script above and also post 1-2 images of you using it on your stock of choice. I may learn something about trading/watching it.

Similar threads