How strategies trade real money: dollar amounts, automatic reconciliation, close-all, and the kill switch.
The trading portfolio is the set of strategies allowed to place real orders. Each strategy in it gets a fixed dollar amount; the reconciler daemon then keeps the positions the strategies themselves opened converged to the combined target — you never place these orders yourself. It only manages its own orders: a position you opened by hand is invisible to it and never touched.
strategy.py ──► state.json ──────────────┐
(cron) ├──► reconciler.py ──► exchange
amounts ──► portfolio_config.json ───┘
Each strategy in the portfolio is assigned an amount in account currency (e.g. USD) — what the strategy trades with when its signal is at full size. The target position per symbol is the sum across strategies:
target[symbol] = Σ ( amount × position )
position is the strategy's signal and can be fractional (a vol-scaled strategy may emit 0.5 or 1.8). The amount you set is exactly what sizes positions — it does not drift with account equity. Exception: for Capital (群益) Taiwan futures strategies the amount is a lot count (number of contracts), not a dollar figure.
manager/portfolio_config.json by hand. Set amounts from the workspace Trading setup page or ask the agent; optimizer weights are applied only through manager.py, which is dry-run by default and writes the config only with --apply after you confirm.
The reconciler is a daemon that polls every 5 seconds and reconciles whenever:
state.json changes)Each pass compares the target against the bot's own book — the reconciler keeps its own ledger, a running total of every order it has placed (manager/orders.jsonl), rather than reading the account's raw exchange positions, so a position you opened by hand is never read as "already held" and never added to or closed. Orders are then placed to close the gap — market orders by default; each strategy can be set to market, TWAP, chase limit, or a custom execution style in Trading setup (Capital (群益) TW futures support market only). Differences under $10 are ignored (TW futures reconcile in whole lots instead). A position flip (long → short) is split into a reduce-only close plus a fresh open, so hedge-mode accounts never hold both sides at once.
If reading positions from the exchange fails 3 times in a row (revoked key, IP not whitelisted, outage), the reconciler trips the kill switch automatically. It never clears it — only you do.
Press Pause trading in the workspace and the dialog offers two choices: Pause, leave positions untouched only trips the kill switch; Pause and close positions (or python3 manager/flatten.py) market-closes the positions the strategies opened — only what is on the bot's own book, so a position you opened by hand is left alone, and spot sells only the coins under strategy management, never your other holdings. It is a panic button, not portfolio management:
While the kill switch is on, any order that would add exposure is refused at the code level. Closing positions, stop-loss / take-profit, and cancels still go through — a halt never traps a position you are trying to reduce.
It is set by Pause trading in the workspace (including Pause and close positions), by telling the agent to stop trading, or automatically on exchange disconnect. It is never cleared automatically — trading resumes only when you press Start trading or explicitly ask the agent to resume. Start trading offers two choices as well: Start and catch up positions places market orders immediately to match each strategy's current signal; Start, wait for new signals places no orders now — each strategy starts trading only at its next entry, exit, or flip. Every order attempt and denial is written to an audit log.
Every executed order is appended to manager/orders.jsonl with its legs — the exchange-confirmed fill price and executed quantity of each individual leg. A position flip records two legs: the closing leg carries the exit price, the opening leg the entry price.
Partial failures are recorded too: if a flip's closing leg filled but the opening leg failed, the entry is kept and marked failed — the history never hides an order that moved real money. The workspace Order History tab renders this file.