Hive document

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.

FusionVectorAether
What it isVector clock + 9 residuals + Aether S/R + temperatureOne volume-clock GBM + 9 residualsSame clock, then a 30-feature kitchen sink
70/30 hit76.76%76.74%76.69%
70/30 Brier0.154380.154440.15429
70/30 ECE0.01130.01360.0112
14 minutes left60.35%60.21%60.26%
ATM Brier0.24690.24670.2471
Weekly walk-forward hit76.60%76.60%76.59%
Weekly walk-forward Brier0.154440.154490.15433
Weekly walk-forward ECE0.00910.01140.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.

At minute t inside the window we do not guess the candle color. We have:

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:

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)

FeatureWhat it isLive weightWhat it is saying
z_clockThe GBM z itself+1.653The clock is the residual’s first feature too. Do not fight it.
range_extreme(4h range position − 0.5) × 2−0.104Fade the 4-hour extreme.
imb55-minute taker-buy share − 0.5+0.287Short-term aggressive flow continues.
imb1515-minute taker-buy share − 0.5−0.351Longer taker imbalance mean-reverts. The two signs disagree on purpose.
jump_zLast bar return / 60m vol−0.020Fade a one-bar spike, slightly.
path60`\sum ret\/ sum\ret\` over 60m+0.114A one-way hour is more likely to keep going than a two-way hour.
vwap_gap(S − session VWAP) / remaining vol+0.005Tiny. Session VWAP is already in the S/R layer.
log_remln(τ / 14)+0.022A small remaining-time tilt.
abs_z`\z\`+0.042When 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):

Nearest level is the closest of those nine. Then:

FeatureWhat it isLive weight
sr_z(S − nearest) / remaining vol−0.023
pinned1 if we are inside 0.30 remaining-vol of that level−0.016
z_ou_gapz_OU − z_GBM+0.036
ou_zThe 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:

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:

FeatureValueWeightContribution
z_clock+0.453+1.653+0.749
path600.35+0.114+0.040
imb5+0.08+0.287+0.023
range_extreme−0.20−0.104+0.021
abs_z0.453+0.042+0.019
imb15+0.04−0.351−0.014
pinned1−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:

SituationzP_clockw_clockWhat Fusion does
ATM, 14 minutes left, S = K + $50.01350.5¢0.33Residual gets most of the vote. Still a coin. Sit.
This worked minute0.45367.5¢0.47Split. A lean, not a ticket by itself.
Late lock, S = K + $500, 2 minutes left3.93~100¢0.99Clock 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.

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:

  1. Build causal features on bars whose open time is already closed. Nothing from the unclosed minute.
  2. Locate this window. K is the close of the bar that opened one minute before the window. τ is minutes left.
  3. Compute σ, vol_spent, z, P_clock.
  4. Find nearest S/R. Compute sr_z, pinned, OU θ, z_OU.
  5. Winsorize the 13 residual features to the training fences.
  6. Logistic residual with the live weights above.
  7. Blend with w_clock.
  8. Temperature 1.05.
  9. 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:

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):

TestWhat it doesResult
Permute labelsShuffle Yes/No on the OOS fold, keep featuresHit 49.95%. If Fusion were fitting noise, this would stay high.
Illegal futureGive the model the settlement close as a featureHits 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:

  1. Believe the clock. z_clock is 1.65. Everything else is a correction.
  2. 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.
  3. Fade location, follow path. Extended on the 4-hour range is a fade. A one-way hour is a follow.
  4. 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

Where the code lives

PiecePath
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.