Dashboard Create Strategy Function Reference

Function & Operator Reference

Based on "101 Formulaic Alphas" (Kakushadze, 2015) — all functions, operators, and expression patterns

1 The Four Layers of an Alpha Expression
Every valid expression in ftInvstr is built as a nested composition of four layers, from the outside in. Each layer has a specific responsibility.
1 order / markov_order Outermost — converts scores to buy/sell decisions. Always the last wrapper.
↑ wraps
2 normalize Scales scores to [0, 1] so thresholds are meaningful. Almost always required before order().
↑ wraps
3 rank / inverted_correlation / markov / operators Computes a raw score per stock using market data. Cross-sectional outputs like rank() produce one value per stock for today, while rank_history() preserves daily cross-sectional rank history so time-series operators can work on it.
↑ consumes
4 'Close' / 'Volume' / 'Net Profit +' / … Innermost — raw market data variables. Always quoted strings.
Why normalize before order? The order() function uses fixed thresholds (default 0.5) to decide whether to buy or sell. Raw operator outputs like delta() or stddev() can be any magnitude — normalize() maps them into [0, 1] so the thresholds are always meaningful. Without it, every stock would either all-buy or all-sell depending on the raw value scale.

Exception — markov_order: markov_order() wraps markov() directly — no normalize needed, because markov() already outputs a probability in [0, 1].
2 Worked Examples
Simple momentum — rank stocks by recent Close, buy the top ones:
expression.alpha
order(normalize(rank('Close')), 0.7, 0.3, 1)
Read inside-out: 'Close'rank() ranks each stock's close against the rest of the universe today → normalize() maps to [0,1] → order(, 0.7, 0.3, 1) buys stocks with score > 0.7, exits if score < 0.3.
Mean-reversion — pick stocks where Close and Volume are inversely correlated:
expression.alpha
order(normalize(inverted_correlation('Close', 'Volume', 20)), 0.7, 0.3, 1)
Markov chain — predict next-state probability, order on it:
expression.alpha
markov_order(markov('Close', 10, 0.6), 1)
Here markov() already returns a probability, so no normalize() is needed. markov_order() handles the thresholding internally.
Multi-operator — rank stocks by a composite signal (close momentum + volume rank):
expression.alpha
order(normalize(rank(delta('Close', 1))), 0.7, 0.3, 1)
Operators like delta() can be nested inside rank() — first compute the 1-day price change per stock, then cross-sectionally rank those changes, then normalize and order.
Conditional branch — switch behavior per stock when a condition is true:
expression.alpha
order(normalize(rank(returns() < 0 ? stddev(returns(), 20) : 'Close')), 0.7, 0.3, 1)
This is evaluated per instrument. When a stock's latest return is negative, the branch uses stddev(returns(), 20); otherwise it uses 'Close'. The builder also accepts Python ternary and the explicit helper form if_else(condition, a, b).
DCF — full backtest-ready strategy that buys undervalued stocks based on discounted forward-FCF from the ML predictions:
expression.alpha
order(normalize(rank(
  add(
    add(
      divide(add(divide('Free Cash Flow', cap()), 'predicted_growth_fcf_1y_rolling_4y_h1'), 1.06),
      divide(add(divide('Free Cash Flow', cap()), add('predicted_growth_fcf_1y_rolling_4y_h1', 'predicted_growth_fcf_1y_rolling_4y_h2')), 1.1236)
    ),
    add(
      divide(add(divide('Free Cash Flow', cap()), add('predicted_growth_fcf_1y_rolling_4y_h1', add('predicted_growth_fcf_1y_rolling_4y_h2', 'predicted_growth_fcf_1y_rolling_4y_h3'))), 1.191016),
      divide(multiply(add(divide('Free Cash Flow', cap()), add('predicted_growth_fcf_1y_rolling_4y_h1', add('predicted_growth_fcf_1y_rolling_4y_h2', 'predicted_growth_fcf_1y_rolling_4y_h3'))), 34.3333), 1.191016)
    )
  )
)), 0.7, 0.3, 1)
Reads outside-in: order() buys when normalized score > 0.7, exits when < 0.3 → normalize() scales to [0,1] → rank() cross-sectionally ranks the per-stock intrinsic-value ratio → the inner block computes intrinsic_value / market_cap by discounting projected FCF over 3 years plus a Gordon-Growth terminal value.
  • divide('Free Cash Flow', cap()) — current FCF yield (FCF in ₹INR ÷ mktcap in ₹INR after the unit-aligned cap()).
  • predicted_growth_fcf_1y_rolling_4y_h{1,2,3} — ML predictions of next 3 years' FCF growth as a fraction of mktcap (rolling 4Y model — the regime-robust default).
  • Constants: 1.06 / 1.1236 / 1.191016 are (1+r)^N at r = 6% discount rate. 34.3333 = (1 + g_terminal) / (r − g_terminal) at g_terminal = 3% — the Gordon Growth perpetuity factor.
For loss-making companies (Free Cash Flow ≤ 0), the formula self-resolves via the forward-FCF chain — if predicted growth turns the cumulative FCF positive in years 1–3 the score stays useful. Bank / NBFC carve-out at the strategy level using a filter like 'Borrowings +' / cap() < 5.
3 Rules & Tips
Always wrap with order()
Every expression must end with order() or markov_order(). Without it, no trades are placed — the engine only computes scores.
normalize() before order()
Use normalize() between order() and your signal so buy/sell thresholds (0.0–1.0) are meaningful. Skip only when the inner function already returns [0,1] (e.g. markov, ts_rank).
Always quote data fields
Market data columns must be quoted strings: 'Close', 'Volume', 'Net Profit +'. Unquoted names are treated as variables and will error.
Operators compose freely
Time-series and math operators can be nested: rank(delta('Close', 1)) — compute 1-day change, then cross-sectionally rank the changes.
Conditional branches are vectorized
Use condition ? a : b, Python ternary, or if_else(condition, a, b). Comparisons such as <, >, and == are evaluated per stock rather than as one global boolean.
Cross-sectional vs time-series nesting
A plain cross-sectional operator like rank('Low') returns one score per stock for the current day only, so it cannot directly feed a time-series operator that needs history. Use rank_history('Low', 9) when you want a time-series operator to act on past daily cross-sectional ranks, for example ts_rank(rank_history('Low', 9), 9).
Threshold defaults
order(signal, 0.7, 0.3, 1) is the typical starting point — buy top 30%, exit bottom 30%. Adjust thresholds to control portfolio turnover.
Window size matters
Short windows (5–10 days) = high-frequency, high-turnover. Long windows (60–252 days) = momentum/trend following. Match window to your rebalancing frequency.
Cross-Sectional 101 Formulaic Alphas §2
Cross-Sectional Operators

Operate across all stocks on a given day — compare each stock against the full universe.

Function Signature Description Example
rank rank(data) Cross-sectional rank of each stock's value vs. the full universe today. Returns fractional rank in [0,1] — 0 = lowest, 1 = highest. rank('Close')
scale scale(data) Normalises values so that sum(|x|) = 1 across all stocks. Preserves sign. Use to make signals dollar-neutral or to compare differently-scaled signals. scale(delta('Close', 1))
Time-Series 101 Formulaic Alphas §2
Time-Series Operators — Window & History

Operate on each stock's own history over a rolling window of d trading days.

Function Signature Description Example
delay delay(field, d) Returns the value of field from exactly d trading days ago. Classic lag operator. delay('Close', 5)
delta delta(field, d) Today's value minus the value d days ago. Measures rate of change. Equivalent to a finite-difference derivative. delta('Close', 1)
ts_min ts_min(field, d) Minimum value of field over the last d trading days per stock. ts_min('Low', 20)
ts_max ts_max(field, d) Maximum value of field over the last d trading days per stock. ts_max('High', 20)
ts_sum ts_sum(field, d) Sum of field over the last d trading days. Useful for cumulating volume or returns. ts_sum('Volume', 5)
product product(field, d) Product of field over the last d trading days per stock. Useful when the paper multiplies a rolling signal instead of summing it. product('Close', 5)
ts_rank ts_rank(field, d) Ranks today's value of field within its own last d values. Returns [0,1]. Unlike cross-sectional rank(), this ranks a stock against its own history — not against other stocks. ts_rank('Volume', 20)
rank_history rank_history(field, d) Builds a rolling history of daily cross-sectional ranks for field. Use this when you want time-series operators to act on past cross-sectional ranks rather than raw field values. ts_rank(rank_history('Low', 9), 9)
ts_argmax ts_argmax(field, d) How many days ago was the maximum within the last d days? Returns 0 if max was today. ts_argmax('High', 20)
ts_argmin ts_argmin(field, d) How many days ago was the minimum within the last d days? Returns 0 if min was today. ts_argmin('Low', 20)
pct_change pct_change(field, d) Percent change over d periods: (current − past) / past × 100. Use for period-over-period growth %. For fundamental fields, d is in trading days but the engine resolves it to the corresponding filing window. pct_change('Net Profit +', 4)
cagr cagr(field, d_periods, periods_per_year=4) Compound Annual Growth Rate of field over d_periods. Annualised using periods_per_year (default 4 for quarterly fundamental data). cagr('Sales +', 12, 4)
Time-Series 101 Formulaic Alphas §2
Time-Series Operators — Statistics & Market Data

Statistical summaries and pre-computed market data signals.

Function Signature Description Example
stddev stddev(field, d) Sample standard deviation (ddof=1) of field over the last d days. Use as a volatility measure. stddev('Close', 20)
decay_linear decay_linear(field, d) Linearly decaying weighted average over last d days. Most recent day gets weight d, oldest gets weight 1. Weights normalised to sum to 1. Smooths noisy signals while favouring recent data. decay_linear('Close', 10)
adv adv(d) Average Daily Volume over last d days. Requires 'Volume' as a configured field. Used as a liquidity filter in many of the 101 alphas. adv(20)
returns returns() Daily close-to-close return = (close_today − close_yesterday) / close_yesterday. No arguments — always uses Close. returns()
vwap_val vwap_val() Volume-Weighted Average Price approximation using (High + Low + Close) / 3 as typical price. Falls back to Close if High/Low not configured. vwap_val()
cap cap() Market capitalisation for each stock, sourced from the universe build's derived mktCap field. Zero-argument. Useful inside ranks and divisions for size-based screens (e.g. FCF yield = divide('Free Cash Flow', cap())). rank(cap())
Math 101 Formulaic Alphas §2
Element-Wise Math Operators

Applied per-stock to a score or field — do not change which stocks are present, only transform their values.

Function Signature Description Example
sign_val sign_val(data) Returns −1, 0, or +1 per stock based on the sign of the input. Useful for building long/short signals. sign_val(delta('Close', 1))
log_val log_val(data) Natural log. Drops stocks with zero or negative values. Apply to strictly positive fields like volume or price. log_val(adv(20))
abs_val abs_val(data) Absolute value per stock. Use to measure magnitude regardless of direction. abs_val(delta('Close', 1))
neg neg(data) Negates a field or signal (multiplies by −1). Used to preserve the paper's leading −1 sign while keeping expressions readable, or to invert a signal's direction. neg(ts_rank(rank('Low'), 9))
signed_power signed_power(data, exp) sign(x) × |x|^exp — applies a power transformation while preserving the sign. Used in several of the 101 alphas (e.g. Alpha#1) to emphasise large moves without flipping direction. signed_power(returns(), 2)
Arithmetic
Arithmetic Operators

Combine two signals element-wise, aligned by instrument. Both inputs must cover the same universe.

Function Signature Description Example
add add(data1, data2) Element-wise addition of two signal tuples, aligned by instrument. add(rank('Close'), rank('Volume'))
subtract subtract(data1, data2) Element-wise data1 − data2, aligned by instrument. Use this instead of Python “-” so tuples stay aligned. subtract(ts_sum('Close',10), ts_sum('Close',20))
multiply multiply(data1, data2) Element-wise multiplication. Useful for combining a directional signal with a magnitude/volatility weight. multiply(sign_val(returns()), rank('Volume'))
divide divide(data1, data2) data1 / data2, element-wise. Stocks with zero denominator are dropped from the result. divide(delta('Close',1), stddev('Close',20))
power power(data1, data2) Dynamic element-wise exponent with sign preservation: sign(x) × |x|^y. Use when the exponent itself is another signal branch. power(rank('Close'), rank('Volume'))
maximum maximum(data1, data2) Element-wise maximum across two aligned signal branches. Matches the paper’s binary max(x, y) operator. maximum(rank('Close'), rank('Volume'))
minimum minimum(data1, data2) Element-wise minimum across two aligned signal branches. Matches the paper’s binary min(x, y) operator. minimum(rank('Close'), rank('Volume'))
Conditionals 101 Formulaic Alphas ternary logic
Branching & Comparison Operators

Use these helpers when a signal should switch behavior based on a per-stock condition.

Function Signature Description Example
if_else if_else(condition, value_if_true, value_if_false) Vectorized branch selection. The engine evaluates the condition for each stock independently and then chooses the matching branch value for that stock. if_else(lt(returns(), 0), stddev(returns(), 20), 'Close')
gt / ge / lt / le gt(x, y), ge(x, y), lt(x, y), le(x, y) Vectorized comparisons that return numeric masks. True becomes 1.0, false becomes 0.0, so the result can be ranked, combined, or fed into if_else(). gt(rank('Close'), rank('Open'))
eq / ne eq(x, y), ne(x, y) Equality and inequality checks for aligned signal branches. These are useful for masks created from sign or discrete regime signals. eq(sign_val(delta('Close', 1)), 1)
logical_and / logical_or / logical_not logical_and(a, b), logical_or(a, b), logical_not(a) Boolean combinators for condition masks. Positive values are treated as true; zero or negative values are treated as false. logical_and(gt(rank('Close'), 0.7), lt(returns(), 0))
Raw ternary syntax condition ? value_if_true : value_if_false The builder accepts paper-style ternary syntax directly and rewrites it to if_else(...) before execution. Python ternary is also accepted. returns() < 0 ? stddev(returns(), 20) : 'Close'
Statistical 101 Formulaic Alphas §2
Correlation & Covariance Operators

Per-instrument rolling statistics comparing two fields over a window.

Function Signature Description Example
rolling_correlation rolling_correlation(field1, field2, d) Per-instrument Pearson correlation between field1 and field2 over last d days. Returns one value per stock in [−1, +1]. Use to find stocks with unusual cross-field relationships. rolling_correlation('Close', 'Volume', 20)
rolling_covariance rolling_covariance(field1, field2, d) Per-instrument rolling covariance between field1 and field2 over last d days. Not normalised — use rolling_correlation for scale-independent measure. rolling_covariance('Close', 'Volume', 20)
inverted_correlation inverted_correlation(feature_1, feature_2, window_size) Selects stocks whose two chosen features are most negatively correlated over the window. Useful for mean-reversion strategies (e.g. when price and volume diverge). inverted_correlation('Close', 'Volume', 20)
Order Generation ftInvstr composition layer
Order Generation & Composition

Outer wrappers that turn a scoring function into buy/sell decisions. Every ftInvstr alpha ends with order(...) or markov_order(...).

Function Signature Description Example
normalize normalize(inner_function) Rescales an inner score to [0, 1] cross-sectionally. Required between a raw scoring function and order() so the buy/sell thresholds (e.g. 0.7 / 0.3) are meaningful. Skip only when the inner function already returns [0, 1] (e.g. rank() on its own). normalize(rank('Close'))
order order(inner, buy_threshold, sell_threshold, position_multiplier) Generates buy/sell signals from the inner score. Buys when score ≥ buy_threshold, exits when score < sell_threshold — the gap creates a hysteresis band that reduces turnover. position_multiplier scales position size; use 1 for equal-weight. order(normalize(rank('Close')), 0.7, 0.3, 1)
markov markov(field, window_size, probability_threshold) Fits a Markov chain on each stock's history of a feature and returns the predicted next-state probability. Stocks whose probability exceeds probability_threshold get a positive score. Pair with markov_order() instead of order(). markov('Close', 10, 0.6)
markov_order markov_order(inner_function, position_multiplier) Companion to order() for Markov-based scores. Skips the buy/sell threshold step because markov() already returns a probability — the threshold is baked in. markov_order(markov('Close', 10, 0.6), 1)
Candlestick
OHLC Candlestick Primitives

Four building-block operators that decompose each daily bar into its structural parts — body, wicks, and range. Combine these with gt(), lt(), logical_and(), and divide() to express any classic candlestick pattern (Doji, Hammer, Engulfing, Shooting Star, etc.) as an alpha signal.

Function Signature Description Example
body_size body_size(open, close) Element-wise candle body size: |Open − Close|. Measures how decisive each day's move was. A large body means strong directional conviction; a tiny body relative to the range signals a Doji or indecision day. body_size('Open', 'Close')
upper_shadow upper_shadow(high, open, close) Upper wick height: High − max(Open, Close). A long upper shadow means buyers pushed price up intraday but sellers rejected the highs — a bearish rejection signal. Used in Shooting Star and Hanging Man patterns. upper_shadow('High', 'Open', 'Close')
lower_shadow lower_shadow(low, open, close) Lower wick height: min(Open, Close) − Low. A long lower shadow shows sellers pushed price down but buyers absorbed the pressure — a bullish reversal signal. Used in Hammer and Inverted patterns. lower_shadow('Low', 'Open', 'Close')
candle_range candle_range(high, low) Total bar range: High − Low. Represents the full intraday volatility of the candle. Used as the denominator when expressing body or shadow ratios — e.g. a Doji is body_size / candle_range < 0.1. candle_range('High', 'Low')
logical_and logical_and(a, b) Boolean AND combinator: returns 1.0 where both a and b are positive (true), 0.0 otherwise. Essential for combining multiple candlestick conditions — e.g. a Hammer requires a long lower shadow AND a small body AND a small upper shadow simultaneously. logical_and(gt(lower_shadow('Low','Open','Close'), multiply(body_size('Open','Close'), 2)), lt(upper_shadow('High','Open','Close'), body_size('Open','Close')))
COMPOSING A PATTERN — Doji example
A Doji forms when the body is tiny relative to the full range — the market opened and closed at almost the same price regardless of intraday swings.
order(normalize(rank(lt(divide(body_size('Open','Close'), candle_range('High','Low')), 0.1))), 0.7, 0.3, 1) Ranks stocks by how Doji-like today's candle is, then buys the most indecisive candles.
rank

Ranks each stock cross-sectionally against the rest of the universe on the current day. Higher rank = stronger relative signal. Commonly used as the inner expression for normalize or order.

signature
rank(data)
Arguments
Parameter Type Description & Allowed Values
data string or function
{{ arg.description }}
'Open' 'High' 'Low' 'Close' 'Volume' 'Adj Close' 'Sales +' 'Revenue +' +132 more
Example
rank('Close')
neg

Negates a field or signal. Use it to preserve the paper's leading -1 sign while keeping expressions readable.

signature
neg(data)
Arguments
Parameter Type Description & Allowed Values
data string or function
{{ arg.description }}
'Open' 'High' 'Low' 'Close' 'Volume' 'Adj Close' 'Sales +' 'Revenue +' +132 more
Example
neg(ts_rank(rank('Low'), 9))
rank_history

Builds a rolling history of daily cross-sectional ranks for a field. Use this when you want time-series operators to act on cross-sectional rank history.

signature
rank_history('field', window_size)
Arguments
Parameter Type Description & Allowed Values
field string
{{ arg.description }}
'Open' 'High' 'Low' 'Close' 'Volume' 'Adj Close' 'Sales +' 'Revenue +' +123 more
window_size integer
{{ arg.description }}
Example
ts_rank(rank_history('Low', 9), 9)
cap

Returns each stock's derived market capitalisation for the active universe date. In ftInvstr this is sourced from the universe build's derived mktCap field.

signature
cap()
Arguments
Parameter Type Description & Allowed Values
Example
rank(cap())
normalize

Scales the output of an inner function to a standardised range (0–1). Wraps another function and removes scale differences between stocks.

signature
normalize(inner_function)
Arguments
Parameter Type Description & Allowed Values
inner_function function
{{ arg.description }}
markov inverted_correlation normalize order markov_order rank neg rank_history +1 more
Example
normalize(rank('Close'))
order

Generates buy/sell signals from the output of an inner function using threshold-based logic. This is the outermost function in most expressions.

signature
order(inner_function, buy_threshold, sell_threshold, position_multiplier)
Arguments
Parameter Type Description & Allowed Values
inner_function function
{{ arg.description }}
markov inverted_correlation normalize order markov_order rank neg rank_history +1 more
buy_threshold decimal (0–1)
{{ arg.description }}
sell_threshold decimal (0–1)
{{ arg.description }}
position_multiplier integer
{{ arg.description }}
Example
order(normalize(rank('Close')), 0.7, 0.3, 1)
inverted_correlation

Selects stocks whose two chosen features are most negatively correlated over the window. Useful for mean-reversion strategies.

signature
inverted_correlation(feature_1, feature_2, window_size)
Arguments
Parameter Type Description & Allowed Values
feature_1 string or function
{{ arg.description }}
'Open' 'High' 'Low' 'Close' 'Volume' 'Adj Close' 'Sales +' 'Revenue +' +132 more
feature_2 string or function
{{ arg.description }}
'Open' 'High' 'Low' 'Close' 'Volume' 'Adj Close' 'Sales +' 'Revenue +' +132 more
window_size integer
{{ arg.description }}
Example
inverted_correlation('Close', 'Volume', 20)
markov

Uses a Markov chain model to predict next-state probabilities for a stock feature. Returns a probability score per stock.

signature
markov('feature', window_size, probability_threshold)
Arguments
Parameter Type Description & Allowed Values
feature string
{{ arg.description }}
'Open' 'High' 'Low' 'Close' 'Volume' 'Adj Close' 'Sales +' 'Revenue +' +123 more
window_size integer
{{ arg.description }}
probability_threshold decimal (0–1)
{{ arg.description }}
Example
markov('Close', 10, 0.6)
markov_order

Combines Markov chain scoring with order generation. Wraps a Markov-based inner function and sizes positions by the multiplier.

signature
markov_order(inner_function, position_multiplier)
Arguments
Parameter Type Description & Allowed Values
inner_function function
{{ arg.description }}
markov inverted_correlation normalize order markov_order rank neg rank_history +1 more
position_multiplier integer
{{ arg.description }}
Example
markov_order(markov('Close', 10, 0.6), 1)
if_else

Vectorised conditional selection. Evaluates the condition per instrument and chooses the true or false branch for each stock independently. Raw `condition ? a : b` and Python ternary `a if condition else b` are both normalized to this helper.

signature
if_else(condition, value_if_true, value_if_false)
Arguments
Parameter Type Description & Allowed Values
condition boolean signal or comparison
{{ arg.description }}
value_if_true scalar, field, or function
{{ arg.description }}
value_if_false scalar, field, or function
{{ arg.description }}
Example
if_else(gt(returns(), 0), rank('Close'), neg(rank('Close')))
gt

Vectorised greater-than comparison. Returns 1.0 where the left branch is greater than the right branch, else 0.0.

signature
gt(left, right)
Arguments
Parameter Type Description & Allowed Values
left scalar, field, or function
{{ arg.description }}
right scalar, field, or function
{{ arg.description }}
Example
gt(rank('Close'), rank('Open'))
ge

Vectorised greater-than-or-equal comparison. Returns 1.0 where left >= right, else 0.0.

signature
ge(left, right)
Arguments
Parameter Type Description & Allowed Values
left scalar, field, or function
{{ arg.description }}
right scalar, field, or function
{{ arg.description }}
Example
ge(ts_rank('Close', 5), 0.8)
lt

Vectorised less-than comparison. Returns 1.0 where the left branch is less than the right branch, else 0.0.

signature
lt(left, right)
Arguments
Parameter Type Description & Allowed Values
left scalar, field, or function
{{ arg.description }}
right scalar, field, or function
{{ arg.description }}
Example
lt(returns(), 0)
le

Vectorised less-than-or-equal comparison. Returns 1.0 where left <= right, else 0.0.

signature
le(left, right)
Arguments
Parameter Type Description & Allowed Values
left scalar, field, or function
{{ arg.description }}
right scalar, field, or function
{{ arg.description }}
Example
le(rank('Close'), 0.25)
eq

Vectorised equality comparison. Returns 1.0 where left and right match exactly, else 0.0.

signature
eq(left, right)
Arguments
Parameter Type Description & Allowed Values
left scalar, field, or function
{{ arg.description }}
right scalar, field, or function
{{ arg.description }}
Example
eq(sign_val(delta('Close', 1)), 1)
ne

Vectorised inequality comparison. Returns 1.0 where left and right differ, else 0.0.

signature
ne(left, right)
Arguments
Parameter Type Description & Allowed Values
left scalar, field, or function
{{ arg.description }}
right scalar, field, or function
{{ arg.description }}
Example
ne(rank('Close'), rank('Open'))
logical_and

Vectorised boolean AND. Treats positive values as true and zero or negative values as false.

signature
logical_and(left_condition, right_condition)
Arguments
Parameter Type Description & Allowed Values
left_condition boolean signal
{{ arg.description }}
right_condition boolean signal
{{ arg.description }}
Example
logical_and(gt(rank('Close'), 0.7), lt(returns(), 0.02))
logical_or

Vectorised boolean OR. Treats positive values as true and zero or negative values as false.

signature
logical_or(left_condition, right_condition)
Arguments
Parameter Type Description & Allowed Values
left_condition boolean signal
{{ arg.description }}
right_condition boolean signal
{{ arg.description }}
Example
logical_or(gt(returns(), 0.03), lt(returns(), -0.03))
logical_not

Vectorised boolean NOT. Converts true to false and false to true per instrument.

signature
logical_not(condition)
Arguments
Parameter Type Description & Allowed Values
condition boolean signal
{{ arg.description }}
Example
logical_not(gt(rank('Close'), 0.7))
add

Element-wise addition of two series or a series and a scalar.

signature
add(left, right)
Arguments
Parameter Type Description & Allowed Values
left scalar, field, or function
{{ arg.description }}
right scalar, field, or function
{{ arg.description }}
Example
add('Profit before tax', 'Other Income +')
subtract

Element-wise subtraction (left minus right).

signature
subtract(left, right)
Arguments
Parameter Type Description & Allowed Values
left scalar, field, or function
{{ arg.description }}
right scalar, field, or function
{{ arg.description }}
Example
subtract('Sales +', 'Expenses +')
multiply

Element-wise multiplication of two series or a series and a scalar.

signature
multiply(left, right)
Arguments
Parameter Type Description & Allowed Values
left scalar, field, or function
{{ arg.description }}
right scalar, field, or function
{{ arg.description }}
Example
multiply('Net Profit +', 100)
divide

Element-wise division (left / right). Used to derive ratios like ROE = NetProfit / Equity, PE = Close / EPS.

signature
divide(numerator, denominator)
Arguments
Parameter Type Description & Allowed Values
numerator scalar, field, or function
{{ arg.description }}
denominator scalar, field, or function
{{ arg.description }}
Example
divide('Net Profit +', 'Equity Capital')
ts_sum

Rolling window sum over the last d periods. Use for trailing aggregates like TTM Sales (4 quarters) or TTM EPS.

signature
ts_sum('field', d)
Arguments
Parameter Type Description & Allowed Values
field field name
{{ arg.description }}
d integer
{{ arg.description }}
Example
ts_sum('Sales +', 4)
delta

Period-over-period change: current value minus value d periods ago. Use for absolute growth.

signature
delta('field', d)
Arguments
Parameter Type Description & Allowed Values
field field name
{{ arg.description }}
d integer
{{ arg.description }}
Example
delta('Net Profit +', 4)
delay

Returns the value of a field d periods ago (lag/shift). Useful as the start point for CAGR or pct change calculations.

signature
delay('field', d)
Arguments
Parameter Type Description & Allowed Values
field field name
{{ arg.description }}
d integer
{{ arg.description }}
Example
delay('Close', 252)
stddev

Rolling standard deviation over the last d periods.

signature
stddev('field', d)
Arguments
Parameter Type Description & Allowed Values
field field name
{{ arg.description }}
d integer
{{ arg.description }}
Example
stddev('Close', 20)
ts_min

Rolling minimum over the last d periods.

signature
ts_min('field', d)
Arguments
Parameter Type Description & Allowed Values
field field name
{{ arg.description }}
d integer
{{ arg.description }}
Example
ts_min('Low', 252)
ts_max

Rolling maximum over the last d periods.

signature
ts_max('field', d)
Arguments
Parameter Type Description & Allowed Values
field field name
{{ arg.description }}
d integer
{{ arg.description }}
Example
ts_max('High', 252)
ts_rank

Rolling rank: percentile of the current value within the last d periods.

signature
ts_rank('field', d)
Arguments
Parameter Type Description & Allowed Values
field field name
{{ arg.description }}
d integer
{{ arg.description }}
Example
ts_rank('Close', 252)
pct_change

Percent change over d periods: (current - past) / past × 100. Use for period-over-period growth %.

signature
pct_change('field', d)
Arguments
Parameter Type Description & Allowed Values
field field name
{{ arg.description }}
d integer
{{ arg.description }}
Example
pct_change('Net Profit +', 4)
cagr

Compound Annual Growth Rate over d periods. Returns annualized growth between start and current value. Assumes 4 periods per year for quarterly data; pass quarters=False to skip annualization.

signature
cagr('field', d_periods, periods_per_year=4)
Arguments
Parameter Type Description & Allowed Values
field field name
{{ arg.description }}
d_periods integer
{{ arg.description }}
periods_per_year integer
{{ arg.description }}
Example
cagr('Sales +', 12, 4)
returns

Daily / per-period simple return: (current_close - prev_close) / prev_close.

signature
returns()
Arguments
Parameter Type Description & Allowed Values
Example
rank(returns())
abs_val

Absolute value (element-wise).

signature
abs_val(value)
Arguments
Parameter Type Description & Allowed Values
value scalar, field, or function
{{ arg.description }}
Example
abs_val(returns())
log_val

Natural logarithm (element-wise).

signature
log_val(value)
Arguments
Parameter Type Description & Allowed Values
value scalar, field, or function
{{ arg.description }}
Example
log_val('Close')
sign_val

Element-wise sign: returns -1 for negative, 0 for zero, 1 for positive.

signature
sign_val(value)
Arguments
Parameter Type Description & Allowed Values
value scalar, field, or function
{{ arg.description }}
Example
sign_val(delta('Close', 1))