Skip to main content

Events export

Download the event log to analyze a backtest with Excel, Python, or another data-analysis tool. Use it to study execution records from your backtest outside Events Viewer. For interactive charts within MesoSim, see Analytics with DataVoyager.

Download the event log​

  1. Open a completed run from MesoSim Backtests.
  2. Open the action menu beside Clone and select Export Events.
  3. Extract the downloaded ZIP file. It contains a JSON file with an array of event records.

See Backtest Results for the action menu and Accounts and Access for export access. If the Portal reports Event log not available, check that the run completed successfully before retrying.

Fields of the event log​

Optional values can be null or absent when an event does not record them. Not every event belongs to a position or contains a trade. A missing variable or an empty snapshot is not a zero value. Exported numbers retain their recorded precision.

FieldMeaning
EventTimeWall-clock timestamp assigned when the export records are assembled; use SimTime for backtest chronology
SimTimeHistorical simulation timestamp; use this for backtest chronology
EventTypeEvent category, such as EntryTrade or ExitPosition
MessageDescription associated with the event
InvestedRecorded investment state
NAV, PnLRecorded account net asset value and running PnL
TradeCnt, SettlementCnt, OpenLegCntTrade, settlement, and open-leg counts
PositionIdPosition associated with the event, when applicable
TradeEventTrade details, when the event contains a trade
VarsStrategy variable values associated with the event

Trade details​

TradeEvent contains PositionId, Contract, execution Price, and signed Qty. The contract identifies the instrument, with fields such as Underlying, option Root, OptionType, Expiration, Strike, and Multiplier where applicable.

Event types and context​

EventsWhat to inspect
EntrySignal, EntryAbortedEntry-condition or abort messages; a signal alone does not establish that a position opened
ExpirationSelected, LegSelectedExpirations and legs chosen while constructing a position
EntryTrade, EnterPositionExecuted entry trades and the position-opening event
AdjustmentSignal, AdjustmentDetail, AdjustmentAbortedAdjustment decisions, actions, and reasons an adjustment could not proceed
VariableSet, VariablesDefinedVariable updates or definitions
ExitSignal, ExitTrade, Settlement, ExitPositionExit decisions, closing trades, settlements, and position closure
EndOfDayPosition snapshots at end of day; the message can include days in trade, such as DIT=0
Start, Finish, Failed, MissingDataRun status and data issues

This is a selection of event types. Processing scripts should tolerate additional types and optional fields.

Keep event type, position, and lifecycle stage together when comparing values. An entry signal, a fill, and a position-opening snapshot may share a timestamp while describing different stages. Preserve the file's order among events with the same SimTime.

Capture the variables you need​

You can define or update custom variables at Entry, Adjustment, and Exit. To include leg-level values in the event export, copy the values you need into custom variables. The captured values are available in exported Vars under your custom names.

  • Entry: use Entry.VarDefines to capture starting values such as initial_delta, initial_theta, or initial_put_delta.
  • Adjustment: use the adjustment action's VarDefines to capture state when it executes, as shown below with MoveLegAdjustment.VarDefines. Use UpdateVarsAdjustment.VarDefines for a separate variable-update action.
  • Exit: use Exit.VarDefines to capture closing values such as exit_delta and exit_theta, after the exit decision and before closing fills.
Capture only what you need

Choose the variables and sampling frequency needed for your analysis. Capturing every available value at every opportunity increases simulation time and adds unnecessary context, making the agent's analysis harder. Use names that describe both the value and its purpose: initial_delta and initial_theta for entry snapshots, adjusted_delta for a snapshot after rebalancing, and exit_delta for an exit snapshot.

Capture entry and exit snapshots​

This strategy fragment records the position's delta and theta at entry and exit, plus a leg-level delta at entry:

{
"Entry": {
"VarDefines": {
"initial_delta": "pos_delta",
"initial_theta": "pos_theta",
"initial_put_delta": "leg_short_put_delta"
}
},
"Exit": {
"VarDefines": {
"exit_delta": "pos_delta",
"exit_theta": "pos_theta"
}
}
}

Merge these definitions into your existing Entry and Exit sections. Replace short_put with your leg's name. Entry definitions are evaluated before abort checks and again after entry fills; use the successful position-opening context when analyzing initial values. Keep initial_* variables unchanged during adjustments so they remain a reference for later comparisons.

Capture state when rebalancing delta​

This strategy fragment extends the adjusting short-strangle example. At the daily adjustment check, it moves the short call when pos_delta > 5, or the short put when pos_delta < -5, to bring the position's delta closer to zero. Each move records the resulting position delta and both leg deltas using MoveLegAdjustment.VarDefines.

{
"Adjustment": {
"Schedule": {
"Every": "day",
"BeforeMarketCloseMinutes": "30"
},
"ConditionalAdjustments": {
"pos_delta > 5": {
"MoveLegAdjustment": {
"LegName": "short_call",
"StrikeSelector": {
"Delta": "abs(pos_delta - leg_short_call_delta) / abs(leg_short_call_qty)"
},
"VarDefines": {
"adjusted_delta": "pos_delta",
"adjusted_call_delta": "leg_short_call_delta",
"adjusted_put_delta": "leg_short_put_delta"
}
}
},
"pos_delta < -5": {
"MoveLegAdjustment": {
"LegName": "short_put",
"StrikeSelector": {
"Delta": "abs(pos_delta - leg_short_put_delta) / abs(leg_short_put_qty)"
},
"VarDefines": {
"adjusted_delta": "pos_delta",
"adjusted_call_delta": "leg_short_call_delta",
"adjusted_put_delta": "leg_short_put_delta"
}
}
}
},
"MaxAdjustmentCount": "5"
}
}

The custom variables are captured after the leg is moved. If the move is aborted, its VarDefines are not evaluated. When neither delta condition is met, this example makes no adjustment and captures no new sample.

Merge the definitions into your existing Adjustment configuration, using your strategy's leg names, delta thresholds, schedule, and adjustment limit. The example checks each day, 30 minutes before market close. Its limit allows five adjustments; a subsequent triggered adjustment closes the position. Adding VarDefines to the move captures its state without adding a separate UpdateVars adjustment.

See the variable reference for available values and their units.

After cloning and rerunning the backtest, export the new event log. Look for VariablesDefined events whose Message names your custom variables, then read their values from Vars. For the rebalancing example, these are adjusted_delta, adjusted_call_delta, and adjusted_put_delta. Each such event is a capture at its SimTime, associated with its PositionId. Other events can carry the last captured value; they do not necessarily represent a fresh measurement. Adding the rule does not populate an earlier run's export.

Example events​

Use these examples as a reference when preparing an event log for an LLM or writing a parser.

Show example events (JSON)

This illustrative excerpt follows one position through an entry trade, position opening, an end-of-day snapshot, and closure. Values are synthetic; other events and fields are omitted for clarity. A complete export contains more records and fields.

[
{
"SimTime": "2024-01-02T09:45:00",
"EventType": "EntryTrade",
"PositionId": 1,
"TradeEvent": {
"PositionId": 1,
"Contract": {
"ContractType": "Options",
"Underlying": "SPX",
"Root": "SPXW",
"OptionType": "Put",
"Expiration": "2024-02-16T00:00:00",
"Strike": 4500,
"Multiplier": 100
},
"Price": 12.5,
"Qty": -1
}
},
{
"SimTime": "2024-01-02T09:45:00",
"EventType": "EnterPosition",
"PositionId": 1,
"TradeEvent": null,
"Vars": {
"pos_delta": 15,
"pos_pnl": 0
}
},
{
"SimTime": "2024-01-02T16:00:00",
"EventType": "EndOfDay",
"Message": "DIT=0",
"PositionId": 1,
"TradeEvent": null,
"Vars": {
"pos_delta": 12,
"pos_pnl": 100
}
},
{
"SimTime": "2024-01-05T10:00:00",
"EventType": "ExitPosition",
"PositionId": 1,
"TradeEvent": null,
"Vars": {
"pos_pnl": 500
}
}
]

When interpreting these records:

  • EntryTrade describes an execution. Here, Qty: -1 sells one option contract; Price is the option price, with the contract's Multiplier recorded separately.
  • EnterPosition marks the position opening. It shares a SimTime with the trade but describes a different lifecycle stage.
  • EndOfDay records a position snapshot. DIT=0 means the position is still on its entry day.
  • ExitPosition marks closure. Its pos_pnl is the recorded result for that position; do not sum successive pos_pnl snapshots as if each were a separate profit.

For a captured-variable sample, a VariablesDefined record can contain Vars such as {"adjusted_delta": 0.5, "adjusted_call_delta": -19.5, "adjusted_put_delta": 20}. These are illustrative values, not additional records from the sequence above.

Guidance for agents​

Provide the extracted JSON, the strategy definition used for that run, and the field definitions. The strategy supplies leg names, capture expressions, schedules, and conditions needed to interpret the records.

  • Request only essential data. Check what is available first, then ask only for the additional values and samples needed to answer the question. Excessive capture increases simulation time and makes analysis harder.
  • Keep the original array order. Use SimTime for historical time and retain the array index to distinguish events at the same timestamp. Do not use EventTime to measure simulation duration.
  • Separate positions and runs. Group position events by PositionId; keep events without a position as run-level context. When combining exports, also retain a run identifier or source filename.
  • Read structured fields first. Use EventType, TradeEvent, and Vars for analysis. Message adds context but is not a substitute for those fields. Accept additional event types and null or missing fields.
  • Check scope and units. NAV and PnL are account-level snapshots; pos_pnl is a position snapshot. Do not sum repeated snapshots. Use the contract multiplier and signed quantity when interpreting option prices. A Settlement and an ExitTrade can describe the same settlement, so do not count both as separate executions.
  • Check capture coverage. Use the relevant VariablesDefined events for custom-variable samples. Report unavailable values and sampling gaps instead of treating them as zero or assuming a later event refreshed the values. If the required data was not captured, propose a minimal capture rule and a rerun.

Further analysis​

  • Excel: import the extracted JSON with Power Query, expand the records and relevant Vars fields, then build tables or charts.
  • Python: load the JSON array, select the event types and positions of interest, and calculate summaries from the relevant recorded fields.
  • Analytics: use the backtest's Analytics tab with DataVoyager for interactive visualization in the Portal.

For example, select ExitPosition events to study completed positions rather than mixing signals, individual fills, and position outcomes. Check the available fields before calculating each measure.

For examples of capturing custom strategy state, see Deltaray's Advanced MesoSim Patterns. Use Quantitative Metrics when comparing your analysis with the definitions used in MesoSim's performance reports.