Swing High/Low Indicator for ThinkorSwim

truth_talker

New member
Many of the books I've read have trading setups which have a series of conditions which must be met and those may happen all over several days. While I am able to write some intermediate-level scripts I haven't been able to figure out how to wait until the multiple conditions are met before raising a signal.

As an example, in Chapter 6 of Explosive Stock Trading Strategies (Explosive Stock Trading Strategies: Samir Elias: 9780984638703: AmazonSmile: Books) the author details a scalping setup for stocks which requires the following steps:
1) Identify a minor support day by finding a peak-valley-peak pattern on the daily chart. Specifically (close[1] > close and close < close[-1])

2) Day "1" is the first day after the minor support day that close < minor support day close

3) Day "2" is the first day after Day "1" where close < Day "1" close

4) Day "3" is the first day after Day "2" where low < Day "2" close

5) The trigger day for the trade is the next day after Day "3".

What is the best way to represent these sequence of conditions in thinkScript?
 

truth_talker

New member
Thank you for responding.

Using the Chart Pattern creation wizard it seems straightforward to create the minor support day pattern in step 1 above. For steps 2-5, however, is it possible to wait an arbitrary number of days until each condition is true?
 

NathanJames

New member
Hello Coders,

I just want to ask if the code below can be converted for my watchlist with matching color CYAN,MAGENTA. This code is not mine as you can tell from code below but i just want to use it for my watchlist. Thank you, have a great day!


Code:
# Swing High and Swing Low
# tomsk
# 11.18.2019
# As requested by chillc15 I have modified [USER=1174]@RobertPayne[/USER] code to include SwingHigh
# points which are now plotted in CYAN with the swing high points painted in PINK.
# So now you have both swing high and low on your charts
#  +------------------------------------------------------------+
# | Example: How to extend levels to the right of the chart |
# | Robert Payne |
# | https://funwiththinkscript.com |
#  +------------------------------------------------------------+
# SWING LOW
# define swing low points
input length = 10;
def bn = BarNumber();
def lastBar = HighestAll(if IsNaN(close) then 0 else bn);
def offset = Min(length - 1, lastBar - bn);
def swingLow = low < Lowest(low[1], length - 1) and low == GetValue(Lowest(low, length), -offset);
# identify the very last swing low point
def lowPointOneBarNumber = HighestAll(if swingLow then bn else 0);
def lowPointOneValue = if bn == lowPointOneBarNumber then low else lowPointOneValue[1];
plot low1 = if bn < lowPointOneBarNumber then Double.NaN else lowPointOneValue;
low1.SetDefaultColor(Color.LIGHT_RED);
# identify the 2nd to last swing low point
def lowPointTwoBarNumber = HighestAll(if swingLow and bn < lowPointOneBarNumber then bn else 0);
def lowPointTwoValue = if bn == lowPointTwoBarNumber then low else lowPointTwoValue[1];
plot low2 = if bn < lowPointTwoBarNumber then Double.NaN else lowPointTwoValue;
low2.SetDefaultColor(Color.Light_RED);
# just keep doing ths for as many lines as you want to add to the chart
# identify then 3rd to last swingHigh point low
def lowPointThreeBarNumber = HighestAll(if swingLow and bn < lowPointTwoBarNumber then bn else 0);
def lowPointThreeValue = if bn == lowPointThreeBarNumber then low else lowPointThreeValue[1];
plot low3 = if bn < lowPointThreeBarNumber then Double.NaN else lowPointThreeValue;
low3.SetDefaultColor(Color.Light_RED);
# identify then 4th to last swingHigh point low
def lowPointFourBarNumber = HighestAll(if swingLow and bn < lowPointThreeBarNumber then bn else 0);
def lowPointFourValue = if bn == lowPointFourBarNumber then low else lowPointFourValue[1];
plot low4 = if bn < lowPointFourBarNumber then Double.NaN else lowPointFourValue;
low4.SetDefaultColor(Color.Light_RED);
# identify then 5th to last swingHigh point low
def lowPointFiveBarNumber = HighestAll(if swingLow and bn < lowPointFourBarNumber then bn else 0);
def lowPointFiveValue = if bn == lowPointFiveBarNumber then low else lowPointFiveValue[1];
plot low5 = if bn < lowPointFiveBarNumber then Double.NaN else lowPointFiveValue;
low5.SetDefaultColor(Color.Light_RED);
# identify then 6th to last swingHigh point low
def lowPointSixBarNumber = HighestAll(if swingLow and bn < lowPointFiveBarNumber then bn else 0);
def lowPointSixValue = if bn == lowPointSixBarNumber then low else lowPointSixValue[1];
plot low6 = if bn < lowPointSixBarNumber then Double.NaN else lowPointSixValue;
low6.SetDefaultColor(Color.Light_RED);
# identify then 7th to last swingHigh point low
def lowPointSevenBarNumber = HighestAll(if swingLow and bn < lowPointSixBarNumber then bn else 0);
def lowPointSevenValue = if bn == lowPointSevenBarNumber then low else lowPointSevenValue[1];
plot low7 = if bn < lowPointSevenBarNumber then Double.NaN else lowPointSevenValue;
low7.SetDefaultColor(Color.Light_RED);
# identify then 8th to last swingHigh point low
def lowPointEightBarNumber = HighestAll(if swingLow and bn < lowPointSevenBarNumber then bn else 0);
def lowPointEightValue = if bn == lowPointEightBarNumber then low else lowPointEightValue[1];
plot low8 = if bn < lowPointEightBarNumber then Double.NaN else lowPointEightValue;
low8.SetDefaultColor(Color.Light_RED);
# identify then 9th to last swingHigh point low
def lowPointNineBarNumber = HighestAll(if swingLow and bn < lowPointEightBarNumber then bn else 0);
def lowPointNineValue = if bn == lowPointNineBarNumber then low else lowPointNineValue[1];
plot low9 = if bn < lowPointNineBarNumber then Double.NaN else lowPointNineValue;
low9.SetDefaultColor(Color.Light_RED);
# identify then 10th to last swingHigh point low
def lowPointTenBarNumber = HighestAll(if swingLow and bn < lowPointNineBarNumber then bn else 0);
def lowPointTenValue = if bn == lowPointTenBarNumber then low else lowPointTenValue[1];
plot low10 = if bn < lowPointTenBarNumber then Double.NaN else lowPointTenValue;
low10.SetDefaultColor(Color.Light_RED);


# SWING HIGH
# define swing high points
def swingHigh = high > Highest(high[1], length - 1) and high == GetValue(Highest(high, length), -offset);
# identify the very last swing high point
def highPointOneBarNumber = HighestAll(if swingHigh then bn else 0);
def highPointOneValue = if bn == highPointOneBarNumber then high else highPointOneValue[1];
plot high1 = if bn < highPointOneBarNumber then Double.NaN else highPointOneValue;
high1.SetDefaultColor(Color.CYAN);
# identify the 2nd to last swing high point
def highPointTwoBarNumber = HighestAll(if swingHigh and bn < highPointOneBarNumber then bn else 0);
def highPointTwoValue = if bn == highPointTwoBarNumber then high else highPointTwoValue[1];
plot high2 = if bn < highPointTwoBarNumber then Double.NaN else highPointTwoValue;
high2.SetDefaultColor(Color.CYAN);
# just keep doing ths for as many lines as you want to add to the chart
def highPointThreeBarNumber = HighestAll(if swingHigh and bn < highPointTwoBarNumber then bn else 0);
def highPointThreeValue = if bn == highPointThreeBarNumber then high else highPointThreeValue[1];
plot high3 = if bn < highPointThreeBarNumber then Double.NaN else highPointThreeValue;
high3.SetDefaultColor(Color.CYAN);
def highPointFourBarNumber = HighestAll(if swingHigh and bn < highPointThreeBarNumber then bn else 0);
def highPointFourValue = if bn == highPointFourBarNumber then high else highPointFourValue[1];
plot high4 = if bn < highPointFourBarNumber then Double.NaN else highPointFourValue;
high4.SetDefaultColor(Color.CYAN);
def highPointFiveBarNumber = HighestAll(if swingHigh and bn < highPointFourBarNumber then bn else 0);
def highPointFiveValue = if bn == highPointFiveBarNumber then high else highPointFiveValue[1];
plot high5 = if bn < highPointFiveBarNumber then Double.NaN else highPointFiveValue;
high5.SetDefaultColor(Color.CYAN);
def highPointSixBarNumber = HighestAll(if swingHigh and bn < highPointFiveBarNumber then bn else 0);
def highPointSixValue = if bn == highPointSixBarNumber then high else highPointSixValue[1];
plot high6 = if bn < highPointsixBarNumber then Double.NaN else highPointsixValue;
high6.SetDefaultColor(Color.CYAN);
def highPointSevenBarNumber = HighestAll(if swingHigh and bn < highPointSixBarNumber then bn else 0);
def highPointSevenValue = if bn == highPointSevenBarNumber then high else highPointSevenValue[1];
plot high7 = if bn < highPointSevenBarNumber then Double.NaN else highPointSevenValue;
high7.SetDefaultColor(Color.CYAN);
def highPointEightBarNumber = HighestAll(if swingHigh and bn < highPointSevenBarNumber then bn else 0);
def highPointEightValue = if bn == highPointEightBarNumber then high else highPointEightValue[1];
plot high8 = if bn < highPointEightBarNumber then Double.NaN else highPointEightValue;
high4.SetDefaultColor(Color.CYAN);
def highPointNineBarNumber = HighestAll(if swingHigh and bn < highPointEightBarNumber then bn else 0);
def highPointNineValue = if bn == highPointNineBarNumber then high else highPointNineValue[1];
plot high9 = if bn < highPointNineBarNumber then Double.NaN else highPointNineValue;
high4.SetDefaultColor(Color.CYAN);
def highPointTenBarNumber = HighestAll(if swingHigh and bn < highPointNineBarNumber then bn else 0);
def highPointTenValue = if bn == highPointTenBarNumber then high else highPointTenValue[1];
plot high10 = if bn < highPointTenBarNumber then Double.NaN else highPointTenValue;
high4.SetDefaultColor(Color.CYAN);

# ADJUST CANDLE COLORS
# change candle colors just to make it easier to see what we are working with
AssignPriceColor(if swingLow then Color.cyan else if swingHigh then Color.mageNTA else Color.current);
# End Swing High and Swing Low
 

MerryDay

Administrative
Staff member
Staff
VIP
@tradeidea20 @Mosd You can keep asking but no matter where you post or where it is moved, it won't get you an answer. I don't know any omnitraders on this forum, who would be able to convert your code.

For future reference, if you post a question and don't get an answer, it is not because your post wasn't viewed as this is a very active forum, it's because no one can help you.
 

Mosd

New member
Thanks for reaching out @merrydad.

Do you know what it would require to build such a indicator for tos? What details do i need to know about wave trader 3?
 

MerryDay

Administrative
Staff member
Staff
VIP
@Mosd If you have the Omnitrader code, if you are legally allowed to share the Omnitrader code and if you can interpret the code then theoretically you have the mathematical logic to write the thinkscript yourself. Scripts in TOS are pretty standard in their logic. You may have to reach out for support of this board if you hit a wall on a more complex syntax issue. The basic issue is that someone has to have the legal right and have the ability to translate the OmniTrader script.

I have to tell you, I think the OmniTrader wave theory 3 is fish oil. It looks slimy, it feels slimy and is portrayed slimy (no offense)
ZigZag (wave) indicators repaint Read About Repainting Indicators. They always look perfect and sometimes they even get it right but when they get it wrong, it can wipe out all your profits. Also, they call this being powered by Fractals. BUT fractals don't work the way that they describe. You can search this forum for Fractals to learn more. But please note, fractals are an advanced investing concept they are NOT an up/down, buy now/sell now indicator which is why the wave theory 3 feels scam-my. IMHO

Otherwise, if your heart is set on a repainting indicator, most of the ZigZags on this forum seem to look similar to wave theory 3. You could try the one in this thread or one of the others on this forum.

PS: NONE of this applies to OmniTrader's Elliot Waves which they describe at the end of their brochure. I know nothing about their product specifically but well-written Elliot Waves (which require deep analysis and interpretation) are an awesome all-around indicator. The only Elliot Waves available on TOS must be bought. But for the advanced research technical swing trader, they are a great weapon to have in a toolbox. AGAIN, is NOT a mindless up/down, buy/sell indicator and run from anyone that says that it is.
 
Last edited:
The code that @netarchitech linked is quite old. I have since developed better methods.

I'll give an example below.

For this example, we will be projecting the low point of the last few 10 bar swing low points. We will start with this code to identify those points.

Ruby:
# define swing low points
input length = 10;
def bn = BarNumber();
def lastBar = HighestAll(if IsNaN(close) then 0 else bn);
def offset = Min(length - 1, lastBar - bn);
def swingLow = low < Lowest(low[1], length - 1) and low == GetValue(Lowest(low, length), -offset);
# change candle colors just to make it easier to see what we are working with
AssignPriceColor(if swingLow then Color.LIME else Color.DARK_GRAY);

XothKPE.png


Ruby:
# identify the very last swing low point
def lowPointOneBarNumber = HighestAll(if swingLow then bn else 0);
def lowPointOneValue = if bn == lowPointOneBarNumber then low else lowPointOneValue[1];
plot low1 = if bn < lowPointOneBarNumber then Double.NaN else lowPointOneValue;
low1.SetDefaultColor(Color.RED);

bXCoN3d.png


Ruby:
# identify the 2nd to last swing low point
def lowPointTwoBarNumber = HighestAll(if swingLow and bn < lowPointOneBarNumber then bn else 0);
def lowPointTwoValue = if bn == lowPointTwoBarNumber then low else lowPointTwoValue[1];
plot low2 = if bn < lowPointTwoBarNumber then Double.NaN else lowPointTwoValue;
low2.SetDefaultColor(Color.RED);

0RD1fIJ.png


Ruby:
#  +------------------------------------------------------------+
#  |  Example: How to extend levels to the right of the chart   |
#  |                        Robert Payne                        |
#  |               https://funwiththinkscript.com               |
#  +------------------------------------------------------------+
# define swing low points
input length = 10;
def bn = BarNumber();
def lastBar = HighestAll(if IsNaN(close) then 0 else bn);
def offset = Min(length - 1, lastBar - bn);
def swingLow = low < Lowest(low[1], length - 1) and low == GetValue(Lowest(low, length), -offset);

# change candle colors just to make it easier to see what we are working with
AssignPriceColor(if swingLow then Color.LIME else Color.DARK_GRAY);

# identify the very last swing low point
def lowPointOneBarNumber = HighestAll(if swingLow then bn else 0);
def lowPointOneValue = if bn == lowPointOneBarNumber then low else lowPointOneValue[1];
plot low1 = if bn < lowPointOneBarNumber then Double.NaN else lowPointOneValue;
low1.SetDefaultColor(Color.RED);

# identify the 2nd to last swing low point
def lowPointTwoBarNumber = HighestAll(if swingLow and bn < lowPointOneBarNumber then bn else 0);
def lowPointTwoValue = if bn == lowPointTwoBarNumber then low else lowPointTwoValue[1];
plot low2 = if bn < lowPointTwoBarNumber then Double.NaN else lowPointTwoValue;
low2.SetDefaultColor(Color.RED);

# just keep doing ths for as many lines as you want to add to the chart
def lowPointThreeBarNumber = HighestAll(if swingLow and bn < lowPointTwoBarNumber then bn else 0);
def lowPointThreeValue = if bn == lowPointThreeBarNumber then low else lowPointThreeValue[1];
plot low3 = if bn < lowPointThreeBarNumber then Double.NaN else lowPointThreeValue;
low3.SetDefaultColor(Color.RED);

VYsjGh2.png
what code do i need to make the chart look like that. i see too many codes thanks for any help.
 

Mosd

New member
@MerryDay

Totally agree with you. The reason i'm very hesitant in buying the Wave trader 3 is that im also getting "fish oil" feeling. Other products they sell is a vwap for 395 bucks...and then they charge 99 bucks for data.

My friend has bought the wave trader and are using it in a very systematical way in a small niche of stocks. Seems to be working awesome there but im sure they are just using a regular indicator and putting a fancy name on it.
 

ravillatheja

New member
VIP
Hi,

I came across this Trading Analysis swing waves indicator. I was wondering if anyone has more information about it..Can someone tell me if this indicator repaints. I want to use it for swing trading..I am not a programmer..so need help from my fellow members..

Code:

Code:
# Trading Analysis Swing Waves
# Version 1.0.1
# 4/20/2015
#
# Author: Brian Strong ([email protected])
# MicroQuant
#

input MajorLeftStr = 13;
input MajorRightStr = 13;
input MinorLeftStr = 5;
input MinorRightStr = 5;
input SwingTickOffset = 2;
input AlertsOn = yes;

# This indicator must be applied to a bar interval larger than 5 ticks.

def offset = TickSize() * (HighestAll(high) - LowestAll(low)) * SwingTickOffset;

#Calculate Major Swings
def pivotH = if high > Highest(high[1], MajorLeftStr) and high > Highest(high[-MajorRightStr], MajorRightStr) then 1 else 0;
def pValH = if pivotH then high + offset else Double.NaN;
def pivotL = if low < Lowest(low[1], MajorLeftStr) and low < Lowest(low[-MajorRightStr], MajorRightStr) then 1 else 0;
def pValL = if pivotL then low - offset else Double.NaN;

#Plot Major Swings
plot MajorSwHigh = pValH;
MajorSwHigh.setpaintingStrategy(paintingStrategy.POINTS);
MajorSwHigh.setLineWeight(5);
MajorSwHigh.setdefaultColor(Color.BLUE);
plot MajorSwLow = pValL;
MajorSwLow.setpaintingStrategy(paintingStrategy.POINTS);
MajorSwLow.setLineWeight(5);
MajorSwLow.setdefaultColor(Color.BLUE);

Thanks
 

rad14733

Well-known member
VIP
@ravillatheja Could you post an image of what the indicator looks like on a chart, pleases...??? It should be standard protocol to give a complete overview to save the rest of us some work... After all, it's you looking for help so make it easy for us to help you and you'll have better luck...
 

Ilya

New member
VIP
True, but in this case, doesn't really matter what it looks like, I am sure it looks great. I am not a great coder, and I have no idea what major/minor str are, but anytime I have seen offset, it always repaints and the indicator is definitely not real time. Whether its useful as far as keeping you in the trade or telling you take profits, depends on how many bars it lags of course.
 

ravillatheja

New member
VIP
True, but in this case, doesn't really matter what it looks like, I am sure it looks great. I am not a great coder, and I have no idea what major/minor str are, but anytime I have seen offset, it always repaints and the indicator is definitely not real time. Whether its useful as far as keeping you in the trade or telling you take profits, depends on how many bars it lags of course.
Thankyou
 

rad14733

Well-known member
VIP
@Ilya and @ravillatheja The idea I'm trying to convey is that members shouldn't be expected to install the code in order to see what the results look like... I could just as easily Copy & Paste the code to see what it looks like rather than using a shared link, but I shouldn't have to do either... I'm asking for an image because we need to have some form of standard protocol here... Members may think I nag a lot, but if it's considered nagging it's for good reason... Code + Image(s), and hopefully a link back to where the code came from when requesting help with new indicators... Shared links are optional... Those of us willing to help are too busy to have to keep asking... Remember, we aren't the ones wanting help, we're the ones willing to provide the help... We can just as easily move on the the next request...
 

Swet

New member
hi, can anyone help with scripts for price labels for swing highs and lows for candles like in stock charts.com. pls help
 

Deepwater

Member
hi, can anyone help with scripts for price labels for swing highs and lows for candles like in stock charts.com. pls help
See if this Code works for hi lo labels:

Code:
input timeFrame = {default day};
input showOnlyToday = no;

def day = GetDay();
def lastday = GetLastDay();
def isToday = If(day >= lastday, 1, 0);


def shouldPlot = If(showOnlyToday and isToday, 1, If(!showOnlyToday, 1, 0));
#-----------------------------
#input paintBars = yes;
#-------------
plot UpperVolatility = isToday;
plot LowerVolatility = !isToday;
#-----------------------

UpperVolatility.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
UpperVolatility.SetLineWeight(3);
UpperVolatility.SetDefaultColor(Color.GREEN);
UpperVolatility.Hide();
#----------------------------
LowerVolatility.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
LowerVolatility.SetLineWeight(3);
LowerVolatility.SetDefaultColor(Color.RED);
LowerVolatility.Hide();
#------------------------------------------
#( today bars )
DefineGlobalColor("up", Color.GREEN);
DefineGlobalColor("dwn", Color.RED);

# ( not today bars )
DefineGlobalColor("invisi", Color.BLACK);

# if not paint bars then paint normal ... if condition1 then bullish scheme ... if condition2 then bearish scheme ... else normal
AssignPriceColor(
if !showOnlyToday
#!paintBars
then Color.CURRENT

else
# ( is today then normal paint )
if UpperVolatility
then
if close > open then GlobalColor("up") else GlobalColor("dwn")
#globalColor( "up"winking smiley

else
# ( is not today then black)
if LowerVolatility
then GlobalColor( "invisi")
else Color.CURRENT);



def today = GetDay() == GetLastDay();
plot dailyHigh = if !today then Double.NaN else high(period = "day" );
plot dailyLow = if !today then Double.NaN else low(period = "day" );
#-----------------------------
# ___________________________________________________________
# ________________  DAY/ HI-LOW / VOLUME ____________________
# ___________________________________________________________
#


input show_label = yes;
input show_bubble = no;


def period_Type = AggregationPeriod.DAY;

def begin = close(period = period_Type)[1];
def end = close(period = period_Type);
def NetChg = end - begin;
def PctChg = (end / begin) - 1;
def DayVolume = volume(period = "DAY");

#AddLabel(show_label, "Open: " + Open + "  High: " + High + "  Low: " + Low +  "   Last: "
#+ close + "  " + " Volume: " + DayVolume + "  " , if #NetChg > 0 then CreateColor( 165, 105, 189 )
#else if NetChg < 0 then CREATEColor( 46, 204, 113 ) else Color.LIGHT_GRAY);

#AddLabel(show_label, " Volume: " + DayVolume + "  ");

AddLabel(show_label, " Volume: " + DayVolume + "  " , if  DayVolume > 0 then CreateColor( 224, 224, 224)
else if  DayVolume == 0 then CreateColor(224, 224, 224) else Color.LIGHT_GRAY);

def bar = if IsNaN(close)
             then if yes
                     then bar[1]
                     else Double.NaN
             else BarNumber();
def ThisBar = HighestAll(bar);
def barCount   = if bar == ThisBar
                 then close
                 else Double.NaN;
 

EDV

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)
                                or
                              (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;
upperLine.EnableApproximation();
upperLine.SetDefaultColor(Color.LIME);
upperLine.SetLineWeight(2);

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

lowerLine.EnableApproximation();
lowerLine.SetDefaultColor(Color.PLUM);
lowerLine.SetLineWeight(2);

# 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);
@RajB , thanks for the Broadening script! I'm no programmer, is there an easy way to modify the code to include historical swings for backtesting purposes? Thanks!
 

Similar threads

Top