Fusion — how the remaining-path engine works
Fusion is the model we trade. It is not a candle reader and it is not Aether.
Every minute inside a 15-minute Kalshi crypto window it prices one number:
P(settlement ≥ strike | price now, time left, volatility, flow, nearby levels)
That is a cash-or-nothing digital. After the window opens, it is a math problem. At the open, unfiltered 15-minute BTC direction is still a coin (49.80% Yes on 36,575 windows). Fusion sits when the digital is still a coin.
Open this page in a browser (this is the working copy):
https://preview.217-216-65-190.sslip.io/fusion-engine/
Live desk: preview /btc-live
24h paper: preview /aether-paper
Not financial advice. Paper only. Binance last is not Kalshi’s CF BRTI print.
The one-sentence recipe
Vector’s volume-clock GBM + Vector’s 9 residuals + Aether’s four S/R pieces + temperature 1.05. No TA laundry, no raw regime π, no ATM specialist.
That string is what is written on the live weights file.
Why Fusion exists
We built three engines on the same 512,050 in-window minutes. Same labels. No look-ahead.
| Fusion | Vector | Aether | |||
|---|---|---|---|---|---|
| What it is | Vector clock + 9 residuals + Aether S/R + temperature | One volume-clock GBM + 9 residuals | Same clock, then a 30-feature kitchen sink | ||
| 70/30 hit | 76.76% | 76.74% | 76.69% | ||
| 70/30 Brier | 0.15438 | 0.15444 | 0.15429 | ||
| 70/30 ECE | 0.0113 | 0.0136 | 0.0112 | ||
| 14 minutes left | 60.35% | 60.21% | 60.26% | ||
| ATM Brier | 0.2469 | 0.2467 | 0.2471 | ||
| Weekly walk-forward hit | 76.60% | 76.60% | 76.59% | ||
| Weekly walk-forward Brier | 0.15444 | 0.15449 | 0.15433 | ||
| Weekly walk-forward ECE | 0.0091 | 0.0114 | 0.0084 | ||
| Locks (\ | P−0.5\ | ≥ 40¢) | 95.74% | 95.97% | — |
Aether still “wins” Brier. It does it by dumping RSI, MACD, ADX, and the four raw regime probabilities into the residual and losing the side. That is not an upgrade for a desk that has to pick Yes or No.
The shipping rule was written before the bake-off and we kept it:
Do not replace Vector with Aether if Aether is worse. Hybrid only ships if it beats Vector on Brier without losing hit.
Fusion is that hybrid.
The contract we are pricing
Kalshi’s 15-minute crypto markets are digital options.
- Window starts on UTC
:00 / :15 / :30 / :45. - Strike K is the official index just before the open (CF BRTI 60-second average). Our research proxy is the last complete Binance 1-minute close before the window.
- Settlement S\* is the official index at the close (again a 60-second average). Our research proxy is the
:14 / :29 / :44 / :59close. - Yes pays $1 if
S* ≥ K. Flat pays Yes.
At minute t inside the window we do not guess the candle color. We have:
S= last complete 1-minute closeτ= minutes left after this bar (14 after the first bar, down to 1)σ= a causal one-minute volatility
The backbone is the Black–Scholes cash-or-nothing under geometric Brownian motion:
z = [ ln(S / K) + (μ − ½ σ²) τ ] / (σ √τ)
P_clock = Φ(z)
μ is zero. There is no drift we trust on a 15-minute crypto window. Φ is the standard normal CDF.
When |z| is large — price is many remaining-vol units through the strike — this is the contract. When |z| is small, leftovers get a residual logit. They are not the price.
The four layers, in order
closed 1m bars
│
▼
volume-clock GBM ──► P_clock, z
│
▼
13-feature residual logit ──► P_residual
│
▼
blend on |z| P = w_clock · P_clock + (1 − w_clock) · P_residual
│
▼
temperature 1.05 on the logit ──► Fusion P
│
▼
paper desk sit / Yes / No (fees, spread, feed-disagree)
Only Fusion can open a paper ticket. Vector and Aether still print as shadows so we can keep score.
Layer 1 — the volume-clock
Plain close-to-close vol is noisy on one-minute bars. Fusion (and Vector before it) uses two causal estimators, then a volume clock.
1. One-minute σ
Half close-to-close, half Parkinson (high/low, less noisy):
σ_cc = std(log returns, 60 bars)
σ_park = sqrt( mean( ln(H/L)² , 60 ) / (4 ln 2) )
σ = sqrt( 0.5 σ_cc² + 0.5 σ_park² )
2. Volume spent
If the last five minutes already printed a lot of volume versus the last hour, more of this window’s variance has already happened. Remaining path should be quieter, so the clock should be more confident.
volz5 = (mean volume last 5 − mean volume last 60) / std(volume, 60)
vol_spent = clip(1 + 0.15 · volz5, 0.55, 1.55)
σ_adj = σ / vol_spent
Then z and P_clock use σ_adj, not raw σ.
This is the object that is actually predictable. The first Aether draft replaced this clock with a four-regime mixture digital. Brier went from 0.154 to 0.163. We threw that clock away. Every later candidate, including Fusion, keeps Vector’s volume-clock GBM as the backbone.
Layer 2 — when we trust the clock
The blend is a sigmoid on |z|:
w_clock = 1 / (1 + exp(−1.35 · (|z| − 0.55)))
P = w_clock · P_clock + (1 − w_clock) · P_residual
Read that in English:
|z|well above 0.55 → almost all weight on the digital. Price is already through the strike relative to time left.|z|near zero → almost all weight on the residual. We are ATM. The clock is a coin and the leftover features have a chance.- Around
|z| = 0.55→ 50/50 mix.
This is why locks print ~96% and ATM prints ~55%. Fusion is not “76% at the open.” It is a remaining-path machine whose accuracy rises as |S−K| / (σ√τ) grows.
Layer 3 — the residual (thirteen numbers, not thirty)
P_residual is a ridge logistic regression. Features are winsorized at the 0.5 / 99.5 percentiles on the training cut so one jump bar cannot dominate.
Vector’s nine (kept)
| Feature | What it is | Live weight | What it is saying | ||||
|---|---|---|---|---|---|---|---|
z_clock | The GBM z itself | +1.653 | The clock is the residual’s first feature too. Do not fight it. | ||||
range_extreme | (4h range position − 0.5) × 2 | −0.104 | Fade the 4-hour extreme. | ||||
imb5 | 5-minute taker-buy share − 0.5 | +0.287 | Short-term aggressive flow continues. | ||||
imb15 | 15-minute taker-buy share − 0.5 | −0.351 | Longer taker imbalance mean-reverts. The two signs disagree on purpose. | ||||
jump_z | Last bar return / 60m vol | −0.020 | Fade a one-bar spike, slightly. | ||||
path60 | `\ | sum ret\ | / sum\ | ret\ | ` over 60m | +0.114 | A one-way hour is more likely to keep going than a two-way hour. |
vwap_gap | (S − session VWAP) / remaining vol | +0.005 | Tiny. Session VWAP is already in the S/R layer. | ||||
log_rem | ln(τ / 14) | +0.022 | A small remaining-time tilt. | ||||
abs_z | `\ | z\ | ` | +0.042 | When the clock is already extreme, push a hair further. |
Bias is −0.0036. The intercept is basically zero. We did not bake in a bullish prior.
Aether’s four S/R pieces (stolen)
These are the only Aether features that survived the walk-forward without costing hit.
Where the levels come from (all causal — no future bars):
- Prior UTC-day floor pivots:
P = (H+L+C)/3, then classicR1/S1/R2/S2. - Confirmed swings: a high (low) at
t−5that is the max (min) of the five bars on each side. Candidate is five minutes old before we accept it. - Session VWAP (UTC day, price × volume).
- 4-hour mid: midpoint of the last 240-minute high/low.
Nearest level is the closest of those nine. Then:
| Feature | What it is | Live weight |
|---|---|---|
sr_z | (S − nearest) / remaining vol | −0.023 |
pinned | 1 if we are inside 0.30 remaining-vol of that level | −0.016 |
z_ou_gap | z_OU − z_GBM | +0.036 |
ou_z | The OU digital’s own z | +0.004 |
sr_z negative means “if we are extended above a level, shade Yes down a little.” Pinning slightly damps the residual. The useful one is z_ou_gap: when the mean-reversion model disagrees with the GBM clock, Fusion listens a little.
The OU that produces those last two
We do not price with the OU. We compute it as a disagreement feature.
Attractor θ is a mix of 4-hour mid, VWAP, and the nearest level. If we are pinned, the nearest level gets 48% of θ. If not, 22%. VWAP is always 32%. The rest is the 4-hour mid.
Log-price is treated as an Ornstein–Uhlenbeck toward ln θ with κ = 0.09 per minute (half-life about 7.7 minutes) and a slightly quieter σ (0.92 × σ). The OU digital z is the usual Gaussian remaining-path z around that pulled mean:
ekt = exp(−κ τ)
mean = ln θ + (ln S − ln θ) · ekt
var = σ_ou² · (1 − ekt²) / (2κ)
z_OU = (mean − ln K) / √var
Then Fusion asks: does that z disagree with the GBM z? That gap is the feature. Replacing the GBM clock with the OU, or with a four-regime mixture of GBM/OU/shock/quiet, lost.
Layer 4 — temperature
Aether’s real gift was calibration, not a new process.
After the blend we take the logit of P and multiply by 1.05, then sigmoid again:
ℓ = ln( P / (1−P) )
P' = sigmoid( 1.05 · ℓ )
One number. Same ranking. Slightly sharper probabilities. That is most of the ECE win versus Vector (0.0113 vs 0.0136 on the 70/30 cut; 0.0091 vs 0.0114 on the weekly walk-forward).
We do not refit a 30-weight kitchen sink to buy that calibration.
A worked minute
These numbers are a clean walkthrough with the live Fusion weights. They are not a live ticket.
Setup:
S = 118,500(last closed 1-minute close)K = 118,400(window strike)τ = 6minutes leftσ = 8.5 bpsper minute- Last five minutes were busy (
volz5 = +0.80) - Price is slightly below the 4-hour extreme, 5-minute takers are buying, we are pinned $20 above a nearby pivot
Clock
vol_spent = clip(1 + 0.15 × 0.80, 0.55, 1.55) = 1.12
σ_adj = 0.00085 / 1.12 = 0.000759
z = ln(118500/118400) / (σ_adj √6) = 0.453
P_clock = Φ(0.453) = 67.5¢
Price is $100 through a strike, with about $247 of remaining one-sigma room. That is not a lock. It is a lean.
S/R + OU
Remaining vol in dollars is ~$247. We are $20 from the nearest pivot, so we are pinned. θ is pulled toward that pivot (48%) plus VWAP (32%) plus the 4-hour mid (20%) → θ ≈ 118,382.
The OU thinks the remaining path is being tugged back toward 118,382, so it is less bullish than the GBM:
z_OU = 0.287 (P_OU = 61.3¢)
z_ou_gap = −0.166
Residual
Almost all of the logit is the clock talking to itself. Everything else is a penny correction:
| Feature | Value | Weight | Contribution |
|---|---|---|---|
z_clock | +0.453 | +1.653 | +0.749 |
path60 | 0.35 | +0.114 | +0.040 |
imb5 | +0.08 | +0.287 | +0.023 |
range_extreme | −0.20 | −0.104 | +0.021 |
abs_z | 0.453 | +0.042 | +0.019 |
imb15 | +0.04 | −0.351 | −0.014 |
pinned | 1 | −0.016 | −0.016 |
| everything else | — | — | −0.028 |
| bias | — | — | −0.004 |
| logit total | +0.790 |
P_residual = sigmoid(0.790) = 68.8¢
w_clock = sigmoid(1.35 × (0.453 − 0.55)) = 0.467
P_blend = 0.467 × 67.5¢ + 0.533 × 68.8¢ = 68.2¢
P_Fusion = temperature 1.05 = 69.0¢
The residual barely moved the clock. That is the point. Fusion is a clock with signed lint, not a 13-indicator vote.
Two other minutes, same σ, so you can see the blend flip:
| Situation | z | P_clock | w_clock | What Fusion does |
|---|---|---|---|---|
| ATM, 14 minutes left, S = K + $5 | 0.013 | 50.5¢ | 0.33 | Residual gets most of the vote. Still a coin. Sit. |
| This worked minute | 0.453 | 67.5¢ | 0.47 | Split. A lean, not a ticket by itself. |
| Late lock, S = K + $500, 2 minutes left | 3.93 | ~100¢ | 0.99 | Clock owns it. Residual is decoration. |
What we left on the bench
These were computed, scored, and rejected. They still draw on the live desk so you can see them. They do not enter Fusion’s price.
- RSI 14, Stochastic %K, MACD histogram, Bollinger %B, Williams %R, CCI, MFI, ADX, +DI/−DI gap, 14-bar close location
- Raw regime probabilities
π_trend / π_chop / π_shock / π_quiet - Regime-gated interactions (
chop × sr_z,trend × z60,shock × −jump) - Aether’s ATM specialist logit (a second model fit only when
|z| < 1) - Shock-gating the clock (trust the clock more in SHOCK) — Brier got worse
- Replacing the clock with Yang–Zhang, Garman–Klass, Merton jumps, Edgeworth skew, CEV, or Heston — none beat the volume-clock on the paired walk-forward by enough to ship
The four-state regime (trend / chop / shock / quiet) is still computed live from path efficiency, range position, jump size, volume z, persistence, and vol/ATR ratios. Mean mix on the panel was about 19 / 37 / 24 / 20. Fusion does not multiply those π’s into the price. They are a dashboard label.
An earlier hybrid picker (calibrate_hybrid.py) wanted VEC+SR+REGX — Vector’s nine, the S/R four, and the three regime-gated interactions. Live Fusion dropped the REGX extras. They did not buy hit. Temperature did the calibration job with one parameter. Leaner won.
How a live price is born
Every few seconds the desk pulls Binance (or MEXC) 1-minute bars. Then, in order:
- Build causal features on bars whose open time is already closed. Nothing from the unclosed minute.
- Locate this window.
Kis the close of the bar that opened one minute before the window.τis minutes left. - Compute
σ,vol_spent,z,P_clock. - Find nearest S/R. Compute
sr_z,pinned, OUθ,z_OU. - Winsorize the 13 residual features to the training fences.
- Logistic residual with the live weights above.
- Blend with
w_clock. - Temperature 1.05.
- Clip to
[0.0001, 0.9999].
That P is Fusion. The same function also emits Vector and Aether as shadows. Only Fusion can open a paper ticket.
How the paper desk uses that number
The 24-hour Kalshi paper is not “bet Fusion’s side.” It is Fusion versus the live book, after fees.
Kalshi taker fee is quadratic: 0.07 × C × P × (1−P). Peak about 1.75¢ at 50¢, about 0.89¢ at 85¢. ATM is the most expensive place to be a hero, which matches where our edge is smallest.
A ticket is allowed only if all of this is true:
- First 45 seconds of the window: sit. The open is a coin and the book is still finding itself.
- Last 120 seconds: sit. Last-minute BRTI average is not our Binance last.
- Spread wider than 10¢: sit.
- Fusion and Kalshi mid disagree by ≥18¢ on BTC/ETH/SOL (≥10¢ on alts): sit. That is almost always feed mismatch (Binance ≠ CF BRTI), not edge.
- Book already locked the other way (mid under 20¢ while we want Yes, or over 80¢ while we want No): sit.
- Lottery locks (mid under 12¢ or over 88¢): sit. Cheap tails would dominate P&L noise.
- Edge after 2× fee + half-spread + 2¢ adverse, and +4¢ extra tax in the 45–80¢ band: only then take.
Fill is paper IOC. Limit = quoted ask + 2¢. We do not walk the stack. Two sleeves: $2.50 and $5.00 on a $100 start. Max heat 40% of book. Settlement is Kalshi’s official result, not our Binance close.
Alts are tagged BTC-transfer. Native weights were fit on BTC. We still print a number, but the sit rules are tighter.
How we know the scorer is not cooking
Two audits on the weekly out-of-sample fold (474,418 minutes):
| Test | What it does | Result |
|---|---|---|
| Permute labels | Shuffle Yes/No on the OOS fold, keep features | Hit 49.95%. If Fusion were fitting noise, this would stay high. |
| Illegal future | Give the model the settlement close as a feature | Hits 100%. Proves the label join is the real contract, not a shifted window. |
Features at minute t use only bars with open_time ≤ t. Strike and settle are joined by window start, not by “next close.” An unfiltered 80% at the open is treated as a join bug, not a win.
The 70/30 cut is the same time cut Vector used, so the comparison is paired. The weekly walk-forward retrains on all prior weeks and tests the next week (first four weeks are burn-in). Live weights are the last walk-forward fold, not the in-sample fit.
What the weights are really saying
Ignore the tiny ones. The residual has four opinions that matter:
- Believe the clock.
z_clockis 1.65. Everything else is a correction. - Taker flow is two-timescale. 5-minute aggressive buying continues; 15-minute aggressive buying fades. If both point the same way they partly cancel. If they disagree, Fusion takes the short one and fades the long one.
- Fade location, follow path. Extended on the 4-hour range is a fade. A one-way hour is a follow.
- S/R is a disagreement term, not a magnet we blindly fade. Being near a pivot (
pinned) slightly damps. The OU-versus-GBM gap is the useful bit.
That is the whole “secret.” There is no RSI threshold. There is no “bullish engulfing.” Those were researched, coded, and they lost hit.
Honest limits
- Open-window 15-minute direction is ~50%. Fusion will not pretend otherwise. The 76% headline is in-window minutes, dominated by late minutes when
|z|is already large. - ATM is still a coin plus a little. ~55% hit, Brier ~0.247. We sit most of those.
- 14 minutes left is ~60%. That is the earliest remaining-path slice. Real, small, not a living.
- Binance ≠ CF BRTI. Huge Fusion-versus-book gaps are usually the feed, which is why
feed_disagreesits. Research scores on Binance. Paper P&L settles on Kalshi’s official print. - Alts are borrowed. Weights are BTC. Transfer is a convenience, not a native model.
- Paper, not live. No Kalshi API key, no real orders. The 24h books are IOC against the public tape.
- Tiny live sample. After a few hours the official-settlement scoreboard is still noisy. Kalshi mid can beat Fusion on Brier in a 30-window sample. That does not overturn 474k walk-forward minutes, and it does not license going live.
- Not a general-purpose trader. Fusion is a 15-minute remaining-path digital. It does not pick stocks, does not swing-trade, and does not know news.
Where the code lives
| Piece | Path |
|---|---|
| Panel, clock, S/R, Aether features | /opt/workshop/preview/btc-15m-predictor/src/calibrate_aether.py |
| Hybrid bake-off (who beat Vector) | …/src/calibrate_hybrid.py |
| Paper desk (this is what trades) | …/src/paper_desk.py |
| Live browser engine | /opt/workshop/preview/btc-live/index.html |
| Live weights | /opt/workshop/preview/btc-live/fusion_live.json |
| Full bake-off dump | /opt/workshop/preview/btc-live/fusion_calibration.json |
Bottom line
Fusion is Vector’s clock with the only Aether pieces that survived a walk-forward, plus one temperature for calibration.
The clock does almost all the work. The residual is a small, signed correction from two-timescale flow, range extremes, path efficiency, and whether nearby levels disagree with the GBM. RSI does not get a vote.
That is why it can win — and why it still sits most of the time.