The single gate that turns a forecast into an approved trade. No stage downstream may bypass it.
Challenge we are solving
A profitable forecast is not enough. The trade must clear strategy caps, liquidity caps, portfolio caps, correlation limits, and the kill-switch state. If any check fails the trade does not exist.
What this stage does
Combines p_hat, q_exec, fees, and uncertainty buffer into a single net_edge number; runs every risk check independently; and produces a final approved size (or a rejection with a reason code).
Why this stage exists
This is where forecasting, execution, and portfolio risk are reconciled into one decision. Every downstream artefact (order, fill, audit) traces back to this gate.
Flow
p_hat0.67 from stage 5
→
q_exec0.645 from stage 6
→
net_edge= p_hat − q_exec − fees − buffer
→
Risk checksbook fresh · within limits · correlation OK
→
DecisionBUY 2,000 YES
What the backend should expose
decision_id, correlation_id (links to stages 3-6)
p_hat, q_exec, fees, uncertainty_buffer, net_edge
risk_checks[] (each with vote, reason_code, owner)
approved_size (min of strategy / liquidity / portfolio caps)
final action (APPROVE · REJECT · WARN-only · paused)
reason_code if rejected
Maths we expect here
Every formula below is implemented in packages/polytraders-bots/ or packages/polytraders-runner/. Treat the worked example as the unit-test sanity check you should be able to reproduce locally.
1
Net edge — the gating quantity
\[net\_edge = \hat p - q\_exec - fees\_per\_share - buffer\]
worked example\[net\_edge=+0.009,\;\;\text{all 7 checks APPROVE} \;\Rightarrow\; \text{TRADE BUY }2{,}000\,\text{YES}\]
A single REJECT vote kills the trade — there is no override. The reason_code is logged on the decision packet.
How a developer codes this stage
Reference TypeScript implementation lives in packages/polytraders-* at the repository root. Stage owners maintain these files — read them before writing new code.
packages/polytraders-contracts/src/RiskVote.tsThe vote each risk check emits. Strict — any single REJECT kills the trade.