vike
ReferenceBinaries

tearsheet

The HTML report generator for a LIVE command journal — the same metrics a backtest produces, computed from the fills that actually happened.

tearsheet reads a live command journal and turns its fill stream into the same tearsheet a backtest produces. It is not a backtest reader: the input is the journal a running paper or live session wrote, and the output is that session's performance (crates/vike-report/src/lib.rs).

usage: tearsheet --journal DIR [--seed CASH] [--name LABEL] [--periods-per-year N] [--json]
                 [--html PATH] [--store DIR [--venue V] [--interval STR]]

--journal DIR is required, or $VIKE_JOURNAL_DIR — the same variable that turns journaling on in the producing binary, so you point the reader at exactly what you enabled. Without it the tool exits 2 with the usage line. That printed line omits --mtm, which is nonetheless a real flag whenever --store is present (crates/vike-report/src/tearsheet_cli.rs's run) — described below.

The parity contract

Every closed-trade round-trip is reconstructed through vike_model::compute_fill — the one cost-basis primitive that vike_exec::Account::fold and vike_backtest's SimBroker::apply_fill both delegate to — and every performance number is a call into vike_analytics::metrics. No metric is reimplemented here. So a live tearsheet and a backtest tearsheet over the same fill sequence are computed bit-for-bit identically.

The analytics edge is deliberately vike-analytics, not vike-backtest

Those modules used to live in vike-backtest, so reusing them meant compiling 32,259 lines to reach ~3,900: the simulator, the paper exchange and the whole gated harness tree came along, and 89% of what this crate built it could never call. vike-analytics depends on vike-model alone, so the catalog now arrives without the machine that produced it. The numbers are the same functions; only their home changed.

Flags

--seed is the account's starting capital, default 10000. It sets the base of the realized-only equity curve, so it scales total_return, cagr and sharpe — pass the session's real starting equity for accurate returns. --name labels the sheet. --periods-per-year is the Sharpe/Sortino/Calmar/CAGR annualization factor, default 252 (report::DAILY_PERIODS_PER_YEAR); note the equity curve here is realized-per-trade rather than a fixed calendar cadence, so annualized ratios are approximate.

--json prints the LiveTearsheet as pretty JSON instead of the human table. --html PATH additionally writes the self-contained HTML tearsheet through crate::render_html — a metrics table, inline-SVG equity and underwater-drawdown charts, and a monthly-returns table when timestamps allow — leaving the terminal output unchanged.

Store enrichment

--store DIR points at a vike-data DataFusion + Parquet hist store root, and needs the crate's hist feature. Given both, two enrichments replace the bare realized-only sheet.

First, the equity curve is read from the store's kind=equity series (crate::equity_curve_from_store) — a true mark-to-market curve. The equity sampler persists the cross-venue account rollup under venue="portfolio", symbol="TOTAL" (per-exchange rows use symbol=<exchange>), and that whole-account curve is what the tearsheet reads; it falls back to the realized-only curve, with a note on stderr, when no such series exists. Second, each reconstructed trade's MAE and MFE is back-filled from the store's OHLC bars over the trade window (crate::backfill_excursions).

--interval is the bar series interval used for the excursion back-fill, default 1m. --venue names the trades' venue for those bar lookups — the Trade type drops venue — and when omitted it is derived from the journal's fills if they all share one; otherwise --venue is required. The equity-curve lookup does not use it, because that series is the portfolio/TOTAL rollup rather than a per-venue one.

--store errors without the hist feature

Built without --features hist, passing --store exits 2: the DataFusion backend is not compiled in. That is a build question, not a store question, and the message says so rather than reporting a missing series.

--mtm (which requires --store) swaps the equity source: instead of the sampler's kind=equity series, the curve is reconstructed from the journal fills marked to market against the store's (--venue, --interval) bars (crate::mtm_curve_from_store) — the sampler stays the default. It additionally renders a "Runtime exposure" section into the --html output — turnover, gross and net exposure, peak margin (crate::RuntimeStats). Without --store it is a no-op, and on the default path everything is byte-identical to before the flag existed.

Where the numbers come from

The report side of this crate is a small set of pure steps, each its own module: journal_read::fills_from_journal reads the journal's fill records, trades::reconstruct_trades folds them into closed round-trips through the shared cost-basis primitive, equity builds the curve from samples, the store or the trades themselves, mtm adds the positions-over-time fold marked against store prices, and html::render_html renders. Nothing in the mtm path is persisted: the live kind=equity sampler stays the primary source.

The bin is a thin shim over vike_report::tearsheet_cli::run, which takes both argv and the environment as parameters — taking VIKE_JOURNAL_DIR from a caller-supplied map rather than std::env::var is what moves its settings-registry row from Layer::Binary to Layer::Injected, the registry's own declared target state.

Related: the command journal, reading the journal, the report, metrics, excursions, read a backtest report.

On this page