Multiple Time Frame (MTF) Squeeze Indicator for ThinkorSwim

C

C4men

Member
All - I've been working on building a comparable setup to John Carter's squeeze pro labels + histogram labels.

I was able to modify code I found here to accomplish the "squeeze pro" portion of this. Unfortunately, it is tough to find a histogram that matches Carter's. Mobius' code has a good histogram but I find it not nearly as smooth as John Carter's. However, I found the "Awesome Oscillator" in TOS to be very close to the TTM_Squeeze histogram when you modify the 2 period lengths in the code to be 9 & 21 instead of 5 & 34. I took this logic and built an "MTF histogram label" that sits just underneath the squeeze label...similar to JC's. I've watched several of his videos and confirmed that the squeeze portion of my code works verbatim to his. The histogram is not exact but it is "damn close."

Pic of my setup here: https://ibb.co/VVTH65K

Here is a link to my shared grid, containing the histogram & squeeze labels: https://tos.mx/xkLakTN

Color legend for those unfamiliar:
  • Top row are the squeezes - Gray = low squeeze, Red = med squeeze (same as the original TTM_Squeeze indicator) and Yellow = high squeeze (this is the tightest squeeze).
  • Bottom row contains histograms: Cyan = increasing positive momentum, Blue = waning positive momentum, Red = increasing negative momentum & Yellow = waning negative momentum.

Let me know your thoughts...
Oh this is good stuff. Thank you sir!
 
M

maverick0987

New member
***For the record - I actually subscribe to John Carter's options room & alert service so I see their charts as compared to mine every day. That being said - I'd like to think I have a decent feel for the accuracy of my "knock-off" indicators. I know the squeeze is spot on. That's the key one to get right anyways. The histogram doesn't always mimic his but it is sort-of secondary in the decision-making process so not a big deal IMO. Either way - if someone can figure out how the original TTM_Squeeze histogram functions and can replicate that....I'd be very interested :)!
 
R

Ramesh16

Member
VIP
I just heard JC this week, and his explosive profit using tttm sqz!
 
R

Rudea80

New member
@maverick0987 - Does the below satisfy? I found this somewhere around the web and modified it to include multiple squeezes

Also, thanks for your code earlier. I noticed you use the Quan Ticks indicator. Is there a guide on how to use that?

Code:
declare lower;

input Length = 20; # Length for Avg True Range & Std. Dev Calcs
input Price = Close; # type of price to use
input minPriceMove = 1; # for scaling
input priceIncrement = 0.01;
input nK = 1.5; # Keltner Channel ATRs from Average
input nBB = 2.0; # Bollinger Band Std. Devs. from Average
input nBB2 = 1.5;
input nBB3 = 3.0;
input AlertLine = 1; # BBS_Index level at which to issue alerts
input SqueezeOnColor = 6;
input SqueezeOffColor = 2;



# scaling factor :
def LHMult = If (priceIncrement <> 0, (minPriceMove / priceIncrement), 0);



# Average True Range

def ATR = Average(TrueRange(high,  close,  low),  Length);

# Standard Deviation

def SDev = StDev(Price, Length);



# -- Calculate Bollinger Band Squeeze Indicator --

# for alert

def Denom = (nK * ATR);

def BBS_Ind3 = If (Denom <> 0, ((nBB3 * SDev) / Denom),0);
def BBS_Ind = If (Denom <> 0, ((nBB * SDev) / Denom), 0);
def BBS_Ind2 = If (Denom <>0, ((nBB2 * SDev) / Denom), 0);



# -- Plot the Index & Alert Line -------------------------

plot BBS_Index = if price > 0 then 0 else Double.NaN;

BBS_Index.AssignValueColor(if BBS_Ind3 < AlertLine then CreateColor(255,255,98) else if BBS_Ind < AlertLine then CreateColor(255,0,58) else if BBS_ind2 < AlertLine then Color.Black else CreateColor(69,197,68));

BBS_Index.SetStyle(4);

BBS_Index.SetLineWeight(3);

# --------------------------------------------------------



# -- Plot delta of price from Donchian mid line ----------

# Inertia = LinearRegValue

def LinearRegValue = Inertia(Price - ((Highest(high, Length) + Lowest(low, Length)) / 2 + ExpAverage(close, Length)) / 2, Length);



#Plot the Green Values

def LRVGreens = If (LinearRegValue >= 0, LinearRegValue, 0);

plot BBSqueeze_Pos = LRVGreens * LHMult;

BBSqueeze_Pos.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);

BBSqueeze_Pos.AssignValueColor(if LRVGreens > LRVGreens[1] then CreateColor(0,255,255) else Createcolor(0,40,255));

BBSqueeze_Pos.SetLineWeight(3);



#Plot the Red Values

def LRVReds = If (LinearRegValue < 0, LinearRegValue, 0);

plot BBSqueeze_Neg = LRVReds * LHMult;

BBSqueeze_Neg.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);

BBSqueeze_Neg.AssignValueColor(if LRVReds < LRVReds[1] then Createcolor(255,95,95) else CreateColor(255,255,95));

BBSqueeze_Neg.SetLineWeight(3);
 
T

tdespenza

New member
VIP
It looks like I cutoff some of the code. paste this at the bottom of my last post.
It's a lower study. The colors represent the dots on the squeeze.

My hope is to make a label - just like yours - that tells me what color dot the squeeze is at for a given timeframe.
(i.e. - if the 5 minute squeeze is a black dot, the 5M label would be black)

Code:
def midSqueeze = BolKelDelta_Mid <= 0;
def triggerMid = if sum(midSqueeze,triggerBars) == triggerBars and !midSqueeze[triggerBars] then 1 else 0;

plot signalMidLong = if triggerMid and ((LongShortDefinition == LongShortDefinition.HistAboveBelowZero and  oscillator > 0) or (LongShortDefinition == LongShortDefinition.HistRisingFalling and  oscillator > oscillator[1]) or (LongShortDefinition == LongShortDefinition.HistRisingFromBelowFallingFromAbove and oscillator > oscillator[1] and oscillator < 0 )) then low-signalOffset else double.nan;

signalMidLong.SetPaintingStrategy(paintingStrategy.ARROW_UP);
signalMidLong.setDefaultColor(color.red);
signalMidLong.setLineWeight(5);

plot signalMidShort = if triggerMid and ((LongShortDefinition == LongShortDefinition.HistAboveBelowZero and  oscillator <= 0) or (LongShortDefinition == LongShortDefinition.HistRisingFalling and  oscillator < oscillator[1]) or (LongShortDefinition == LongShortDefinition.HistRisingFromBelowFallingFromAbove and oscillator < oscillator[1] and oscillator > 0 )) then high+signalOffset else double.nan;

signalMidShort.SetPaintingStrategy(paintingStrategy.ARROW_Down);
signalMidShort.setDefaultColor(color.red);
signalMidShort.setLineWeight(5);

def highSqueeze = BolKelDelta_High <= 0;
def triggerHigh = if sum(highSqueeze,triggerBars) == triggerBars and !highSqueeze[triggerBars] then 1 else 0;

plot signalHighLong = if triggerHigh and ((LongShortDefinition == LongShortDefinition.HistAboveBelowZero and  oscillator > 0) or (LongShortDefinition == LongShortDefinition.HistRisingFalling and  oscillator > oscillator[1]) or (LongShortDefinition == LongShortDefinition.HistRisingFromBelowFallingFromAbove and oscillator > oscillator[1] and oscillator < 0 )) then low-signalOffset else double.nan;

signalHighLong.SetPaintingStrategy(paintingStrategy.ARROW_UP);
signalHighLong.setDefaultColor(color.dark_orange);
signalHighLong.setLineWeight(5);

plot signalHighShort = if triggerHigh and ((LongShortDefinition == LongShortDefinition.HistAboveBelowZero and  oscillator <= 0) or (LongShortDefinition == LongShortDefinition.HistRisingFalling and  oscillator < oscillator[1]) or (LongShortDefinition == LongShortDefinition.HistRisingFromBelowFallingFromAbove and oscillator < oscillator[1] and oscillator > 0 )) then high+signalOffset else double.nan;

signalHighShort.SetPaintingStrategy(paintingStrategy.ARROW_Down);
signalHighShort.setDefaultColor(color.dark_orange);
signalHighShort.setLineWeight(5);

So are you looking for a lower timeframe study or an upper timeframe study?
 
M

maverick0987

New member
Yep I believe my post accomplishes this. You can add the shared grid from my post to get the code...I'm too lazy to post it in here but I don't mind if someone else does. John Carter's version requires you to add multiple instances of the label for each time frame you want, for both the squeeze and the histogram. My solution functions the same way. The pic in my post does not show labels for the 1m, 2m, 3m or 4m as I find those too short to be reliable
 
Last edited:
L

LG40

New member
All - I've been working on building a comparable setup to John Carter's squeeze pro labels + histogram labels.

I was able to modify code I found here to accomplish the "squeeze pro" portion of this. Unfortunately, it is tough to find a histogram that matches Carter's. Mobius' code has a good histogram but I find it not nearly as smooth as John Carter's. However, I found the "Awesome Oscillator" in TOS to be very close to the TTM_Squeeze histogram when you modify the 2 period lengths in the code to be 9 & 21 instead of 5 & 34. I took this logic and built an "MTF histogram label" that sits just underneath the squeeze label...similar to JC's. I've watched several of his videos and confirmed that the squeeze portion of my code works verbatim to his. The histogram is not exact but it is "damn close."

Pic of my setup here:



Here is a link to my shared grid, containing the histogram & squeeze labels: https://tos.mx/xkLakTN

Color legend for those unfamiliar:
  • Top row are the squeezes - Gray = low squeeze, Red = med squeeze (same as the original TTM_Squeeze indicator) and Yellow = high squeeze (this is the tightest squeeze).
  • Bottom row contains histograms: Cyan = increasing positive momentum, Blue = waning positive momentum, Red = increasing negative momentum & Yellow = waning negative momentum.

Let me know your thoughts...
This looks just like the histogram I saw on the newest JC multi squeeze pro and histogram. However, when I try to use your link I get an error message. I'm not sure if I'm doing something wrong.
 
M

maverick0987

New member
This looks just like the histogram I saw on the newest JC multi squeeze pro and histogram. However, when I try to use your link I get an error message. I'm not sure if I'm doing something wrong.
@LG40 - did you import it into Thinkorswim? You will have to hit setup in the top right corner of TOS, select "open shared item", then paste this link in the box: https://tos.mx/xkLakTN.

Let me know if you still have issues

Cheers!
 
C

coffeewin

New member
@maverick0987 This is incredible, thank you! I have a few questions. With regards to the squeeze labels (Monthly, Weekly, Daily, Hourly ... Minute), is there any way to display all the labels regardless of the timeframe? For instance with a 6M:1D timeframe, it only displays (M, W, 4D, 3D, 2D, and D). The timeframe would need to be adjusted to the 1 minute to be able to see lower labels. My second question involves the histogram labels, is there any other way to get a 2nd row of labels instead of using the "hack" of adding blank labels?
 
M

maverick0987

New member
@maverick0987 This is incredible, thank you! I have a few questions. With regards to the squeeze labels (Monthly, Weekly, Daily, Hourly ... Minute), is there any way to display all the labels regardless of the timeframe? For instance with a 6M:1D timeframe, it only displays (M, W, 4D, 3D, 2D, and D). The timeframe would need to be adjusted to the 1 minute to be able to see lower labels. My second question involves the histogram labels, is there any other way to get a 2nd row of labels instead of using the "hack" of adding blank labels?
@coffeewin Unfortunately the timeframe issue is a limitation of TOS. You can only view aggregations that are greater than the chart you are on. So a 1m chart can aggregate all timeframes. A weekly chart can only aggregate weekly, monthly, quarterly and greater. I use the grid setup with the 1m chart on the right and change the timeframe on the left when I see a signal from the labels I want to investigate.

I've seen JC's "edit studies" popup during a live session and he has an instance of the label for each timeframe and a blanklabel to get the histogram on the second line. My "blanklabel" is pretty shoddy from a coding standpoint - I'm sure there is someone on here that can make it start on a new line a lot cleaner. For the record although I have some previous programming experience, I literally learned Thinkscript syntax Friday night while trying to build this tool so my experience is very limited. There invariably may be an easier way to do all of this.
 
C

coffeewin

New member
@coffeewin Unfortunately the timeframe issue is a limitation of TOS. You can only view aggregations that are greater than the chart you are on. So a 1m chart can aggregate all timeframes. A weekly chart can only aggregate weekly, monthly, quarterly and greater. I use the grid setup with the 1m chart on the right and change the timeframe on the left when I see a signal from the labels I want to investigate.

I've seen JC's "edit studies" popup during a live session and he has an instance of the label for each timeframe and a blanklabel to get the histogram on the second line. My "blanklabel" is pretty shoddy from a coding standpoint - I'm sure there is someone on here that can make it start on a new line a lot cleaner. For the record although I have some previous programming experience, I literally learned Thinkscript syntax Friday night while trying to build this tool so my experience is very limited. There invariably may be an easier way to do all of this.
I see that makes sense. After browsing around, JC seems to confirm what you have said in this article: How to Configure a Multi-Time Frame label study on TOS. They don't show exactly how they define the blank labels but it seems like it's the same as how you do it. I've also been looking around to see if it's possible to have a transparent/opaque label but looking at the CreateColor documentation, it seems impossible to add an alpha value since the function only takes RGB instead of RGBA. To get around this limitation, the best alternative I've found is to make the color of the label the same as the chart background to make it seem invisible. I did this by screenshotting the chart, using a color picker to obtain the RGB color values, and then setting the label color to this RGB value. The other method was not even using blank labels by resizing the window width to just the right size so that the interval and histogram labels are on two different rows. This is probably how JC does it as well since in all his videos, the double row is always in a small window.
 
6

68sooner

New member
VIP
@maverick0987 I have been trying (unsuccessfully) at creating a scanner from the study. I am trying to find the stocks that are in a squeeze in the 15 min, 30 min, and daily. Have you tried scanning using the study?
 
B

BTExpress

New member
@maverick0987 I have been trying (unsuccessfully) at creating a scanner from the study. I am trying to find the stocks that are in a squeeze in the 15 min, 30 min, and daily. Have you tried scanning using the study?
I think it is somelike like this as a custom filer in scan: "TTM_Squeeze()."SqueezeAlert" is equal to 0" then select the timeframe you want
 
M

maverick0987

New member
@maverick0987 I have been trying (unsuccessfully) at creating a scanner from the study. I am trying to find the stocks that are in a squeeze in the 15 min, 30 min, and daily. Have you tried scanning using the study?
@68sooner You know, I haven't tried that yet. What I have done, though, is setup my watchlist to flash red/gray/yellow if there is a squeeze and added multiple columns for multiple timeframes. So I can get a quick glimpse at what is going on. My opinion of the squeeze is that its just a tool - and a good strategy and psychology is needed to be successful - no matter the indicator. That being said, I tend to follow a strict set of 100 stocks or so and click thru the watchlist once or twice a day, look at the chart, and determine whether there's a trade worth taking or not.

FWIW: John Carter has said in the past, "I look at the chart and if in 5 seconds I don't know exactly what trade to take - I move on. If you look at a chart long enough you'll talk yourself into a trade." From listening to him off and on over the past 6 months he also looks for price patterns and other factors that are less mechanical and more discretionary when taking a trade.

I have worked up a new grid layout, that puts a 5m chart in the bottom left-hand corner of the screen with all the squeeze/histogram labels so I keep the majority of my workspace open for a larger chart with other indicators. You can add it here: https://tos.mx/WiB2Myo

Cheers-

**EDIT: inside of my grid (link above) I've (sortof) solved the issue with the blank label to separate the squeeze labels and the histogram. Now you can edit the study without modifying the code. Just add/subtract dashes (----) from the input field to lengthen/shorten the spacer label. :)
 
Last edited:
V

VicD

Member
Here is one https://tos.mx/kBnZqHh 14 period squeeze indicator, you can add lower time frames. It's so big though. Very elegant code though. I'm impressed.

Code:
#Visual DMI (The 10x Bars) MTF Labels for ThinkorSwim V1.6
#Last Updated on Monday, November 25 2019 at 09:51:52 PM
#
#CREDITS
# John Carter's 10x bars, @sierioiza, @tomsk, @horserider, @markos
#
#CHANGELOG
# 2019.11.25 1.0 @diazlaz - Updated Port
# 2019.11.25 1.1 @diazlaz - Added Month Time frame
# 2019.11.25 1.2 @diazlaz - Added additional timecheck on chart and instructions
# 2019.11.25 1.2 @diazlaz - Added additional aggregation periods (18 total)
# 2019.11.25 1.2 @diazlaz - Added additional periods 4MIN, 20MIN, 2DAYS, 4DAYS
# 2019.11.25 1.3 @diazlaz - Added adxlength and showlabels inputs
# 2019.11.25 1.4 @diazlaz - Added states and stats labels
# 2019.11.25 1.5 @diazlaz - Added fix for NaN when data is not available
#                           such as monthly for UBER due to recent IPO.
#                           colors Label as Dark Gray when no data is available.
#                           handles count of stats when error is encountered.
# 2019.11.25 1.6 @diazlaz - Added inputs for label display all aggregation periods
#                           default display all set to yes.
#                           Note:
#                            STATS still calc all periods. if this is a ask to filter
#                            based on displayed aggregation periods please let me know
#                            and will incorporate this request.
#
#DESCRIPTION
# For TSLA, we can see the 10X bars across various time frames,
# from the Weekly down to the 1-minute chart.  We can see at a
# glance that there is strong GREEN momentum across most time frames.
# Any short-term red sets up a buying opportunity back in the direction
# of the longer-term greens and vice versa.
#
#
#INSTRUCTIONS
# Set timeframe charts to 1 minute and 30 days.
#
#

#INPUTS
input length = 14; #DI+- length
input adxlength = 20; #ADX sideways length
input averageType = AverageType.WILDERS;
input showlabels = yes; #show labels
input showstats = yes; #show stats

input show1MIN = yes; #show ONE MINUTE label
input show2MIN = yes; #show TWO MINUTES label
input show3MIN = yes; #show THREE MINUTES label
input show4MIN = yes; #show FOUR MINUTES label
input show5MIN = yes; #show FIVE MINUTES label
input show10MIN = yes; #show TEN MINUTES label
input show15MIN = yes; #show FIFTEEN MINUTES label
input show20MIN = yes; #show TWENTY MINUTES label
input show30MIN = yes; #show THIRTY MINUTES label
input show1HOUR = yes; #show HOUR label
input show2HOUR = yes; #show TWO HOURS label
input show4HOUR = yes; #show FOUR HOURS label
input show1DAY = yes; #show ONE DAY label
input show2DAY = yes; #show TWO DAYS label
input show3DAY = yes; #show THREE DAYS label
input show4DAY = yes; #show FOUR DAYS label
input showWEEK = yes; #show ONE WEEK label
input showMONTH = yes; #show ONE MONTH label

#CORE
DefineGlobalColor("Bullish", Color.GREEN);
DefineGlobalColor("Bearish", Color.RED);
DefineGlobalColor("Neutral", Color.YELLOW);

#TIMEFRAME CHECK
def currentTimeFrame = getAggregationPeriod();
#AddLabel(showLabels, "TimeFrame: " + currentTimeFrame, COLOR.CYAN);
#assert(currentTimeFrame == AggregationPeriod.MIN, "ERROR: timeFrame needs to be 1 minute");

#LABELS
AddLabel(showlabels, "10X System V1.6", COLOR.CYAN);


# AGGREGATION 1 - ONE MINUTE


def aM1 = if currentTimeFrame <= aggregationPeriod.MIN then aggregationPeriod.MIN else currentTimeFrame;
def M1Available = if currentTimeFrame <= aggregationPeriod.MIN then yes else no;
def hiDiffM1 = high(period = aM1) - high(period = aM1)[1];
def loDiffM1 = low(period = aM1)[1] - low(period = aM1);

def plusDMM1 = if hiDiffM1 > loDiffM1 and hiDiffM1 > 0 then hiDiffM1 else 0;
def minusDMM1 =  if loDiffM1 > hiDiffM1 and loDiffM1 > 0 then loDiffM1 else 0;

def ATRM1 = MovingAverage(averageType, TrueRange(high(period = aM1), close(period = aM1), low(period = aM1)), length);
def "DI+M1" = 100 * MovingAverage(averageType, plusDMM1, length) / ATRM1;
def "DI-M1" = 100 * MovingAverage(averageType, minusDMM1, length) / ATRM1;

def DXM1 = if ("DI+M1" + "DI-M1" > 0) then 100 * AbsValue("DI+M1" - "DI-M1") / ("DI+M1" + "DI-M1") else 0;
def ADXM1 = MovingAverage(averageType, DXM1, length);

def bullishM1 = ("DI+M1" > "DI-M1") and (ADXM1 > adxlength);
def bearishM1 = ("DI+M1" < "DI-M1") and (ADXM1 > adxlength);
def sidewaysM1 = (ADXM1 < adxlength);

def sStateM1 = if bullishM1 then 100 else if bearishM1 then -100 else 0;
def sPOSM1 = if IsNan(sStateM1) then 0 else bullishM1;
def sNEGM1 = if IsNan(sStateM1) then 0 else bearishM1;
def sSIDM1 = if IsNan(sStateM1) then 0 else if sPOSM1 or sNEGM1 then 0 else sidewaysM1;

AddLabel(showlabels and show1MIN and M1Available, "1MIN", if IsNan(sStateM1) then COLOR.DARK_GRAY else
if sStateM1 == 100 then GlobalColor("Bullish") else
if sStateM1 == -100 then GlobalColor("Bearish")
else GlobalColor("Neutral"));



# AGGREGATION 2 - TWO MINUTES
def aM2 = if currentTimeFrame <= AggregationPeriod.TWO_MIN then AggregationPeriod.TWO_MIN else currentTimeFrame;
def M2Available = if currentTimeFrame <= aggregationPeriod.TWO_MIN then yes else no;
#def aM2 = aggregationPeriod.TWO_MIN;

def hiDiffM2 = high(period = aM2) - high(period = aM2)[1];
def loDiffM2 = low(period = aM2)[1] - low(period = aM2);

def plusDMM2 = if hiDiffM2 > loDiffM2 and hiDiffM2 > 0 then hiDiffM2 else 0;
def minusDMM2 =  if loDiffM2 > hiDiffM2 and loDiffM2 > 0 then loDiffM2 else 0;

def ATRM2 = MovingAverage(averageType, TrueRange(high(period = aM2), close(period = aM2), low(period = aM2)), length);
def "DI+M2" = 100 * MovingAverage(averageType, plusDMM2, length) / ATRM2;
def "DI-M2" = 100 * MovingAverage(averageType, minusDMM2, length) / ATRM2;

def DXM2 = if ("DI+M2" + "DI-M2" > 0) then 100 * AbsValue("DI+M2" - "DI-M2") / ("DI+M2" + "DI-M2") else 0;
def ADXM2 = MovingAverage(averageType, DXM2, length);

def bullishM2 = ("DI+M2" > "DI-M2") and (ADXM2 > adxlength);
def bearishM2 = ("DI+M2" < "DI-M2") and (ADXM2 > adxlength);
def sidewaysM2 = (ADXM2 < adxlength);

def sStateM2 = if bullishM2 then 100 else if bearishM2 then -100 else 0;
def sPOSM2 = if IsNan(sStateM2) then 0 else bullishM2;
def sNEGM2 = if IsNan(sStateM2) then 0 else bearishM2;
def sSIDM2 = if IsNan(sStateM2) then 0 else if sPOSM2 or sNEGM2 then 0 else sidewaysM2;

AddLabel(showlabels and show2MIN and M2Available, "2MIN", if IsNan(sStateM2) then COLOR.DARK_GRAY else
if sStateM2 == 100 then GlobalColor("Bullish") else
if sStateM2 == -100 then GlobalColor("Bearish")
else GlobalColor("Neutral"));


# AGGREGATION 3 - THREE MINUTES
def aM3 = if currentTimeFrame <= aggregationPeriod.THREE_MIN then aggregationPeriod.THREE_MIN else currentTimeFrame;
def M3Available = if currentTimeFrame <= aggregationPeriod.THREE_MIN then yes else no;
#def aM3 = aggregationPeriod.THREE_MIN;
def hiDiffM3 = high(period = aM3) - high(period = aM3)[1];
def loDiffM3 = low(period = aM3)[1] - low(period = aM3);

def plusDMM3 = if hiDiffM3 > loDiffM3 and hiDiffM3 > 0 then hiDiffM3 else 0;
def minusDMM3 =  if loDiffM3 > hiDiffM3 and loDiffM3 > 0 then loDiffM3 else 0;

def ATRM3 = MovingAverage(averageType, TrueRange(high(period = aM3), close(period = aM3), low(period = aM3)), length);
def "DI+M3" = 100 * MovingAverage(averageType, plusDMM3, length) / ATRM3;
def "DI-M3" = 100 * MovingAverage(averageType, minusDMM3, length) / ATRM3;

def DXM3 = if ("DI+M3" + "DI-M3" > 0) then 100 * AbsValue("DI+M3" - "DI-M3") / ("DI+M3" + "DI-M3") else 0;
def ADXM3 = MovingAverage(averageType, DXM3, length);

def bullishM3 = ("DI+M3" > "DI-M3") and (ADXM3 > adxlength);
def bearishM3 = ("DI+M3" < "DI-M3") and (ADXM3 > adxlength);
def sidewaysM3 = (ADXM3 < adxlength);

def sStateM3 = if bullishM3 then 100 else if bearishM3 then -100 else 0;
def sPOSM3 = if IsNan(sStateM3) then 0 else bullishM3;
def sNEGM3 = if IsNan(sStateM3) then 0 else bearishM3;
def sSIDM3 = if IsNan(sStateM3) then 0 else if sPOSM3 or sNEGM3 then 0 else sidewaysM3;

AddLabel(showlabels and show3MIN and M3Available, "3MIN", if IsNan(sStateM3) then COLOR.DARK_GRAY else
if sStateM3 == 100 then GlobalColor("Bullish") else
if sStateM3 == -100 then GlobalColor("Bearish")
else GlobalColor("Neutral"));


# AGGREGATION 4 - FOUR MINUTES
def aM4 = if currentTimeFrame <= aggregationPeriod.FOUR_MIN then aggregationPeriod.FOUR_MIN else currentTimeFrame;
def M4Available = if currentTimeFrame <= aggregationPeriod.FOUR_MIN then yes else no;
#def aM4 = aggregationPeriod.FOUR_MIN;
def hiDiffM4 = high(period = aM4) - high(period = aM4)[1];
def loDiffM4 = low(period = aM4)[1] - low(period = aM4);

def plusDMM4 = if hiDiffM4 > loDiffM4 and hiDiffM4 > 0 then hiDiffM4 else 0;
def minusDMM4 =  if loDiffM4 > hiDiffM4 and loDiffM4 > 0 then loDiffM4 else 0;

def ATRM4 = MovingAverage(averageType, TrueRange(high(period = aM4), close(period = aM4), low(period = aM4)), length);
def "DI+M4" = 100 * MovingAverage(averageType, plusDMM4, length) / ATRM4;
def "DI-M4" = 100 * MovingAverage(averageType, minusDMM4, length) / ATRM4;

def DXM4 = if ("DI+M4" + "DI-M4" > 0) then 100 * AbsValue("DI+M4" - "DI-M4") / ("DI+M4" + "DI-M4") else 0;
def ADXM4 = MovingAverage(averageType, DXM4, length);

def bullishM4 = ("DI+M4" > "DI-M4") and (ADXM4 > adxlength);
def bearishM4 = ("DI+M4" < "DI-M4") and (ADXM4 > adxlength);
def sidewaysM4 = (ADXM4 < adxlength);

def sStateM4 = if bullishM4 then 100 else if bearishM4 then -100 else 0;
def sPOSM4 = if IsNan(sStateM4) then 0 else bullishM4;
def sNEGM4 = if IsNan(sStateM4) then 0 else bearishM4;
def sSIDM4 = if IsNan(sStateM4) then 0 else if sPOSM4 or sNEGM4 then 0 else sidewaysM4;

AddLabel(showlabels and show4MIN and M4Available, "4MIN", if IsNan(sStateM4) then COLOR.DARK_GRAY else
if sStateM4 == 100 then GlobalColor("Bullish") else
if sStateM4 == -100 then GlobalColor("Bearish")
else GlobalColor("Neutral"));


# AGGREGATION 5 - FIVE MINUTES
def aM5 = if currentTimeFrame <= aggregationPeriod.FIVE_MIN then aggregationPeriod.FIVE_MIN else currentTimeFrame;
def M5Available = if currentTimeFrame <= aggregationPeriod.FIVE_MIN then yes else no;
#def aM5 = aggregationPeriod.FIVE_MIN;
def hiDiffM5 = high(period = aM5) - high(period = aM5)[1];
def loDiffM5 = low(period = aM5)[1] - low(period = aM5);

def plusDMM5 = if hiDiffM5 > loDiffM5 and hiDiffM5 > 0 then hiDiffM5 else 0;
def minusDMM5 =  if loDiffM5 > hiDiffM5 and loDiffM5 > 0 then loDiffM5 else 0;

def ATRM5 = MovingAverage(averageType, TrueRange(high(period = aM5), close(period = aM5), low(period = aM5)), length);
def "DI+M5" = 100 * MovingAverage(averageType, plusDMM5, length) / ATRM5;
def "DI-M5" = 100 * MovingAverage(averageType, minusDMM5, length) / ATRM5;

def DXM5 = if ("DI+M5" + "DI-M5" > 0) then 100 * AbsValue("DI+M5" - "DI-M5") / ("DI+M5" + "DI-M5") else 0;
def ADXM5 = MovingAverage(averageType, DXM5, length);

def bullishM5 = ("DI+M5" > "DI-M5") and (ADXM5 > adxlength);
def bearishM5 = ("DI+M5" < "DI-M5") and (ADXM5 > adxlength);
def sidewaysM5 = (ADXM5 < adxlength);

def sStateM5 = if bullishM5 then 100 else if bearishM5 then -100 else 0;
def sPOSM5 = if IsNan(sStateM5) then 0 else bullishM5;
def sNEGM5 = if IsNan(sStateM5) then 0 else bearishM5;
def sSIDM5 = if IsNan(sStateM5) then 0 else if sPOSM5 or sNEGM5 then 0 else sidewaysM5;

AddLabel(showlabels and show5MIN and M5Available, "5MIN", if IsNan(sStateM5) then COLOR.DARK_GRAY else
if sStateM5 == 100 then GlobalColor("Bullish") else
if sStateM5 == -100 then GlobalColor("Bearish")
else GlobalColor("Neutral"));


# AGGREGATION 6 - TEN MINUTES
def aM10 = if currentTimeFrame <= aggregationPeriod.TEN_MIN then aggregationPeriod.TEN_MIN else currentTimeFrame;
def M10Available = if currentTimeFrame <= aggregationPeriod.TEN_MIN then yes else no;
#def aM10 = aggregationPeriod.TEN_MIN;
def hiDiffM10 = high(period = aM10) - high(period = aM10)[1];
def loDiffM10 = low(period = aM10)[1] - low(period = aM10);

def plusDMM10 = if hiDiffM10 > loDiffM10 and hiDiffM10 > 0 then hiDiffM10 else 0;
def minusDMM10 =  if loDiffM10 > hiDiffM10 and loDiffM10 > 0 then loDiffM10 else 0;

def ATRM10 = MovingAverage(averageType, TrueRange(high(period = aM10), close(period = aM10), low(period = aM10)), length);
def "DI+M10" = 100 * MovingAverage(averageType, plusDMM10, length) / ATRM10;
def "DI-M10" = 100 * MovingAverage(averageType, minusDMM10, length) / ATRM10;

def DXM10 = if ("DI+M10" + "DI-M10" > 0) then 100 * AbsValue("DI+M10" - "DI-M10") / ("DI+M10" + "DI-M10") else 0;
def ADXM10 = MovingAverage(averageType, DXM10, length);

def bullishM10 = ("DI+M10" > "DI-M10") and (ADXM10 > adxlength);
def bearishM10 = ("DI+M10" < "DI-M10") and (ADXM10 > adxlength);
def sidewaysM10 = (ADXM10 < adxlength);

def sStateM10 = if bullishM10 then 100 else if bearishM10 then -100 else 0;
def sPOSM10 = if IsNan(sStateM10) then 0 else bullishM10;
def sNEGM10 = if IsNan(sStateM10) then 0 else bearishM10;
def sSIDM10 = if IsNan(sStateM10) then 0 else if sPOSM10 or sNEGM10 then 0 else sidewaysM10;

AddLabel(showlabels and show10MIN and M10Available, "10MIN", if IsNan(sStateM10) then COLOR.DARK_GRAY else
if sStateM10 == 100 then GlobalColor("Bullish") else
if sStateM10 == -100 then GlobalColor("Bearish")
else GlobalColor("Neutral"));


# AGGREGATION 7 - FIFTEEN MINUTES
def aM15 = if currentTimeFrame <= aggregationPeriod.FIFTEEN_MIN then aggregationPeriod.FIFTEEN_MIN else currentTimeFrame;
def M15Available = if currentTimeFrame <= aggregationPeriod.FIFTEEN_MIN then yes else no;
#def aM15 = aggregationPeriod.FIFTEEN_MIN;
def hiDiffM15 = high(period = aM15) - high(period = aM15)[1];
def loDiffM15 = low(period = aM15)[1] - low(period = aM15);

def plusDMM15 = if hiDiffM15 > loDiffM15 and hiDiffM15 > 0 then hiDiffM15 else 0;
def minusDMM15 =  if loDiffM15 > hiDiffM15 and loDiffM15 > 0 then loDiffM15 else 0;

def ATRM15 = MovingAverage(averageType, TrueRange(high(period = aM15), close(period = aM15), low(period = aM15)), length);
def "DI+M15" = 100 * MovingAverage(averageType, plusDMM15, length) / ATRM15;
def "DI-M15" = 100 * MovingAverage(averageType, minusDMM15, length) / ATRM15;

def DXM15 = if ("DI+M15" + "DI-M15" > 0) then 100 * AbsValue("DI+M15" - "DI-M15") / ("DI+M15" + "DI-M15") else 0;
def ADXM15 = MovingAverage(averageType, DXM15, length);

def bullishM15 = ("DI+M15" > "DI-M15") and (ADXM15 > adxlength);
def bearishM15 = ("DI+M15" < "DI-M15") and (ADXM15 > adxlength);
def sidewaysM15 = (ADXM15 < adxlength);

def sStateM15 = if bullishM15 then 100 else if bearishM15 then -100 else 0;
def sPOSM15 = if IsNan(sStateM15) then 0 else bullishM15;
def sNEGM15 = if IsNan(sStateM15) then 0 else bearishM15;
def sSIDM15 = if IsNan(sStateM15) then 0 else if sPOSM15 or sNEGM15 then 0 else sidewaysM15;

AddLabel(showlabels and show15MIN and M15Available, "15MIN", if IsNan(sStateM15) then COLOR.DARK_GRAY else
if sStateM15 == 100 then GlobalColor("Bullish") else
if sStateM15 == -100 then GlobalColor("Bearish")
else GlobalColor("Neutral"));


# AGGREGATION 8 - TWENTY MINUTES
def aM20 = if currentTimeFrame <= aggregationPeriod.TWENTY_MIN then aggregationPeriod.TWENTY_MIN else currentTimeFrame;
def M20Available = if currentTimeFrame <= aggregationPeriod.TWENTY_MIN then yes else no;
#def aM20 = aggregationPeriod.TWENTY_MIN;
def hiDiffM20 = high(period = aM20) - high(period = aM20)[1];
def loDiffM20 = low(period = aM20)[1] - low(period = aM20);

def plusDMM20 = if hiDiffM20 > loDiffM20 and hiDiffM20 > 0 then hiDiffM20 else 0;
def minusDMM20 =  if loDiffM20 > hiDiffM20 and loDiffM20 > 0 then loDiffM20 else 0;

def ATRM20 = MovingAverage(averageType, TrueRange(high(period = aM20), close(period = aM20), low(period = aM20)), length);
def "DI+M20" = 100 * MovingAverage(averageType, plusDMM20, length) / ATRM20;
def "DI-M20" = 100 * MovingAverage(averageType, minusDMM20, length) / ATRM20;

def DXM20 = if ("DI+M20" + "DI-M20" > 0) then 100 * AbsValue("DI+M20" - "DI-M20") / ("DI+M20" + "DI-M20") else 0;
def ADXM20 = MovingAverage(averageType, DXM20, length);

def bullishM20 = ("DI+M20" > "DI-M20") and (ADXM20 > adxlength);
def bearishM20 = ("DI+M20" < "DI-M20") and (ADXM20 > adxlength);
def sidewaysM20 = (ADXM20 < adxlength);

def sStateM20 = if bullishM20 then 100 else if bearishM20 then -100 else 0;
def sPOSM20 = if IsNan(sStateM20) then 0 else bullishM20;
def sNEGM20 = if IsNan(sStateM20) then 0 else bearishM20;
def sSIDM20 = if IsNan(sStateM20) then 0 else if sPOSM20 or sNEGM20 then 0 else sidewaysM20;

AddLabel(showlabels and show20MIN and M20Available, "20MIN", if IsNan(sStateM20) then COLOR.DARK_GRAY else
if sStateM20 == 100 then GlobalColor("Bullish") else
if sStateM20 == -100 then GlobalColor("Bearish")
else GlobalColor("Neutral"));


# AGGREGATION 9 - THIRTY MINUTES
def aM30 = if currentTimeFrame <= aggregationPeriod.THIRTY_MIN then aggregationPeriod.THIRTY_MIN else currentTimeFrame;
def M30Available = if currentTimeFrame <= aggregationPeriod.THIRTY_MIN then yes else no;
#def aM30 = aggregationPeriod.THIRTY_MIN;
def hiDiffM30 = high(period = aM30) - high(period = aM30)[1];
def loDiffM30 = low(period = aM30)[1] - low(period = aM30);

def plusDMM30 = if hiDiffM30 > loDiffM30 and hiDiffM30 > 0 then hiDiffM30 else 0;
def minusDMM30 =  if loDiffM30 > hiDiffM30 and loDiffM30 > 0 then loDiffM30 else 0;

def ATRM30 = MovingAverage(averageType, TrueRange(high(period = aM30), close(period = aM30), low(period = aM30)), length);
def "DI+M30" = 100 * MovingAverage(averageType, plusDMM30, length) / ATRM30;
def "DI-M30" = 100 * MovingAverage(averageType, minusDMM30, length) / ATRM30;

def DXM30 = if ("DI+M30" + "DI-M30" > 0) then 100 * AbsValue("DI+M30" - "DI-M30") / ("DI+M30" + "DI-M30") else 0;
def ADXM30 = MovingAverage(averageType, DXM30, length);

def bullishM30 = ("DI+M30" > "DI-M30") and (ADXM30 > adxlength);
def bearishM30 = ("DI+M30" < "DI-M30") and (ADXM30 > adxlength);
def sidewaysM30 = (ADXM30 < adxlength);

def sStateM30 = if bullishM30 then 100 else if bearishM30 then -100 else 0;
def sPOSM30 = if IsNan(sStateM30) then 0 else bullishM30;
def sNEGM30 = if IsNan(sStateM30) then 0 else bearishM30;
def sSIDM30 = if IsNan(sStateM30) then 0 else if sPOSM30 or sNEGM30 then 0 else sidewaysM30;

AddLabel(showlabels and show30MIN and M30Available, "30MIN", if IsNan(sStateM30) then COLOR.DARK_GRAY else
if sStateM30 == 100 then GlobalColor("Bullish") else
if sStateM30 == -100 then GlobalColor("Bearish")
else GlobalColor("Neutral"));


# AGGREGATION 10 - HOUR
def aH1 = if currentTimeFrame <= aggregationPeriod.HOUR then AggregationPeriod.HOUR else currentTimeFrame;
def H1Available = if currentTimeFrame <= aggregationPeriod.HOUR then yes else no;
#def aH1 = aggregationPeriod.HOUR;
def hiDiffH1 = high(period = aH1) - high(period = aH1)[1];
def loDiffH1 = low(period = aH1)[1] - low(period = aH1);

def plusDMH1 = if hiDiffH1 > loDiffH1 and hiDiffH1 > 0 then hiDiffH1 else 0;
def minusDMH1 =  if loDiffH1 > hiDiffH1 and loDiffH1 > 0 then loDiffH1 else 0;

def ATRH1 = MovingAverage(averageType, TrueRange(high(period = aH1), close(period = aH1), low(period = aH1)), length);
def "DI+H1" = 100 * MovingAverage(averageType, plusDMH1, length) / ATRH1;
def "DI-H1" = 100 * MovingAverage(averageType, minusDMH1, length) / ATRH1;

def DXH1 = if ("DI+H1" + "DI-H1" > 0) then 100 * AbsValue("DI+H1" - "DI-H1") / ("DI+H1" + "DI-H1") else 0;
def ADXH1 = MovingAverage(averageType, DXH1, length);

def bullishH1 = ("DI+H1" > "DI-H1") and (ADXH1 > adxlength);
def bearishH1 = ("DI+H1" < "DI-H1") and (ADXH1 > adxlength);
def sidewaysH1 = (ADXH1 < adxlength);

def sStateH1 = if bullishH1 then 100 else if bearishH1 then -100 else 0;
def sPOSH1 = if IsNan(sStateH1) then 0 else bullishH1;
def sNEGH1 = if IsNan(sStateH1) then 0 else bearishH1;
def sSIDH1 = if IsNan(sStateH1) then 0 else if sPOSH1 or sNEGH1 then 0 else sidewaysH1;

AddLabel(showlabels and show1HOUR and H1Available, "1HOUR", if IsNan(sStateH1) then COLOR.DARK_GRAY else
if sStateH1 == 100 then GlobalColor("Bullish") else
if sStateH1 == -100 then GlobalColor("Bearish")
else GlobalColor("Neutral"));


# AGGREGATION 11 - TWO HOURS
def aH2 = if currentTimeFrame <= aggregationPeriod.TWO_HOURS then aggregationPeriod.TWO_HOURS else currentTimeFrame;
def H2Available = if currentTimeFrame <= aggregationPeriod.TWO_HOURS then yes else no;
#def aH2 = aggregationPeriod.TWO_HOURS;
def hiDiffH2 = high(period = aH2) - high(period = aH2)[1];
def loDiffH2 = low(period = aH2)[1] - low(period = aH2);

def plusDMH2 = if hiDiffH2 > loDiffH2 and hiDiffH2 > 0 then hiDiffH2 else 0;
def minusDMH2 =  if loDiffH2 > hiDiffH2 and loDiffH2 > 0 then loDiffH2 else 0;

def ATRH2 = MovingAverage(averageType, TrueRange(high(period = aH2), close(period = aH2), low(period = aH2)), length);
def "DI+H2" = 100 * MovingAverage(averageType, plusDMH2, length) / ATRH2;
def "DI-H2" = 100 * MovingAverage(averageType, minusDMH2, length) / ATRH2;

def DXH2 = if ("DI+H2" + "DI-H2" > 0) then 100 * AbsValue("DI+H2" - "DI-H2") / ("DI+H2" + "DI-H2") else 0;
def ADXH2 = MovingAverage(averageType, DXH2, length);

def bullishH2 = ("DI+H2" > "DI-H2") and (ADXH2 > adxlength);
def bearishH2 = ("DI+H2" < "DI-H2") and (ADXH2 > adxlength);
def sidewaysH2 = (ADXH2 < adxlength);

def sStateH2 = if bullishH2 then 100 else if bearishH2 then -100 else 0;
def sPOSH2 = if IsNan(sStateH2) then 0 else bullishH2;
def sNEGH2 = if IsNan(sStateH2) then 0 else bearishH2;
def sSIDH2 = if IsNan(sStateH2) then 0 else if sPOSH2 or sNEGH2 then 0 else sidewaysH2;

AddLabel(showlabels and show2HOUR and H2Available, "2HOUR", if IsNan(sStateH2) then COLOR.DARK_GRAY else
if sStateH2 == 100 then GlobalColor("Bullish") else
if sStateH2 == -100 then GlobalColor("Bearish")
else GlobalColor("Neutral"));


# AGGREGATION 12 - FOUR HOURS
def aH4 = if currentTimeFrame <= aggregationPeriod.FOUR_HOURS then aggregationPeriod.FOUR_HOURS else currentTimeFrame;
def H4Available = if currentTimeFrame <= aggregationPeriod.FOUR_HOURS then yes else no;
#def aH4 = aggregationPeriod.FOUR_HOURS;
def hiDiffH4 = high(period = aH4) - high(period = aH4)[1];
def loDiffH4 = low(period = aH4)[1] - low(period = aH4);

def plusDMH4 = if hiDiffH4 > loDiffH4 and hiDiffH4 > 0 then hiDiffH4 else 0;
def minusDMH4 =  if loDiffH4 > hiDiffH4 and loDiffH4 > 0 then loDiffH4 else 0;

def ATRH4 = MovingAverage(averageType, TrueRange(high(period = aH4), close(period = aH4), low(period = aH4)), length);
def "DI+H4" = 100 * MovingAverage(averageType, plusDMH4, length) / ATRH4;
def "DI-H4" = 100 * MovingAverage(averageType, minusDMH4, length) / ATRH4;

def DXH4 = if ("DI+H4" + "DI-H4" > 0) then 100 * AbsValue("DI+H4" - "DI-H4") / ("DI+H4" + "DI-H4") else 0;
def ADXH4 = MovingAverage(averageType, DXH4, length);

def bullishH4 = ("DI+H4" > "DI-H4") and (ADXH4 > adxlength);
def bearishH4 = ("DI+H4" < "DI-H4") and (ADXH4 > adxlength);
def sidewaysH4 = (ADXH4 < adxlength);

def sStateH4 = if bullishH4 then 100 else if bearishH4 then -100 else 0;
def sPOSH4 = if IsNan(sStateH4) then 0 else bullishH4;
def sNEGH4 = if IsNan(sStateH4) then 0 else bearishH4;
def sSIDH4 = if IsNan(sStateH4) then 0 else if sPOSH4 or sNEGH4 then 0 else sidewaysH4;

AddLabel(showlabels and show4HOUR and H4Available, "4HOUR", if IsNan(sStateH4) then COLOR.DARK_GRAY else
if sStateH4 == 100 then GlobalColor("Bullish") else
if sStateH4 == -100 then GlobalColor("Bearish")
else GlobalColor("Neutral"));


# AGGREGATION 13 - ONE DAY
def aD1 = if currentTimeFrame <= aggregationPeriod.DAY then aggregationPeriod.DAY else currentTimeFrame;
def D1Available = if currentTimeFrame <= aggregationPeriod.DAY then yes else no;
#def aD1 = aggregationPeriod.DAY;
def hiDiffD1 = high(period = aD1) - high(period = aD1)[1];
def loDiffD1 = low(period = aD1)[1] - low(period = aD1);

def plusDMD1 = if hiDiffD1 > loDiffD1 and hiDiffD1 > 0 then hiDiffD1 else 0;
def minusDMD1 =  if loDiffD1 > hiDiffD1 and loDiffD1 > 0 then loDiffD1 else 0;

def ATRD1 = MovingAverage(averageType, TrueRange(high(period = aD1), close(period = aD1), low(period = aD1)), length);
def "DI+D1" = 100 * MovingAverage(averageType, plusDMD1, length) / ATRD1;
def "DI-D1" = 100 * MovingAverage(averageType, minusDMD1, length) / ATRD1;

def DXD1 = if ("DI+D1" + "DI-D1" > 0) then 100 * AbsValue("DI+D1" - "DI-D1") / ("DI+D1" + "DI-D1") else 0;
def ADXD1 = MovingAverage(averageType, DXD1, length);

def bullishD1 = ("DI+D1" > "DI-D1") and (ADXD1 > adxlength);
def bearishD1 = ("DI+D1" < "DI-D1") and (ADXD1 > adxlength);
def sidewaysD1 = (ADXD1 < adxlength);

def sStateD1 = if bullishD1 then 100 else if bearishD1 then -100 else 0;
def sPOSD1 = if IsNan(sStateD1) then 0 else bullishD1;
def sNEGD1 = if IsNan(sStateD1) then 0 else bearishD1;
def sSIDD1 = if IsNan(sStateD1) then 0 else if sPOSD1 or sNEGD1 then 0 else sidewaysD1;

AddLabel(showlabels and show1DAY and D1Available, "1DAY", if IsNan(sStateD1) then COLOR.DARK_GRAY else
if sStateD1 == 100 then GlobalColor("Bullish") else
if sStateD1 == -100 then GlobalColor("Bearish")
else GlobalColor("Neutral"));


# AGGREGATION 14 - TWO DAYS
def aD2 = if currentTimeFrame <= aggregationPeriod.TWO_DAYS then aggregationPeriod.TWO_DAYS else currentTimeFrame;
def D2Available = if currentTimeFrame <= aggregationPeriod.TWO_DAYS then yes else no;
#def aD2 = aggregationPeriod.TWO_DAYS;
def hiDiffD2 = high(period = aD2) - high(period = aD2)[1];
def loDiffD2 = low(period = aD2)[1] - low(period = aD2);

def plusDMD2 = if hiDiffD2 > loDiffD2 and hiDiffD2 > 0 then hiDiffD2 else 0;
def minusDMD2 =  if loDiffD2 > hiDiffD2 and loDiffD2 > 0 then loDiffD2 else 0;

def ATRD2 = MovingAverage(averageType, TrueRange(high(period = aD2), close(period = aD2), low(period = aD2)), length);
def "DI+D2" = 100 * MovingAverage(averageType, plusDMD2, length) / ATRD2;
def "DI-D2" = 100 * MovingAverage(averageType, minusDMD2, length) / ATRD2;

def DXD2 = if ("DI+D2" + "DI-D2" > 0) then 100 * AbsValue("DI+D2" - "DI-D2") / ("DI+D2" + "DI-D2") else 0;
def ADXD2 = MovingAverage(averageType, DXD2, length);

def bullishD2 = ("DI+D2" > "DI-D2") and (ADXD2 > adxlength);
def bearishD2 = ("DI+D2" < "DI-D2") and (ADXD2 > adxlength);
def sidewaysD2 = (ADXD2 < adxlength);

def sStateD2 = if bullishD2 then 100 else if bearishD2 then -100 else 0;
def sPOSD2 = if IsNan(sStateD2) then 0 else bullishD2;
def sNEGD2 = if IsNan(sStateD2) then 0 else bearishD2;
def sSIDD2 = if IsNan(sStateD2) then 0 else if sPOSD2 or sNEGD2 then 0 else sidewaysD2;

AddLabel(showlabels and show2DAY and D2Available, "2DAY", if IsNan(sStateD2) then COLOR.DARK_GRAY else
if sStateD2 == 100 then GlobalColor("Bullish") else
if sStateD2 == -100 then GlobalColor("Bearish")
else GlobalColor("Neutral"));


# AGGREGATION 15 - THREE DAYS
def aD3 = if currentTimeFrame <= aggregationPeriod.THREE_DAYS then aggregationPeriod.THREE_DAYS else currentTimeFrame;
def D3Available = if currentTimeFrame <= aggregationPeriod.THREE_DAYS then yes else no;
#def aD3 = aggregationPeriod.THREE_DAYS;
def hiDiffD3 = high(period = aD3) - high(period = aD3)[1];
def loDiffD3 = low(period = aD3)[1] - low(period = aD3);

def plusDMD3 = if hiDiffD3 > loDiffD3 and hiDiffD3 > 0 then hiDiffD3 else 0;
def minusDMD3 =  if loDiffD3 > hiDiffD3 and loDiffD3 > 0 then loDiffD3 else 0;

def ATRD3 = MovingAverage(averageType, TrueRange(high(period = aD3), close(period = aD3), low(period = aD3)), length);
def "DI+D3" = 100 * MovingAverage(averageType, plusDMD3, length) / ATRD3;
def "DI-D3" = 100 * MovingAverage(averageType, minusDMD3, length) / ATRD3;

def DXD3 = if ("DI+D3" + "DI-D3" > 0) then 100 * AbsValue("DI+D3" - "DI-D3") / ("DI+D3" + "DI-D3") else 0;
def ADXD3 = MovingAverage(averageType, DXD3, length);

def bullishD3 = ("DI+D3" > "DI-D3") and (ADXD3 > adxlength);
def bearishD3 = ("DI+D3" < "DI-D3") and (ADXD3 > adxlength);
def sidewaysD3 = (ADXD3 < adxlength);

def sStateD3 = if bullishD3 then 100 else if bearishD3 then -100 else 0;
def sPOSD3 = if IsNan(sStateD3) then 0 else bullishD3;
def sNEGD3 = if IsNan(sStateD3) then 0 else bearishD3;
def sSIDD3 = if IsNan(sStateD3) then 0 else if sPOSD3 or sNEGD3 then 0 else sidewaysD3;

AddLabel(showlabels and show3DAY and D3Available, "3DAY", if IsNan(sStateD3) then COLOR.DARK_GRAY else
if sStateD3 == 100 then GlobalColor("Bullish") else
if sStateD3 == -100 then GlobalColor("Bearish")
else GlobalColor("Neutral"));


# AGGREGATION 16 - FOUR DAYS
def aD4 = if currentTimeFrame <= aggregationPeriod.FOUR_DAYS then aggregationPeriod.FOUR_DAYS else currentTimeFrame;
def D4Available = if currentTimeFrame <= aggregationPeriod.FOUR_DAYS then yes else no;
#def aD4 = aggregationPeriod.FOUR_DAYS;
def hiDiffD4 = high(period = aD4) - high(period = aD4)[1];
def loDiffD4 = low(period = aD4)[1] - low(period = aD4);

def plusDMD4 = if hiDiffD4 > loDiffD4 and hiDiffD4 > 0 then hiDiffD4 else 0;
def minusDMD4 =  if loDiffD4 > hiDiffD4 and loDiffD4 > 0 then loDiffD4 else 0;

def ATRD4 = MovingAverage(averageType, TrueRange(high(period = aD4), close(period = aD4), low(period = aD4)), length);
def "DI+D4" = 100 * MovingAverage(averageType, plusDMD4, length) / ATRD4;
def "DI-D4" = 100 * MovingAverage(averageType, minusDMD4, length) / ATRD4;

def DXD4 = if ("DI+D4" + "DI-D4" > 0) then 100 * AbsValue("DI+D4" - "DI-D4") / ("DI+D4" + "DI-D4") else 0;
def ADXD4 = MovingAverage(averageType, DXD4, length);

def bullishD4 = ("DI+D4" > "DI-D4") and (ADXD4 > adxlength);
def bearishD4 = ("DI+D4" < "DI-D4") and (ADXD4 > adxlength);
def sidewaysD4 = (ADXD4 < adxlength);

def sStateD4 = if bullishD4 then 100 else if bearishD4 then -100 else 0;
def sPOSD4 = if IsNan(sStateD4) then 0 else bullishD4;
def sNEGD4 = if IsNan(sStateD4) then 0 else bearishD4;
def sSIDD4 = if IsNan(sStateD4) then 0 else if sPOSD4 or sNEGD4 then 0 else sidewaysD4;

AddLabel(showlabels and show4DAY and D4Available, "4DAY", if IsNan(sStateD4) then COLOR.DARK_GRAY else
if sStateD4 == 100 then GlobalColor("Bullish") else
if sStateD4 == -100 then GlobalColor("Bearish")
else GlobalColor("Neutral"));


# AGGREGATION 17 - ONE WEEK
def aW1 = if currentTimeFrame <= aggregationPeriod.WEEK then aggregationPeriod.WEEK else currentTimeFrame;
def W1Available = if currentTimeFrame <= aggregationPeriod.WEEK then yes else no;
#def aW1 = aggregationPeriod.WEEK;
def hiDiffW1 = high(period = aW1) - high(period = aW1)[1];
def loDiffW1 = low(period = aW1)[1] - low(period = aW1);

def plusDMW1 = if hiDiffW1 > loDiffW1 and hiDiffW1 > 0 then hiDiffW1 else 0;
def minusDMW1 =  if loDiffW1 > hiDiffW1 and loDiffW1 > 0 then loDiffW1 else 0;

def ATRW1 = MovingAverage(averageType, TrueRange(high(period = aW1), close(period = aW1), low(period = aW1)), length);
def "DI+W1" = 100 * MovingAverage(averageType, plusDMW1, length) / ATRW1;
def "DI-W1" = 100 * MovingAverage(averageType, minusDMW1, length) / ATRW1;

def DXW1 = if ("DI+W1" + "DI-W1" > 0) then 100 * AbsValue("DI+W1" - "DI-W1") / ("DI+W1" + "DI-W1") else 0;
def ADXW1 = MovingAverage(averageType, DXW1, length);

def bullishW1 = ("DI+W1" > "DI-W1") and (ADXW1 > adxlength);
def bearishW1 = ("DI+W1" < "DI-W1") and (ADXW1 > adxlength);
def sidewaysW1 = (ADXW1 < adxlength);

def sStateW1 = if bullishW1 then 100 else if bearishW1 then -100 else 0;
def sPOSW1 = if IsNan(sStateW1) then 0 else bullishW1;
def sNEGW1 = if IsNan(sStateW1) then 0 else bearishW1;
def sSIDW1 = if IsNan(sStateW1) then 0 else if sPOSW1 or sNEGW1 then 0 else sidewaysW1;

AddLabel(showlabels and showWEEK and W1Available, "WEEK", if IsNan(sStateW1) then COLOR.DARK_GRAY else
if sStateW1 == 100 then GlobalColor("Bullish") else
if sStateW1 == -100 then GlobalColor("Bearish")
else GlobalColor("Neutral"));


# AGGREGATION 18 - ONE MONTH
def aMM = if currentTimeFrame <= aggregationPeriod.MONTH then aggregationPeriod.MONTH else currentTimeFrame;
def MMAvailable = if currentTimeFrame <= aggregationPeriod.MONTH then yes else no;
#def aMM = aggregationPeriod.MONTH;
def hiDiffMM = high(period = aMM) - high(period = aMM)[1];
def loDiffMM = low(period = aMM)[1] - low(period = aMM);

def plusDMMM = if hiDiffMM > loDiffMM and hiDiffMM > 0 then hiDiffMM else 0;
def minusDMMM =  if loDiffMM > hiDiffMM and loDiffMM > 0 then loDiffMM else 0;

def ATRMM = MovingAverage(averageType, TrueRange(high(period = aMM), close(period = aMM), low(period = aMM)), length);
def "DI+MM" = 100 * MovingAverage(averageType, plusDMMM, length) / ATRMM;
def "DI-MM" = 100 * MovingAverage(averageType, minusDMMM, length) / ATRMM;

def DXMM = if ("DI+MM" + "DI-MM" > 0) then 100 * AbsValue("DI+MM" - "DI-MM") / ("DI+MM" + "DI-MM") else 0;
def ADXMM = MovingAverage(averageType, DXMM, length);

def bullishMM = ("DI+MM" > "DI-MM") and (ADXMM > adxlength);
def bearishMM = ("DI+MM" < "DI-MM") and (ADXMM > adxlength);
def sidewaysMM = (ADXMM < adxlength);

def sStateMM = if bullishMM then 100 else if bearishMM then -100 else 0;
def sPOSMM = if IsNan(sStateMM) then 0 else bullishMM;
def sNEGMM = if IsNan(sStateMM) then 0 else bearishMM;
def sSIDMM = if IsNan(sStateMM) then 0 else if sPOSMM or sNEGMM then 0 else sidewaysMM;

AddLabel(showlabels and showMONTH and MMAvailable, "MONTH", if IsNan(sStateMM) then COLOR.DARK_GRAY else
if sStateMM == 100 then GlobalColor("Bullish") else
if sStateMM == -100 then GlobalColor("Bearish")
else GlobalColor("Neutral"));

#STATS
def sPOS = sPOSM1 + sPOSM2 + sPOSM3 + sPOSM4 + sPOSM5 + sPOSM10 + sPOSM15 +
sPOSM20 + sPOSM30 + sPOSH1 + sPOSH2 + sPOSH4 + sPOSD1 + sPOSD2 + sPOSD3 +
sPOSD4 + sPOSW1 + sPOSMM;

def sNEG = sNEGM1 + sNEGM2 + sNEGM3 + sNEGM4 + sNEGM5 + sNEGM10 + sNEGM15 +
sNEGM20 + sNEGM30 + sNEGH1 + sNEGH2 + sNEGH4 + sNEGD1 + sNEGD2 + sNEGD3 +
sNEGD4 + sNEGW1 + sNEGMM;

def sSID = sSIDM1 + sSIDM2 + sSIDM3 + sSIDM4 + sSIDM5 + sSIDM10 + sSIDM15 +
sSIDM20 + sSIDM30 + sSIDH1 + sSIDH2 + sSIDH4 + sSIDD1 + sSIDD2 + sSIDD3 +
sSIDD4 + sSIDW1 + sSIDMM;

def sTOL = sPOS + sNEG + sSID;

AddLabel (showstats, "Bullish: " + sPOS + " (" +
  AsPercent(Round(sPOS / sTOL, 2)) + ")", GlobalColor("Bullish"));

AddLabel (showstats, "Bearish: " + sNEG + " (" +
  AsPercent(Round(sNEG / sTOL, 2)) + ")", GlobalColor("Bearish"));

AddLabel (showstats, "Neutral: " + sSID + " (" +
  AsPercent(Round(sSID / sTOL, 2)) + ")", GlobalColor("Neutral"));


# END OF Visual DMI (The 10x Bars) MTF Labels for ThinkorSwim
"
 

Similar threads

Top