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
- Open a completed run from MesoSim Backtests.
- Open the action menu beside Clone and select Export Events.
- 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.
| Field | Meaning |
|---|---|
EventTime | Wall-clock timestamp assigned when the export records are assembled; use SimTime for backtest chronology |
SimTime | Historical simulation timestamp; use this for backtest chronology |
EventType | Event category, such as EntryTrade or ExitPosition |
Message | Description associated with the event |
Invested | Recorded investment state |
NAV, PnL | Recorded account net asset value and running PnL |
TradeCnt, SettlementCnt, OpenLegCnt | Trade, settlement, and open-leg counts |
PositionId | Position associated with the event, when applicable |
TradeEvent | Trade details, when the event contains a trade |
Vars | Strategy 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
| Events | What to inspect |
|---|---|
EntrySignal, EntryAborted | Entry-condition or abort messages; a signal alone does not establish that a position opened |
ExpirationSelected, LegSelected | Expirations and legs chosen while constructing a position |
EntryTrade, EnterPosition | Executed entry trades and the position-opening event |
AdjustmentSignal, AdjustmentDetail, AdjustmentAborted | Adjustment decisions, actions, and reasons an adjustment could not proceed |
VariableSet, VariablesDefined | Variable updates or definitions |
ExitSignal, ExitTrade, Settlement, ExitPosition | Exit decisions, closing trades, settlements, and position closure |
EndOfDay | Position snapshots at end of day; the message can include days in trade, such as DIT=0 |
Start, Finish, Failed, MissingData | Run 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.VarDefinesto capture starting values such asinitial_delta,initial_theta, orinitial_put_delta. - Adjustment: use the adjustment action's
VarDefinesto capture state when it executes, as shown below withMoveLegAdjustment.VarDefines. UseUpdateVarsAdjustment.VarDefinesfor a separate variable-update action. - Exit: use
Exit.VarDefinesto capture closing values such asexit_deltaandexit_theta, after the exit decision and before closing fills.
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:
EntryTradedescribes an execution. Here,Qty: -1sells one option contract;Priceis the option price, with the contract'sMultiplierrecorded separately.EnterPositionmarks the position opening. It shares aSimTimewith the trade but describes a different lifecycle stage.EndOfDayrecords a position snapshot.DIT=0means the position is still on its entry day.ExitPositionmarks closure. Itspos_pnlis the recorded result for that position; do not sum successivepos_pnlsnapshots 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
SimTimefor historical time and retain the array index to distinguish events at the same timestamp. Do not useEventTimeto 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, andVarsfor analysis.Messageadds context but is not a substitute for those fields. Accept additional event types and null or missing fields. - Check scope and units.
NAVandPnLare account-level snapshots;pos_pnlis a position snapshot. Do not sum repeated snapshots. Use the contract multiplier and signed quantity when interpreting option prices. ASettlementand anExitTradecan describe the same settlement, so do not count both as separate executions. - Check capture coverage. Use the relevant
VariablesDefinedevents 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
Varsfields, 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.