Elhadi.
← All posts
4 min readAI-written · in Suhaib Elhadi's voice

What "high confluence" actually means when you have to define it in code

This update was drafted on a schedule by the AI I build with, from real project notes — part of the vibecoding experiment this blog documents.

Here's a thing that sounds simple and isn't. Confluence is built on the idea that a trade setup is worth more when several independent factors line up — the way a disciplined trader actually evaluates things, instead of firing an alert off one moving average. I've argued that case plenty. But at some point "multiple factors agree" stops being a philosophy and has to become a function that takes market data and returns a number. And that's where it gets genuinely hard, because most ways of writing that function are secretly just one indicator wearing a coat.

The trap, stated plainly

Say I've got five signals: trend, momentum, a support/resistance level, volume, and a volatility filter. The obvious move is to score each one 0 to 1 and add them up. Setup fires when the total clears some threshold.

Looks like confluence. Often isn't. Here's why: if three of those five signals are all derived from price over the same lookback — trend, momentum, and the S/R level are all basically "where is price relative to its recent range" — then my five-factor score is really a two-factor score, and one of those two factors is being counted three times. I've built a weighted average that feels like a committee but is actually one loud voice and some echoes.

The failure is invisible in a backtest. The number goes up, the equity curve looks plausible, and I don't notice I've spent weeks building a fancier version of the single indicator I was trying to get away from.

Independence is the whole game

Confluence only means something if the factors can disagree. If two signals mathematically almost always move together, stacking them adds confidence the data doesn't actually support — you feel more sure, the score says more sure, and nothing new was learned.

So before any scoring, the real work is grouping the signals by what underlying thing they measure:

  • Price structure — trend direction, distance from key levels, higher-highs/lower-lows.
  • Participation — volume, breadth, whether the move is backed by activity or drifting.
  • Volatility regime — is the market expanding or contracting, is this a breakout environment or a chop environment.
  • Time / context — session, proximity to a scheduled event, day-of-week effects if they survive scrutiny.

Within a group, signals are largely redundant — pick the best one or blend them into a single group score. Across groups is where confluence actually lives. A price-structure signal and a participation signal agreeing tells you something a second price-structure signal never could.

How I actually score it now

The version I've landed on, roughly:

  1. Each group produces one score, −1 to +1, for its read on the setup. Bearish to bullish, with zero meaning "no opinion".
  2. Confluence is about agreement, not sum. I look at how many groups have a strong opinion and whether those opinions point the same way. Four groups at +0.7 is high confluence. Two groups at +0.9 and two near zero is a weaker setup with a smaller sample of opinions, even if the naive sum is similar. One group at +1.0 and the rest silent is explicitly not a confluence setup, however strong that one group is.
  3. Disagreement is information, not noise. If price structure says long and participation says the move is unsupported, the score drops hard rather than averaging to "meh". A conflict between independent groups is a reason to stand aside, and the function should treat it that way.
  4. The threshold to fire is stated as "how many independent groups must agree", not as a magic total. That keeps the whole thing honest — I can look at any fired signal and say these three groups agreed, here's what each one saw.

The check that keeps it real

The one test I run whenever I add or change a signal: correlate its output against every signal already in the model, over a long stretch of history. If the new one is highly correlated with an existing one, it doesn't get to be its own factor — it goes into an existing group or it replaces something. It is not allowed to add to the count just because it has a different name and a different formula.

Because the number the whole product reports — "high confluence" — is a claim that several independent things agreed. If the independence isn't real, the number is a lie told confidently, which is the exact thing I built this to avoid. Confluence isn't hard to compute. It's hard to compute honestly, and the honesty is entirely in refusing to count the same evidence twice.

Confluence is still built and not live — no signal track record to point at yet. But this is the part I most wanted to get right before it ever goes near real money: making sure "multiple factors agree" means what it says.

This one's auto-drafted from my notes on a schedule. If a number isn't in the notes, it doesn't show up here — I'd rather leave a blank than make something up.