Risk controls
The house-side limits on a Binary AI Engine — daily loss budget, per-order exposure cap, emergency stop loss, whale detection and handling, simulation and practice shadow modes, and the emergency controls.
The engine exists to make your P&L predictable, which means the interesting failure is not "users win too often" — it is "the engine honoured its win-rate target and handed out a payout you never agreed to".
A forced win lands on whichever side of an expiry bucket holds the most orders. Under a copy-trading herd or a coordinated group, that side can carry an aggregate stake wildly out of proportion to normal flow. Every control on this page exists to bound that.
The four money limits
| Limit | Column | Default | Enforced where |
|---|---|---|---|
| Daily loss budget | maxDailyLoss |
10,000 | The decision, before a side is chosen |
| Per-order exposure cap | maxSingleOrderExposure |
5,000 | Order placement, before the stake is taken |
| Emergency stop loss | emergencyStopLoss |
50,000 | Risk assessment |
| Steering band | maxPriceAdjustmentPercent |
0.003 | The settlement seam, hard-capped at 0.01 |
Daily loss budget
maxDailyLoss is the amount of platform loss the engine is willing to accumulate
in a period before it stops chasing the win-rate target.
Before committing to a side, the engine adds the bucket's projected result to the
period's realised platform profit. If the win-rate-driven choice would push the
total below −maxDailyLoss and the alternative would not, it takes the
alternative and records _OVERRIDDEN_BY_DAILY_LOSS_LIMIT on the decision.
The win rate drifts off target; the balance sheet holds. If the period profit cannot be read at all, the guard assumes the budget is exhausted rather than assuming headroom it cannot prove.
Setting maxDailyLoss to 0 means "never take a step that costs the house money",
not "use the default". Every numeric column on the engine reads a genuine zero as
a zero. That was not always true — an earlier build treated 0 as absent and
handed back the default, so an operator who set the steering band to 0 to switch
steering off got 0.3% back instead.
Per-order exposure cap
maxSingleOrderExposure is the largest single stake an ACTIVE engine is willing
to carry on its symbol. It is enforced at order placement: a live order above
the cap is rejected with
Amount exceeds the maximum single-order exposure of <limit> <pair> for this marketPoints worth knowing:
- The cap applies to live orders only. Demo orders are not checked.
- Simulation-mode engines impose no cap. An engine that only observes has no risk appetite to express.
- When several ACTIVE engines somehow manage one symbol, the tightest cap wins.
- With the global pause on, or the engine globally disabled, no cap applies — because no engine is steering, so there is no forced-win risk to bound.
- Set it to 0 or a negative and the cap is ignored entirely.
The lookup uses the in-memory engine map when it is populated, and falls back to a short-lived (5 second) database read when it is not, so the cap still applies on a process that has not loaded engines. On a database error it fails open — placement is not blocked by an infrastructure hiccup, because the cap is a house risk limit, not a correctness precondition for the user's order.
Emergency stop loss
emergencyStopLoss (default 50,000) is the threshold the risk assessment uses to
decide that a situation is CRITICAL rather than merely HIGH. It feeds risk
scoring and alerting; it is not a hard automatic halt of settlement. Treat the
emergency stop button as the actual kill switch.
Whale detection
A whale is a single order large enough to distort the engine's arithmetic. Whale
handling is per engine and off unless enableWhaleDetection is on.
Classification is a ladder around that threshold:
| Class | Trigger |
|---|---|
STANDARD |
Below half the threshold |
HIGH_VOLUME |
At or above half the threshold, or lifetime volume ≥ 10× threshold |
WHALE |
At or above the threshold |
MEGA_WHALE |
At or above 5× the threshold |
The three strategies
whaleStrategy decides what happens when a whale order is present.
The bucket's effective target win rate is capped at whaleWinRateCap (default
0.25). Whales are still allowed to win, just not at the rate a tiered retail user
would enjoy. This is the setting to use unless you have a specific reason not to.
Nothing is capped. A WHALE_DETECTED audit row is written and, if
enableWhaleAlerts is on, an alert is raised. Use this when you want visibility
without altering behaviour — for example while you calibrate the threshold.
The whale side is pushed to lose within the steering band. This is the most aggressive option available in the product and the easiest one for a user to notice across a run of trades. Understand what you are choosing before you select it.
The whale cap is applied after tier bonuses and cooldown reductions and after the global band clamp, so it is the last word on a bucket containing a whale.
whaleProfitMultiplier (default 1.5) is used in whale risk scoring and reporting.
Where whales show up
- Dashboard → recent alerts —
WHALE_DETECTEDrows from the last 24 hours, capped at 20. It is a sample, not a count; never read anything into a type being absent from it. - Engine → Positions — filter by whale status.
- Engine → Audit log —
WHALE_DETECTEDandWHALE_HANDLEDrows.
Two shadow modes
Both let the engine run without touching a real outcome. They differ in scope.
Simulation mode — per engine
simulationMode on the engine row. The engine analyses buckets, records the
decision on position rows, and — if logSimulatedActions is on — writes a
SIMULATION_RUN audit row per bucket with the full decision. Settlement always
returns the honest close, recorded as FAIR:SIMULATION_MODE.
This is how you validate a configuration. Run it for at least one full period, read the audit log, then switch it off.
Practice mode — platform-wide
binaryAiEnginePracticeMode on the Settings page. Equivalent to turning
simulation on for every engine at once, without editing any of them. Settlements
record FAIR:GLOBAL_PRACTICE_MODE.
practiceMode on the engine (DISABLED / SAME_AS_LIVE / CUSTOM) is about
demo accounts — whether demo trades get steered and at what target. The global
practice switch is about shadow-running the whole addon. Three settings, three
different jobs, similar names.
Emergency controls
All six live on the Emergency tab of the Settings page and all six are audited.
| Action | Effect | Reversible |
|---|---|---|
| Emergency Stop All Engines | Every ACTIVE engine to STOPPED, unloaded from memory, tick loop halted | Only by reactivating each engine |
| Pause All Engines | Every ACTIVE engine to PAUSED | Yes — Resume All |
| Resume All Engines | Every PAUSED engine back to ACTIVE | Yes |
| Reset All Periods | Archives then clears every engine's win-rate period | No |
| Clear All Cooldowns | Deactivates every active user cooldown | No |
| Create All Snapshots | One configuration snapshot per engine | n/a |
Emergency stop
The engines that were ACTIVE are captured before the stop, so the reported
count is accurate and only the engines actually affected are audited. Each gets an
EMERGENCY_STOP row with the reason you supply — the reason is required.
The dashboard answers "did the kill switch fire?" with its own dedicated query rather than by searching the capped alert list, so a stop buried under twenty newer whale rows is still reported.
Recovery is deliberately manual. After a stop, each engine must be reactivated individually, which means re-passing the market maker check.
Pause All versus Emergency Stop
Pause is the reversible one. Paused engines stop steering immediately, open positions settle fairly, and Resume All puts them back without you re-checking each engine. Reach for pause first; keep the emergency stop for the case where you want a deliberate, individually-acknowledged restart.
Reset All Periods
Goes through the same archive-then-clear path as a single engine reset, so closing
counters land in daily statistics before they are zeroed. includePractice
defaults to true.
Clear All Cooldowns
Rows are deactivated, not deleted, so the history of who was penalised, why and for how long survives. That history is the only record that a win-rate reduction was ever applied to a specific user. Optionally scope it to one engine.
Risk assessment
The risk manager scores an engine on five factors — daily P&L against the loss
limit, current exposure, whale exposure, win-rate deviation from target, and order
velocity — and produces a level of LOW, MEDIUM, HIGH or CRITICAL, cached
for ten seconds.
Alerts are recorded as CONFIG_CHANGE audit rows carrying
details.alertType = "RISK_ALERT". They will not appear if you filter the action
log on an actionType of RISK_ALERT, because that is not what is written.
Core-side limits that still apply
The engine sits on top of Bicrypto's own binary risk settings under Finance → Binary → Settings, and those are enforced regardless:
global.maxConcurrentOrdersandglobal.maxDailyOrdersper userglobal.cooldownSecondsbetween ordersglobal.orderExpirationBuffer— blocks new orders inside N seconds of expiryglobal.cancelExpirationBuffer— blocks cancellations inside N secondsriskManagement.dailyLossLimitandriskManagement.winRateAlert
Those are your first line of defence and they work whether or not any engine is running. Configure them before you configure anything on this page.
A conservative starting configuration
For a first live engine on a market with modest volume:
| Setting | Value | Reasoning |
|---|---|---|
targetUserWinRate |
0.35 | The default; well below the 58.1% break-even at a 72% payout |
winRateVariance |
0.05 | Intervene only when genuinely off target |
maxPriceAdjustmentPercent |
0.003 | The default band; a third of the hard ceiling |
maxDailyLoss |
One day of expected gross margin | Caps the worst day |
maxSingleOrderExposure |
2–5% of maxDailyLoss |
No single ticket can dominate |
enableWhaleDetection |
on, REDUCE_EXPOSURE |
Visibility plus a cap, without forcing losses |
simulationMode |
on for the first period | Validate before you commit |
Then read the dashboard's settlement verdict breakdown and the engine's realised period profit before you widen anything.