Skip to content

The risk engine

No person approves the desks' orders. The risk engine is the only gate between a desk and the market, so its limits are written in code, read from your TradingRules.md, and cannot be changed by any model. It runs before every order from every desk, and refuses with every reason it found, which the desk reads and can act on.

How the risk engine judges an order The six questions the risk engine asks of every order, from the limits in TradingRules.md to who owns the instrument. Risk engine: plain code, before every order; no model can change it 1 Read the limits from TradingRules.md unreadable → nothing new can be opened 2 Read the account from UBI balance, margin in use, today's P&L, positions, holdings 3 Loss limits: 15% today, 35% this week of the live balance; reached → the kill switch fires, once 4 Is the exchange open? NSE/BSE 09:15–15:30 · currency 09:00–17:00 · MCX to 23:30/23:55 5 Whose instrument is it? another desk's, or your own holding (INFY, KWIL…) → refused 6 Opening a position? Then every limit halts · trading switch · no option writing · margin ≤ 25% · capital 7 Approve: claim the instrument, record it closing your own position always passes; every reason is reported Order tool evaluate(order) the decision: approved or refused, with every reason UBI funds, positions, holdings such as ₹1,53,583.08 Kill switch Account.flatten halt recorded first; dry run in dry_run mode; never twice Risk ledger who owns which instrument, approvals, daily P&L, halts risk_ledger.db the order being checked the decision going back Against the real account: INFY and KWIL refused as your holdings, one NIFTY futures lot refused for its margin.
The six questions the risk engine asks of every order, in order. The blue dots are answers read from TradingRules.md, from UBI and from the risk ledger.

The limits

The limits are a fenced block in workspace/shared/TradingRules.md tagged toml limits. This is the block on this machine today:

[account]
trading_enabled = true
capital_percent = 100
daily_loss_limit_percent = 15
weekly_loss_limit_percent = 35
maximum_order_value_percent = 25
trading_window = "exchange_hours"
allow_option_writing = false

[desks.general]
allowed_products = []
allowed_instruments = []

[desks.intraday]
allowed_products = ["mis"]

[desks.scalper]
allowed_products = ["mis"]
daily_loss_limit_percent = 3

[desks.positional]
allowed_products = ["cnc", "nrml"]

Account limits

Setting Meaning
trading_enabled Whether any desk may open or enlarge a position
capital_percent The share of the total balance the agent may commit as margin
daily_loss_limit_percent Today's loss, as a share of the live balance, that stops every desk and closes every position
weekly_loss_limit_percent This week's loss that stops every desk until Monday
maximum_order_value_percent The largest margin one order may block
maximum_open_positions The most instruments held at once, or no cap
trading_window "exchange_hours" for each exchange's own session, or "HH:MM-HH:MM" in India time
allow_option_writing Whether a desk may sell options to open or enlarge a short position

Desk limits

Setting Meaning
capital_share_percent The desk's share of the agent's capital, or the shared pool
allowed_products The products the desk may use; empty allows all
allowed_instruments The symbols the desk may trade; empty allows all
maximum_orders_per_minute How many orders the desk may send in a minute
daily_loss_limit_percent Today's loss on the stocks this desk owned that stops this desk alone

The scalper is the only desk with a loss limit of its own: at a 3% loss for the day on the stocks it owned, it stops for the rest of the day. You added it with its strategy on 18 October 2026. The other desks have none, so only the account's 15% daily and 35% weekly limits apply to them.

One stock, one desk

The desks share one account, so two desks trading the same stock would tangle their positions. The risk ledger records which desk owns each stock: a desk claims it with its first order, and releases it when it is flat. Another desk's order in that stock is refused with "INFY belongs to the intraday desk; one desk trades an instrument at a time." A claim on a stock the desk ordered but never bought lapses after risk.ownership_grace_minutes, 30 by default.

Four desks and one risk engine Each desk sends its orders through the same risk engine, which gives each stock to one desk at a time and enforces every limit. approved main Claude first; any product; the conversation so far intraday Claude first; mis; flat by 15:15 heartbeat 10 min; 09:05 15:05 15:35 scalper Qwen first; mis; bracket orders heartbeat 2 min; 09:10 15:05 positional Claude first; cnc, nrml 08:45 12:30 15:40; no heartbeat One risk engine one desk per stock at a time each desk's products only a desk at its own loss limit stops alone the account at 15% a day stops everyone getting out is never blocked Risk ledger who owns each stock now, and who owned it today, for desk P&L UBI tagged with the desk; dry runs until you go live Market watcher account and each desk's P&L Every message starts with the time, what woke the desk and the market line: next trading day Mon, holiday Tue (Dussehra) an order from a desk refused: the stock belongs to intraday
Orange dots are orders from the four desks reaching the one risk engine; the blue dot is the scalper being refused a stock the intraday desk holds.

Two principles

When in doubt, no. If the limits cannot be read from TradingRules.md, or the account cannot be read from UBI, every new position is refused. That is why the Files page will not save a TradingRules.md whose limits cannot be read.

Getting out is never blocked. Every limit applies to opening or enlarging a position. An order that only reduces or closes the desk's own position is always allowed, even when the desk or the account is halted, because a limit that stopped you leaving would make the loss worse.

The kill switch

At the account's daily loss limit, the market watcher fires the kill switch: every desk is halted until the next day and UBI is asked to flatten the whole account. In dry_run mode the flatten is a dry run. You can fire it yourself on the Trading page, by typing FLATTEN, or on Telegram with /kill CONFIRM <reason>.

A desk reaching its own daily loss limit stops only that desk, for the rest of the day.