VIZANIXTrading Software Development
Bot architectureRisk8 min read

A risk engine is a list of things the bot is not allowed to do

Risk management in a trading bot is not a calculation. It is a set of refusals, enforced in code, that the strategy cannot argue with.

Vizanix engineering · about the author

ARTICLE
8 minreading time
SECTION
Bot architecture
PUBLISHED
2026-08-28
CHAPTERS
6
READ NEXT
3
LANGUAGE
written in English
An engineering breakdown, not a rewrite of the docs.
RISK ENGINEKILL SWITCHDAILY LOSSEXPOSURECORRELATION

Strategies are optimistic by construction — they exist to find reasons to trade. The risk engine exists to say no. If those two live in the same code, the optimism wins, because the person writing the strategy is the one under pressure to make it perform.

Refusals, not adjustments

A risk engine evaluates an intent and returns approved, resized, or rejected — with a reason recorded either way. It does not politely suggest. The execution layer obeys it, and there is no path from strategy code to the exchange that bypasses it.

python
@dataclass
class Verdict:
    approved: bool
    qty: Decimal          # may be smaller than requested
    reason: str           # always populated, including on approval

def evaluate(intent, portfolio, day) -> Verdict:
    for rule in RULES:                     # order matters: cheapest and hardest first
        v = rule(intent, portfolio, day)
        if not v.approved:
            return v
    return Verdict(True, intent.qty, "ok")

The rules that earn their place

RuleEnforcesTypical failure it prevents
Max position per symbolNotional cap per instrumentOne signal repeatedly firing into an enormous position
Max total exposureGross and net across the bookTen uncorrelated-looking symbols that are all beta to BTC
Concurrent position countSlot limitA regime change opening everything at once
Daily loss limitRealised plus unrealised, since session openA bad day compounding into a catastrophic one
Drawdown stopPeak-to-current equitySlow bleed nobody noticed
Leverage capHard ceiling below the venue'sEffective leverage drifting up as equity falls
Liquidation distanceMinimum buffer per positionThe venue closing the position for you, at its price
Loss streak per symbolAuto-blacklist after N lossesOne instrument the strategy has stopped understanding

That last one is worth implementing even though it feels crude. Our signal engine tracks a loss streak per symbol and blacklists automatically. Sometimes an instrument changes character — a listing matures, liquidity moves, a market maker leaves — and the strategy is simply wrong about it now. Counting is a cheap proxy for noticing.

Positions correlate, and the risk engine must know

The most common quiet failure: five positions each risking one percent, described as five percent of risk. In a correlated market they are one position risking five percent, and they will hit their stops within the same minute.

You do not need a full covariance matrix to improve on this. A crude grouping — majors, alts, anything that moves with BTC — with a per-group exposure cap catches most of the damage. Our risk calculator makes the arithmetic visible: simultaneous risk against a daily limit, which is the comparison people skip.

The kill switch must be dumb

Every risk engine needs a single action that cancels all orders and flattens all positions, and it must be the simplest code in the system. No strategy consultation, no clever unwinding, no waiting for a better price.

Requirements that sound obvious and are frequently violated:

  • It runs at the highest request priority — cancels go out before anything else.
  • It is reachable manually, from the control plane, in one command.
  • It is idempotent. Triggering it twice does nothing the second time.
  • It works when the strategy layer is hung, because it does not call into it.
  • It is tested. A kill switch nobody has fired is a hypothesis.

Unrealised counts

A daily loss limit that only counts closed trades can be satisfied while the account is deeply underwater in open positions. Count realised and unrealised together, marked to the current price, and re-evaluate on every position update rather than on a timer.

Every refusal gets logged

A risk engine that silently declines is indistinguishable from a broken strategy. Record the intent, the rule that rejected it and the state at the time. This is the same discipline as recording why a signal did not fire — it turns “the bot did nothing today” from a worry into a query.

It also produces the evidence for tuning. Limits that never bind are decoration; limits that bind constantly are miscalibrated or are telling you the strategy wants more risk than you agreed to give it. Both are worth knowing.

This article describes engineering practice. It is not investment advice. Vizanix develops software and does not promise trading returns.

Blog

Read next

Want this running for you?

We write about what we build. If you need it built, get in touch — scoping is free.

Brief

Get a project estimate

Four questions and your contact. No deposit required to talk — if the job is not a fit, we say so straight away.

01What do you need
02Exchange
03Market
04Strategy
05Contacts

Prefer to write directly? Telegram @vx_ceo

Discuss a system