The ta leg screens for technical events — crossovers, breakouts, squeezes, divergences, Ichimoku signals, and more — across daily, weekly, or monthly bars.
Structure
ta leg shape
"ta": [
{
"anchor": [ <signal>, ... ],
"quals": [ { "any": [ <signal>, ... ], "within": 5 }, ... ]
},
...
]
The ta array is a list of steps chained in temporal order (THEN logic): step 1 must have fired before step 2 within the window_bars lookback.
Step fields
| Field | Type | Description |
|---|
anchor | Signal[] | OR-group — at least one must have fired to trigger this step. |
quals | Qual[] | Conditions that must hold concurrently with the anchor (AND-ed). |
Qual fields
| Field | Type | Default | Description |
|---|
any | Signal[] | — | At least one of these must hold at the same time as the anchor. |
within | number | 5 | How many bars before/after the anchor the qual must hold. |
Signal fields
| Field | Type | Required | Description |
|---|
pattern | string | ✅ | Pattern token. Resolve unknown phrases with POST /v1/ta/find-signal. |
a | string | depends | First operand — indicator, line, or level. |
b | string | depends | Second operand. |
for_bars | number | — | Sustained duration: how many bars the state must have held. For state patterns (above, held_above, overbought, rising, etc.). |
window_bars | number | — | Per-signal lookback override. |
timeframe | 1|2|3 | — | Per-signal timeframe override. Supported on quals only (not anchors). |
:::tip for_bars vs window_bars
These are different things. window_bars = "how far back to search for this event." for_bars = "how long the state must have been continuously true." Use for_bars with held_above, overbought, rising, etc. to require a sustained condition, not just a momentary one.
:::
Patterns
Use POST /v1/ta/find-signal to resolve any plain-language phrase to a pattern token. Patterns fall into six groups:
Crossover & state
| Pattern | Operands | What it detects |
|---|
crossover_up | a, b | a crossed above b — golden cross: a=ema50, b=ema200 |
crossover_dn | a, b | a crossed below b — death cross |
above | a, b | a is currently above b (single-bar check) |
below | a, b | a is currently below b |
held_above | a, b, for_bars | a has been above b for at least for_bars bars continuously |
held_below | a, b, for_bars | a has been below b for at least for_bars bars |
overbought | a (oscillator) | Oscillator in overbought zone — RSI ≥ 70, Stoch ≥ 80 by default |
oversold | a | Oscillator in oversold zone — RSI ≤ 30, Stoch ≤ 20 |
in_range | a (oscillator), b ("lo-hi") | Oscillator held in a specific range. b format is "40-60" |
rising | a, for_bars | Line has been rising for for_bars consecutive bars |
falling | a, for_bars | Line has been falling |
Convergence & divergence
| Pattern | Operands | What it detects |
|---|
converge / squeeze | a, b | Two lines moving toward each other |
expand_up | a, b | Lines spreading — a expanding upward |
expand_dn | a, b | Lines spreading — b expanding downward |
near_ma | a=close, b (MA) | Price within ~ATR of a moving average. Supported MAs: ema50, ema200, sma200 |
divergence_bull | a (oscillator) | Price making lower lows, oscillator making higher lows (classic bull div) |
divergence_bear | a | Price making higher highs, oscillator making lower highs |
hidden_divergence_bull | a=rsi14 | Price making higher lows, RSI making lower lows — trend continuation |
hidden_divergence_bear | a=rsi14 | Price making lower highs, RSI making higher highs |
Squeeze & volatility
| Pattern | Operands | What it detects |
|---|
ttm_squeeze | for_bars | Bollinger Bands inside Keltner Channels — classic low-volatility coil |
bb_squeeze | — | Bollinger Bands at historically narrow width |
squeeze_started | — | TTM squeeze just entered (first bar of a new coil) |
squeeze_fired | — | TTM squeeze just released in either direction |
squeeze_fired_up | — | Squeeze released with upward momentum |
squeeze_fired_dn | — | Squeeze released with downward momentum |
Volume
| Pattern | Operands | What it detects |
|---|
vol_spike | — | Volume surge relative to its N-bar average |
vol_dryup | — | Volume unusually low — often precedes a directional move |
rising_volume | for_bars | Volume rising for for_bars consecutive bars (default: 3) |
Price change & 52-week range
| Pattern | Operands | What it detects |
|---|
net_change_up | window_bars, b (optional threshold) | Net price return positive over the lookback window |
net_change_dn | window_bars, b | Net price return negative — b as a fraction: "0.10" = must have fallen ≥ 10% |
at_52w_high | — | Price within 0.5% of its 52-week high |
near_52w_high | b (fraction, default "0.03") | Price within b fraction of 52-week high |
at_52w_low | — | Price within 0.5% of its 52-week low |
near_52w_low | b | Price within b fraction of 52-week low |
off_high | b (default "0.10") | Price has pulled back ≥ b from 52-week high |
Ichimoku Cloud
Ichimoku patterns use the four cloud lines as operands and the two cloud-shape patterns below.
| Pattern | Operands | What it detects |
|---|
crossover_up | a=ichi_tenkan, b=ichi_kijun | TK cross bullish — Tenkan crossed above Kijun |
crossover_dn | a=ichi_tenkan, b=ichi_kijun | TK cross bearish |
above | a=close, b=ichi_senkou_a | Price above the cloud's top edge (bullish Kumo breakout) |
above | a=ichi_senkou_a, b=ichi_senkou_b | Bullish cloud — Senkou A above Senkou B |
below | a=close, b=ichi_senkou_b | Price below the cloud's bottom edge (bearish) |
kumo_squeeze | — | Cloud narrowing — Senkou A and B converging (indecision / low vol) |
kumo_expand | — | Cloud expanding — Senkou A and B diverging (trend accelerating) |
Operands
Moving averages
| Operand | Aliases | Description |
|---|
ema5 ema10 ema20 ema50 ema100 ema200 | ema + period | Exponential moving average. Unsupported periods snap to nearest via log-ratio. |
sma10 sma20 sma50 sma100 sma200 | sma + period, ma + period | Simple moving average. |
Supported EMA periods: 5, 10, 20, 50, 100, 200. Supported SMA periods: 10, 20, 50, 100, 200. Other families (HMA, WMA, TEMA, VWMA…) are aliased to the nearest EMA with a note.
Price
| Operand | Aliases | Description |
|---|
close | price | Current closing price |
Oscillators
| Operand | Aliases | Description |
|---|
rsi14 | rsi | 14-period RSI (0–100). Overbought ≥ 70, oversold ≤ 30. |
stoch_k | stoch, %k, k | Stochastic %K (0–100). Overbought ≥ 80, oversold ≤ 20. |
stoch_d | %d, d | Stochastic %D (smoothed %K). |
adx | dmi14_adx | Average Directional Index (0–100). Trending when > 25. |
plus_di | +di, di_plus, pdi | DMI +DI — upward directional strength. |
minus_di | -di, di_minus, mdi | DMI −DI — downward directional strength. |
MACD
| Operand | Aliases | Description |
|---|
macd | macd_line | MACD line (fast EMA − slow EMA) |
macd_signal | signal | MACD signal line (EMA of MACD line) |
Bollinger Bands
| Operand | Aliases | Description |
|---|
bb_upper | bb20_upper, upper_band | Upper Bollinger Band (2 std above 20-period SMA) |
bb_lower | bb20_lower, lower_band | Lower Bollinger Band |
bb_mid | bb20_mid, middle_band | Middle band (20-period SMA) |
Ichimoku
| Operand | Aliases | Description |
|---|
ichi_tenkan | tenkan, tenkan_sen, conversion | Conversion line (9-period midpoint) |
ichi_kijun | kijun, kijun_sen, base_line | Base line (26-period midpoint) |
ichi_senkou_a | senkou_a, span_a, leading_span_a | Leading Span A — upper cloud edge (bullish cloud) |
ichi_senkou_b | senkou_b, span_b, leading_span_b | Leading Span B — lower cloud edge |
Realized volatility
| Operand | Aliases | Description |
|---|
realized_vol_pct_1y | rvol, realized_vol_pct | 30-day realized vol as a percentile of the 1-year range (0–1). 0.9 = vol near its 1-year high. Useful with overbought/in_range. |
realized_vol_30d | rvol_30d | 30-day realized volatility (annualized, decimal). 0.25 = 25% annual vol. |
Numeric levels
Pass any number as a string operand for threshold-based comparisons:
{ "pattern": "above", "a": "rsi14", "b": "50" }
{ "pattern": "in_range", "a": "rsi14", "b": "40-60" }
{ "pattern": "overbought", "a": "rsi14", "b": "65" }
:::info Operand snapping
Unsupported periods (e.g. ema45) snap to the nearest supported line (ema50). Unsupported indicator families (HMA, WMA…) snap to EMA. All snapping is surfaced in the response notes[] — you always know what was actually used.
:::
Timeframe
Controls which price series the TA leg reads.
timeframe | Bars | Operand meaning |
|---|
1 (default) | Daily | ema50 = 50-day MA; window_bars=30 = 30 trading days |
2 | Weekly | ema50 = 50-week MA; window_bars=30 = 30 weeks (~7 months) |
3 | Monthly | ema50 = 50-month MA |
Set globally at the request level, or override per-signal in quals with "timeframe": 2.
Examples
Golden cross: EMA50 crossed above EMA200
"ta": [{ "anchor": [{ "pattern": "crossover_up", "a": "ema50", "b": "ema200" }] }]
Oversold RSI + price still above 200-day MA
"ta": [{
"anchor": [{ "pattern": "oversold", "a": "rsi14" }],
"quals": [{ "any": [{ "pattern": "above", "a": "close", "b": "sma200" }] }]
}]
TTM volatility squeeze (Bollinger inside Keltner)
"ta": [{ "anchor": [{ "pattern": "ttm_squeeze" }] }]
Squeeze released upward (momentum confirmed)
"ta": [{ "anchor": [{ "pattern": "squeeze_fired_up" }] }]
Dip buyer: down >10% in 20 days, RSI not deeply oversold
"ta": [{
"anchor": [{ "pattern": "net_change_dn", "b": "0.10", "window_bars": 20 }],
"quals": [{ "any": [{ "pattern": "above", "a": "rsi14", "b": "30" }] }]
}]
Bull divergence on MACD
"ta": [{ "anchor": [{ "pattern": "divergence_bull", "a": "macd" }] }]
Price near 52-week high (breakout candidate, within 5%)
"ta": [{ "anchor": [{ "pattern": "near_52w_high", "b": "0.05" }] }]
Ichimoku TK cross with price above the cloud
"ta": [{
"anchor": [{ "pattern": "crossover_up", "a": "ichi_tenkan", "b": "ichi_kijun" }],
"quals": [{ "any": [{ "pattern": "above", "a": "close", "b": "ichi_senkou_a" }] }]
}]
Kumo squeeze — cloud narrowing, big move expected
"ta": [{ "anchor": [{ "pattern": "kumo_squeeze" }] }]
Price above bullish cloud (Senkou A > Senkou B)
"ta": [{
"anchor": [{ "pattern": "above", "a": "close", "b": "ichi_senkou_a" }],
"quals": [{ "any": [{ "pattern": "above", "a": "ichi_senkou_a", "b": "ichi_senkou_b" }] }]
}]
MACD bullish cross THEN price crossed above 50-day (two-step THEN)
"ta": [
{ "anchor": [{ "pattern": "crossover_up", "a": "macd", "b": "macd_signal" }] },
{ "anchor": [{ "pattern": "crossover_up", "a": "close", "b": "ema50" }] }
]
Weekly trend up + daily oversold (multi-timeframe)
"ta": [{
"anchor": [{ "pattern": "oversold", "a": "rsi14" }],
"quals": [{
"any": [{ "pattern": "above", "a": "close", "b": "ema200", "timeframe": 2 }]
}]
}],
"timeframe": 1
Stoch %K crossed above 20 (coming out of oversold)
"ta": [{ "anchor": [{ "pattern": "crossover_up", "a": "stoch_k", "b": "20" }] }]
ADX rising above 25 (new trend starting) with +DI above −DI
"ta": [{
"anchor": [{ "pattern": "crossover_up", "a": "adx", "b": "25" }],
"quals": [{ "any": [{ "pattern": "above", "a": "plus_di", "b": "minus_di" }] }]
}]
Realized volatility spiking to 1-year high (vol in top 10%)
"ta": [{ "anchor": [{ "pattern": "overbought", "a": "realized_vol_pct_1y", "b": "0.9" }] }]
Volume drying up + price near 52w high (quiet breakout setup)
"ta": [{
"anchor": [{ "pattern": "vol_dryup" }],
"quals": [{ "any": [{ "pattern": "near_52w_high", "b": "0.03" }] }]
}]