How To Combine Lower Chart Indicators (Oscillators)

jphilli11

Member
Hi all,

I'm trying to compare the TTM_Wave()."Wave1" to the MACD()."Value" and need to find a common denominator. I've been trying to formulate them as a % of their ranges but I'm not getting the results I'd hoped. I've included the code below - I have it displaying a chart bubble so I can compare value but the final version would simply be an arrow and/or an alert. I can see the result I want when I merge the MACD and TTM_WAVE on the desktop app so I've included a pic of that to help illustrate the event I'm trying to identify:

For additional clarity, I have the TTM_Wave1 shown as a line instead of histogram - it's the blue line on the lower portion.




Code:
#MACD Ratio
def M_Range = Highest(MACD()."Value") - Lowest(MACD()."Value");
Def M_Cur = MACD()."Value";
def M_ratio = M_Cur/M_Range;

#TTM_Wave Ratio
Def T_Range = Highest(TTM_Wave()."Wave1") - Lowest(TTM_Wave()."Wave1");
Def T_Cur = TTM_Wave()."Wave1";
Def T_Ratio = T_cur/T_Range;

#if t_ratio crosses below M_ratio
Def breakdown = if T_Ratio[1] > M_Ratio[1] and T_Ratio < M_Ratio  then 1 else 0;

AddChartBubble(Breakdown,close[1], "TTM = " + T_Ratio + "  MACD = " + M_Ratio, color.orange, no);
 

XeoNoX

Well-known member
VIP
you stated:
"I'm trying to compare the TTM_Wave()."Wave1" to the MACD()."Value" and need to find a common denominator. "

without even looking or doing the math a common denominator would be 1 every single time, therefore making it the actual value of the lines... therefore making your point of interest as the crossing point of the two lines every single time. so you can just say when macd crosses ttm get the value.
 
Last edited:

jphilli11

Member
Hi Xeo, thanks for the response. I tried this originally but it didn't seem to give the result I was looking for. It seems that these two indicators are not necessarily on the same scale and undergo some sort of transformation/smoothing when I merge the indicators. This is why I though using the ratio of each against their respective ranges might work - which didn't. I'm trying to achieve this as a custom indicator (arrow) that I can also use as a scan which is why I can't just settle for using the built-in studies as-is. .

As you can see on this chart, the custom indicator is alerting but not where the TTM crossed under the MACD.

One more note: I can see that the zero lines for both studies is not in a fixed position to each other. When I change symbols these will be in a new position. It seems TOS is moving the zero line (up or down) in order to keep these on a visually equal scale. If that makes sense?

y4mvEhF-goIhRz4u-iRIqoNEF3kkiv5DakqCJVx7lNilEpof6YZeQGb1MYTeU7mBAA8CbL9BTtE-Pt_cQwIbIo6-pno7wCyJrpSlDRO_mOjHNUIcfE8OEk4R-z1PQumHOKKXSTyGYLwAlN6sdnOuG2zkxuVLSlDoIKdnqhSbb5jRINf50othVfjM1sM-6JjQY45



Code:
Def Breakdown = if TTM_Wave()."Wave1" crosses below MACD()."Value" then 1 else 0;

AddChartBubble(Breakdown,close[1], "Breakdown", color.orange, no);
 

XeoNoX

Well-known member
VIP
looks like it works to me
plot your macd/ttmwave use this code to verify it... and you will see your code works works

Code:
plot Breakdown =  TTM_Wave();

plot x = MACD();


capture.png
 

jphilli11

Member
Sorry, how do I incorporate the code you suggest? Can you show me in completed form, please?

Will you also pull up NUUU with your code and see if you get the proper result? I'm using 20 day hourly.

It looks like, on the studies I'm referencing, TOS is using the highest point of TTM and MACD as an anchor and the zero lines are adjusted from there. I need to find a way to replicate this offset to get the same results from a scan.

y4m16RJYfSM73x6z8hjj8qxeD0AiWp3NcXSnm0OOsQFbN4GUHrQgSCMpRPUM52qzbf29SoHid78jSRY0Rj7rOvRrhdhYsFbytdIPJx2mfv9N7J_yIbU2nh_0p1EA_cOqW0_7V5LZ2vCLUPLaeIHxAmwx62uyb08I3fEqCVFLB3B005zkLBUBMvq8stwp4RThGDJ
 
Last edited:

jphilli11

Member
Hey Ben, thanks for the reply. These two indicators can be merged together and I have them so on my desktop - that what the lower study is in the pic above. I'm trying to recreate whatever behind-the-scenes magic that TOS is doing to accommodate this. It doesn't seem to be a simple arithmetic equation though and I'm not much for math. The closest I can get is to take the % of the lower study high to the upper study high and apply that as an adjustment. It works for the points I'm looking for but also gives false positives. See below:

y4mO95ZgH2pLNq0u7LcWwouH-zc0N8DC3gZDSnheobqKOJzV8AXmC8YvyN-VBJr0-URdQLKhhfQNdniCOz8G68uasf9pr9u3GOerypYfzgkYCh4STgnFi2vYS6pG05qWWpK8EMVAmqu6OGbXe9yOdWpINLZmk4-lH1t7WQ5T9an7mO8Ttc296jZGg4GkaiG1oVn


Code:
def T_h = Highest(TTM_Wave()."Wave1");
def M_h = Highest(MACD()."Value");

#define offset as the % ratio of then highest points
def offset = if T_h > M_h then M_h / T_h else T_h / M_h;

#Adjust the values as a % ------------------------------
def T_adj = if T_h > M_h then T_h * offset else T_h;
def M_adj = if M_h > T_h then M_h * offset else M_h;

def Breakdown = T_adj crosses below M_adj;
#plot Breakdown = T_adj crosses below M_adj;
#Breakdown.setpaintingStrategy(paintingstrategy.boolean_ARROW_DOWN);
#Breakdown.SetDefaultColor(Color.orange);

AddChartBubble(Breakdown,close[1], "Breakdown", color.RED, no);
 

BenTen

Administrative
Staff member
Staff
VIP
@jphilli11 You can "merge" any indicator together by placing them into the same lower section in TOS, but that is not the right way to do it. The line/signal will move around as you zoom in and out of your chart.
 

XeoNoX

Well-known member
VIP
the code works as ive mentioned however i think you are comparing the wrong average, without the full code, full screenshot, full description of the colored lines and a replica of the chart you are looking at it it is hard to tell what those lines are even though you are saying its the peak, it appears to be the peak of a different average.
 

Slippage

Well-known member
@jphilli11 I've never tried this but here's code that is supposed to do what I think you're looking for from https://jshingler.github.io/TOS-and-Thinkscript-Snippet-Collection/TOS & Thinkscript Collection.html

B&C-NORMALIZATION​

If you want to compare two (or more) indicators that have values much different that are non-receptive to comparison, you can normalize each of the two (or more) indicators and compare them on a basis you define i.e. 0 to 100%, -1 to +1, -100 to +100, or whatever you want. Below is the code to do normalization and an example. Note that not all studies can be normalized e.g. 'AccDist' has no parameters and cannot be normalized.

Ruby:
#Usage: 'input data = close' is substituted by an indicator and its parameters.
declare lower;

script normalizePlot {
  input data = close;
  input newRngMin = -1;
  input newRngMax = 1;

  def HHData = HighestAll( data );
  def LLData = LowestAll( data );
  plot nr = ((( newRngMax - newRngMin ) * ( data - LLData )) / ( HHData - LLData )) + newRngMin;
}

Example:
Ruby:
input price = close;
input CCI_length = 7;
input Momentum_length = 12;
input RSI_length = 4;
input WR_length = 10;
input newRngMax = 100;#Maximum normalized  value
input newRngMin = 0;#Minimum normalized  value
input OverBought = 80;#Fixed value upper line for reference
input OverSold = 20;#Fixed lower value line for reference

def newCCI = normalizePlot( CCI( CCI_length).CCI, newRngMin, newRngMax );
def newMomentum = normalizePlot( Momentum( length = Momentum_length ).Momentum, newRngMin, newRngMax );
def newWPR = normalizePlot( WilliamsPercentR( length = WR_length ).WR, newRngMin, newRngMax );
def newRSIWilder = normalizePlot( RSIWilder( length = RSI_length ).RSI, newRngMin, newRngMax );

plot CCI = newCCI;
plot Momentum = newMomentum;
plot WPR = newWPR;
plot RSIWilder = newRSIWilder;
plot Over_Bought = 80;
plot Over_Sold = 20;

There's more examples at the link above.
 

jphilli11

Member
Does anybody have any experience with normalizeplot? I tried to follow the example but I keep getting the error "at least one plot should be defined." My attempt below:
Code:
declare lower;

script normalizePlot {
    def TTM = TTM_Wave()."Wave1";
    Def MACDD = MACD()."Value";
    input MACD_Fast_length = 12;
    input MACD_Slow_length = 26;
    input MACD_length = 9;

    input newRngMax = 100;#Maximum normalized  value
    input newRngMin = 0;#Minimum normalized  value

    def HHTTM = HighestAll(TTM_Wave()."Wave1");
    def LLTTM = LowestAll(TTM_Wave()."Wave1");
    def NewTTM = ((( newRngMax - newRngMin ) * ( TTM - HHTTM )) / ( HHTTM - LLTTM )) + newRngMin;

    def HHMACD = HighestAll( MACD("fast length" = MACD_Fast_length, "slow length" = MACD_Slow_length, "macd length" = MACD_length)."Value");
    def LLMACD = LowestAll( MACD("fast length" = MACD_Fast_length, "slow length" = MACD_Slow_length, "macd length" = MACD_length)."Value");
     def NewMACD = ((( newRngMax - newRngMin ) * ( MACDD - HHMACD )) / ( HHMACD - LLMACD )) + newRngMin;

plot MACD = NewMACD;
plot TTMW = NewTTM;
}
 

jphilli11

Member
That did it! Thanks so much! For what it's worth, this is a killer indicator for exiting swing trades. Apply it on the 30 min chart and you'll see it routinely exits just before a major sell-off. And it's simple enough to add as a scan or watchlist column without any issues.

Thanks for everyone's help!

Code:
#Scan version (for 30min chart)

def TTM = TTM_Wave()."Wave1";
def MACDD = MACD()."Value";
input MACD_Fast_length = 12;
input MACD_Slow_length = 26;
input MACD_length = 9;

input newRngMax = 100;#Maximum normalized  value
input newRngMin = 0;#Minimum normalized  value

def HHTTM = HighestAll(TTM_Wave()."Wave1");
def LLTTM = LowestAll(TTM_Wave()."Wave1");
def NewTTM = ((( newRngMax - newRngMin ) * ( TTM - HHTTM )) / ( HHTTM - LLTTM )) + newRngMin;

def HHMACD = HighestAll( MACD("fast length" = MACD_Fast_length, "slow length" = MACD_Slow_length, "macd length" = MACD_length)."Value");
def LLMACD = LowestAll( MACD("fast length" = MACD_Fast_length, "slow length" = MACD_Slow_length, "macd length" = MACD_length)."Value");
def NewMACD = ((( newRngMax - newRngMin ) * ( MACDD - HHMACD )) / ( HHMACD - LLMACD )) + newRngMin;

plot Breakdown = NewTTM crosses below NewMACD;
 

jphilli11

Member
For the indicator version I just added a white down arrow so I could use it on my mobile device as well.

Code:
def TTM = TTM_Wave()."Wave1";
def MACDD = MACD()."Value";
input MACD_Fast_length = 12;
input MACD_Slow_length = 26;
input MACD_length = 9;

input newRngMax = 100;#Maximum normalized  value
input newRngMin = 0;#Minimum normalized  value

def HHTTM = HighestAll(TTM_Wave()."Wave1");
def LLTTM = LowestAll(TTM_Wave()."Wave1");
def NewTTM = ((( newRngMax - newRngMin ) * ( TTM - HHTTM )) / ( HHTTM - LLTTM )) + newRngMin;

def HHMACD = HighestAll( MACD("fast length" = MACD_Fast_length, "slow length" = MACD_Slow_length, "macd length" = MACD_length)."Value");
def LLMACD = LowestAll( MACD("fast length" = MACD_Fast_length, "slow length" = MACD_Slow_length, "macd length" = MACD_length)."Value");
def NewMACD = ((( newRngMax - newRngMin ) * ( MACDD - HHMACD )) / ( HHMACD - LLMACD )) + newRngMin;

Def Breakdown = NewTTM crosses below NewMACD;
plot data = Breakdown;
data.setpaintingStrategy(paintingstrategy.boolean_ARROW_DOWN);
data.SetDefaultColor(Color.white);
 

Similar threads

Top