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
..else 2 lines that form a pyramid peak
..if bar qty = len