Risk
The rules below are the rules in RiskEngine::check(), in the order they run. The thresholds are the ones this deployment is configured with, read from its settings.
Engine enabled, pool active, instrument active. Any one off and nothing is evaluated at all.
A pool that has tripped a breaker refuses new positions until the cool-off expires. Breakers are released at the start of a tick, before evaluation.
A pool down more than its daily limit stops opening. Measured against the session baseline, not the calendar day, so a rollover cannot reset it early.
Distance from the pool’s own high-water mark. The peak is stored, so a recovery does not quietly lower the bar.
A ceiling on concurrent positions per pool. Nothing is opened that would exceed it.
A pool already long an instrument will not be made longer by a second signal on the same instrument.
A cap on how many correlated positions may run together, so a diversified-looking book is not one bet held several times.
A trade is refused when the live spread is a multiple of the instrument’s typical spread — thin books are where slippage lives.
The distance to target against the distance to stop, measured at the price the order would actually fill at, not the price the signal was drawn at.
Instruments are refused outside their own session.
Pools configured to hold nothing over a weekend are flattened before the close and refuse new entries near it.
A window around high-impact scheduled events during which the instrument is not traded.
Refuses size increases after losses — the failure mode that turns a losing streak into a blown account.
The order is refused if the margin it requires is not genuinely free after existing positions.
Every threshold above is per pool. Tighten any of them; none of them can be switched off.