VEEMANDocs
DocumentationSupportOpen Dashboard

Getting started

  • Introduction
  • Quick start
  • Core concepts

Importing data

  • Supported formats
  • How import works
  • Splitting a file
  • Troubleshooting

Building your portfolio

  • Workspace & equity
  • Weights & capital
  • Weekday filter
  • Library
  • Variants & comparison
  • History (undo/redo)
  • Shared spaces

Analytics

  • Metrics reference
  • Charts (deep-dive)
  • Monthly P&L
  • Correlations
  • Strategy comparison
  • Monte Carlo
  • Equity Control
  • Optimization
  • Veeman AI

Reference

  • Keyboard & command palette
  • Exporting data
  • Settings

Technical

  • Architecture
  • API reference
  • Security
  • Your data & privacy
  • Risk disclosure
← PreviousShared spacesNext →Charts (deep-dive)

Metrics reference

The Metrics module reports the portfolio's performance, risk and return distribution. This page documents every figure exactly as the engine computes it, so you always know what a number means.

What period a metric covers

By default every figure on this page is computed over the entire history of the loaded portfolio — including stretches where only some strategies were live (a strategy that started in 2020 and one that joined in 2022 are both measured across the full span; the earlier period is not dropped). Narrowing the Workspace range alone does not change that: on its own the range selector is a chart zoom.

Turn on align starting capital in the workspace and the metrics follow the framed period: the same engine recomputes every figure over that window alone, rebased to the initial capital at the window start, with drawdown re-anchored there. A band above the figures names the active period and offers a full history button to widen back; the range and the checkbox also reset when you load a different portfolio. Short windows still annualise — Sharpe by √252 and CAGR over the window's own calendar span — so a strong month reads as a large annualised figure.

How the window is rebased follows the curve exactly: the period is recomposed strategy by strategy, each leg carried over with its own factor — untouched when its P/L does not depend on account size (fixed contracts, or a binding max/min contracts limit, or manual costs charged per trade or per day), scaled by initial capital ÷ equity at the window start when it does. The figures on this page are therefore the same period the chart draws, down to the rounding of the trade ledger.

Pinned variants follow the same window: each one is recomputed over that period, with the same per-leg recomposition, so the comparison against a framed Current is period-for-period. Their frozen full-history figures still describe them everywhere the period does not apply — the variants tray and the archive table.

The same window drives the Monthly P&L grid, the Weekday breakdown, the per-strategy register and Strategy comparison, each with the same band on top. The per-strategy figures use the same per-leg recomposition described above, so the visible legs' window profits add back up to the portfolio's.

How the series is built

Before any metric is computed, VEEMAN builds two series from your weighted daily P/L:

  • Equity — initial_capital + cumulative_sum(daily P/L), on the full calendar (weekends are carried flat). Drawdown figures use this series.
  • Daily returns — the percentage change of equity resampled to business days (Mon–Fri). Resampling avoids diluting volatility with flat weekend days. Sharpe, Sortino and volatility use the full business-day series (flat no-trade days kept — idle days are part of time-based, annualised performance, and dropping them would break the √252 annualisation). CAGR is the exception: it annualises over the calendar span (first-to-last date), not the bar count.
  • Traded-day returns — the same business-day returns with the flat no-position days removed (a day the book didn't trade enters as a 0% return). VaR and CVaR use these, so the account tail measures a day you were actually on the market rather than a calendar padded with zeros.

Shared assumptions

  • Annualisation: √252 for Sharpe, Sortino and volatility; CAGR over the calendar span (365.25 days/year), not a bar count.
  • Risk-free rate: the period-average 3-month US T-bill — the mean short rate over the backtest window itself (source: ^IRX), applied as rf / 252 per day and used by Sharpe and Sortino. A book traded in 2020-21 is measured against the ~0% rate that prevailed then; one traded in 2023-24 against ~5%. This is why it is not a single fixed number: today's rate is the wrong yardstick for a historical test, and a period-average keeps Sharpe/Sortino reproducible (they don't drift as rates move). Falls back to 2% if the rate series can't be fetched, so metrics never depend on the network.
  • VaR / CVaR: historical method, 95% confidence, 1-day horizon.
  • Percentages are reported as percentages (a 0.15 return shows as 15.0).

Annualisation and VaR/CVaR are fixed, industry-standard conventions; the risk-free rate is data-driven so Sharpe and Sortino reflect the real cost of capital during the tested period. The rate actually used is reported back with the metrics (risk_free_rate, in % per year).

Manual costs

By default VEEMAN uses each strategy's P/L exactly as imported. If your export is gross (no costs baked in), you can subtract commissions and slippage per strategy from the Costs control in the workspace (the $ chip on a strategy row, or the strategy detail panel). When enabled the daily P/L becomes net, and every downstream number — equity, drawdown, Sharpe, monthly, Monte Carlo, correlations, weekday — reflects it.

The cost per day is charged on the most precise unit the data exposes:

daily_cost(day) = units(day) × (commission + slippage)      // dollars per unit
net_pnl(day)    = gross_pnl(day) − daily_cost(day)
  • Per contract — units = contracts closed that day. Available when the CSV carries a quantity column (TradingView, TradeStation, IBKR, Option Omega). Most accurate, and it scales when a strategy is weighted up.
  • Per trade — units = number of trades closed that day. Available for any per-trade export.
  • Per day — units = 1 per trading day. The universal fallback for equity-curve exports with no trade detail.

VEEMAN auto-selects the richest available basis; you can switch among the ones a strategy supports. Amounts are round-turn dollars (entry + exit) per unit.

Don't double-count costs

Enable manual costs only on gross P/L. Some exports are already net — Option Omega P/L already subtracts commissions and fees, and a TradingView backtest that configured commissions in its strategy properties bakes them into "Net Profit". Adding costs on top would count them twice. The control is off by default; enabling it is your call, where the data is cost-free.

Capital & profit

MetricDefinition
Initial capitalThe starting equity you set.
Final equityLast value of the equity curve.
Net profitfinal_equity − initial_capital (account currency).
Profit %(final_equity / initial_capital − 1) × 100.

Return

CAGR — Compound Annual Growth Rate, the smoothed annual rate that would take you from initial to final equity:

years = (last_date − first_date) / 365.25    # calendar span
CAGR  = (final_equity / initial_capital) ^ (1 / years) − 1

CAGR is one of the four hero KPIs. It assumes positive initial and final equity; otherwise it reads 0. The span is calendar time, not a bar count. Counting weekdays (~261/year, holidays included) and dividing by 252 would mix two conventions — inflating the elapsed years by ~3.6% and understating CAGR. A 252-day backtester that counts ~252 trading days (holidays removed) and divides by 252 lands on the same figure as the calendar span; VEEMAN uses the calendar span so no exchange-holiday calendar is needed.

Risk-adjusted ratios

These reward return per unit of risk. Higher is better for all four.

MetricFormulaReads as
Sharpemean(excess) / std(excess) × √252Return per unit of total volatility.
Sortinomean(excess) / downside_dev × √252Return per unit of downside volatility only.
CalmarCAGR% / |Max Drawdown %|Return per unit of worst drawdown.
K-Ratioslope / std_error(slope) / n of a linear fit of cumulative P/L vs. trading-day indexSteadiness of the trend.

Where excess = daily_return − rf/252 (with rf the period-average short rate above), and downside_dev = √(mean(min(excess, 0)²)) — i.e. Sortino only penalises days below the risk-free line, so a strategy isn't punished for big up days.

K-Ratio, in words

The K-Ratio fits a straight line through the cumulative P/L and divides its slope by the standard error of that slope, then normalises by the sample length (Kestner 2003). A higher K-Ratio means steadier, more linear growth; a low or negative one means a choppy or declining curve. The fit runs over trading days only (P/L = 0 idle days are excluded), so the portfolio K-Ratio is measured on the same basis as the per-strategy one and the two reconcile.

The denominator is the slope's standard error, not the spread of the residuals around the fit. That distinction is what makes the number comparable across track records of different lengths — which is the entire point of the metric. Residual spread grows with the sample, so dividing by it would make the same strategy look worse the more history you feed it.

Drawdown

Drawdown is the decline from the running peak of equity, computed on the full calendar-day curve.

MetricDefinition
Max Drawdown ($)min(equity − running_max) — the deepest peak-to-trough drop in currency.
Max Drawdown (%)the same trough as a percentage of the peak; always ≤ 0. A hero KPI.
Max DD durationlongest unbroken stretch (in days) spent below a prior peak.
Avg DD durationaverage length of all underwater stretches.

The peak starts at your initial capital

The equity series begins on the first day with data, so its first point is a balance that has already moved. The running peak is therefore anchored to the initial capital: a strategy that loses from day one is underwater from day one.

Concretely, with $100,000 of capital and a P/L of [-5,000, -3,000, +500], max drawdown is −$8,000 (−8.00%) — measured from the capital you put in, not from the $95,000 balance at the end of the first day.

Inside a reading period the anchor is the period's own opening balance, which the sliced curve already contains.

Note the consequence with the example above: a full-width window is not the same as the full history. Full history anchors at the $100,000 you put in and reports −$8,000; a window covering everything anchors at the end of its first day — a $95,000 balance — and reports −$3,000. Same curve, two honest answers to two different questions ("how far below my capital did I go" versus "how far below the start of this period"). The window's first day belongs to the period before it, which is also why its P/L is not counted in the framed profit.

Volatility & tail risk

MetricDefinitionMeaning
Annual volatilitystd(daily_returns) × √252 × 100, on the full business-day seriesDispersion of daily returns, annualised.
VaR 95%magnitude of the traded-day return at position ⌊0.05 × n⌋ of the sorted seriesLoss not exceeded on 95% of the days you trade.
CVaR 95%mean of the returns worse than that oneAverage loss on the worst 5% of traded days (beyond VaR).

How the percentile is picked, and when to distrust it

The cut is a position in the sorted list, not an interpolated percentile: with 200 traded days it is the 10th worst, with 40 it is the 2nd. Two consequences worth knowing. Below 20 traded days the position lands on 0, so VaR becomes simply your single worst day and CVaR equals it — no tail is being estimated, and the figure should be read as "worst observed", not as a risk level. And both are reported as magnitudes: on a strategy that wins more than 95% of its days the 5th-percentile return is still positive, and it is displayed as a positive number that is not a loss.

Daily returns are (equity_t − equity_{t−1}) / equity_{t−1}, and the equity before the first day is your initial capital — so day one counts, in volatility, in Sharpe and Sortino, and in the VaR/CVaR tail. It is the same day that worst day, win rate and profit factor already counted.

Weekend trades

The return-based metrics (volatility, Sharpe, Sortino, VaR/CVaR) are computed on a business-day calendar: a Saturday or Sunday P/L — which some data sources produce, forex among them — is carried into the following Monday rather than counted as its own day. The count-based figures (win rate, best and worst day, streaks) read the raw daily series instead and do count those days separately. On a Monday-to-Friday book the two agree exactly; on a book that trades weekends they read slightly different sets of days.

VaR and CVaR are historical: they read straight off your actual return distribution rather than assuming a bell curve, so fat tails are respected. CVaR (a.k.a. Expected Shortfall) is always at least as large as VaR and describes how bad the bad days are. They are taken over the traded days only (weekends and idle 0% days excluded), so a selective strategy's tail isn't flattened toward zero by the days it sat out — the same basis as the charts deep-dive distribution views. Volatility, by contrast, keeps every business day because it is an annualised, time-based figure.

Per-trade loss tail (strategy detail)

The VaR / CVaR above are account-level: a percentage of capital, taken from the traded-day return series (idle days excluded, so the tail is no longer diluted). That is the right lens for the risk of the allocated account on a day it trades, but still not "how much can a single trade lose", which is what you need to size positions.

So each strategy's detail panel (expand a row in the per-strategy table) adds a separate block, Per-trade risk ($), computed directly on the dollar P/L distribution — one value per trade (or per active trading day when no trade list exists), with no padding for idle days and no capital scaling:

MetricDefinitionMeaning
5% threshold loss (VaR)5th percentile of per-trade P/L, in $ on 1 contractThe single trade loss not exceeded 95% of the time.
Worst-5% mean loss (CVaR)mean of the trades at or below that 5th percentile, in $ on 1 contractExpected Shortfall: the average of the deep-tail trades.

Account VaR ≠ per-trade VaR

Both now share the traded-day basis (no idle-day dilution), but they still measure different things: the account VaR is a percentage of the whole allocated capital on a day you trade, the per-trade VaR is dollars on a single contract. Use the per-trade $ figure for position sizing — it is exactly the loss distribution you size against. It appears once at least 20 trades (or active days) exist; below that a percentile is too noisy to trust.

Daily distribution

How individual days are shaped.

MetricDefinition
Win rateshare of trading days that closed positive: positive days / (positive + negative days). Non-operative days (weekends, holidays, gaps with no trade) are excluded from the denominator, so they do not dilute the figure.
Profit factorsum(winning days) / |sum(losing days)|. Above 1 is profitable.
Avg daily winmean P/L across positive days.
Avg daily lossmean P/L across negative days (reported negative).
Median daily winmedian P/L across positive days — the typical winning day, less swayed by one outsized day than the average.
Median daily lossmedian P/L across negative days (reported negative) — the typical losing day.
Daily P055th percentile of daily P/L in dollars, over trading days only. The loss not exceeded on 95% of trading days — a dollar counterpart to the account-level VaR 95% (which is a percentage of capital).
Best day / Worst daylargest single-day gain / loss, taken over trading days only (idle P/L = 0 days excluded, so a flat non-operative day can never surface as the best/worst).
Max win streak / loss streaklongest run of consecutive winning / losing trading days. Counted on the raw daily P/L: only days with a non-zero result are considered — flat days (P/L = 0) and non-operative days are skipped, so they do not break a streak.

Where to see these

The Workspace shows a compact KPI strip (the four hero metrics). The full table lives on the Metrics page, grouped exactly as above. You can export all of it to CSV — with delta columns for any pinned variants.

A note on interpretation

These metrics describe the history you uploaded. They are descriptive, not predictive: a great Sharpe on a short or curve-fit sample can still disappoint live. Pair them with Monte Carlo (to see a range of outcomes) and Correlations (to check the diversification you're relying on).