Three inputs, each weighted, combined into a single score between -1 and 1. If it crosses 0.4, you enter. Below that, you wait.

The three inputs are orderbook imbalance (40%), 1-minute momentum (35%), and the perpetual funding rate (25%). Orderbook imbalance is the simplest — how much more volume sits on the bid side versus the ask side, normalised to [-1, 1]. Momentum is the average recent return, scaled so a 1% move fills the signal completely. Funding rate works in reverse: when longs are paying shorts, the market's overstretched long, so negative funding flips the signal bullish.

Why composite

I could have just picked one signal and built around it. The composite approach came from noticing that any single factor was too noisy on its own — you'd get dozens of false positives in a flat market. The combination filters those out. Specifically, an orderbook imbalance spike during adverse funding and decelerating momentum is a very different signal than an imbalance spike with everything else confirming.

BTC only. TP at +0.15%, SL at -0.075%. That's a 2:1 reward-to-risk ratio. Max 10% of capital per trade, 30-trades-per-day hard cap, 60-second cooldown between entries.

The architecture

The structure underneath is hexagonal. The core business logic — the signal computation, the position sizing, the trade resolution — doesn't know if it's talking to Hyperliquid, a fake exchange, or a file. It knows prices and it knows how to compute a score. Everything else is adapters.

Every value in the system is a Decimal. Every domain object is a frozen dataclass. The first time I got a float rounding error in a risk calculation I spent an hour hunting it. After that, floats were banned from anything touching money.

The 60-second cooldown and the 30-trades-per-day limit came from watching paper logs — the model would sometimes fire four times in ten minutes during volatile periods, each entry marginal. Rate-limiting is the simplest form of risk management that doesn't require any analysis at all.

The QRNG jitter came later — adding ±0.3% randomness to stop-loss placement using quantum randomness from Origin's 60-qubit QPU, so automated strategies running similar parameters couldn't hunt each other's stops. That's a story for another post.