Troubleshooting
Why an ACTIVE Binary AI Engine steers nothing, why a setting appears to be ignored, what each FAIR settlement reason means in practice, and how to recover a stuck engine.
Almost every report about this addon is one of two things: an engine that looks ACTIVE but is not steering, or a setting that looks saved but is not taking effect. Both have short diagnostic paths.
Start here
Three checks answer most questions before you open a log file.
-
Is the cron registered? Admin → System → Cron should list
processBinaryAiEnginewith a 10 second period. If it is missing, thebinary_ai_engineextension row is off — nothing else on this page will help until it is on. -
What does the dashboard say about settlements? The dashboard aggregates the last 24 hours of live settlements by verdict. If everything reads
FAIR:<something>, the reason is right there. The table further down explains each one. -
Is the engine attached? Change the engine's status (even to the value it already has) and read
engineAttachedin the response.falsemeans this process is not running the engine, only recording that it should.
The engine is ACTIVE but nothing is being steered
Work down the list. Each entry names the verdict you would see on the dashboard.
processBinaryAiEngine is gated on the binary_ai_engine extension row. With the
extension disabled, no engine is ever loaded into memory, no period rolls over,
and the settlement hook finds nothing resident. The engine rows can sit at ACTIVE
the whole time and look perfectly healthy.
Enable the extension under Admin → System → Extensions. The scheduler picks it up within a cycle, without a restart.
Check binaryAiEngineEnabled and binaryAiEngineGlobalPause on the
Settings page. Either one suppresses all steering
platform-wide while leaving every engine row untouched.
The enabled switch also fails closed: if the settings store cannot be read at all, the addon behaves as disabled. If Redis or the settings cache is unhealthy, that is your answer.
simulationMode on the engine, or binaryAiEnginePracticeMode on the Settings
page. Both are easy to leave on after testing. In simulation the audit log fills
with SIMULATION_RUN rows, which is the confirmation you are in it.
Under Finance → Binary → Markets, the pair's source must be ECOSYSTEM.
Markets created by the Import action come in as EXCHANGE and can never be
steered — the tape belongs to the exchange.
You cannot flip a market's source to fix this if no ecosystem market exists for
the pair; the create endpoint rejects ECOSYSTEM without one.
The attached AI Market Maker must be ACTIVE. Activation checks this, but restart recovery does not — so a reboot can revive an engine whose market maker has since stopped, leaving an ACTIVE engine that legitimately refuses to steer.
Start the market maker. The engine resumes on the next settlement.
The steered close has to become the close of the candle covering expiry. Once that minute has rolled over, the candle is history and a client may already have seen it, so the engine refuses and records how many minutes late it was.
This is a symptom of slow settlement, not of the engine. Look at cron health, database latency and how long the binary settlement job is taking. A rising share of this verdict is worth an alert.
The bucket was never analysed. Three usual causes:
minPositionForOptimizationis above your actual stakes. Default 10. Compare it to the median stake on the market.adjustmentLeadTimeSecondsis too short. Default 30. A bucket only becomes eligible inside that window; if settlement runs before a tick lands in it, nothing is recorded.- The order is not
RISE_FALL. Nothing else is ever steered.
maxPriceAdjustmentPercent is 0 on the engine. That genuinely means "do not
steer" — a zero is honoured, not replaced by the default.
The steered close could not be written into the ecosystem candle series. Usually the market maker addon is not resolvable, or the ecosystem market is missing. The engine refuses to settle on a price nobody could see.
A setting appears to be ignored
Most fields on the Settings page are defaults for new engines, read only at creation time. The nine that act immediately are: enabled, global pause, practice mode, min win rate, max win rate and the adjustment speed.
To change a running engine, edit the engine.
The five tier bonus fields there are the platform profile. The bonuses actually applied come from the per-engine tier rows under Users → User Tiers. Edit the tier row.
The controller works against the current period, and it only intervenes when
the realised rate leaves target ± variance. Two things to check:
- Reset the period after a material change, otherwise the engine spends the rest of the window correcting toward the old number.
- Look at the variance. At ±5% around a 35% target, anything between 30% and
40% is
WITHIN_RANGEand no outcome is forced at all.
Active-cooldown lookups are cached for 30 seconds, tier lookups for 60. Give it a minute.
Two clamps apply on load. maxPriceAdjustmentPercent is re-capped at 0.01 no
matter what the column says, and the effective target win rate is clamped into the
global min/max band on every decision. Both are deliberate.
Errors you may see
Returned as a 400 on activation. Start the attached market maker first. This is the same condition the settlement path checks, so activation and steering agree.
The relationship is one-to-one, enforced by a unique index. Pick a different market maker, or edit the existing engine.
A user hit maxSingleOrderExposure on an ACTIVE engine's market. Raise the cap on
the engine if that is a legitimate ticket size; otherwise it is doing its job.
Only one experiment runs per engine. If the blocking test has no durationDays,
it runs until you stop it — check Analytics → A/B Testing.
You enabled monitoring without naming a provider, or named one outside BINANCE,
COINGECKO, CRYPTOCOMPARE. The request is rejected rather than saving a
configuration that would report enabled while permanently down.
The hard ceiling. 1% is already an order of magnitude wider than the 0.3% default; beyond it the nudge stops being a nudge and the published candle stops being credible.
Zero would make every period instantly overdue, so the controller resets before it can measure anything and win-rate targeting silently stops working. A row written by a direct database edit can still be in that state.
Recovering a stuck engine
The database says one thing and the process another. Set it to PAUSED and back to ACTIVE — both operations work whether or not the engine is resident, so this is safe. If it stays detached, the cron is not running.
Restart recovery reloads every DB-ACTIVE engine on the cron's first successful cycle. If initialisation failed transiently, the reconcile pass on the next cycle recovers it. Give it a minute before intervening.
Global Pause on the Settings page is the fastest reversible option — engines stay loaded and lift instantly. Emergency Stop All is the deliberate, individually-acknowledged option: recovery requires reactivating each engine, which re-runs the market maker check.
Every engine update takes an automatic snapshot before it writes. Go to System → Snapshots, compare against current, and roll back. The rollback itself snapshots the state it replaces, so it is reversible too.
Note that status is deliberately not part of a snapshot — restore
configuration, then set status yourself.
Analytics problems
Normal on a young engine. The model needs enough settled live positions in the window. Nothing is broken and nothing needs chasing.
Three guards, any of which is enough to no-op: confidence below 0.5, the last training run's accuracy below 0.5, or the recommended change below the minimum step. Each returns a readable reason.
Apply Winner refuses on an inconclusive result. Either the arms have not reached the target sample size per arm, or the difference is not significant on the chosen primary metric. Let it run longer, or accept that the arms do not differ.
They report realised platform profit from position rows, not a projection
based on an assumed payout. They will not match a back-of-envelope
stake × payout calculation, and that is the point — payouts differ by order type
and duration and are stamped on each order at placement.
Hourly buckets are in UTC, because position timestamps are stored in UTC. Offset them to your own timezone when you read the chart.
Correlation monitoring problems
Monitors are started only for engines that are ACTIVE and have
enableExternalCorrelation on. A paused or stopped engine has its monitor torn
down, as does the global pause and the global disable.
Compare maxDeviationPercent to the volatility of your market. On a thin
ecosystem market a 2% threshold will fire all day. Raise the threshold, or raise
alertOnConsecutiveDeviations so a single spike does not alert.
A sustained HIGH or CRITICAL deviation on a market you steer means your
published price has genuinely left the wider market behind. Pause the engine and
investigate before you tune the threshold.
Where to look next
| Question | Page |
|---|---|
| Why does the engine refuse to steer at all? | Pricing and settlement |
| What does this setting actually change? | Global settings |
| How do I undo a change? | Snapshots and audit |
| Which permission is this endpoint gated on? | API reference |
| The whole platform is misbehaving, not just this addon | Bicrypto troubleshooting |
When you raise a support ticket, include: the engine's status and
engineAttached, the last 24 hours of the dashboard's settlement verdict
breakdown, the attached market maker's status, the binary market's source, and
whether processBinaryAiEngine is registered. Those five facts resolve most
cases without a further round trip.