ensemble statistical forecast ?

jonshank62

New member
ensemble statistical forecast is a way of using multiple indicators to achieve a score . I have currently started doing this by hand before every trade.
I like to use 5 different indicators grade each one -.5 = short , 0 = natural , +.5 =long add them all up and get a score.
my particular favorites are

200pma
20pma
true momentum
on balance volume
breakout range

Is their a way to make a algorithm for this ?
 
Solution
ensemble statistical forecast is a way of using multiple indicators to achieve a score . I have currently started doing this by hand before every trade.
I like to use 5 different indicators grade each one -.5 = short , 0 = natural , +.5 =long add them all up and get a score.
my particular favorites are

200pma
20pma
true momentum
on balance volume
breakout range

Is their a way to make a algorithm for this ?

iJyHGUZ.png


Ruby:
def score1 = if close > Average(close, 200) then 0.5 else -0.5;
def score2 = if Average(close, 20) > Average(close, 20)[1] then 0.5 else -0.5 ;
def score3 = if Momentum(10, close) > 0 then 0.5 else -0.5;
def score4 = if onbalanceVolume() > onbalanceVolume()[1] then 0.5 else -0.5 ...
ensemble statistical forecast is a way of using multiple indicators to achieve a score . I have currently started doing this by hand before every trade.
I like to use 5 different indicators grade each one -.5 = short , 0 = natural , +.5 =long add them all up and get a score.
my particular favorites are

200pma
20pma
true momentum
on balance volume
breakout range

Is their a way to make a algorithm for this ?

iJyHGUZ.png


Ruby:
def score1 = if close > Average(close, 200) then 0.5 else -0.5;
def score2 = if Average(close, 20) > Average(close, 20)[1] then 0.5 else -0.5 ;
def score3 = if Momentum(10, close) > 0 then 0.5 else -0.5;
def score4 = if onbalanceVolume() > onbalanceVolume()[1] then 0.5 else -0.5 ;
def score5 = if close > Highest(high, 20)[1] then 0.5 else
             if close < Lowest(low, 20)[1] then -0.5 else 0;

def finalScore = score1 + score2 + score3 + score4 + score5;

declare lower;

plot zero = 0 ;
zero.SetDefaultColor(color.gray);

plot Score = finalScore;
Score.SetLineWeight(3);
Score.SetPaintingStrategy(PaintingStrategy.SQUARED_HISTOGRAM);
Score.AssignValueColor(if finalScore > 0 then Color.GREEN else
if finalScore < 0 then Color.RED else Color.gray);
 
Solution

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

iJyHGUZ.png


Ruby:
def score1 = if close > Average(close, 200) then 0.5 else -0.5;
def score2 = if Average(close, 20) > Average(close, 20)[1] then 0.5 else -0.5 ;
def score3 = if Momentum(10, close) > 0 then 0.5 else -0.5;
def score4 = if onbalanceVolume() > onbalanceVolume()[1] then 0.5 else -0.5 ;
def score5 = if close > Highest(high, 20)[1] then 0.5 else
             if close < Lowest(low, 20)[1] then -0.5 else 0;

def finalScore = score1 + score2 + score3 + score4 + score5;

declare lower;

plot zero = 0 ;
zero.SetDefaultColor(color.gray);

plot Score = finalScore;
Score.SetLineWeight(3);
Score.SetPaintingStrategy(PaintingStrategy.SQUARED_HISTOGRAM);
Score.AssignValueColor(if finalScore > 0 then Color.GREEN else
if finalScore < 0 then Color.RED else Color.gray);
should they be weighted?
 
should they be weighted?

The actual definitions were kept simplistic, as it is assumed the poster would be inserting his unspecified secret sauce.

Given that the 200avg is a factor along with other lagging indicators; it can be assumed that this score is being applied to swing trades.

For swing trading, a weighting system such as this would be appropriate:
input w1 = 3.0; # 200 SMA (macro trend)
input w2 = 1.5; # 20 SMA slope (micro trend)
input w3 = 1.0; # Momentum
input w4 = 0.75; # OBV
input w5 = 2.5; # Breakout range
Giving the most weight to the 200avg trend while allowing the short-term slope minor influence.
Momentum is only for direction confirmation, and OBV is only supportive, so light-weighted.
And lastly Breakouts are the other heavyweights.

A VIP version would probably also include smoothing.

Ruby:
#   WEIGHTED ENSEMBLE SYSTEM
#   Five‑Factor Market Bias Model

declare lower;
# These defaults reflect real-world behavioral importance:
# 200 SMA (macro trend) > Breakout > 20 SMA > Momentum > OBV

input w1 = 3.0;     # Weight for 200 SMA trend regime
input w2 = 1.5;     # Weight for 20 SMA slope
input w3 = 1.0;     # Weight for Momentum
input w4 = 0.75;    # Weight for OBV direction
input w5 = 2.5;     # Weight for Breakout Range

def score1 =
    if close > Average(close, 200) then 0.5 else -0.5;

def score2 =
    if Average(close, 20) > Average(close, 20)[1] then 0.5 else -0.5;

def score3 =
    if Momentum(10, close) > 0 then 0.5 else -0.5;

def score4 =
    if OnBalanceVolume() > OnBalanceVolume()[1] then 0.5 else -0.5;

def score5 =
    if close > Highest(high, 20)[1] then 0.5 else
    if close < Lowest(low, 20)[1] then -0.5 else 0;

def finalScore =
      score1 * w1
    + score2 * w2
    + score3 * w3
    + score4 * w4
    + score5 * w5;

plot ZeroLine = 0;
ZeroLine.SetDefaultColor(Color.GRAY);

plot Score = finalScore;
Score.SetLineWeight(3);
Score.SetPaintingStrategy(PaintingStrategy.SQUARED_HISTOGRAM);

Score.AssignValueColor(
    if finalScore > 0 then Color.GREEN else
    if finalScore < 0 then Color.RED else
    Color.GRAY
);


input showLabel = yes;
AddLabel(showLabel,
         "Weighted Score: " + Round(finalScore, 2),
         if finalScore > 0 then Color.GREEN else
         if finalScore < 0 then Color.RED else
         Color.GRAY);
 
Last edited:
Then a variation of load pressure hypothesis, main script is Convex position sizing curve (the "Edge"), added Risk/Cap mathematics, direction label, and time frame alignment multiplier See it applied to different time frames.


Code:
# ================================ #
# WEIGHTED ENSEMBLE → POSITION SIZING WITH HTF ALIGNMENT + OPTIONS MAPPING #
# AdeodatusTravelLink Series #
# ================================ #

declare lower;

# ----------------
# WEIGHTS
# ----------------
input w1 = 3.0;     # 200 SMA regime
input w2 = 1.5;     # 20 SMA slope
input w3 = 1.0;     # Momentum
input w4 = 0.75;    # OBV
input w5 = 2.5;     # Breakout

# ----------------
# CORE SCORES
# ----------------
def score1 = if close > Average(close, 200) then 0.5 else -0.5;
def score2 = if Average(close, 20) > Average(close, 20)[1] then 0.5 else -0.5;
def score3 = if Momentum(10, close) > 0 then 0.5 else -0.5;
def score4 = if OnBalanceVolume() > OnBalanceVolume()[1] then 0.5 else -0.5;

def score5 =
    if close > Highest(high, 20)[1] then 0.5
    else if close < Lowest(low, 20)[1] then -0.5
    else 0;

# ----------------
# FINAL SCORE
# ----------------
def finalScore =
      score1 * w1
    + score2 * w2
    + score3 * w3
    + score4 * w4
    + score5 * w5;

# ----------------
# NORMALIZATION
# ----------------
def maxScore = 4.375;
def normScore = finalScore / maxScore;

# ----------------
# DEAD ZONE
# ----------------
input deadZone = 0.15;

def activeScore =
    if AbsValue(normScore) < deadZone then 0
    else normScore;

# ----------------
# CONVEX SIZING CURVE
# ----------------
input curvePower = 1.8;

def sizeCurve =
    Sign(activeScore) *
    Power(AbsValue(activeScore), curvePower);

# ----------------
# TIMEFRAME ALIGNMENT (HTF)
# Daily 200 SMA vs current price
# ----------------
def dailyClose = close(period = AggregationPeriod.DAY);
def daily200 = Average(dailyClose, 200);

def htfAligned =
    if dailyClose > daily200 then 1 else 0;

def tfMultiplier =
    if htfAligned then 1.10 else 0.75;

# ----------------
# FINAL POSITION SIZE
# ----------------
input maxPosition = 1.0;

def rawSize = AbsValue(sizeCurve) * tfMultiplier;

def positionSize =
    Min(maxPosition, rawSize);

def direction =
    if sizeCurve > 0 then 1
    else if sizeCurve < 0 then -1
    else 0;

# ----------------
# OPTIONS DELTA TRANSLATION
# ----------------
def deltaLow =
    if positionSize < 0.30 then 0.25
    else if positionSize < 0.60 then 0.35
    else 0.50;

def deltaHigh =
    if positionSize < 0.30 then 0.30
    else if positionSize < 0.60 then 0.45
    else 0.65;

# ----------------
# PLOTS
# ----------------
plot ZeroLine = 0;
ZeroLine.SetDefaultColor(Color.GRAY);

plot BiasScore = finalScore;
BiasScore.SetPaintingStrategy(PaintingStrategy.SQUARED_HISTOGRAM);
BiasScore.SetLineWeight(3);
BiasScore.AssignValueColor(
    if finalScore > 0 then Color.GREEN
    else if finalScore < 0 then Color.RED
    else Color.GRAY
);

plot Size = positionSize;
Size.SetLineWeight(3);
Size.SetDefaultColor(Color.CYAN);

# ----------------
# LABELS
# ----------------
AddLabel(yes,
    "Bias Score: " + Round(finalScore, 2),
    if finalScore > 0 then Color.GREEN
    else if finalScore < 0 then Color.RED
    else Color.GRAY
);

AddLabel(yes,
    "Direction: " +
    (if direction == 1 then "LONG"
     else if direction == -1 then "SHORT"
     else "FLAT")
     + " | Size: " + AsPercent(positionSize),
    if direction == 1 then Color.GREEN
    else if direction == -1 then Color.RED
    else Color.GRAY
);

AddLabel(yes,
    "Options Delta Guide: " +
    deltaLow + " – " + deltaHigh,
    Color.YELLOW
);

AddLabel(yes,
    "HTF Alignment: " +
    (if htfAligned then "BULLISH" else "BEARISH"),
    if htfAligned then Color.GREEN else Color.RED
);
 
RSI instead of momentum seems to give better results

tweaking the grading might help for instance I consider the break out zone as 0 just above that is 5 and just above that is 4 and above that is 3 and so on thank you for the basic script finding the secret sauce could prove harder.

I changed momentum to macd and added a w6 rsi much more sensitive actually might work on lower time frames for day trading.

Code:
# WEIGHTED ENSEMBLE SYSTEM
# Six‑Factor Market Bias Model

declare lower;
# These defaults reflect real-world behavioral importance:
# 200 SMA (macro trend) > Breakout > 20 SMA > Macd > OBV >Rsi

input w1 = 2.0; # Weight for 200 SMA trend regime
input w2 = 1.5; # Weight for 20 SMA slope
input w3 = 1.0; # Weight for Macd
input w4 = 2.0; # Weight for OBV direction
input w5 = 2.0; # Weight for Breakout Range
input w6 = 4.0; # Weight for Relative Stregnth

def score1 =
if close > Average(close, 200) then 0.5 else -0.5;

def score2 =
if Average(close, 20) > Average(close, 20)[1] then 0.5 else -0.5;

def score3 =
if MACD() > 0 then 0.5 else -0.5;

def score4 =
if OnBalanceVolume() > OnBalanceVolume()[1] then 0.5 else -0.5;

def score5 =
if close > Highest(high, 20)[1] then 0.5 else
if close < Lowest(low, 20)[1] then -0.5 else 0;

def score6 =
if RSI(10, close) > 0 then 0.5 else -0.5;

def finalScore =
score1 * w1
+ score2 * w2
+ score3 * w3
+ score4 * w4
+ score5 * w5
+ score5 * w6;

plot ZeroLine = 0;
ZeroLine.SetDefaultColor(Color.GRAY);

plot Score = finalScore;
Score.SetLineWeight(3);
Score.SetPaintingStrategy(PaintingStrategy.SQUARED_HISTOGRAM);

Score.AssignValueColor(
if finalScore > 0 then Color.GREEN else
if finalScore < 0 then Color.RED else
Color.GRAY
);


input showLabel = yes;
AddLabel(showLabel,
"Weighted Score: " + Round(finalScore, 2),
if finalScore > 0 then Color.GREEN else
if finalScore < 0 then Color.RED else
Color.GRAY);
 
Last edited by a moderator:
RSI instead of momentum seems to give better results

tweaking the grading might help for instance I consider the break out zone as 0 just above that is 5 and just above that is 4 and above that is 3 and so on thank you for the basic script finding the secret sauce could prove harder.

I changed momentum to macd and added a w6 rsi much more sensitive actually might work on lower time frames for day trading.

Code:
# WEIGHTED ENSEMBLE SYSTEM
# Six‑Factor Market Bias Model

declare lower;
# These defaults reflect real-world behavioral importance:
# 200 SMA (macro trend) > Breakout > 20 SMA > Macd > OBV >Rsi

input w1 = 2.0; # Weight for 200 SMA trend regime
input w2 = 1.5; # Weight for 20 SMA slope
input w3 = 1.0; # Weight for Macd
input w4 = 2.0; # Weight for OBV direction
input w5 = 2.0; # Weight for Breakout Range
input w6 = 4.0; # Weight for Relative Stregnth

def score1 =
if close > Average(close, 200) then 0.5 else -0.5;

def score2 =
if Average(close, 20) > Average(close, 20)[1] then 0.5 else -0.5;

def score3 =
if MACD() > 0 then 0.5 else -0.5;

def score4 =
if OnBalanceVolume() > OnBalanceVolume()[1] then 0.5 else -0.5;

def score5 =
if close > Highest(high, 20)[1] then 0.5 else
if close < Lowest(low, 20)[1] then -0.5 else 0;

def score6 =
if RSI(10, close) > 0 then 0.5 else -0.5;

def finalScore =
score1 * w1
+ score2 * w2
+ score3 * w3
+ score4 * w4
+ score5 * w5
+ score5 * w6;

plot ZeroLine = 0;
ZeroLine.SetDefaultColor(Color.GRAY);

plot Score = finalScore;
Score.SetLineWeight(3);
Score.SetPaintingStrategy(PaintingStrategy.SQUARED_HISTOGRAM);

Score.AssignValueColor(
if finalScore > 0 then Color.GREEN else
if finalScore < 0 then Color.RED else
Color.GRAY
);


input showLabel = yes;
AddLabel(showLabel,
"Weighted Score: " + Round(finalScore, 2),
if finalScore > 0 then Color.GREEN else
if finalScore < 0 then Color.RED else
Color.GRAY);
Be careful cause RSI and momentum are NOT interchangeable. They may look like they act the same but they are telling you two different things!!!! RSI is a filter, momentum is an actionable tattle tail!!!
 
RSI = where you are in a bounded pressure cycle
Momentum = how fast price is actually moving right now
They answer two different questions.
Below is the clean, trader-useful way to think about it.

RSI (Relative Strength Index)- What RSI really measures
RSI is a normalized oscillator built from:
  • average up closes
  • vs
  • average down closes
over a fixed window. So conceptually:
RSI measures buying vs selling pressure, not speed.
It is bounded:
  • 0 to 100
What RSI is good at:
  • overbought / oversold regimes
  • compression / reversion environments
  • divergence detection
In other words:
👉 RSI is a regime / condition indicator

The most important limitation (for you), RSI does not care how big the bars are. A series of tiny green candles can push RSI up the same way a series of large impulse candles can. So RSI can look strong while price is barely moving.

For my style I already trade:
  • breakouts
  • structure breaks
  • momentum continuation
So RSI for you should mainly be used as:
  • a filter
  • not a trigger
Example you already lean toward RSI > 55–60 = bullish regime, RSI < 45 = bearish regime

That’s exactly how you should use it.

Momentum

Now here’s the key distinction. “Momentum” indicators usually measure some form of:


price(t) − price(t−n)

or a smoothed / normalized version of that.

Conceptually Momentum measures velocity of price change. It is not bounded.

What momentum is good at and what Momentum is very good for:
  • detecting impulses
  • catching early acceleration
  • confirming breakouts
In physics terms (which fits your process-engineering mindset):
RSI = pressure balance
Momentum = flow rate

The big advantage for your trading, Momentum reacts immediately when:
  • displacement expands
  • bars start to stretch
  • range increases

That is exactly what you want on:
  • 1-5 minute
  • breakout
  • expansion legs
The real difference in one line

RSI answers “Is buying pressure dominant lately?”

Momentum answers “Is price actually moving faster right now?”

Why people get confused is that both go up in uptrends.
So visually they look similar. But internally:

FeatureRSIMomentum
Boundedyes (0–100)no
Uses up vs down closesyesno
Uses size of moveindirectlydirectly
Good for regimes✅❌
Good for breakouts❌✅
Good for divergences✅⚠️ sometimes


This is the key for the above system

From everything I've built:
  • PCM
  • TDFI
  • SuperTrend + slope
  • volume-weighted momentum
  • my Doppler idea
I am already building velocity and force models

That means:
👉 momentum belongs in the signal engine
👉 RSI belongs in the context engine

How I would wire them in my style pipeline

Very clean and very “Antwerks style”:
Step 1 – regime filter


RSI(14) > 55

Only then…

Step 2 – entry / continuation trigger

Use:
  • your momentum line crossing its zero / baseline
  • or your acceleration / deceleration state
One subtle but important trap

RSI can stay overbought for a long time in strong trends. If you try to fade:


RSI > 70
in a breakout system…You will kill your best trades.


RSI overbought is
a warning in range markets
a feature in trend markets
Where momentum beats RSI (especially for the above system)
You trade:
  • opening ranges
  • structure reclaim
  • CHoCH / IDM
  • fast rotations
Momentum will turn before RSI in:
  • breakout bars
  • displacement candles
  • squeeze releases

RSI lags because it averages up/down pressure.

In my words (process analogy), this fits a flow / throttling analogy perfectly:
  • RSI = pressure balance in the system
  • Momentum = actual flow through the pipe

High pressure with no flow → compression
High flow → breakout

Practical takeaway for these charts, if you only keep one as a trigger:
👉 keep momentum

If you only keep one as a filter:
👉 keep RSI

Final rule for you

Do not choose between them, use them like this:

RSI tells you if you should even be looking long or short
Momentum tells you when the move is actually happening

That separation will clean up a lot of the “almost good” signals you’ve been fighting in your 1-minute entries.
 

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

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