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
  • Keyframes
  • Currencies & FX
  • Library
  • Strike guard
  • Variants & comparison
  • History (undo/redo)
  • Shared spaces

Analytics

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

Research

  • Research overview
  • Define
  • Composing a backtest
  • How the engine trades
  • Results & archive
  • Parameter study
  • Rewind
  • Tactics
  • Indicators

Reference

  • Keyboard & command palette
  • Exporting data
  • Settings

Technical

  • Architecture
  • API reference
  • Security
  • Your data & privacy
  • Risk disclosure
← PreviousWeekday filterNext →Currencies & FX

Keyframes on the equity line

A weight is one number for the whole history. But books change: you doubled a strategy in March, you parked another one over the summer, you cut everything back after a drawdown. Reading that history at today's size tells you what a portfolio you never ran would have done.

A keyframe is a dated allocation event. From that day onward — until the next keyframe — a strategy, a group or the whole portfolio runs at a different size, or not at all. Everything downstream (equity, drawdown, metrics, monthly grid, correlations) is computed from the result.

Anatomy

Every keyframe has four parts:

PartValuesMeaning
Dateany datethe event applies from this day, inclusive
Scopestrategy · group · portfoliowhat it acts on
Overridecontracts · statewhat it changes
Notefree text, optionalwhy you did it — it never affects the maths

Contracts pins the size to a number. It is available on strategy scope only: a group or the portfolio has no single contract count to pin. State switches the scope on or off, and works at every level.

A keyframe replaces the number, it does not multiply it: a leg at weight 2 with a contracts = 5 keyframe runs at 5, not 10, from that date on.

How the timeline resolves

The engine walks the keyframes in date order and produces, per strategy, a list of segments — intervals where the declared size and the on/off state are constant. Before the first keyframe the strategy sits on its base configuration (its weight × its group's scale).

weight 1                kf: contracts 3          kf: state off
├───────────────────────┼────────────────────────┼──────────────▶
   ×1 (base)                 3 contracts              muted

Size and state are independent. A segment carries both, and each keyframe writes one of them, so several keyframes on the same date compose: they are applied from the least to the most specific, and the more specific one wins on the dimension it touches. Precedence is strategy › group › portfolio.

So switching the whole portfolio off on 3 March and pinning strategy A to 5 contracts on 3 March does both: A is off, and carries 5 contracts for when it comes back. If you meant "everything down except A", say so — add an explicit state = on keyframe on A for the same date, and the more specific scope wins.

Pinning contracts after a shutdown also switches the strategy back on, which is almost always what you mean. That is a default, not a rule: an explicit state keyframe on the same date decides instead.

A keyframe dated before your first trade applies to the whole history; one dated after your last trade changes nothing. A keyframe pointing at a strategy or a group that no longer exists is dropped when the portfolio is reopened, rather than left as a marker that moves nothing.

Fixed legs and sized legs behave differently

This is the part worth reading twice, because the same gesture means two different things depending on the strategy's sizing regime.

On a fixed leg the keyframe is what you would expect: a daily multiplier on that leg's P/L, switching at the segment boundaries. Margin scales with it.

On a dynamically sized leg the size is decided per trade by the risk/margin engine, so there is no single multiplier to swap. The keyframe acts on the engine instead:

  • a state = off keyframe removes the trades that open inside the muted interval;
  • a contracts keyframe pins the engine's Min and Max to that number inside that segment, and only there. Your own Min/Max bounds do not apply over that span — the keyframe decides, and the workspace says so in a sizing note.

Pinning zero contracts means the same thing in both regimes: the strategy does not run. On a sized leg it cannot go through Min/Max, where zero means "no limit", so those trades are dropped the way a state = off keyframe drops them.

Why the open date, in both regimes

A keyframe is read against each trade's opening date, whether the leg is fixed or sized. "From March I run three contracts" is a decision you take when you enter: a position already open cannot be resized. It is the same reason the weekday filter is an entry rule. A trade opened on 28 February and closed on 2 March therefore keeps its old size, even though its P/L lands after the keyframe. For intraday books open and close coincide and nothing changes.

The one exception is a strategy imported as a daily equity series with no trade-level data: there is no opening date to read, so the keyframe applies on the series' own calendar. It is the same compromise the weekday filter already makes, for the same reason.

Working with them

Keyframes live on the equity chart in the workspace, behind a single control in the chart's toolbar. With none placed it reads keyframe and opens the editor; once you have some it shows how many, and opens the list — every keyframe with its date, what it does and its note, whether or not it falls inside the range you are looking at. That count is deliberate: a curve reshaped by three keyframes should not look like the raw one.

You can also click a point on the curve to open the editor with that date prefilled. Existing keyframes show as vertical markers; clicking a marker — or a row in the list — opens the before/after panel, which lists every strategy the event touches with its declared size on each side, and lets you edit or delete it from there.

The trade book follows too: a leg pinned to three contracts shows three in the contracts column from that date on, and a muted interval drops those trades entirely rather than showing them at zero. The book and the curve always sum to the same number — that is how you check one against the other.

Each create, edit and delete is one History entry, so a single undo takes it back.

Keyframes are part of the recipe: they are saved with the portfolio and restored with it, they travel into a variant when you freeze one, and they are mirrored in the session draft, so a restart does not lose them. Because they change the numbers, a portfolio saved with keyframes is not comparable to the same portfolio without them — the engine version is recorded alongside so old variants stay readable.

Keyframes describe your book, not a forecast

A keyframe reconstructs the allocation you actually ran. It is not a what-if optimizer: nothing here searches for a better schedule, and a curve reshaped by hand until it looks good is a curve fitted in hindsight. Use Monte Carlo and the optimizer's out-of-sample checks to tell the two apart.