Expression Types — Field Reference

One card per operand type: what it returns, what is mandatory, what is optional, and the logic in a sentence. Mandatory fields are exactly what the builder's validator enforces — if one is missing, Save fails and names the field.

"100 ticks" is two different operands — do not mix them up.
Price travelled 100 ticksPriceMoveObject. Distance, measured in ticks from where the move began.
100 quote updates arrivedTicksPerPeriod. A message count — activity and liquidity, never price.
Neither can be completed in Quick Create; both are built in the visual builder or via JSON Import.
Returns matters. A type marked value produces a number — a getter, a building block that never fires on its own. event types are conditions you can attach to an alert. Values compose into values; the top of the chain must be a condition. See value getters.
Timeframe is mandatory for indicators, candle patterns, OHLC, Heikin Ashi, Renko, Trend, Channel, Pivot and Price Move. Quotes, account and position types are current-state and take none.

The expression model — read this first

Every GTS expression has exactly one of two shapes. There is no third form: no inline formulas, no three-operand expressions, no nested arithmetic inside one side.

ShapeFormReturns
UnaryONE operand. No operator, no right side. The operand may itself reference other saved expressions — unary does not mean simple or terminal.A value (a getter — a building block), or fires on its own if the operand is an event such as a candle pattern
BinaryLEFT  OPERATOR  RIGHTDepends entirely on the operator ↓
Operator on a binaryReturnsMeaning
> < == != >= <=, crossedbooleanA condition. This is what an alert or handler fires on.
AND ORbooleanCombines two saved conditions by name.
- + * /valueArithmetic. Still a getter — binary does not mean boolean.
Arithmetic exists — but not in Quick Create. The builder and JSON Import fully support - + * / as operators between two operands. What is not supported anywhere is inline arithmetic inside one side: EMA(50) > EMA(200) + 2 will never parse, and neither will width / duration > 0.83. Each side must resolve to a single operand. To express a calculation, make it its own expression — build EMA(50) - EMA(200) as a value, save it, then compare that saved value to a number. Saying "GTS has no arithmetic" is wrong; saying "you cannot write arithmetic inline on one side" is right.
"A GTS expression is binary" is wrong — and it leads people to the wrong design. Unary is a first-class shape, and a unary expression is fully composable: it can consume other saved expressions. Composition does not require a binary. Several operand types are unary precisely so they can take other expressions as input:
Unary typeWhat it consumes
UserExpressionOne saved expression, referenced by name — on its own, with no operator
PriceMoveObjectA mandatory source expression supplying the price series
ExpressionMetaA mandatory source expression whose firing history it reports on
CollectionTransformA SOURCE expression (plus SOURCE B for binary ops) to build a derived collection
ConsensusScoreTwo or more child expressions it scores agreement across
StateMachineExpressionTwo or more child expressions forming an ordered sequence
HistValueOne or two child expressions to run statistics over

Add to that the unary operations — ABS, NOT, Max, Min, History, Z-Score, Momentum, Accel, Pct Rank, Dir Strength — which wrap any operand, including a referenced expression. So a unary expression can sit several levels deep in a composition chain while still having no operator and no right side.

Depth comes from composition, never from longer lines. Save any expression and reference it by name as a UserExpression in the next one. Values compose into values for as many levels as you need; the top of the chain is a condition. That is the answer to every "but I need something more complicated" question — not a bigger expression, more expressions.

Building in the visual builder — the actual steps

  1. Pick the left operand type, then fill its mandatory fields (each card below lists them).
  2. Pick the operator — or leave it unset to save a unary getter.
  3. Set the right operand — only if you chose an operator.
  4. Name it and Save.
There is no "choose a symbol" step — expressions on this site never carry one. The symbol is bound by the strategy at deploy. If a walkthrough tells you to pick a symbol while building an expression, it is describing something else.
Timeframe is not a universal step either. It appears only for the types that require it (indicators, candle patterns, OHLC, Heikin Ashi, Renko, Trend, Channel, Pivot, Price Move). Quotes, account and position types have none. And for TicksPerPeriod the builder hides the timeframe selector entirely, because its Period setting is the timeframe.
"Build two expressions and combine them" is not a general rule. You need two expressions only when the logic genuinely has two conditions (or when you are turning a calculated value into a condition). Plenty of rules are a single expression — and some, like a price move, are a single unary one. Reach for composition when the logic needs it, not by default.

Worked example — "100 quote updates in 2 minutes"

This is one expression, not two:

StepSetting
Left operandTicksPerPeriod, Period = 2Min
Operator>
Right operandFixedVal = 100

Available periods are 1Min, 2Min, 5Min, 10Min, 15Min, 30Min, 1Hour, 2Hours, 4Hour, 12Hours, Daily, Weekly, Monthly — so a two-minute window is directly expressible, with no combining required.

Remember which "100 ticks" this is. The expression above counts quote updates. If you meant price travelled 100 ticks, that is PriceMoveObject — a different operand, unary, with the threshold as a parameter.

Symbols, ticks and exchanges — GTS handles it, you handle logic

The mental model: an expression is a class; the strategy instantiates it.
An expression is a blueprint — logic with no instrument attached, exactly like a class definition with no object yet. It is not "unfinished"; it is generic on purpose. When a strategy picks a symbol, that blueprint is instantiated: the engine binds the instrument and every symbol-specific value — tick size, point value, contract specs — is resolved for that instance. Attach the same expression to five symbols and you get five instances of one class, each correctly parameterised.
Object-orientedGTS
Class definitionThe saved expression — logic only, no symbol
new Foo(symbol)The strategy binding a symbol at deploy
Constructor argumentsSymbol, timeframe context and instrument reference data
Instance field resolved at constructionSymbol.TicksInPoint and friends, resolved per bound instrument
One class, many instancesOne expression, many symbols — no duplication
Why this matters for reasoning about GTS. "The same expression behaves differently on EURUSD and BTCUSD" is the wrong conclusion — it implies the expression is unreliable. The right one is that one class produced two instances, each resolving its own instrument's tick size correctly. The logic is identical; only the constructor argument differs. That is the intended design, not a caveat — it is what lets one rule cover a whole watchlist. The only thing that does not auto-scale is a magnitude you typed (a literal "100 ticks"), which is why Symbol.TicksInPoint exists: divide by it and even the magnitude becomes instrument-relative.
An expression carries no symbol. You build logic only. There is no symbol field on an expression, and you never convert ticks to price, look up a contract size, or account for exchange differences. The strategy binds the symbol when it is deployed — and it can bind many. The same saved expression runs against every symbol attached to it.

What GTS resolves for you at runtime

MechanicWho handles it
Tick size / point value — turning a raw price distance into a tick countGTS. The engine divides by the instrument's tick size itself (diff = abs((current − base) / divideFactor)).
Exchange and instrument specifics — contract size, min unit, marginGTS, from the instrument's reference data.
Which symbol this run is forThe strategy, dynamically, at deploy time.
The logic — what condition should fireYou. That is the whole job.
Symbols are set dynamically, and your logic still works. Write the rule once; attach it to one symbol or fifty. Nothing in the expression needs to change, because every symbol-specific mechanic is resolved beneath it. This is why expressions are reusable across an entire watchlist instead of being rebuilt per instrument.

When the algorithm genuinely needs to know the symbol

Symbol-agnostic does not mean symbol-blind. If your logic really does depend on instrument properties, use the Symbol operand — it exposes the bound instrument's reference data at runtime, so the expression adapts itself per symbol instead of you maintaining one copy per instrument:

NeedHow
Branch on instrument typeSymbolType
Scale a threshold by the instrument's tick sizeSymbolTicks In Point, used as a value inside a bigger expression
Respect sizing or margin limitsSymbolMin Unit Size, Margin, Buy/Sell Interest
Because Symbol is a normal value operand, it composes like any other — reference it inside a comparison, or build it into a calculated helper. The expression stays one expression and still runs across every symbol you attach.

Recipe — a distance in ticks (price vs SMA, or EMA vs EMA)

"How far is price from the 200 SMA, in ticks?" is a calculation, so it cannot be typed into Quick Create — there is no inline arithmetic. It is built bottom-up, and the tick conversion is one division:

ticks = price difference ÷ Symbol.TicksInPoint — this is exactly what the engine does internally (getSpreadInTicks() = abs((ask − bid) / getTip()), where getTip() is the same value Symbol.TicksInPoint exposes). Because Symbol resolves against whatever instrument the strategy bound, the same chain gives correct ticks on every symbol — you never hard-code a tick size.
#ExpressionBuilt fromReturns
1SRC_CLOSE_1HOHLC close, 1Hour, no operatorvalue
2SRC_SMA200_1HSMA(200), 1Hour, no operatorvalue
3GAP_PRICE#1 - #2, ABS appliedvalue — in price units
4GAP_TICKS#3 / Symbol.TicksInPointvalue — in ticks
5GAP_TICKS_GT_50#4 > FixedVal 50boolean — the alert

Swap steps 1–2 for EMA(50) and EMA(200) and you have the EMA separation filter — the same shape as the bundled EMA_DIFF_H1_ABSEMA_DIFF_H1_ABS_GT_0_0002 chain, except that one compares in raw price units while this one compares in ticks and therefore travels across instruments unchanged.

Where to build it. Steps 3 and 4 use math operators, so: the visual builder, JSON Import, or Generate with AI (the Quick Create box will reject the arithmetic). The AI row on the Builder page has ready prompts for both the SMA gap and the EMA gap.
The one thing that is yours: magnitude. A tick threshold is a quantity, not a percentage. GTS converts it correctly for whatever instrument is bound, but 100 ticks is a different economic move on different instruments — so choose a number that suits the set you intend to attach, or read Ticks In Point and scale it in the logic.

Technical

valueGTSIndicatorsIndicators

Runs a named indicator on a timeframe and returns its number. Multi-output indicators (MACD, BBANDS) need the output field picked.

Mandatory Optional Fields

ABERRATION, ABOVE, ACCBANDS, AD, ADI, ADOSC, ADX, ADXR, ALMA, AMAT, AO, AOBV, APO, AROON, AROONOSC, ATR, AV, AVGDEV, AVGPRICE, AwesomeOscillator, BBANDS, BELOW, BIAS, BOP, BOS, BRAR, BollingerBands, CAGR, CCI, CDL_DOJI, CDL_INSIDE, CDL_Z, CFO, CG, CHOCH, CHOP, CKS, CKSP, CMF, CMO, COPPOCK, CR, CROSS, CTI, ChaikinMoneyFlow, CumulativeReturn, DECAY, DECREASING, DEMA, DLR, DM, DONCHIAN, DOWNSIDE_DEVIATION, DPO, DR, DRAWDOWN, DX, DailyLogReturn, DailyReturn, DonchianChannel, EBSW, EFI, EMA, ENTROPY, EOM, ER, ERI, FI, FIBONACCI, FISHER, FVG, FWMA, GEOMETRIC_MEAN, HA, HIGH_LOW_RANGE, HILO, HL2, HLC3, HLCC4, HMA, HT.DCPERIOD, HT.DCPHASE, HT.PHASOR, HT.SINE, HT.TRENDLINE, HT.TRENDMODE, HTDCPERIOD, HTDCPHASE, HTPHASOR, HTSINE, HTTRENDLINE, HTTRENDMODE, HWC, HWMA, ICHIMOKU, IMI, INCREASING, INERTIA, IchimokuIndicator, JMA, KAMA, KC, KDJ, KST, KURTOSIS, KVO, KeltnerChannel, LINEARREG, LINEARREGANGLE, LINEARREGINTERCEPT, LINEARREGSLOPE, LINREG, LIQUIDITY_VOID, LN, LOG10, LOG_RETURN, LONG_RUN, LRSI, MACD, MAD, MAMA, MASSI, MAX_DRAWDOWN, MCGD, MEDIAN, MFI, MI, MIDPOINT, MIDPRICE, MINUS_DI, MINUS_DM, MOM, MSB, NATR, NVI, OBV, OHLC4, ORDER_BLOCK, PDIST, PERCENT_RETURN, PGO, PLUS_DI, PLUS_DM, PO, PPO, PSL, PVI, PVO, PVOL, PVR, PVT, PWMA, QQE, QStick, QUANTILE, RAINBOW, RMA, ROC, ROCP, ROCR, ROCR100, RSI, RSX, RVGI, RVI, SAR, SHORT_RUN, SIN, SINH, SINWMA, SKEW, SLOPE, SMA, SMI, SQUEEZE, SQUEEZE_PRO, SSF, SSMA, STC, STDDEV, STDEV, STOCH, STOCHF, STOCHRSI, SUPERTREND, SWING_HIGH, SWING_LOW, SWMA, StochasticOscillator, T3, TD_SEQ, TEMA, THERMO, TRANGE, TREND_RETURN, TRIMA, TRIX, TRIXH, TRUE_RANGE, TSF, TSI, TTM_TREND, TYPPRICE, TrendMassIndex, UI, ULCER, ULTOSC, UO, UlcerIndex, UltimateOscillator, VAR, VARIANCE, VFI, VHF, VIDYA, VOLATILITY, VORTEX, VP, VPT, VTX, VWAP, VWMA, VWMACD, VolumePriceTrend, VolumeWeightedAveragePrice, VortexIndicator, WCLPRICE, WCP, WILLR, WMA, ZLMA, ZSCORE

Lua / C++

getInd(name, frame[, field])

JSON example

Getter example

{
  "ExpressionName": "RSI14_5m",
  "Expression_left_ElementType": "GTSIndicators",
  "Expression_left_ElementValue": "RSI",
  "Expression_left_Frame": "5Min",
  "Expression_left_Size1": 14
}

Comparison example

{
  "ExpressionName": "RSI14_GT_50_5m",
  "Expression_left_ElementType": "GTSIndicators",
  "Expression_left_ElementValue": "RSI",
  "Expression_left_Frame": "5Min",
  "Expression_left_Size1": 14,
  "Expression_left_operation": ">",
  "Expression_right_ElementType": "FixedVal",
  "Expression_right_ElementValue": "50"
}
Builder tile

In the operand grid this type appears as Indicators (category: technical). The ElementType stored in JSON is GTSIndicators.

value or eventExtendedIndicatorsExtended Indicators

Advanced/ML detectors — FVG, Order Block, SMC/ICT, regime. Some return a value, some a signal you compare with > 0.

Mandatory Optional Fields

FvgDetector, BreakOfStructure.signal, OrderBlockDetector

Lua / C++

getExt(name, frame[, field])

JSON example

Getter example

{
  "ExpressionName": "IRSI_SIGNAL_5m",
  "Expression_left_ElementType": "ExtendedIndicators",
  "Expression_left_ElementValue": "InertialRsi",
  "Expression_left_Frame": "5Min",
  "Expression_left_Param_L_min": 14,
  "Expression_left_FieldName": "signal"
}

Comparison example

{
  "ExpressionName": "IRSI_SIGNAL_LT30_5m",
  "Expression_left_ElementType": "ExtendedIndicators",
  "Expression_left_ElementValue": "InertialRsi",
  "Expression_left_Frame": "5Min",
  "Expression_left_Param_L_min": 14,
  "Expression_left_FieldName": "signal",
  "Expression_left_operation": "<",
  "Expression_right_ElementType": "FixedVal",
  "Expression_right_ElementValue": "30"
}
Builder tile

In the operand grid this type appears as Extended Indicators (category: technical). The ElementType stored in JSON is ExtendedIndicators.

Quick Create (confirmed)

Verified by the parser's own test suite — these resolve to this type.

eventTA_CandlePatternsCandle Patterns

Fires when the pattern forms. Boolean directional event — compare with > 0, never == 100. A trend is required.

Mandatory Fields

ENGULFING, HAMMER, DOJI, Bullish, Bearish

Lua / C++

getCdl(name, frame, trend)

Watch out. Event: true only on the bar it forms. Compare > 0 — never == 100. A Trend is REQUIRED; without it the pattern will not resolve.
JSON example

Event example

{
  "ExpressionName": "ENGULFING_BULL_5m",
  "Expression_left_ElementType": "TA_CandlePatterns",
  "Expression_left_ElementValue": "ENGULFING",
  "Expression_left_Frame": "5Min",
  "Expression_left_Trend": "Bullish",
  "Expression_left_operation": ">",
  "Expression_right_ElementType": "FixedVal",
  "Expression_right_ElementValue": "0"
}
Builder tile

In the operand grid this type appears as Candle Patterns (category: technical). The ElementType stored in JSON is TA_CandlePatterns.

Quick Create (confirmed)

Verified by the parser's own test suite — these resolve to this type.

value 0..1ConsensusScoreConsensus Score

Weighted vote across children. Use when several signals should agree before firing.

Mandatory Optional Fields

child expression names, optional weights

Lua / C++

getConsensus(exprA, exprB[, ...])

Builder tile

In the operand grid this type appears as Consensus Score (category: technical). The ElementType stored in JSON is ConsensusScore.

Price & Bars

valueOHLC_BarOHLC Bar

Reads one field of a bar: open, high, low, close, volume, body, needles, typical price.

Mandatory Optional Fields

OPEN_PRICE, HIGH_PRICE, LOW_PRICE, CLOSE_PRICE, VOLUME, BODY_LEN, DIRECTION

Lua / C++

getOhlc(field, frame[, source])

JSON example

Getter example

{
  "ExpressionName": "OHLC_CLOSE_PRICE_5m",
  "Expression_left_ElementType": "OHLC_Bar",
  "Expression_left_ElementValue": "CLOSE_PRICE",
  "Expression_left_Frame": "5Min"
}

Comparison example

{
  "ExpressionName": "OHLC_CLOSE_GT_100_5m",
  "Expression_left_ElementType": "OHLC_Bar",
  "Expression_left_ElementValue": "CLOSE_PRICE",
  "Expression_left_Frame": "5Min",
  "Expression_left_operation": ">",
  "Expression_right_ElementType": "FixedVal",
  "Expression_right_ElementValue": "100"
}
Builder tile

In the operand grid this type appears as OHLC Bar (category: price). The ElementType stored in JSON is OHLC_Bar.

Quick Create (confirmed)

Verified by the parser's own test suite — these resolve to this type.

valueQuotesQuotes

Live quote snapshot — bid, ask, mid, spread in ticks. No timeframe: quotes are current by definition.

Mandatory Fields

Bid, Ask, MidPrice, SpreadInTicks, TicksInPoint

Lua / C++

getQuote(field)

JSON example

Getter example

{
  "ExpressionName": "QUOTE_BID",
  "Expression_left_ElementType": "Quotes",
  "Expression_left_ElementValue": "Bid"
}

Comparison example

{
  "ExpressionName": "SPREAD_LT_3",
  "Expression_left_ElementType": "Quotes",
  "Expression_left_ElementValue": "SpreadInTicks",
  "Expression_left_operation": "<",
  "Expression_right_ElementType": "FixedVal",
  "Expression_right_ElementValue": "3"
}
Builder tile

In the operand grid this type appears as Quotes (category: price). The ElementType stored in JSON is Quotes.

Quick Create (confirmed)

Verified by the parser's own test suite — these resolve to this type.

value or eventRenkoBarRenko Bar

Bricks built from price movement only, ignoring time. Filters time-based noise.

Mandatory Optional Fields

ON_BAR_CREATION, DIRECTION, CLOSE_PRICE, CURRENT_SPEED

Lua / C++

getRenko(field, frame, boxSize)

Watch out. Bricks form on price movement only, ignoring time. ON_BAR_CREATION is an event — true at detection only.
JSON example

Getter example

{
  "ExpressionName": "RENKO_CLOSE_5m_B10",
  "Expression_left_ElementType": "RenkoBar",
  "Expression_left_ElementValue": "CLOSE_PRICE",
  "Expression_left_FieldName": "CLOSE_PRICE",
  "Expression_left_Frame": "5Min",
  "Expression_left_boxsize": 10
}

Event example

{
  "ExpressionName": "RENKO_CREATED_5m_B10",
  "Expression_left_ElementType": "RenkoBar",
  "Expression_left_ElementValue": "ON_BAR_CREATION",
  "Expression_left_FieldName": "ON_BAR_CREATION",
  "Expression_left_Frame": "5Min",
  "Expression_left_boxsize": 10,
  "Expression_left_operation": ">",
  "Expression_right_ElementType": "FixedVal",
  "Expression_right_ElementValue": "0"
}
Builder tile

In the operand grid this type appears as Renko Bar (category: price). The ElementType stored in JSON is RenkoBar.

valueHeikinAshiBarHeikin Ashi

Smoothed candles — same fields as OHLC but averaged, so trend direction reads cleaner.

Mandatory Fields

OPEN_PRICE, HIGH_PRICE, LOW_PRICE, CLOSE_PRICE, DIRECTION

Lua / C++

getAshi(field, frame)

JSON example

Getter example

{
  "ExpressionName": "HA_OPEN_PRICE_5m",
  "Expression_left_ElementType": "HeikinAshiBar",
  "Expression_left_ElementValue": "OPEN_PRICE",
  "Expression_left_Frame": "5Min"
}

Comparison example

{
  "ExpressionName": "HA_CLOSE_GT_100_5m",
  "Expression_left_ElementType": "HeikinAshiBar",
  "Expression_left_ElementValue": "CLOSE_PRICE",
  "Expression_left_Frame": "5Min",
  "Expression_left_operation": ">",
  "Expression_right_ElementType": "FixedVal",
  "Expression_right_ElementValue": "100"
}
Builder tile

In the operand grid this type appears as Heikin Ashi (category: price). The ElementType stored in JSON is HeikinAshiBar.

Quick Create (confirmed)

Verified by the parser's own test suite — these resolve to this type.

value or eventTickRevBarTick/Rev Bar

Bars that close on a tick reversal instead of a clock. Carries AB/BC leg lengths and ticks-per-minute.

Mandatory Fields

TickRevEvent, Direction, Close Price, Length AB

Lua / C++

getTickRev(field, tickRevVal, direction)

Watch out. Bars close on tick reversal, not the clock. Ticks Per Min AB/BC are ticks per MINUTE. TickRevEvent is an event — true at detection only.
JSON example

Getter example

{
  "ExpressionName": "TICKREV_TPM_AB_TR10_BID",
  "Expression_left_ElementType": "TickRevBar",
  "Expression_left_ElementValue": "Ticks Per Min AB",
  "Expression_left_TickRevVal": 10,
  "Expression_left_TickRevDirection": "BID"
}

Event example

{
  "ExpressionName": "TICKREV_EVENT_TR10_BID",
  "Expression_left_ElementType": "TickRevBar",
  "Expression_left_ElementValue": "TickRevEvent",
  "Expression_left_TickRevVal": 10,
  "Expression_left_TickRevDirection": "BID",
  "Expression_left_operation": ">",
  "Expression_right_ElementType": "FixedVal",
  "Expression_right_ElementValue": "0"
}
Builder tile

In the operand grid this type appears as Tick/Rev Bar (category: price). The ElementType stored in JSON is TickRevBar.

Quick Create (confirmed)

Verified by the parser's own test suite — these resolve to this type.

Patterns

value or eventABCPatternABC Pattern

Three-leg wave structure. Pick the wave (AB, BC, CD…) then the field — distance, direction, duration, ratio.

Mandatory Optional Fields

Direction, Distance, Start Price, End Price, Start Date, End Date, Duration Minutes, Ticks Per Minute

Lua / C++

getABC(field, wave, tickRevVal, numElements)

Watch out. Pick the WAVE (AB/BC/CD…) first, then the field. Speed here is ticks per MINUTE — not per second like Price Move, not per hour like Trend.
JSON example

Getter example

{
  "ExpressionName": "ABC_AB_DISTANCE_TR10",
  "Expression_left_ElementType": "ABCPattern",
  "Expression_left_ElementValue": "Distance",
  "Expression_left_WaveName": "AB",
  "Expression_left_NumElements": 5,
  "Expression_left_TickRevVal": 10
}

Comparison example

{
  "ExpressionName": "ABC_AB_DISTANCE_GT_20_TR10",
  "Expression_left_ElementType": "ABCPattern",
  "Expression_left_ElementValue": "Distance",
  "Expression_left_WaveName": "AB",
  "Expression_left_NumElements": 5,
  "Expression_left_TickRevVal": 10,
  "Expression_left_operation": ">",
  "Expression_right_ElementType": "FixedVal",
  "Expression_right_ElementValue": "20"
}
Builder tile

In the operand grid this type appears as ABC Pattern (category: pattern). The ElementType stored in JSON is ABCPattern.

Quick Create (confirmed)

Verified by the parser's own test suite — these resolve to this type.

eventPricePatternPrice Pattern

Chart-structure recognition: double top/bottom, head & shoulders, wedges, 40+ patterns. Only OnFormationDone is supported — Strength is rejected.

Mandatory Optional Fields

BullFlag, DoubleBottom, HeadAndShoulders

Lua / C++

getPricePattern(name, tickRevVal, frame[, leg])

Watch out. Only the OnFormationDone event is supported — Strength is rejected by the engine. Event: true on detection, false otherwise; compare > 0.
JSON example

Event example

{
  "ExpressionName": "BULLFLAG_DONE_TR10",
  "Expression_left_ElementType": "PricePattern",
  "Expression_left_ElementValue": "BullFlag",
  "Expression_left_FieldName": "OnFormationDone",
  "Expression_left_TickRevVal": 10,
  "Expression_left_operation": ">",
  "Expression_right_ElementType": "FixedVal",
  "Expression_right_ElementValue": "0"
}
Builder tile

In the operand grid this type appears as Price Pattern (category: pattern). The ElementType stored in JSON is PricePattern.

Quick Create (confirmed)

Verified by the parser's own test suite — these resolve to this type.

value or eventTrendObjectTrend

Trend state from a fast/slow pair: side, length in ticks, duration, speed in ticks per HOUR, start/min/max.

Mandatory Optional Fields

FastPrice, SlowPrice, TrendSide, TrendStartPrice, Trend Duration Minutes, Trend Len Ticks, Trend Len Ema Slow ticks, Trend Len Ema Fast ticks, TrendSpeedPerHour, TotalUpVolume, TotalDownVolume, TotalUpTicks, TotalDownTicks, OnTrendStart, OnTrendDone, OnMinMaxReached, MinMaxPrice, MinMaxDate

Lua / C++

getTrend(field, frame, fastSize, slowSize)

Watch out. Speed is ticks per HOUR. TrendSide is 1=Up, -1=Down, 0=None. OnTrendStart/OnTrendDone/OnMinMaxReached are events (true at detection only).
JSON example

Getter example

{
  "ExpressionName": "TREND_SIDE_5m_9_21",
  "Expression_left_ElementType": "TrendObject",
  "Expression_left_ElementValue": "TrendSide",
  "Expression_left_FieldName": "TrendSide",
  "Expression_left_Period": "5Min",
  "Expression_left_FastSize": 9,
  "Expression_left_SlowSize": 21
}

Event example

{
  "ExpressionName": "TREND_START_5m_9_21",
  "Expression_left_ElementType": "TrendObject",
  "Expression_left_ElementValue": "OnTrendStart",
  "Expression_left_FieldName": "OnTrendStart",
  "Expression_left_Period": "5Min",
  "Expression_left_FastSize": 9,
  "Expression_left_SlowSize": 21,
  "Expression_left_operation": ">",
  "Expression_right_ElementType": "FixedVal",
  "Expression_right_ElementValue": "0"
}
Builder tile

In the operand grid this type appears as Trend (category: pattern). The ElementType stored in JSON is TrendObject.

Quick Create (confirmed)

Verified by the parser's own test suite — these resolve to this type.

value or eventChannelObjectChannel

Detects a price channel and exposes upper/lower bound, width, leg and the done event.

Mandatory Optional Fields

UpperChannel, LowerChannel, CurrentLeg, EventOnChannelDone

Lua / C++

getChannel(field, frame, minWidth, doneTicks)

Watch out. Done-ticks is what closes the channel — set it or nothing fires. EventOnChannelDone is an event: true at detection, false otherwise.
JSON example

Getter example

{
  "ExpressionName": "CHANNEL_UPPER_5m",
  "Expression_left_ElementType": "ChannelObject",
  "Expression_left_ElementValue": "UpperChannel",
  "Expression_left_MinChannelWidth": 20,
  "Expression_left_ChannelDoneTicks": 10
}

Event example

{
  "ExpressionName": "CHANNEL_DONE_5m",
  "Expression_left_ElementType": "ChannelObject",
  "Expression_left_ElementValue": "EventOnChannelDone",
  "Expression_left_MinChannelWidth": 20,
  "Expression_left_ChannelDoneTicks": 10,
  "Expression_left_operation": ">",
  "Expression_right_ElementType": "FixedVal",
  "Expression_right_ElementValue": "0"
}
Builder tile

In the operand grid this type appears as Channel (category: pattern). The ElementType stored in JSON is ChannelObject.

Quick Create (confirmed)

Verified by the parser's own test suite — these resolve to this type.

value or eventFibonnaciBarFibonacci

Fibonacci retracement ratios off tick-reversal legs. Fires on the ratio event.

Mandatory Fields

TickRevRatioEvent, Current Ratio, Direction, Length AB, Length BC, Ticks Per Min AB/BC

Lua / C++

getFibo(field, tickRevRatio, minLenAB)

Watch out. Needs BOTH the tick-reversal ratio and the minimum AB leg length. TickRevRatioEvent is an event — true at detection only.
JSON example

Getter example

{
  "ExpressionName": "FIBO_DIRECTION_TR10",
  "Expression_left_ElementType": "FibonnaciBar",
  "Expression_left_ElementValue": "Direction",
  "Expression_left_TickRevRatio": 2,
  "Expression_left_TickRevMinLenAB": 10
}

Event example

{
  "ExpressionName": "FIBO_RATIO_EVENT_TR10",
  "Expression_left_ElementType": "FibonnaciBar",
  "Expression_left_ElementValue": "TickRevRatioEvent",
  "Expression_left_TickRevRatio": 2,
  "Expression_left_TickRevMinLenAB": 10,
  "Expression_left_operation": ">",
  "Expression_right_ElementType": "FixedVal",
  "Expression_right_ElementValue": "0"
}
Builder tile

In the operand grid this type appears as Fibonacci (category: pattern). The ElementType stored in JSON is FibonnaciBar.

valuePivotObjectPivot Points

Classic pivots — pivot point plus support 1-3 and resistance 1-3 for the monitored frame.

Mandatory Fields

Pivot Point, Support 1-3, Resistance 1-3

Lua / C++

getPivot(field, monitoredFrame)

Watch out. Pure values, no events. Pivot levels recompute per monitored frame; compare price against them.
JSON example

Getter example

{
  "ExpressionName": "PIVOT_POINT_DAILY",
  "Expression_left_ElementType": "PivotObject",
  "Expression_left_ElementValue": "Pivot Point",
  "Expression_left_MonitoredFrame": "Daily"
}

Comparison example

{
  "ExpressionName": "PIVOT_SUPPORT1_GT_100_DAILY",
  "Expression_left_ElementType": "PivotObject",
  "Expression_left_ElementValue": "Support 1",
  "Expression_left_MonitoredFrame": "Daily",
  "Expression_left_operation": ">",
  "Expression_right_ElementType": "FixedVal",
  "Expression_right_ElementValue": "100"
}
Builder tile

In the operand grid this type appears as Pivot Points (category: pattern). The ElementType stored in JSON is PivotObject.

Quick Create (confirmed)

Verified by the parser's own test suite — these resolve to this type.

value or eventPriceMoveObjectPrice Move

A directional move measured from where it started: width in ticks, speed in ticks per SECOND, duration. The threshold and time limit are parameters, not comparisons — this operand is unary. Here "100 ticks" means price travelled 100 ticks; for a count of quote updates see TicksPerPeriod.

Mandatory Optional Fields

onPriceMove, Direction, getCurrentWidth, getCurrentSpeed, getCurrentDuration

Lua / C++

getMove(field, frame)

Detecting a move in EITHER direction

A price move is directional — one expression detects one direction. For "moved 100 ticks either way" the normal solution is three expressions:

#ExpressionDirection
1PM_UP_100_IN_120SUp
2PM_DOWN_100_IN_120SDown
3PM_EITHER_100_IN_120S = UserExpression #1 OR UserExpression #2either

Both share the same source getter, so the total is one getter plus three. There is no "both directions" setting — PriceMoveDirection takes Up or Down only.

Anchored move — NOT a rolling window
Read this before promising "100 ticks in any 2-minute window". This operand measures from an armed base, not over a sliding window. The base is set at the first quote and does not reset when 120 seconds elapse — it only re-arms once the width is reached (pass or fail). Worked failure: base 1000. Price drifts to 1050 over ten minutes, then jumps 1050→1150 in one minute. The detector is still measuring from 1000, hits its 100-tick width at 1100, records it as too slow, and re-bases at 1100 — so it sees only the remaining 50 ticks of the fast leg and never reports the 100-tick move the user meant. If you need "highest minus lowest over the last 120 seconds", that is a rolling-range calculation and this operand does not do it. Use the anchored form when you want "a directional move of N ticks completed within T seconds of starting".
Choosing the source expression

Which source to pick — the resolution of the move is the resolution of the source.

Source getterUpdatesUse when
QuotesMidPriceEvery quote (no timeframe — Quotes is not frame-required)Recommended for short windows. Neutral between bid and ask, so it does not jump with spread.
QuotesBid or AskEvery quoteYou are modelling one side of the book specifically.
OHLC_BarCLOSE_PRICE, 1MinOnce per minuteBar-granularity logic. Marginal for a 120s window.
OHLC_Bar → CLOSE_PRICE, 5MinOnce per 5 minWrong for a 2-minute rule — it may yield no new sample inside the window at all.
Why a source is needed at all: the operand measures how far some value has travelled. It does not assume "price" — that value is whatever getter you name, which is why the same operand works on an indicator or any other series. It also means a coarse source silently blinds a short move.

The picker accepts any saved expression, so the choice is yours — and it decides what the move can detect. The move only sees what the source samples. A source built on a closed 5Min bar close produces one new value every five minutes, so a "100 ticks within 120 seconds" rule cannot resolve — inside that window it may get no new sample at all. Use the finest source that matches the window: a 1Min OHLC close for minute-scale moves (the bundled PM_SRC_OHLC_CLOSE_1MIN_V1 is labelled "higher resolution than 5Min — more accurate for fast markets"), or a quote-based source (Quotes Bid / Ask / MidPrice) for genuine tick resolution. Every source that ships bundled is bar- or indicator-based (OHLC_Bar CLOSE_PRICE, ATR, RSI, EMA); a quote-based source is permitted by the picker but has no bundled example — verify it live before relying on it.

You can start one from Quick Create after all. The full phrase price moves 100 ticks up within 120 sec parses and prefills width, direction and time limit. Only the source expression cannot be inferred from text, so the builder asks for it before Save. The field aliases alone (move_size > 50) do not work — they leave the mandatory settings unset.
What it is, in one line

Price move consumes another expression and measures how far that value has moved from its base — optionally requiring the move to complete within a seconds limit. That is the whole operand.

Event field vs value fields — they behave differently
FieldBehaviour
onPriceMove (the event)True on the bar the move completes, false otherwise. The flag is cleared when the next bar arrives, so you read it on the bar it fires. Compare with > 0.
getCurrentWidth, getCurrentSpeed, getCurrentDuration, VolumeLive and continuous — they always report the move in progress relative to the current base. They are not zero when idle and not a stale copy of the last completed move.
So you do not need an extra leg to gate the value fields. getCurrentWidth is the running distance from the current base, updated every quote. It is signed by the configured direction: positive as price moves the way you asked, negative while it moves against. It returns 0 only when there is no source operand at all.
This is the general rule for every event-detecting operand in GTS — candle patterns, price patterns, channel-done, tick-reversal, ABC, Fibonacci, price move. The event is true at the moment it is detected and false at every other time. That is what "event" means here: you are testing "did it just happen", not "is it still true". Compare event fields with > 0.
How the engine detects a move

Verified against the engine (PriceMoveBoolOperand / PriceMoveDetector):

QuestionAnswer
"100 ticks from where?"From the base price — the source value at the moment the detector last armed. That is either the first quote after the expression starts, or the price at which the previous detection completed. There is no reversal threshold and no timeout re-base; the base only moves when a detection completes.
Duration unitsSeconds, always. getCurrentDuration is (quote time − start time) in whole seconds, and Max Seconds is the same unit. getCurrentSpeed is therefore ticks per second.
Is it bar-driven?No — it is quote-driven. The detector runs on every quote. The mandatory timeframe governs the source expression (how often the source yields a new value), not the move logic. A frame is neither ignored nor an error: it sets the source's sampling rate, which is why a coarse frame blinds a short move.
Fires once or repeatedly?Once per completed move, then it re-arms. When the width is met in the correct direction the operand reports the result and immediately re-bases to the current price with a fresh start time. It does not keep firing on every later quote while price runs on.
Width met, wrong direction?No detection and no reset — it keeps tracking from the same base.
Width met but too slow?The detection completes as a failure (result false) and still re-bases. A move that crawls past the threshold consumes the base and starts a new window.
The time limit is strict. Success requires duration < Max Seconds, not . With Max Seconds = 120, a move taking exactly 120 seconds does not qualify.
Tick size is handled for you. The engine divides the raw price distance by the instrument's tick size to get ticks. You never convert anything — this is what makes the expression symbol-agnostic.
Watch out. UNARY: it consumes another expression and measures how far THAT value moved from its base. Width/time are PARAMETERS, not comparisons. Speed is ticks per SECOND. onPriceMove is true only on the bar the move completes; the value fields are live and continuous, and width is signed (negative against your direction). Time limit is strict: duration < Max Seconds.
Builder tile

In the operand grid this type appears as Price Move (category: pattern). The ElementType stored in JSON is PriceMoveObject.

Quick Create (confirmed)

Verified by the parser's own test suite — these resolve to this type.

Fundamentals

valueFundamentalFundamental

EDGAR financials — revenue, EPS, cash flow, ratios. Stock symbols only; other families take the engine down.

Mandatory Optional Fields

revenue, netIncome, epsBasic, operatingCashflow

Lua / C++

getFund(field, periodMode[, offset])

JSON example

Getter example

{
  "ExpressionName": "FUND_TRAILING_PE",
  "Expression_left_ElementType": "Fundamental",
  "Expression_left_ElementValue": "trailingPE",
  "Expression_left_FieldName": "trailingPE"
}

Comparison example

{
  "ExpressionName": "FUND_TRAILING_PE_LT15",
  "Expression_left_ElementType": "Fundamental",
  "Expression_left_ElementValue": "trailingPE",
  "Expression_left_FieldName": "trailingPE",
  "Expression_left_operation": "<",
  "Expression_right_ElementType": "FixedVal",
  "Expression_right_ElementValue": "15"
}
Builder tile

In the operand grid this type appears as Fundamental (category: fundamental). The ElementType stored in JSON is Fundamental.

Account & Positions

valueClosePositionObjectClosed Position

Last closed position — realized profit, open/close price, duration, side, filled units.

Mandatory Fields

CurrentProfitTicks, ClosePrice, Units, Duration

Lua / C++

getClosedPos(field)

JSON example

Getter example

{
  "ExpressionName": "LAST_CLOSED_PROFIT",
  "Expression_left_ElementType": "ClosePositionObject",
  "Expression_left_ElementValue": "Profit"
}

Comparison example

{
  "ExpressionName": "LAST_CLOSED_PROFIT_LT0",
  "Expression_left_ElementType": "ClosePositionObject",
  "Expression_left_ElementValue": "Profit",
  "Expression_left_operation": "<",
  "Expression_right_ElementType": "FixedVal",
  "Expression_right_ElementValue": "0"
}
Builder tile

In the operand grid this type appears as Closed Position (category: trading). The ElementType stored in JSON is ClosePositionObject.

Quick Create (confirmed)

Verified by the parser's own test suite — these resolve to this type.

valueStrategyOpenPositionsOpen Positions

Aggregate across all open positions — total units, count, combined open profit.

Mandatory Optional Fields

TotalUnits, Count, CurrentProfitTicks, CurrentProfit

Lua / C++

getOpenPos(field[, side])

JSON example

Getter example

{
  "ExpressionName": "OPEN_BID_POSITIONS",
  "Expression_left_ElementType": "StrategyOpenPositions",
  "Expression_left_ElementValue": "TotalPositions",
  "Expression_left_OpenPositionsSide": "BID"
}

Comparison example

{
  "ExpressionName": "OPEN_BID_POSITIONS_GT0",
  "Expression_left_ElementType": "StrategyOpenPositions",
  "Expression_left_ElementValue": "TotalPositions",
  "Expression_left_OpenPositionsSide": "BID",
  "Expression_left_operation": ">",
  "Expression_right_ElementType": "FixedVal",
  "Expression_right_ElementValue": "0"
}
Builder tile

In the operand grid this type appears as Open Positions (category: trading). The ElementType stored in JSON is StrategyOpenPositions.

Quick Create (confirmed)

Verified by the parser's own test suite — these resolve to this type.

valueLastOpenPositionObjectLast Open Position

The most recent open position — open price, units, current profit in ticks or percent, duration.

Mandatory Fields

OpenPrice, StartTime, Units, CurrentProfitTicks, CurrentProfitPercent, OpenPNL, CurrentDurationMinutes, PositionSide, ExchangePositionId

CurrentProfitTicks / CurrentProfitPercent are the unrealised profit, positive when the position is winning for both BID and ASK. Percent is diff / open price × 100 (so 0.2 means 0.2%), which keeps one stop/target rule meaning the same thing on every symbol — ticks do not, since 10 ticks is 0.088% on EURUSD and 0.067% on USDJPY.

Lua / C++

getLastPos(field)

JSON example

Getter example

{
  "ExpressionName": "LAST_OPEN_PNL",
  "Expression_left_ElementType": "LastOpenPositionObject",
  "Expression_left_ElementValue": "OpenPNL"
}

Comparison example

{
  "ExpressionName": "LAST_OPEN_PNL_GT0",
  "Expression_left_ElementType": "LastOpenPositionObject",
  "Expression_left_ElementValue": "OpenPNL",
  "Expression_left_operation": ">",
  "Expression_right_ElementType": "FixedVal",
  "Expression_right_ElementValue": "0"
}
Builder tile

In the operand grid this type appears as Last Open Position (category: trading). The ElementType stored in JSON is LastOpenPositionObject.

Quick Create (confirmed)

Verified by the parser's own test suite — these resolve to this type.

valueAccountObjectAccount

Account snapshot: balance, equity, margin, open and closed PNL, wins/losses, drawdown.

Mandatory Optional Fields

Balance, OpenPNL, ClosedPNL, UsedMargin, AvailableMargin, contexts: Account/Symbol/Strategy

Lua / C++

getAccount(field[, context])

JSON example

Getter example

{
  "ExpressionName": "ACCOUNT_OPEN_PNL",
  "Expression_left_ElementType": "AccountObject",
  "Expression_left_ElementValue": "OpenPNL"
}

Comparison example

{
  "ExpressionName": "ACCOUNT_OPEN_PNL_LT_MINUS500",
  "Expression_left_ElementType": "AccountObject",
  "Expression_left_ElementValue": "OpenPNL",
  "Expression_left_operation": "<",
  "Expression_right_ElementType": "FixedVal",
  "Expression_right_ElementValue": "-500"
}
Builder tile

In the operand grid this type appears as Account (category: trading). The ElementType stored in JSON is AccountObject.

Quick Create (confirmed)

Verified by the parser's own test suite — these resolve to this type.

valueAccFrameObjectAccount Frame

The same account metrics but scoped to a period — per hour, per day, etc.

Mandatory Optional Fields

Balance, ClosedPNL, OpenPNL, MaxDrawdown, Wins/Losses, contexts: Account/Symbol/Strategy

Lua / C++

getAccFrame(field, frame[, context])

JSON example

Getter example

{
  "ExpressionName": "ACCFRAME_CLOSEDPNL_1h",
  "Expression_left_ElementType": "AccFrameObject",
  "Expression_left_ElementValue": "ClosedPNL",
  "Expression_left_Frame": "1Hour",
  "Expression_left_ContextType": "Account"
}

Comparison example

{
  "ExpressionName": "ACCFRAME_DRAWDOWN_GT_100_1h",
  "Expression_left_ElementType": "AccFrameObject",
  "Expression_left_ElementValue": "MaxDrawdown",
  "Expression_left_Frame": "1Hour",
  "Expression_left_ContextType": "Account",
  "Expression_left_operation": ">",
  "Expression_right_ElementType": "FixedVal",
  "Expression_right_ElementValue": "100"
}
Builder tile

In the operand grid this type appears as Account Frame (category: trading). The ElementType stored in JSON is AccFrameObject.

Quick Create (confirmed)

Verified by the parser's own test suite — these resolve to this type.

Utility & Composition

valueFixedValFixed Value

A constant. The 30 in "RSI(14) < 30". Almost always the right-hand side.

Mandatory JSON example

Right-side example

{
  "ExpressionName": "CLOSE_GT_100_5m",
  "Expression_left_ElementType": "OHLC_Bar",
  "Expression_left_ElementValue": "CLOSE_PRICE",
  "Expression_left_Frame": "5Min",
  "Expression_left_operation": ">",
  "Expression_right_ElementType": "FixedVal",
  "Expression_right_ElementValue": "100"
}
Builder tile

In the operand grid this type appears as Fixed Value (category: utility). The ElementType stored in JSON is FixedVal.

Quick Create (confirmed)

Verified by the parser's own test suite — these resolve to this type.

valueDateValueDate Value

A fixed calendar date for date comparisons.

Mandatory JSON example

Right-side example

{
  "ExpressionName": "BAR_END_AFTER_DATE",
  "Expression_left_ElementType": "OHLC_Bar",
  "Expression_left_ElementValue": "END_DATE",
  "Expression_left_Frame": "Daily",
  "Expression_left_operation": ">",
  "Expression_right_ElementType": "DateValue",
  "Expression_right_ElementValue": "2026-01-01"
}
Builder tile

In the operand grid this type appears as Date Value (category: utility). The ElementType stored in JSON is DateValue.

Quick Create (confirmed)

Verified by the parser's own test suite — these resolve to this type.

valueHourValueHour Value

Session filter — restrict firing to a window of the trading day.

Mandatory JSON example

Right-side example

{
  "ExpressionName": "BAR_HOUR_AFTER_9",
  "Expression_left_ElementType": "OHLC_Bar",
  "Expression_left_ElementValue": "END_DATE",
  "Expression_left_Frame": "1Hour",
  "Expression_left_operation": ">",
  "Expression_right_ElementType": "HourValue",
  "Expression_right_ElementValue": "9"
}
Builder tile

In the operand grid this type appears as Hour Value (category: utility). The ElementType stored in JSON is HourValue.

Quick Create (confirmed)

Verified by the parser's own test suite — these resolve to this type.

valueSideValueDirection

A trade direction constant for directional filtering.

Mandatory JSON example

Right-side example

{
  "ExpressionName": "LAST_POSITION_SIDE_BID",
  "Expression_left_ElementType": "LastOpenPositionObject",
  "Expression_left_ElementValue": "PositionSide",
  "Expression_left_operation": "==",
  "Expression_right_ElementType": "SideValue",
  "Expression_right_ElementValue": "Bid"
}
Builder tile

In the operand grid this type appears as Direction (category: utility). The ElementType stored in JSON is SideValue.

Quick Create (confirmed)

Verified by the parser's own test suite — these resolve to this type.

valueSymbolSymbol

Instrument reference data — ticks in point, margin, min unit size, contract specs.

Mandatory Builder tile

In the operand grid this type appears as Symbol (category: utility). The ElementType stored in JSON is Symbol.

Quick Create (confirmed)

Verified by the parser's own test suite — these resolve to this type.

value (a count)TicksPerPeriodQuote Updates

Counts quote updates (messages) received in the period — market activity and liquidity. It never measures price. Here "100 ticks" means 100 updates arrived; if you mean price travelled 100 ticks, that is PriceMoveObject, a different operand. Cannot be built in Quick Create.

MandatoryHow to build it

One binary expression: TicksPerPeriod (Period = 2Min) > FixedVal 100. No second expression, no combining. See the builder steps.

Fields

1Min, 5Min, 30Min, 1Hour

Lua / C++

getTicks(frame)

Watch out. Counts QUOTE UPDATES, never price. Its Period IS the timeframe — the builder hides the normal timeframe selector. One binary expression does it: TicksPerPeriod(2Min) > 100.
Builder tile

In the operand grid this type appears as Ticks/Period (category: utility). The ElementType stored in JSON is TicksPerPeriod.

whatever the child returnsUserExpressionUser Expression

References another saved expression by name. This is how getters compose into conditions — the backbone of bottom-up building.

Mandatory JSON example

Combiner example

{
  "ExpressionName": "A_AND_B",
  "Expression_left_ElementType": "UserExpression",
  "Expression_left_ElementValue": "A",
  "Expression_left_operation": "AND",
  "Expression_right_ElementType": "UserExpression",
  "Expression_right_ElementValue": "B"
}

Price-move wrapper example

{
  "ExpressionName": "pm_HA_CLOSE_PRICE_5m_10t_UP_10s",
  "Expression_left_ElementType": "UserExpression",
  "Expression_left_ElementValue": "HA_CLOSE_PRICE_5m",
  "Expression_left_FieldName": "onPriceMove",
  "Expression_left_PriceMoveValue": 10,
  "Expression_left_PriceMoveDirection": "Up",
  "Expression_left_TimeLimitSeconds": 10
}
Builder tile

In the operand grid this type appears as User Expression (category: utility). The ElementType stored in JSON is UserExpression.

Quick Create (confirmed)

Verified by the parser's own test suite — these resolve to this type.

eventStateMachineExpressionSeq State Exp

Ordered sequence — step 1 fires, then step 2, then the machine reports complete.

Mandatory Fields

IsComplete, CurrentStep, StepScore

Lua / C++

getStateMachine(field, exprA, exprB[, ...])

JSON example

Event example

{
  "ExpressionName": "SEQ_A_B_DONE",
  "Expression_left_ElementType": "StateMachineExpression",
  "Expression_left_ElementValue": "SEQ_A_B_DONE",
  "Expression_left_Steps": [
    "A",
    "B"
  ],
  "Expression_left_Getter": "ISCOMPLETE",
  "Expression_left_operation": ">",
  "Expression_right_ElementType": "FixedVal",
  "Expression_right_ElementValue": "0"
}
Builder tile

In the operand grid this type appears as Seq State Exp (category: utility). The ElementType stored in JSON is StateMachineExpression.

valueExpressionMetaExpression Meta

Metadata about a saved expression — fire count, fire rate, time since last fire, consecutive true bars.

Mandatory Optional Builder tile

In the operand grid this type appears as Expression Meta (category: utility). The ElementType stored in JSON is ExpressionMeta.

valueCollectionTransformCollection Op

Builder-only derived collection: compare a value expression against its own last N stored values, build a derived collection, then return one indexed member or one reducer over it.

Mandatory Optional
GTS — Global Trading Station • Expression Types Reference • How-toNLP ReferenceBuilder tile

In the operand grid this type appears as Collection Op (category: utility). The ElementType stored in JSON is CollectionTransform.