v2 to v3 Migration
MesoSim converts saved v2 strategy definitions when you open them in the Job Editor through Clone. This guide explains the automatic changes and the behavior to review before running the converted strategy.
For the current format, use the Strategy Definition Reference. The MesoSim v3 release overview on the Deltaray blog explains the broader changes.
Convert and review a strategy
- Open the old backtest from Backtests and choose Clone to load it in the Job Editor.
- In MesoSim v2 to v3 Conversion, select Show details and review all three groups:
- Auto-updated:
[AUTO]notes describe changes already applied. - Manual intervention required:
[WARN]and[ERROR]notes identify items to resolve. - Other notes: Review these for behavioral changes and additional migration guidance.
- Auto-updated:
- Review the converted expressions and settings, then select Validate and resolve the reported issues.
- Run a representative period and compare the selected contracts, entries, adjustments, and exits with the original. Use Backtest Results and the Events Viewer to investigate differences.
Conversion updates the format and common expressions. Validation checks the definition; a comparison run helps confirm that the strategy still implements your intended rules.
Field layout changes
| v2 field | v3 field |
|---|---|
Name, Start, End, Cash | Corresponding fields inside Backtest; Cash is an expression |
TemplateName | StrategyName |
SimSettings.FillModel | Settings.Sim.FillModel |
SimSettings.SlippageAmt | Settings.Sim.SlippageAmt |
SimSettings.Commission | Settings.Sim.Commission |
SimSettings.PositionMonitor | Settings.Sim.PositionMonitor |
SimSettings.Margin | Settings.Core.Margin |
SimSettings.LegSelectionConstraint | Settings.Core.LegSelectionConstraint |
SimSettings.ExpirationSelectionConstraint | Settings.Core.ExpirationSelectionConstraint |
The following examples show partial definitions. Keep the strategy's other required sections.
Backtest fields: before and after
v2
{
"Name": "generate",
"TemplateName": "MyStrategy",
"Start": "2021-01-01T00:00:00",
"End": "2021-12-31T00:00:00",
"Cash": 10000,
"Symbol": "SPX"
}
v3
{
"StrategyName": "MyStrategy",
"Backtest": {
"Name": "generate",
"Start": "2021-01-01T00:00:00",
"End": "2021-12-31T00:00:00",
"Cash": "10000"
},
"Symbol": "SPX"
}
Simulation and core settings: before and after
v2
{
"SimSettings": {
"FillModel": "AtMidPrice",
"SlippageAmt": "0",
"Commission": { "CommissionModel": "FixedFee", "OptionFee": "1.5" },
"PositionMonitor": { "TraceCollectionInterval": "Hourly" },
"LegSelectionConstraint": "FullyUnique",
"ExpirationSelectionConstraint": "AbortOnReuse",
"Margin": { "Model": "RegT", "RegTMode": "CBOEPermissive" }
}
}
v3
{
"Settings": {
"Sim": {
"FillModel": "AtMidPrice",
"SlippageAmt": "0",
"Commission": { "CommissionModel": "FixedFee", "OptionFee": "1.5" },
"PositionMonitor": { "TraceCollectionInterval": "Hourly" }
},
"Core": {
"LegSelectionConstraint": "FullyUnique",
"ExpirationSelectionConstraint": "AbortOnReuse",
"Margin": { "Model": "RegT", "RegTMode": "CBOEPermissive" }
}
}
}
This example preserves the original selection constraints. See Settings for the current fields and defaults.
Strike selectors
Each leg must specify exactly one selector: BidPrice, AskPrice, MidPrice, Delta, StrikePrice, or Complex.
The converter renames a selector's top-level Statement to StrikePrice. For example, this v3 fragment selects a strike relative to a previously selected leg:
{
"StrikeSelector": {
"StrikePrice": "leg_short_put_strike - 25"
}
}
The dedicated v2 selectors Gamma, Theta, Vega, WVega, Rho, and IV require a manual rewrite. Use Complex strike selection when the target depends on one of these values.
Complex.Statement remains valid: it defines the score to compare with Complex.Target. Put restrictions in Complex.Constraints; selector-level Min and Max cannot be combined with Complex. See the strike selector reference for details.
Variable and volatility changes
The converter applies these common expression rewrites. Check the Auto-updated notes before making the same change manually.
| v2 expression | v3 equivalent |
|---|---|
open_trades_cnt | open_legs_cnt |
days_in_trade | timing.days_in_trade |
minutes_after_open | timing.minutes_after_open |
minutes_before_close | timing.minutes_before_close |
underlying_iv | (underlying_iv / 100) to preserve the old fractional units |
underlying_hv | (underlying_hv / 100) to preserve the old fractional units |
In v3, underlying Implied Volatility and historical volatility use percentage units: 20 means 20%. For example:
| Form | Condition for Implied Volatility above 20% |
|---|---|
| Original v2 expression | underlying_iv > 0.20 |
| Automatically converted expression | (underlying_iv / 100) > 0.20 |
| Equivalent expression written directly for v3 | underlying_iv > 20 |
Use either v3 form consistently. If conversion has already inserted / 100, leave the fractional threshold unchanged. underlying_iv_rank, underlying_iv_pct, and leg IV variables are not rescaled by this conversion. See Implied and Historical Volatility.
Removed indicators and account variables
- The v2
Indicatorssection and built-in indicator functions require a manual replacement. Import precomputed signals using External Data. - Account-level
acc_*variables are removed. Rewrite their conditions or calculations using the variables appropriate to the strategy's intended scope; the Script Engine reference lists the available variables.
Review expressions throughout the strategy, including leg quantities, adjustment conditions, and Complex targets.
Behavioral changes to review
Fractional days
Days-based values such as leg_LEGNAME_dte, leg_LEGNAME_dit, expiration_EXPNAME_dte, and timing.days_in_trade include fractional days. A scheduled check can pass a threshold without landing exactly on it.
For an exit when one day or less remains, use:
leg_long_put_dte <= 1
If you deliberately want a whole-day bucket, use int(leg_long_put_dte) == 1. These conditions have different meanings; choose the one that matches the intended exit. See Timing for property types and calendar calculations.
Weighted vega
Weighted vega uses fractional DTE in v3. Review thresholds or sizing rules based on leg_LEGNAME_wvega or pos_wvega, especially close to expiration, where the difference from whole-day calculations can be substantial.
Marker legs
Leg-level Greeks for a marker (Qty: 0) are exposed as if its quantity were one. Its contribution to position Greeks remains zero. Review expressions that use markers to observe contracts outside the traded structure; see Marker Legs for examples.
Entry delays and contract selection
The current v3 default for Entry.ReentryDays is 0. Set the intended delay explicitly when migrating; see ReentryDays for its meaning and fractional values.
The v3 default for Settings.Core.LegSelectionConstraint is UniqueInPosition, which allows contract reuse across positions. The converter carries over the legacy setting, including the v2 default of FullyUnique. Review the converted value before changing it; see LegSelectionConstraint.
Tearsheets
The legacy Settings.Sim.TearsheetGeneration field is ignored. Open Tearsheet on the backtest result to generate the report on demand; see Tearsheets.