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);
 
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:
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);
 
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
 
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:
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);
 
@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.
 
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.
 
@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.
 
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;
}
 
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;
 
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);
 

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

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
409 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

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

Frequently Asked Questions

What is useThinkScript?

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

How do I get started?

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

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

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