Dynamic triangular moving average

Human

Member
I would like to create an indicator that uses a triangular moving average. Here is the hard part. I would like to shift the highest weight forward or back over the length of the moving average. I could have the weight all the way forward on the current bar, near the current bar, nearly back to the oldest data in the sampled period, or on the bar that will be dropped off next. The slope from the highest weighted bar to each end would be linear. Each end of the sample would always have the lowest weight unless the weight was shifted to the first or the last bar of the moving average length. Can this be done? I am most interested in learning how this could be coded in ThinkSript.
 
I would like to create an indicator that uses a triangular moving average. Here is the hard part. I would like to shift the highest weight forward or back over the length of the moving average. I could have the weight all the way forward on the current bar, near the current bar, nearly back to the oldest data in the sampled period, or on the bar that will be dropped off next. The slope from the highest weighted bar to each end would be linear. Each end of the sample would always have the lowest weight unless the weight was shifted to the first or the last bar of the moving average length. Can this be done? I am most interested in learning how this could be coded in ThinkSript.

maybe this can be a starting point, for some experimenting.

this draws 1 or 2 lines, as a peak, over the last x bars on the chart.
the line(s) represent the weights.

change this to choose where the peak will be.
input peak_bars_back_from_last_bar = 3;
..if bar qty = 1, then 1 line, that is highest on last bar
..if bar qty = len, then 1 line, that is highest on first bar of len group
..else 2 lines that form a pyramid peak

i don't know what a triangle average is, so no comment on that.
when posting about something different, post a link that describes it, so others don't have to go searching.

i found this. looks to be an average of a set of averages
https://www.thebalancemoney.com/triangular-moving-average-tma-description-and-uses-1031203#:~:text=The triangular moving average (TMA) shows the average price of,a simple moving average would.


Code:
# weighted_avg_move_peak_00

#https://usethinkscript.com/threads/dynamic-triangular-moving-average.16252/
#Dynamic triangular moving average  Human  8/2  #1

# draw 1 or 2 lines, above the last len bars

def na = double.nan;
def bn = barnumber();

def lastbn = HighestAll(If(IsNaN(close), 0, bn));
def lastbar = if (bn == lastbn) then 1 else 0;
#def lastbar = !isnan(close[0]) and isnan(close[-1]);


input len = 10;
input peak_bars_back_from_last_bar = 3;
input peakht = 5;

def rngfirst = if (lastbn - len + 1) == bn then 1 else 0;
def peakbn = (Lastbn - peak_bars_back_from_last_bar + 1);
def rng = if bn >= rngfirst and bn <= lastbn then 1 else 0;


addlabel(1, "  ", color.black);
addlabel(1, "quantity of bars " + len, color.cyan);
addlabel(1, "bars back to peak " + peak_bars_back_from_last_bar, color.cyan);
addlabel(1, "peak height " + peakht, color.cyan);


plot z5 = if bn == peakbn then high else na;
z5.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
z5.SetDefaultColor(Color.cyan);


#find highest over next len bars. baseline for weight lines
def rnghi;
if bn == 1 then {
 rnghi = 0;
} else if rngfirst then {
 rnghi = highest(high[ -(len-1) ], len );
} else {
rnghi = rnghi[1];
}


#calc line slopes  (chg in wt)
def slopebefore;
def slopeafter;
if bn == 1 then {
 slopebefore = 0;
 slopeafter = 0;
} else if rngfirst then {
 slopebefore = if peak_bars_back_from_last_bar == len then 0 else ( peakht / (len - (peak_bars_back_from_last_bar + 0)) );
 slopeafter = if peak_bars_back_from_last_bar == 0 then 0 else -( peakht / (peak_bars_back_from_last_bar - 1) );
} else {
 slopebefore = slopebefore[1];
 slopeafter = slopeafter[1];
}


def sl;
if bn == 1 or bn == (lastbn + 1) then {
 sl = 0;
} else if rngfirst and peak_bars_back_from_last_bar == len then {
 sl = 0;
# sl = rnghi + wtpeakht;
} else if rngfirst and peak_bars_back_from_last_bar > 0 then {
 sl = slopebefore;
} else if (peakbn + 1) == bn then {
 sl = slopeafter;
} else {
 sl = sl[1];
}


def slopeline;
if bn == 1 or isnan(close) then {
 slopeline = 0;
#} else if rngfirst then {
} else if rngfirst and peak_bars_back_from_last_bar == len then {
 slopeline = rnghi +  peakht;
} else if rngfirst then {
 slopeline = rnghi;
} else {
 slopeline = slopeline[1] + sl;
}


plot z1 = if slopeline > 0 then slopeline else na;

# baseline
plot z2 = if slopeline > 0 then rnghi else na;
# upper line
plot z3 = z2 + peakht;


input test_bubble = no;
addchartbubble(test_bubble, z1*1.008,
#addchartbubble(test_bubble , 36,
rnghi + "\n" +
 slopebefore + "\n" +
 slopeafter + "\n" +
sl + "\n" +
 slopeline
, color.yellow, yes);

#


choose where the peak will be.
..if bar qty = 1
fdoQjBH.jpg


..else 2 lines that form a pyramid peak
lV9CSnS.jpg


..if bar qty = len
5tRoQTj.jpg
 

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

maybe this can be a starting point, for some experimenting.

this draws 1 or 2 lines, as a peak, over the last x bars on the chart.
the line(s) represent the weights.

change this to choose where the peak will be.
input peak_bars_back_from_last_bar = 3;
..if bar qty = 1, then 1 line, that is highest on last bar
..if bar qty = len, then 1 line, that is highest on first bar of len group
..else 2 lines that form a pyramid peak

i don't know what a triangle average is, so no comment on that.
when posting about something different, post a link that describes it, so others don't have to go searching.

i found this. looks to be an average of a set of averages
https://www.thebalancemoney.com/triangular-moving-average-tma-description-and-uses-1031203#:~:text=The triangular moving average (TMA) shows the average price of,a simple moving average would.


Code:
# weighted_avg_move_peak_00

#https://usethinkscript.com/threads/dynamic-triangular-moving-average.16252/
#Dynamic triangular moving average  Human  8/2  #1

# draw 1 or 2 lines, above the last len bars

def na = double.nan;
def bn = barnumber();

def lastbn = HighestAll(If(IsNaN(close), 0, bn));
def lastbar = if (bn == lastbn) then 1 else 0;
#def lastbar = !isnan(close[0]) and isnan(close[-1]);


input len = 10;
input peak_bars_back_from_last_bar = 3;
input peakht = 5;

def rngfirst = if (lastbn - len + 1) == bn then 1 else 0;
def peakbn = (Lastbn - peak_bars_back_from_last_bar + 1);
def rng = if bn >= rngfirst and bn <= lastbn then 1 else 0;


addlabel(1, "  ", color.black);
addlabel(1, "quantity of bars " + len, color.cyan);
addlabel(1, "bars back to peak " + peak_bars_back_from_last_bar, color.cyan);
addlabel(1, "peak height " + peakht, color.cyan);


plot z5 = if bn == peakbn then high else na;
z5.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
z5.SetDefaultColor(Color.cyan);


#find highest over next len bars. baseline for weight lines
def rnghi;
if bn == 1 then {
 rnghi = 0;
} else if rngfirst then {
 rnghi = highest(high[ -(len-1) ], len );
} else {
rnghi = rnghi[1];
}


#calc line slopes  (chg in wt)
def slopebefore;
def slopeafter;
if bn == 1 then {
 slopebefore = 0;
 slopeafter = 0;
} else if rngfirst then {
 slopebefore = if peak_bars_back_from_last_bar == len then 0 else ( peakht / (len - (peak_bars_back_from_last_bar + 0)) );
 slopeafter = if peak_bars_back_from_last_bar == 0 then 0 else -( peakht / (peak_bars_back_from_last_bar - 1) );
} else {
 slopebefore = slopebefore[1];
 slopeafter = slopeafter[1];
}


def sl;
if bn == 1 or bn == (lastbn + 1) then {
 sl = 0;
} else if rngfirst and peak_bars_back_from_last_bar == len then {
 sl = 0;
# sl = rnghi + wtpeakht;
} else if rngfirst and peak_bars_back_from_last_bar > 0 then {
 sl = slopebefore;
} else if (peakbn + 1) == bn then {
 sl = slopeafter;
} else {
 sl = sl[1];
}


def slopeline;
if bn == 1 or isnan(close) then {
 slopeline = 0;
#} else if rngfirst then {
} else if rngfirst and peak_bars_back_from_last_bar == len then {
 slopeline = rnghi +  peakht;
} else if rngfirst then {
 slopeline = rnghi;
} else {
 slopeline = slopeline[1] + sl;
}


plot z1 = if slopeline > 0 then slopeline else na;

# baseline
plot z2 = if slopeline > 0 then rnghi else na;
# upper line
plot z3 = z2 + peakht;


input test_bubble = no;
addchartbubble(test_bubble, z1*1.008,
#addchartbubble(test_bubble , 36,
rnghi + "\n" +
 slopebefore + "\n" +
 slopeafter + "\n" +
sl + "\n" +
 slopeline
, color.yellow, yes);

#


choose where the peak will be.
..if bar qty = 1
fdoQjBH.jpg


..else 2 lines that form a pyramid peak
lV9CSnS.jpg


..if bar qty = len
5tRoQTj.jpg

This does not look like what I was describing. I might be using the wrong terminology. However, I think I can learn from this example in general even if I am not learning exactly what I originally wanted to learn. Thank you for responding the best you could considering my poor explanation.
 
The easiest thing to do would be to use the ToS triangular moving average. Though it doesn't allow different weighting, so if you want that specifically you'd have to do something different.

You may also look at the Recursive Moving Average Difference, which accomplishes a lot more than a triangular moving average. It samples a range of moving average lengths and determines trend from changes in the moving averages. It's dynamic, so it's better than simply adding a few averages together.

There's a post on this forum here:
https://usethinkscript.com/threads/...difference-for-thinkorswim.15658/#post-126816


1691109740174.png
 
This does not look like what I was describing. I might be using the wrong terminology. However, I think I can learn from this example in general even if I am not learning exactly what I originally wanted to learn. Thank you for responding the best you could considering my poor explanation.

that is exactly what your post 1 words describe, lines to a peak, sloping down to first and last bars.
 
Thread starter Similar threads Forum Replies Date
S 4 color dynamic chart label? Questions 3
ChaChing Dynamic MacD indicator Questions 1
F Dynamic Labels Questions 5
MP432 Dynamic Response Questions 2
dpxpress Looking For A Dynamic Price Indicator Line Questions 2

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
313 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