Skip to main content

Script Engine

Updated for v3 · Migration Guide

MesoSim's Script Engine allows you to express trading logic with Lua expressions that control leg selections, entries, trade adjustments and exits. Every field in the Strategy Definition is evaluated by the ScriptEngine during simulation, allowing the users to create trading strategies with minimal code.

The fields in the Strategy Definition can reference live variables (underlying, legs, position, account, timing, and external data) and they can use the provided Options Valuation and Timing modules to create sophisticated trading logic.

This page introduces the expression language, operators, variables, and a high‑level overview of Timing and Options Valuation functions.

For where expressions are used and when they are evaluated, see Expressions Quick Reference.

Language Primer: Lua

Expressions use the Lua language syntax. You don’t need full programs — just expressions that evaluate to a number (for quantities/thresholds) or boolean (for conditions).

  • Comparisons: < <= > >= == ~= (not equal)
  • Logical operators: and, or, not (note: nil behaves as false)
  • Use parentheses to control precedence, e.g., (a and b) or c
  • Function calls: fn(arg1, arg2)

Lua language reference: https://www.lua.org/manual/5.4/ Learn Lua in 15 minutes: https://tylerneylon.com/a/learn-lua/

Operations

Common arithmetic and logical operators for expressions.

OperatorCategoryDescription
+ArithmeticAddition
-ArithmeticSubtraction
*ArithmeticMultiplication
/ArithmeticFloat division
//ArithmeticFloor division
%ArithmeticModulo
^ArithmeticExponentiation
- (unary)ArithmeticUnary minus
andLogicalTrue if both operands are true, else false
orLogicalTrue if at least one operand is true, else false
notLogicalNegates input (true → false, false → true)

Note: In logical operations, nil evaluates to false.

Built-in Functions

Use standard Lua call syntax, for example: abs(leg_short_delta).

SignatureDescription
abs(x) -> numberAbsolute value
min(a, b, ...) -> numberMinimum of arguments
max(a, b, ...) -> numberMaximum of arguments
floor(x) -> numberLargest integer ≤ x
ceil(x) -> numberSmallest integer ≥ x
sqrt(x) -> numberSquare root
pow(x, y) -> numberPower function x^y (you can also use ^)
log(x) -> numberNatural logarithm (base e)
log10(x) -> numberBase‑10 logarithm
exp(x) -> numbere raised to x
random([m[, n]]) -> numberRandom integer in [m, n] if bounds provided; otherwise (0,1)
int(x) -> intTruncate toward zero (floor for positive, ceil for negative)

Variables

The following variables are available during a backtest and can be used anywhere the ScriptEngine evaluates expressions (Entry, Exit, Adjustments, selectors, etc.). Where a name contains placeholders, replace them with your own names (e.g., leg_<name>_delta).

Expiration

Variables related to Expiration targets.

NameDescription
expiration_EXPNAME_dteDays to expiration for alias EXPNAME (auto‑updated)
expiration_EXPNAME_minMinimum allowed days when selecting EXPNAME (constraint)
expiration_EXPNAME_maxMaximum allowed days when selecting EXPNAME (constraint)

Leg

Per-leg quotes, greeks, and properties for legs defined in the structure and adjustments.

NameDescription
leg_LEGNAME_priceMark price used for liquidation semantics
leg_LEGNAME_bidCurrent bid price
leg_LEGNAME_askCurrent ask price
leg_LEGNAME_qtyQuantity of the leg (0 for marker legs)
leg_LEGNAME_ivImplied volatility (percent)
leg_LEGNAME_deltaLeg delta (qty‑scaled; per‑1‑unit for marker legs)
leg_LEGNAME_gammaLeg gamma (qty‑scaled; per‑1‑unit for marker legs)
leg_LEGNAME_thetaLeg theta (qty‑scaled; per‑1‑unit for marker legs)
leg_LEGNAME_vegaLeg vega (qty‑scaled; per‑1‑unit for marker legs)
leg_LEGNAME_wvegaWeighted vega using option DTE (qty‑scaled)
leg_LEGNAME_rhoLeg rho (qty‑scaled; per‑1‑unit for marker legs)
leg_LEGNAME_ditDays in trade for this leg since creation (decimal days)
leg_LEGNAME_dteDays to expiration for this leg (decimal days)
leg_LEGNAME_strikeStrike price for the option contract
leg_LEGNAME_pnlLeg PnL including realized amounts (where applicable)

Position

Aggregated greeks, PnL, and position-level thresholds computed across all open legs; commonly used in exit conditions, and conditional adjustments .

NameDescription
profit_targetUser‑defined profit target for the position
stop_lossUser‑defined stop loss for the position
pos_pnlTotal position PnL (open + realized)
pos_realized_pnlCumulative realized PnL for the position
pos_deltaSum of leg deltas (qty‑scaled)
pos_gammaSum of leg gammas (qty‑scaled)
pos_thetaSum of leg thetas (qty‑scaled)
pos_vegaSum of leg vegas (qty‑scaled)
pos_wvegaPosition weighted vega (DTE‑weighted)
pos_rhoSum of leg rhos (qty‑scaled)
pos_marginEstimated position margin (PM‑like model if enabled)
open_legs_cntNumber of currently open legs in the position

Account

Account-level balances and counts useful for sizing, gating, and concurrency; often applied in Entry sizing (QtyMultiplier) and concurrency

NameDescription
navNet Asset Value of the account
initial_cashInitial cash configured for the backtest run
pos_in_flightNumber of positions currently in‑flight (open or in progress)

Underlying

Current underlying price and volatility measures available throughout the run; often used in Entry and Adjustment conditions. See also: Implied & Historical Volatility.

NameDescription
underlying_priceCurrent underlying price
underlying_today_openToday’s opening price (if available)
underlying_prevday_closePrevious day’s close (if available)
underlying_ivUnderlying implied volatility (percent)
underlying_iv_rankIV rank (0–100) at current implied volatility
underlying_iv_pctIV percentile (0–100) versus lookback window
underlying_hvUnderlying historical volatility (percent)

External Data Variables

If you specify External CSV data in the Strategy Definition, each CSV column becomes a variable available to expressions for the corresponding dates. The variable names are shown in the Job Editor under “External Data from CSV”.

For examples and setup, see FAQs Use External Data and Share External Data.

Modules

Modules provide specialized functions for common tasks. Two modules are available:

Timing

Timing functions help you count trading or calendar days relative to key anchors (weeks, months, option expirations, and other events) to build rules like “enter only in the first N trading days of the month.”

See the Timing Module documentation for details.

Available Functions:

SignatureDescription
timing.trading_days_until(anchor, [boundary]) -> decimalTrading days from now until anchor (optional boundary)
timing.trading_days_after(anchor, [boundary]) -> decimalTrading days after anchor up to boundary (optional)
timing.calendar_days_until(anchor, [boundary]) -> decimalCalendar days from now until anchor (optional boundary)
timing.calendar_days_after(anchor, [boundary]) -> decimalCalendar days after anchor up to boundary (optional)
timing.trading_days_in(anchorA, [anchorB], [a_boundary], [b_boundary]) -> decimalTrading‑day count within a window
timing.calendar_days_in(anchorA, [anchorB], [a_boundary], [b_boundary]) -> decimalCalendar‑day count within a window

For timing variables, anchors/boundaries, examples, and best practices, see Timing Module

Options Valuation

Project greeks and PnL at future anchors/DTEs or scan a price range to locate minima/maxima or roots. Useful for gating entries, shaping adjustments, or early exits based on how the Risk Graph changes.

For full documentation please refer to the Options Valuation page.

Available Functions:

SignatureDescription
options.model(target, dteDaysOrAnchor, underlyingPrice, metric[, model_params]) -> numberEvaluate position/leg at a time anchor or DTE using a scenario underlying price and return the selected metric
options.model_solver(target, dteOrKey, start, end, metric, goal, result[, solver_params]) -> numberScan a price range to minimize/maximize/zero a metric and return value or price per result

Best Practices

  • Prefer simple, readable expressions; use parentheses to make intent clear.
  • Use Entry.VarDefines to capture initial values for later comparisons (e.g., initial_theta).
  • When Expression fails to evaluate: check variable names, parentheses, and types.