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.
PriceMoveObject. Distance, measured in ticks from where the move began.TicksPerPeriod. A message count — activity and liquidity, never price.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.
| Shape | Form | Returns |
|---|---|---|
| Unary | ONE 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 |
| Binary | LEFT OPERATOR RIGHT | Depends entirely on the operator ↓ |
| Operator on a binary | Returns | Meaning |
|---|---|---|
> < == != >= <=, crossed | boolean | A condition. This is what an alert or handler fires on. |
AND OR | boolean | Combines two saved conditions by name. |
- + * / | value | Arithmetic. Still a getter — binary does not mean boolean. |
- + * / 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.| Unary type | What it consumes |
|---|---|
UserExpression | One saved expression, referenced by name — on its own, with no operator |
PriceMoveObject | A mandatory source expression supplying the price series |
ExpressionMeta | A mandatory source expression whose firing history it reports on |
CollectionTransform | A SOURCE expression (plus SOURCE B for binary ops) to build a derived collection |
ConsensusScore | Two or more child expressions it scores agreement across |
StateMachineExpression | Two or more child expressions forming an ordered sequence |
HistValue | One 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.
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.TicksPerPeriod the builder hides the timeframe selector entirely, because its Period setting is the timeframe.This is one expression, not two:
| Step | Setting |
|---|---|
| Left operand | TicksPerPeriod, Period = 2Min |
| Operator | > |
| Right operand | FixedVal = 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.
PriceMoveObject — a different operand, unary, with the threshold as a parameter.| Object-oriented | GTS |
|---|---|
| Class definition | The saved expression — logic only, no symbol |
new Foo(symbol) | The strategy binding a symbol at deploy |
| Constructor arguments | Symbol, timeframe context and instrument reference data |
| Instance field resolved at construction | Symbol.TicksInPoint and friends, resolved per bound instrument |
| One class, many instances | One expression, many symbols — no duplication |
Symbol.TicksInPoint exists: divide by it and even the magnitude becomes instrument-relative.| Mechanic | Who handles it |
|---|---|
| Tick size / point value — turning a raw price distance into a tick count | GTS. The engine divides by the instrument's tick size itself (diff = abs((current − base) / divideFactor)). |
| Exchange and instrument specifics — contract size, min unit, margin | GTS, from the instrument's reference data. |
| Which symbol this run is for | The strategy, dynamically, at deploy time. |
| The logic — what condition should fire | You. That is the whole job. |
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:
| Need | How |
|---|---|
| Branch on instrument type | Symbol → Type |
| Scale a threshold by the instrument's tick size | Symbol → Ticks In Point, used as a value inside a bigger expression |
| Respect sizing or margin limits | Symbol → Min Unit Size, Margin, Buy/Sell Interest |
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."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:
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.| # | Expression | Built from | Returns |
|---|---|---|---|
| 1 | SRC_CLOSE_1H | OHLC close, 1Hour, no operator | value |
| 2 | SRC_SMA200_1H | SMA(200), 1Hour, no operator | value |
| 3 | GAP_PRICE | #1 - #2, ABS applied | value — in price units |
| 4 | GAP_TICKS | #3 / Symbol.TicksInPoint | value — in ticks |
| 5 | GAP_TICKS_GT_50 | #4 > FixedVal 50 | boolean — 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_ABS → EMA_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.
Ticks In Point and scale it in the logic.Runs a named indicator on a timeframe and returns its number. Multi-output indicators (MACD, BBANDS) need the output field picked.
MandatoryABERRATION, 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
getInd(name, frame[, field])
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 tileIn the operand grid this type appears as Indicators (category: technical). The ElementType stored in JSON is GTSIndicators.
Advanced/ML detectors — FVG, Order Block, SMC/ICT, regime. Some return a value, some a signal you compare with > 0.
MandatoryFvgDetector, BreakOfStructure.signal, OrderBlockDetector
getExt(name, frame[, field])
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 tileIn the operand grid this type appears as Extended Indicators (category: technical). The ElementType stored in JSON is ExtendedIndicators.
Verified by the parser's own test suite — these resolve to this type.
InertialRsi(14)inertialrsi(14)AdaptiveCentricMa(200)Fires when the pattern forms. Boolean directional event — compare with > 0, never == 100. A trend is required.
MandatoryENGULFING, HAMMER, DOJI, Bullish, Bearish
getCdl(name, frame, trend)
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 tileIn the operand grid this type appears as Candle Patterns (category: technical). The ElementType stored in JSON is TA_CandlePatterns.
Verified by the parser's own test suite — these resolve to this type.
DOJIdoji bearishbullish engulfingWeighted vote across children. Use when several signals should agree before firing.
Mandatorychild expression names, optional weights
getConsensus(exprA, exprB[, ...])
In the operand grid this type appears as Consensus Score (category: technical). The ElementType stored in JSON is ConsensusScore.
Reads one field of a bar: open, high, low, close, volume, body, needles, typical price.
MandatoryOPEN_PRICE, HIGH_PRICE, LOW_PRICE, CLOSE_PRICE, VOLUME, BODY_LEN, DIRECTION
getOhlc(field, frame[, source])
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 tileIn the operand grid this type appears as OHLC Bar (category: price). The ElementType stored in JSON is OHLC_Bar.
Verified by the parser's own test suite — these resolve to this type.
closeClosehighLive quote snapshot — bid, ask, mid, spread in ticks. No timeframe: quotes are current by definition.
MandatoryBid, Ask, MidPrice, SpreadInTicks, TicksInPoint
getQuote(field)
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 tileIn the operand grid this type appears as Quotes (category: price). The ElementType stored in JSON is Quotes.
Verified by the parser's own test suite — these resolve to this type.
bidaskmidBricks built from price movement only, ignoring time. Filters time-based noise.
MandatoryON_BAR_CREATION, DIRECTION, CLOSE_PRICE, CURRENT_SPEED
getRenko(field, frame, boxSize)
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 tileIn the operand grid this type appears as Renko Bar (category: price). The ElementType stored in JSON is RenkoBar.
Smoothed candles — same fields as OHLC but averaged, so trend direction reads cleaner.
MandatoryOPEN_PRICE, HIGH_PRICE, LOW_PRICE, CLOSE_PRICE, DIRECTION
getAshi(field, frame)
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 tileIn the operand grid this type appears as Heikin Ashi (category: price). The ElementType stored in JSON is HeikinAshiBar.
Verified by the parser's own test suite — these resolve to this type.
ha_closeHeikinAshiBar.HA_Close.5MinHeikinAshiBar.CLOSE_PRICE.5MinsBars that close on a tick reversal instead of a clock. Carries AB/BC leg lengths and ticks-per-minute.
MandatoryTickRevEvent, Direction, Close Price, Length AB
getTickRev(field, tickRevVal, direction)
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 tileIn the operand grid this type appears as Tick/Rev Bar (category: price). The ElementType stored in JSON is TickRevBar.
Verified by the parser's own test suite — these resolve to this type.
ab speedThree-leg wave structure. Pick the wave (AB, BC, CD…) then the field — distance, direction, duration, ratio.
MandatoryDirection, Distance, Start Price, End Price, Start Date, End Date, Duration Minutes, Ticks Per Minute
getABC(field, wave, tickRevVal, numElements)
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 tileIn the operand grid this type appears as ABC Pattern (category: pattern). The ElementType stored in JSON is ABCPattern.
Verified by the parser's own test suite — these resolve to this type.
abc speedChart-structure recognition: double top/bottom, head & shoulders, wedges, 40+ patterns. Only OnFormationDone is supported — Strength is rejected.
MandatoryBullFlag, DoubleBottom, HeadAndShoulders
getPricePattern(name, tickRevVal, frame[, leg])
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 tileIn the operand grid this type appears as Price Pattern (category: pattern). The ElementType stored in JSON is PricePattern.
Verified by the parser's own test suite — these resolve to this type.
DoubleBottomHeadAndShouldersBullFlagTrend state from a fast/slow pair: side, length in ticks, duration, speed in ticks per HOUR, start/min/max.
MandatoryFastPrice, 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
getTrend(field, frame, fastSize, slowSize)
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 tileIn the operand grid this type appears as Trend (category: pattern). The ElementType stored in JSON is TrendObject.
Verified by the parser's own test suite — these resolve to this type.
trendsidetrendspeedperhourtrend speedDetects a price channel and exposes upper/lower bound, width, leg and the done event.
MandatoryUpperChannel, LowerChannel, CurrentLeg, EventOnChannelDone
getChannel(field, frame, minWidth, doneTicks)
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 tileIn the operand grid this type appears as Channel (category: pattern). The ElementType stored in JSON is ChannelObject.
Verified by the parser's own test suite — these resolve to this type.
upperchannelchannellengthFibonacci retracement ratios off tick-reversal legs. Fires on the ratio event.
MandatoryTickRevRatioEvent, Current Ratio, Direction, Length AB, Length BC, Ticks Per Min AB/BC
getFibo(field, tickRevRatio, minLenAB)
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 tileIn the operand grid this type appears as Fibonacci (category: pattern). The ElementType stored in JSON is FibonnaciBar.
Classic pivots — pivot point plus support 1-3 and resistance 1-3 for the monitored frame.
MandatoryPivot Point, Support 1-3, Resistance 1-3
getPivot(field, monitoredFrame)
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 tileIn the operand grid this type appears as Pivot Points (category: pattern). The ElementType stored in JSON is PivotObject.
Verified by the parser's own test suite — these resolve to this type.
pps1r1A 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.
onPriceMove, Direction, getCurrentWidth, getCurrentSpeed, getCurrentDuration
getMove(field, frame)
A price move is directional — one expression detects one direction. For "moved 100 ticks either way" the normal solution is three expressions:
| # | Expression | Direction |
|---|---|---|
| 1 | PM_UP_100_IN_120S | Up |
| 2 | PM_DOWN_100_IN_120S | Down |
| 3 | PM_EITHER_100_IN_120S = UserExpression #1 OR UserExpression #2 | either |
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.
Which source to pick — the resolution of the move is the resolution of the source.
| Source getter | Updates | Use when |
|---|---|---|
Quotes → MidPrice | Every quote (no timeframe — Quotes is not frame-required) | Recommended for short windows. Neutral between bid and ask, so it does not jump with spread. |
Quotes → Bid or Ask | Every quote | You are modelling one side of the book specifically. |
OHLC_Bar → CLOSE_PRICE, 1Min | Once per minute | Bar-granularity logic. Marginal for a 120s window. |
OHLC_Bar → CLOSE_PRICE, 5Min | Once per 5 min | Wrong for a 2-minute rule — it may yield no new sample inside the window at all. |
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.
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.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| Field | Behaviour |
|---|---|
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, Volume | Live 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. |
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.> 0.Verified against the engine (PriceMoveBoolOperand / PriceMoveDetector):
| Question | Answer |
|---|---|
| "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 units | Seconds, 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. |
duration < Max Seconds, not ≤. With Max Seconds = 120, a move taking exactly 120 seconds does not qualify.In the operand grid this type appears as Price Move (category: pattern). The ElementType stored in JSON is PriceMoveObject.
Verified by the parser's own test suite — these resolve to this type.
onpricemoveprice speedprice move speedEDGAR financials — revenue, EPS, cash flow, ratios. Stock symbols only; other families take the engine down.
Mandatoryrevenue, netIncome, epsBasic, operatingCashflow
getFund(field, periodMode[, offset])
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 tileIn the operand grid this type appears as Fundamental (category: fundamental). The ElementType stored in JSON is Fundamental.
Last closed position — realized profit, open/close price, duration, side, filled units.
MandatoryCurrentProfitTicks, ClosePrice, Units, Duration
getClosedPos(field)
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 tileIn the operand grid this type appears as Closed Position (category: trading). The ElementType stored in JSON is ClosePositionObject.
Verified by the parser's own test suite — these resolve to this type.
ClosePositionObject.ProfitAggregate across all open positions — total units, count, combined open profit.
MandatoryTotalUnits, Count, CurrentProfitTicks, CurrentProfit
getOpenPos(field[, side])
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 tileIn the operand grid this type appears as Open Positions (category: trading). The ElementType stored in JSON is StrategyOpenPositions.
Verified by the parser's own test suite — these resolve to this type.
StrategyOpenPositions.OpenPNLpositions_openpnlThe most recent open position — open price, units, current profit in ticks or percent, duration.
MandatoryOpenPrice, 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.
getLastPos(field)
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 tileIn the operand grid this type appears as Last Open Position (category: trading). The ElementType stored in JSON is LastOpenPositionObject.
Verified by the parser's own test suite — these resolve to this type.
LastOpenPositionObject.OpenPNLAccount snapshot: balance, equity, margin, open and closed PNL, wins/losses, drawdown.
MandatoryBalance, OpenPNL, ClosedPNL, UsedMargin, AvailableMargin, contexts: Account/Symbol/Strategy
getAccount(field[, context])
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 tileIn the operand grid this type appears as Account (category: trading). The ElementType stored in JSON is AccountObject.
Verified by the parser's own test suite — these resolve to this type.
balanceopenpnlema(20) of balanceThe same account metrics but scoped to a period — per hour, per day, etc.
MandatoryBalance, ClosedPNL, OpenPNL, MaxDrawdown, Wins/Losses, contexts: Account/Symbol/Strategy
getAccFrame(field, frame[, context])
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 tileIn the operand grid this type appears as Account Frame (category: trading). The ElementType stored in JSON is AccFrameObject.
Verified by the parser's own test suite — these resolve to this type.
AccFrameObject.Balance.DailyA constant. The 30 in "RSI(14) < 30". Almost always the right-hand side.
MandatoryRight-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 tileIn the operand grid this type appears as Fixed Value (category: utility). The ElementType stored in JSON is FixedVal.
Verified by the parser's own test suite — these resolve to this type.
300.5-10A fixed calendar date for date comparisons.
MandatoryRight-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 tileIn the operand grid this type appears as Date Value (category: utility). The ElementType stored in JSON is DateValue.
Verified by the parser's own test suite — these resolve to this type.
datetimeSession filter — restrict firing to a window of the trading day.
MandatoryRight-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 tileIn the operand grid this type appears as Hour Value (category: utility). The ElementType stored in JSON is HourValue.
Verified by the parser's own test suite — these resolve to this type.
14:0009:0024:00A trade direction constant for directional filtering.
MandatoryRight-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 tileIn the operand grid this type appears as Direction (category: utility). The ElementType stored in JSON is SideValue.
Verified by the parser's own test suite — these resolve to this type.
SideValue.BIDSideValue.ASKInstrument reference data — ticks in point, margin, min unit size, contract specs.
MandatoryIn the operand grid this type appears as Symbol (category: utility). The ElementType stored in JSON is Symbol.
Verified by the parser's own test suite — these resolve to this type.
Symbol.TicksInPointCounts 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.
One binary expression: TicksPerPeriod (Period = 2Min) > FixedVal 100. No second expression, no combining. See the builder steps.
1Min, 5Min, 30Min, 1Hour
getTicks(frame)
In the operand grid this type appears as Ticks/Period (category: utility). The ElementType stored in JSON is TicksPerPeriod.
References another saved expression by name. This is how getters compose into conditions — the backbone of bottom-up building.
MandatoryCombiner 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 tileIn the operand grid this type appears as User Expression (category: utility). The ElementType stored in JSON is UserExpression.
Verified by the parser's own test suite — these resolve to this type.
UserExpression.RSI_Below_30UserExpression(Balance_GT_100)exp.My_SignalOrdered sequence — step 1 fires, then step 2, then the machine reports complete.
MandatoryIsComplete, CurrentStep, StepScore
getStateMachine(field, exprA, exprB[, ...])
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 tileIn the operand grid this type appears as Seq State Exp (category: utility). The ElementType stored in JSON is StateMachineExpression.
Metadata about a saved expression — fire count, fire rate, time since last fire, consecutive true bars.
MandatoryIn the operand grid this type appears as Expression Meta (category: utility). The ElementType stored in JSON is ExpressionMeta.
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- + * /In the operand grid this type appears as Collection Op (category: utility). The ElementType stored in JSON is CollectionTransform.