Documentation
27. v0.12.0 — Paper trading
- Created
- Aug 28, 2026
- Updated
- Sep 1, 2026
Current reliability, replay, persistence, authorization, privacy, and shortcut behavior is superseded by v0.12.1 — Paper trading reliability. This page records the feature as introduced.
Released 2026-08-29. This release adds paper trading — a simulated broker that lets you take practice trades on the chart's live feed: market, limit, stop, and stop-limit orders, take-profit / stop-loss brackets, netted positions with live P&L, an Account Manager dock, order and position lines on the chart, a Buy/Sell trading panel, and a right-click Trade menu. It is modelled on TradingView's Paper Trading and Broker API, so the order lifecycle, fill semantics, and panel layout are the ones traders already know. Everything runs and is stored in your browser; no real money and no brokerage connection are involved. See the Paper Trading guide. Follows v0.11.2.
Added
- Paper broker engine. A pure, deterministic matching engine fills orders from the price updates the chart already receives — no extra connections. Market orders fill at the ask (buy) or bid (sell) when the provider exposes them (Binance, OKX, Kraken), else at the last price, plus configurable slippage; limits fill at their own price once the market reaches them (a marketable limit fills immediately with a warning in the ticket); stops trigger on the last price and fill as market orders (a gap fills at the gap price); stop-limits become working limits when triggered. Without a tick feed, and in replay, each bar is walked open → nearer extreme → farther extreme → close so levels inside a bar fill at their own price. Positions are netted — one per symbol, average price on adds, FIFO lots on partial closes — and equity is always balance plus unrealized P&L. Durations: GTC, DAY (expires at the next US Eastern calendar day), GTT, IOC/FOK; an optional regular-session-only gate for equities. See Positions, Brackets & Fills.
- Brackets as real orders. A take profit and/or stop loss creates child orders that are inactive until the parent fills, then working against the position, sized to it, and OCO — one fills, the other cancels. The stop loss fills as a market order; closing a position cancels its brackets; a partial close resizes them; reversing drops them.
- Trading panel. A
[Sell bid] [− qty +] [Buy ask] [⚡ 1-click]strip on the active pane, toggled by a new Trading panel toolbar button (⇄ icon) or⌥P, with the spread above the quantity, per-symbol remembered quantity, and feed-quality badges — Delayed, Stale (a realtime feed gone quiet: no tick and the latest bar older than two intervals + 30 s), Replay, No realtime.⇧B/⇧Sdo the same as the Buy / Sell buttons, only while the panel is visible, and never open the symbol search then. See Placing Orders. - One-click trading. A broker setting, off by default, with a visible ⚡ 1-click toggle at the end of the trading panel. Off, Buy / Sell (and
⇧B/⇧S, the chart's Buy / Sell at price items and the price-scale+items) open the prefilled order ticket; on, they place the order immediately and the on-chart line buttons skip their confirmations. While it is on the toggle is lit amber, the panel border turns amber, and the Sell / Buy sides are filled solid so a click visibly trades at once; switching it either way shows a toast. The order ticket's Preview step and the Account Manager's buttons keep following Confirm orders. Settings saved before this release with Confirm orders off start with one-click on, preserving their instant placement. See Placing Orders — One-click trading. - Order ticket. Buy/Sell toggle with bid and ask; Market / Limit / Stop / Stop-limit tabs; quantity and price steppers on the instrument's lot and tick steps; take-profit and stop-loss rows with Price · Ticks · % · $ units showing the resulting price and P&L; duration (GTC default, DAY, GTT with date-time, IOC/FOK for limit types); an order-info block with notional, commission, buying power after, and risk:reward; Preview (with Confirm orders on) then Place order; a Modify mode for working orders.
- Order, bracket, and position lines on the chart. Dashed order lines, dotted (inactive) or dashed (working) bracket lines, and a solid position line with quantity and live P&L, all labelled at the price axis with buttons — ✕ cancel/close, ⇄ reverse, TP / SL add a bracket, ✎ modify. Drag an order or bracket to a new price (a stop-limit moves both legs together); double-click a line to edit. Every execution places a fill marker; closing fills are coloured by realized P&L.
- Trade group in the chart context menu. Right-click offers Buy/Sell at market, Buy/Sell limit-or-stop @ cursor price (limit on the near side of the market, stop on the far side — TradingView semantics), Create new order…, Close position when one is open, and Trading properties…. The price-scale
+menu also offers Buy limit / Sell limit at the hovered price. - Account Manager. A bottom-dock panel — opened from a new wallet toolbar button (which shows an amber dot while a position is open) or
?panel=paper-trading— with Positions, Orders (status filter), History (outcome filter, CSV export), Trades, Account Summary, and Journal tabs; an account dropdown in the workspace's menu style whose rows reveal Export (per-account JSON) and, for archived records, Delete on hover; a live summary row (Balance · Equity · Open P&L · Realized P&L); Trade, Reset, and Settings buttons; and expand / float / close like the Strategy Tester. Account Summary reports balance, equity, open and realized P&L, commission paid, and performance statistics (net profit, win rate, profit factor, max drawdown, average trade, …) computed with the same definitions as the Strategy Tester. See Account Manager. - Paper trading in replay. Running a bar replay automatically creates a separate Replay demo account, named after the ticker and start time (e.g. Replay BTCUSDT · Aug 28, 22:41), and switches the Account Manager to it; leaving replay cancels its working orders, archives it — it stays in the dropdown as (ended), read-only — and returns to the live paper account. Every replay, including one started after a page reload, gets a fresh account; an ended session is never reopened, and a session left open by a closed tab is closed on the next load. Orders placed, modified, or closed during replay are stamped with the replay clock, so fills, journal entries, and markers land on the replayed bars rather than today, and markers are anchored to the bar they filled in on every timeframe. Replay prices never reach the live account (nor live prices the replay account), and the live account cannot be traded from the chart while a replay runs. Replay bars drive fills through the intrabar path rule, and CSV symbols — untradable on a live chart — become tradable inside replay. Trading lines and fill markers are the first interactive overlays rendered during replay. See Paper Trading in Replay.
- AI assistant reads and manages paper accounts. Six auto-executed read tools (
get_paper_account,get_paper_positions,get_paper_orders,get_paper_trades,get_paper_performance,get_paper_journal) let the assistant answer questions about any paper account — the live one, a running replay, or an archived session — with positions and open risk, paged fills and closed trades, and deterministic performance breakdowns by symbol, side, weekday, hour, and holding time, plus streaks, excursions, and risk ratios computed by the app (never by the model). The chat context carries a compact summary of the selected account. Five approval-gated write tools (place_paper_order,modify_paper_order,cancel_paper_order,close_paper_position,set_paper_brackets) propose simulated orders that run through the broker's validation and preview on Apply and respect the same refusals as the UI. Server-proxied providers (Bedrock, Vertex) receive a capped snapshot of the selected account. A new Share paper trading with the AI assistant setting (on by default) turns the surface off. See AI and Paper Trading. - Settings, reset, and export. Initial balance ($100,000 default), commission per asset class (% of notional, cash per order, or cash per unit), slippage in ticks, Fill limit at gap price, One-click trading, Confirm orders (ticket preview plus cancel / close / reverse confirmations), Regular session only, and default duration (GTC or DAY). Reset first archives the current run — positions, orders, history, executions, closed trades, statistics, and journal — as a read-only
<account> · until <date>account in the dropdown, then restores the starting balance (the journal records it and a toast names the archive); a never-traded account leaves no archive. Export / Import the whole state as JSON; Export history CSV writes one row per execution. See Settings, Reset & Export.
Changed
⌘J/Ctrl+Jtoggles the right sidebar. One shortcut closes whatever the sidebar holds — watchlist, alerts, or the docked AI chat — even from inside its text fields, and reopens the last content when nothing is open. The watchlist and alerts toolbar buttons show the shortcut in their tooltips. Registered in the shared shortcut registry, so⌘⇧Jand plainJdo not trigger it. See Keyboard Shortcuts.- Dismiss all notifications at once. Alert and paper-trading toasts share one stack in the top-right corner; when two or more are showing, a ✕ Dismiss all pill with the count appears beside the stack and clears every toast in one click, instead of swiping or closing each card.
- "Open chart workspace" remembers your last chart.
/chartis now a launcher that returns to the symbol, provider, and asset class you had open last in this browser (falling back to BTCUSDT on a first visit) while keeping?panel=…launch intents; the landing page, footer, pricing, and 404 links all use it. - The bottom dock hosts a second panel. The Account Manager shares the Strategy Tester's dock slot and chrome, and the workspace can be launched into it with
?panel=paper-trading(see The Workspace Tour). - Ticker overviews carry exchange trading metadata. Binance (
exchangeInfofilters), OKX (instruments), and Kraken (asset pairs and futures contract size) now expose tick size, lot step, minimum and maximum quantity, and contract multiplier; Massive exposes round lots. The ticket, the trading panel, and the fill engine use them for price and quantity steps, falling back to the chart's price precision elsewhere. - Strategy Tester result widgets are shared. The tester's stat tiles, sections, and tab strip moved into a reusable module, and the backtesting module now exports its statistics engine, so the Account Summary tab renders the same figures the same way.
- Telemetry. Four new consent-gated, non-PII events —
paper.order_changed,paper.order_filled,paper.account_reset,paper.panel_toggled— carry only categorical dimensions (order type, side, whether brackets were attached, position effect, price source, panel). Symbols, prices, quantities, and balances are never sent.
Fixed — post-audit hardening
A line-by-line audit of the branch (engine, persistence, workspace, AI, performance) was run before tagging; everything it found is fixed in this release:
- Fills. Brackets activated by an entry are evaluated against the rest of that bar's path only, never against prices seen before the entry. A partial close re-averages the remaining position over its open lots, so closing part of a position at the market leaves equity unchanged. Live bar-only feeds never re-walk a forming bar — a chart just opened, a timeframe switch, or a trade feed handing over to bars feeds the current price only. Regular session only now also gates the immediate fill after placing, modifying, closing, or editing brackets. Fill limit at gap price applies to the limit leg of a stop-limit that converts on a gapped tick. Bracket children are reduce-only and refuse a quantity edit. A second Close / Reverse while a closing order is pending is refused instead of stacking. A DAY order's trading day (US Eastern for stocks and futures, UTC for crypto and forex) and a stop-limit's triggered state are stored with the order and survive reloads. Break-even closes record realized 0 and render as closing fills.
- Persistence. Import merges by account id (with a confirmation and a backup of the previous state) instead of replacing everything; single-account exports no longer carry a padded empty live account. A refused save shows a Not saved pill and retries, trimming archived records first; the 12-account cap is enforced as records are created, with a notice; an unreadable or newer-version blob is backed up rather than overwritten; another tab's newer save is adopted unless this tab has unsaved changes; archived records keep the marks they were frozen at; the persisted closed-trade ledger is trusted; prototype-key account ids and out-of-range timestamps are rejected.
- Surfaces. One shared trading policy (blocked account → confirmation → one-click or ticket) drives the panel, the context menu, the price-scale
+, chart lines, the Account Manager, the dialogs and the AI applier, so confirmation semantics no longer differ by surface, and the broker itself refuses live-account actions while a replay runs. Overview bid / ask are used for fills only while fresh (15 s) and near the last price; the overview is refreshed while a trading surface is open, retried after failures, and fetched on demand for any symbol the account touches. Confirmations queue instead of replacing each other; the position dialog resets per position and the ticket per quantity; quantity and bracket fields keep what you type and validate on submit; a click on a line no longer journals a no-op modification; daily and weekly panes are never flagged stale; the Account Manager's symbol click keeps the asset class. - Performance. The engine copies account collections only when it mutates them, returns the same state for a stale sample, and the broker notifies the UI only on material changes (fills, orders, positions) — marks are read during the render a tick already causes. Line-model and marker caches are keyed on ledger identity,
Intlformatters are cached, long ledgers page at 200 rows, the trading-lines overlay no longer rebuilds its subscriptions on every tick, and panes without strategy markers reuse the cached marker array. - AI. Proxy snapshots carry the untrimmed ledger totals so account summaries count correctly, ship a smaller ledger (150 fills / 150 trades), spell out infinite profit factors instead of
null, validate paging cursors, and the pane-read tool guard no longer matches the paper tools.
Notes
- This is a simulation. Fills assume unlimited liquidity at the quoted price, never partially fill, and are only as good as the feed driving them; a delayed or idle feed produces prices no venue would have given you. Fractal Chart is not a broker. See the Risk Disclosure.
- Orders fill only for symbols open on a chart, because the engine consumes the chart's own feed, and only while the browser tab is open. A symbol on no pane waits, and its Account Manager rows show
—for Last and P&L, until you open its chart again. - Storage is local to this browser (
localStorage), not synced across devices, and removed by clearing site data. Per account, history keeps the newest 2,000 final orders, 5,000 executions, and 2,000 journal entries, with up to 500 working orders; up to 12 accounts are kept (the live one plus the newest archived replay sessions and pre-reset records). Export to back up or move an account. - Several tabs. Every tab saves the whole state; when another tab saves a newer copy this tab adopts it (a toast says so) unless it has unsaved changes of its own, in which case its changes win the next save and it warns once. A replay open in one tab is never touched by another tab's copy. Keep active trading in one tab at a time. If the browser refuses to save, a Not saved pill appears, archived records are trimmed to make room, and saving is retried — export regularly on busy accounts.
- Live bar-only feeds fill on the segment since the last update. On providers that stream bars but no trades (OKX), each update evaluates orders only against the price path since the previous update — a bar is never re-walked, not even after a timeframe switch or when a quiet trade feed hands over to bars — so a level the bar touched before an order existed cannot fill it. Whole-bar evaluation is reserved for replay, where bars are complete.
- Rewinding a replay does not undo fills. Scrubbing the cursor back stops feeding the account until it passes the furthest bar already replayed in the session; the journal is append-only.
- Bid/ask comes from the ticker overview on Binance, OKX, and Kraken and is used for fills only while less than 15 seconds old and within 2 % of the last price; Massive and Alpaca fill at the last price. Add slippage to approximate a spread.
- Not in this release: trailing stops, leverage and margin, hedge mode (individual positions), streamed bid/ask — see the Roadmap.
Verification
- A frozen dependency install (
bun install --frozen-lockfile, 879 installs across 931 packages, no changes), the complete automated suite, TypeScript, lint, and the optimized production build passed during release preparation. The suite covered 283 test files and 2,255 tests (the runner now ignores editor worktrees under.claude/);tsc --noEmitis clean;next lintreports only pre-existing hook-dependency warnings in the workspace; the build generated all 115 static pages, including the new/chartlauncher. - Three independent review passes over the branch — the engine and broker, the React integration, and the documentation against the code — ran before tagging. They surfaced, and this release fixes, replay accounts being reused after a page reload, replay prices leaking into the live account (and live prices into replay accounts), archived sessions disappearing from the account dropdown, look-ahead fills on bar-only live feeds, replay rewinds re-feeding bars, futures P&L in the Positions table ignoring the contract multiplier, reversals recorded as plain closes, and replay-triggered fills mislabelled as live.
- Focused regressions cover: fresh account per replay session (including id collisions after reload and sessions left open by a closed tab), clock-domain isolation of marks and samples, archived accounts listed and read-only, archive-on-reset, per-account export and delete, one-click trading gating and the settings migration, the ⚡ toggle model, replay-clock stamping of user actions, marker anchoring on every bar alignment, live bar-segment evaluation, account naming, the AI paper-trading snapshot/query layer (including a property test that every breakdown axis reconciles with the account net), the AI tool registry/parsers/executor/applier, the Bedrock/Vertex paper snapshot round trip, the system prompt, the
⌘Jshortcut, and the/chartlauncher's remembered-chart resolution. - Verified in a running workspace against live Binance data: a market buy placed during replay fills at the replayed bar's close, stamped on the replay clock, with its marker on that bar; the one-click toggle switches the panel between outlined (ticket) and solid (instant) modes with a confirming toast; the finished session appears as (ended) in the dropdown; the themed account dropdown reveals Export / Delete on hover; the notification stack clears with one click;
⌘Jcloses and reopens the sidebar; the chat drawer opens with the paper-trading tools registered.
Next steps
Back to the release list.
Next: Release Notes