Indicadores por API: POST /v1/indicators¶
Qué vas a aprender¶
- Qué hace
POST /v1/indicatorsy en qué se diferencia de un backtest. - Las 39 primitivas registradas (33 calculables en modo canónico), sus parámetros de ejemplo y su regla de primer valor válido (
first_valid_rule). - El paso directo al motor: cómo la API calcula otros 342 indicadores sin garantías canónicas (375 ejecutables en total; 11 no ejecutables con motivo).
- Cómo construir la petición:
data,indicator(indicator,params,source,periods_batch),engine,engine_options. - Cómo leer la respuesta:
provider,first_valid_index,n_valid,mask_summary,values_tail. - Por qué el RSI14 tiene
first_valid_index14 en VectorTA y 13 en Nautilus, y por qué sus valores no convergen (variante declarada, no error). - Cómo aprovechar el
example_curlde cada ficha y cuáles son los errores típicos.
1. La idea: pedir una curva, no una estrategia¶
Un backtest responde «¿cuánto habría ganado?». POST /v1/indicators responde algo más modesto y muy útil: «dame esta curva sobre estos datos y dime desde qué barra es fiable». Es la herramienta para:
- comprobar que un indicador se comporta como esperas antes de meterlo en una estrategia;
- comparar la misma curva en los dos motores;
- medir cuánto cuesta calcularla.
Un indicador no es una estrategia
Por eso esta ruta no usa strategy sino un IndicatorSelector. No hay ejecución, ni costes, ni contabilidad: signature.execution_contract es null.
Sustituye a las rutas del contrato anterior, v0 (POST /indicators, /indicators/rsi, /indicators/ema de los servicios :8001/:8002), y añade lo que aquellas no tenían: ventana, first_valid_index, mask_summary, proveedor declarado, stage_timings, periods_batch y sobre.
flowchart LR
R[POST /v1/indicators] --> V{¿Indicador en el<br/>registro del proyecto?}
V -- no --> PT[paso directo al motor<br/>ver sección 7]
V -- sí --> S{¿source ∈ inputs?}
S -- no --> E2[422 INDICATOR_PARAMS_INVALID<br/>field: indicator.source]
S -- sí --> L[Cargar barras de la ventana]
L --> Z{¿Hay barras?}
Z -- no --> E3[409 INSUFFICIENT_HISTORY]
Z -- sí --> C[Calcular por motor<br/>y por periodo de periods_batch]
C --> OUT["200: results con provider,<br/>first_valid_index, mask, cola"]
2. Las 39 primitivas registradas¶
Solo los indicadores con contrato del proyecto se calculan en modo canónico, con fórmula y paridad (ver niveles de capacidad en el capítulo 2); el resto va por paso directo al motor (sección 7). Las 39 primitivas son estas; 33 son calculables por esta ruta y 6 (bandwidth, rolling_quantile, linreg_endpoint, sma_of, session_position, cross_sectional_rank) solo se usan dentro de estrategias. Aparecen con sus params de ejemplo tal y como los publica el catálogo aprobado (examples/api/16_indicators_catalog_approved.response.json):
| Primitiva | Params (ejemplo) | Entradas | Salidas | first_valid_rule |
|---|---|---|---|---|
sma |
period=10 |
close | sma | period_minus_1 |
ema |
period=10 |
close | ema | period_minus_1 |
rma |
period=10 |
close | rma | period_minus_1 |
wma |
period=20 |
close | wma | period_minus_1 |
hma |
period=32 |
close | hma | chained_sum |
sma_of |
period=20 |
tr | sma | chained_sum |
hl2 |
— | high, low | hl2 | none |
hlc3 |
— | high, low, close | hlc3 | none |
log_price |
— | close | log_price | none |
linreg_endpoint |
period=20 |
val | linreg_endpoint | chained_sum |
rolling_quantile |
period=20, q=0.1 |
bandwidth | quantile | chained_shifted_window |
| Primitiva | Params (ejemplo) | Entradas | Salidas | first_valid_rule |
|---|---|---|---|---|
rsi |
period=14 |
close | rsi | period |
macd |
fast=12, slow=26, signal=9 |
close | macd, signal, hist | chained_sum |
stochrsi |
rsi_period=14, stoch_period=14, smooth_k=3, smooth_d=3 |
close | k, d | chained |
dmi |
period=14 |
high, low, close | plus_di, minus_di, adx | chained |
wavetrend |
channel=10, average=21 |
high, low, close | wt1, wt2 | chained |
squeeze_momentum |
period=20, bb_k=2.0, kc_k=1.5 |
high, low, close | squeeze, val, m | chained_sum |
log_return |
lag=1 |
close | log_return | period |
momentum |
lookback=12, skip=1 |
close | momentum | period |
| Primitiva | Params (ejemplo) | Entradas | Salidas | first_valid_rule |
|---|---|---|---|---|
stddev |
period=20 |
close | stddev | period_minus_1 |
bbands |
period=20, k=2.0 |
close | middle, upper, lower | period_minus_1 |
bandwidth |
period=20, k=2.0 |
middle, upper, lower | bandwidth | chained |
tr |
— | high, low, close | tr | none |
atr |
period=14 |
high, low, close | atr | period_minus_1 |
keltner_sma |
period=20, k=1.5 |
high, low, close | middle, upper, lower | chained |
atr_trailing_stop |
period=10, key_value=3.0 |
high, low, close | stop | chained |
chandelier |
period=22, k=3.0 |
high, low, close | long_stop, short_stop, direction | chained |
rolling_vol |
window=21 |
close | rolling_vol | chained_sum |
| Primitiva | Params (ejemplo) | Entradas | Salidas | first_valid_rule |
|---|---|---|---|---|
donchian |
period=20 |
high, low | upper, lower | period |
supertrend |
period=10, multiplier=3.0 |
high, low, close | upper_final, lower_final, direction | chained |
rolling_max |
period=20 |
high | rolling_max | period_minus_1 |
rolling_min |
period=20 |
low | rolling_min | period_minus_1 |
ichimoku |
tenkan=9, kijun=26, span_b=52, displacement=26 |
high, low | tenkan, kijun, senkou_a, senkou_b | chained |
psar |
acceleration=0.02, maximum=0.2 |
high, low, close | sar, direction, ep, af | fixed_index |
confirmed_pivots |
pivot_half_window=3 |
high, low | pivot_high_level, pivot_low_level | chained |
session_position |
— | session_id, market_open_ns, market_close_ns | bar_index_in_session, … | session_local |
opening_range |
range_minutes=30 |
high, low, market_open_ns, market_close_ns, session_id | range_high, range_low, range_complete, in_range | session_local |
session_vwap |
— | high, low, close, volume, session_id | vwap, var, cum_volume | session_local |
cross_sectional_rank |
descending=false, tiebreak=asset_id_asc |
score_panel, eligible_panel | rank | none |
Qué significa cada first_valid_rule:
| Regla | Lectura |
|---|---|
none |
Válido desde la primera barra (no hay ventana). |
period_minus_1 |
El primer valor válido está en el índice period − 1 (la ventana se llena). |
period |
Un índice más: necesita period diferencias (RSI, retornos). |
chained, chained_sum, chained_shifted_window |
Encadenado: depende de otras features (p. ej. MACD = EMA de EMAs). |
fixed_index |
Índice fijo propio del algoritmo (PSAR). |
session_local |
Se reinicia en cada sesión de mercado. |
Indicadores con entradas no-OHLC
Algunas primitivas consumen otras features (bandwidth consume middle/upper/lower; sma_of consume tr; cross_sectional_rank consume paneles). Existen sobre todo como piezas de estrategias; para explorarlas, empieza por su dossier GET /v1/help/{name}.
3. La petición¶
Petición real examples/api/05_indicators_rsi14_nvda.request.json (payload):
{
"data": { "asset_id": "NVDA", "assets": null, "timeframe": "1min",
"window": { "start": null, "end": null, "mode": "reset_flat", "checkpoint_id": null } },
"indicator": { "indicator": "rsi", "params": { "period": 14 }, "source": "close", "periods_batch": null },
"engine": "both",
"cache": { "cache_mode": "WARM_DATA", "write_through": true, "checkpoint_out": null },
"output": { "output_mode": "metrics", "include_timings": true, "include_parity": true, "tail_rows": 5 },
"profile": { "profile": "one_core", "repetitions": null },
"engine_options": {
"vectorta": { "kernel": "scalar", "use_batch": false, "streaming_provider": "vectorta_stream" },
"nautilus": { "adapter": "NT_ONLINE", "account_type": "MARGIN", "indicator_provider": "native",
"fill_model": null, "latency_model": null, "use_message_queue": false, "log_level": "ERROR" }
}
}
| Campo | Significado |
|---|---|
data |
Igual que en el backtest. Con start/end a null, todo el dataset. |
indicator.indicator |
Nombre de la primitiva (una de las 39). |
indicator.params |
Parámetros de la fórmula (period, k, …). |
indicator.source |
Columna de entrada: open, high, low, close, hl2, hlc3. Debe estar entre las inputs de la primitiva. |
indicator.periods_batch |
Rejilla de periodos en una sola petición; devuelve una entrada por periodo y motor, en el orden pedido. |
engine |
vectorta, nautilus o both. |
output.tail_rows |
Cuántas filas finales devuelve en values_tail. |
import requests
BASE = "http://localhost:8000"
body = {"schema_version": "v1", "payload": {
"data": {"asset_id": "NVDA", "timeframe": "1min",
"window": {"start": None, "end": None, "mode": "reset_flat"}},
"indicator": {"indicator": "rsi", "params": {"period": 14}, "source": "close"},
"engine": "both",
"output": {"output_mode": "metrics", "tail_rows": 5},
"engine_options": {"vectorta": {"kernel": "scalar"}},
}}
p = requests.post(f"{BASE}/v1/indicators", json=body, timeout=600).json()["payload"]
for r in p["results"]:
print(r["engine"], r["provider"]["variant"], r["first_valid_index"],
[round(v["value"], 2) for v in r["values_tail"]])
4. La respuesta (ejemplo real)¶
examples/api/05_indicators_rsi14_nvda.response.json, recortado:
{
"status": "PASS",
"warnings": [],
"signature": { "data_hash": "e8b5fc36…95b0", "formula_version": "1", "params": { "period": 14 },
"execution_contract": null, "cache_mode": "WARM_DATA", "output_mode": "metrics", "…": "…" },
"results": [
{
"engine": "vectorta", "adapter": "VTA_CPU_LEDGER",
"provider": { "provider": "vectorta", "provider_version": "0.2.8", "primitive": "rsi",
"variant": "canonical", "kernel": "scalar", "first_valid_index": 14 },
"n_bars_in": 631735, "n_valid": 631721, "first_valid_index": 14,
"mask_summary": { "leading_nan": 14, "interior_nan": 0, "trailing_nan": 0 },
"values_tail": [
{ "index": 631730, "datetime": "2026-09-14T19:56:00Z", "value": 29.542436906085864 },
"…",
{ "index": 631734, "datetime": "2026-09-14T20:00:00Z", "value": 25.983092554457702 }
],
"stage_timings": { "read_decode_ns": 345387690, "feature_build_ns": 223880436, "end_to_end_wall_ns": 572561393, "…": 0 },
"memory": { "peak_rss_bytes": 631099392 }
},
{
"engine": "nautilus", "adapter": "NT_FEATURES",
"provider": { "provider": "nautilus", "provider_version": "1.231.0", "primitive": "rsi",
"variant": "nt_init_period_minus_1_scaled_0_1", "kernel": "cython", "first_valid_index": 13 },
"n_bars_in": 631735, "n_valid": 631722, "first_valid_index": 13,
"mask_summary": { "leading_nan": 13, "interior_nan": 0, "trailing_nan": 0 },
"values_tail": [
{ "index": 631730, "datetime": "2026-09-14T19:56:00Z", "value": 26.49663618891308 },
"…",
{ "index": 631734, "datetime": "2026-09-14T20:00:00Z", "value": 21.649139543227847 }
],
"…": "…"
}
],
"parity": null,
"cache": { "features_hits": [], "features_misses": ["rsi"], "result_hit": false, "…": "…" }
}
4.1 Campo a campo¶
| Campo | Qué te dice |
|---|---|
provider.provider |
La librería que calculó (vectorta, nautilus, canonical), nunca una función. |
provider.variant |
La forma exacta: canonical o una variante declarada (nt_init_period_minus_1_scaled_0_1). |
provider.kernel |
El kernel realmente ejecutado (scalar, cython…), no el pedido. |
n_bars_in |
Barras de entrada: 631 735 barras de 1 minuto de NVDA. |
n_valid |
Barras con valor válido. |
first_valid_index |
Primera barra fiable (con varias salidas, el máximo de todas). |
mask_summary |
NaN al principio, en medio y al final. interior_nan: 0 significa que no hay huecos inesperados. |
values_tail |
Últimas tail_rows filas con índice, fecha y valor. |
Comprobación aritmética: n_bars_in − leading_nan = n_valid → 631 735 − 14 = 631 721 (VectorTA) y 631 735 − 13 = 631 722 (Nautilus).
4.2 14 frente a 13, y 25,98 frente a 21,65: semilla y fórmula¶
Por qué el RSI de Nautilus «empieza antes» y da otros valores
Hay dos diferencias distintas entre las dos curvas del ejemplo, y conviene no mezclarlas.
1. La semilla (explica 14 frente a 13). El RSI suaviza ganancias y pérdidas con una media exponencial que hay que sembrar:
- La primitiva canónica (VectorTA) siembra con las primeras
perioddiferencias ⇒ primer valor en el índice 14. - Nautilus marca
initializedenperiod − 1y trabaja internamente en 0..1 (el proveedor lo reescala a 0..100) ⇒ primer valor en el índice 13.
Una diferencia de semilla decae como (1−α)^k y, tras cientos de miles de barras, desaparece.
2. La fórmula de suavizado (explica 25,98 frente a 21,65). En la última barra del ejemplo (índice 631 734) VectorTA da 25,98 y Nautilus 21,65: más de 4 puntos tras 631 735 barras. Eso no es semilla. El RelativeStrengthIndex de nautilus_trader 1.231.0, con su media por defecto, suaviza con una EMA de α = 2/(n+1) (2/15 con n = 14), mientras que el RSI de Wilder que implementa la primitiva canónica usa α = 1/n (1/14). Medido en esta revisión sobre 20 000 puntos sintéticos: la curva de Nautilus coincide con un RSI de α = 2/15 hasta 1,4e-14 y difiere del de Wilder hasta 15,7 puntos en las últimas 1 000 barras. Las dos curvas no convergen nunca: es una diferencia de definición, como la BB de Nautilus sobre precio típico.
Lo firme: la ficha del RSI declara el carril de Nautilus como variant (nt_init_period_minus_1_scaled_0_1), no como native, y esta ruta no afirma paridad (parity: null). Una variante declarada no es un bug; una variante escondida sí lo sería.
Dos textos del repositorio dicen otra cosa
examples/api/README.md (paseo 5) afirma que en la cola la diferencia medida es de ~1e-13 sobre 632 095 barras, y el docstring de finazbench/features/provider_nautilus.py dice que el RSI de Nautilus converge «asintóticamente» a la canónica. El fichero regenerado (631 735 barras, 25,98 frente a 21,65) y la medida anterior los contradicen. Los backtests con NT_FEATURES sí pasan paridad porque ese adaptador comparte las features del lado canónico: la diferencia del RSI nativo de Nautilus solo aparece cuando Nautilus calcula el indicador por su cuenta.
Detalles de implementación que conviene conocer (compute_indicator en finazbench/runner/from_api.py)
stage_timingsse mide una sola vez para toda la petición (lectura más el cálculo de los dos motores) y el mismo diccionario se copia en cada entrada deresults: por eso las dos entradas del ejemplo tienen cifras idénticas (read_decode_ns≈ 345 ms,feature_build_ns≈ 224 ms, que suma los dos motores, total ≈ 573 ms). No leas esas cifras como el coste de cada motor.- El
adapterde cada entrada no sale de la petición: el código escribeVTA_CPU_LEDGERpara VectorTA yNT_FEATURESfijo para Nautilus. Por eso el ejemplo publicaNT_FEATURESaunque pidaNT_ONLINE;engine_optionssolo se valida. En esta ruta el indicador de Nautilus es siempre el nativo de la librería, con cualquier adaptador. parityes siemprenullen esta ruta, también conengine: "both"einclude_parity: true: el código no compara las curvas. La comparación formal vive enPOST /v1/parity(capítulo 4), no aquí.statuses"PASS"siempre que el cálculo termina: significa «calculado», no «los motores coinciden».values_tailtrae solo la primera salida de la primitiva (spec.outputs[0]); en indicadores con varias salidas, el resto no aparece en la cola.- La caché de features no está cableada (DEV-06b-01):
features_misses: ["rsi"]siempre.
5. periods_batch: una rejilla en una llamada¶
Cuando quieres varias longitudes del mismo indicador (p. ej. EMAs de 5 a 200 para un barrido), periods_batch evita N peticiones:
"indicator": { "indicator": "ema", "params": { "period": 20 }, "source": "close",
"periods_batch": [5, 10, 20, 40, 50, 100, 150, 200] }
La respuesta trae una entrada por periodo y por motor, en el orden pedido. Solo aplica a primitivas con parámetro period.
use_batch hoy no acelera
engine_options.vectorta.use_batch permite usar la forma <primitiva>_batch de VectorTA. El contrato documenta una medida en la que ema_batch(5..50) tardó 40 ms frente a 30 ms en bucle: con el wheel PyPI actual el batch no paraleliza. El resultado es idéntico en cualquier caso.
6. Copiar y pegar: example_curl¶
Cada ficha registrada (GET /v1/indicators/{name} o GET /v1/help/{name}) trae un example_curl que funciona tal cual. El real del RSI (09_indicator_detail.response.json):
curl -sS -X POST "$BASE/v1/indicators" -H 'Content-Type: application/json' -d '{"schema_version": "v1", "payload": {"data": {"asset_id": "NVDA", "timeframe": "1d", "window": {"start": null, "end": null, "mode": "reset_flat"}}, "indicator": {"indicator": "rsi", "params": {"period": 14}, "source": "close"}, "engine": "both", "engine_options": {"vectorta": {"kernel": "scalar", "use_batch": true}, "nautilus": {"adapter": "NT_FEATURES", "indicator_provider": "native"}}}}'
Un truco para cualquier primitiva:
NAME=bbands
curl -sS "$BASE/v1/help/$NAME" | jq -r '.payload.example_curl' > /tmp/req.sh
BASE=$BASE bash /tmp/req.sh | jq '.payload.results[] | {engine, first_valid_index, n_valid}'
7. Paso directo al motor¶
Las 39 primitivas registradas no son todo lo que la API sabe calcular. Para los 347 indicadores
que solo existen en un motor (nivel discovered), POST /v1/indicators ofrece un segundo modo:
el paso directo al motor (execution_mode: engine_passthrough). La API llama al motor que
posee el indicador y devuelve exactamente lo que el motor calcula, sin reinterpretarlo.
Cifra (medida por tools/probe_indicators.py, runs/env/indicators_probe.json) |
Valor |
|---|---|
| Entradas del catálogo | 386 |
Ejecutables por POST /v1/indicators |
375 |
| …en modo canónico (fórmula canónica y paridad verificada) | 33 |
| …por paso directo al motor (sin garantías canónicas) | 342 (323 con VectorTA, 21 con Nautilus; 2 en ambos) |
No ejecutables, con not_computable_reason |
11 |
flowchart LR
R["POST /v1/indicators"] --> K{"¿Primitiva<br/>registrada?"}
K -- sí --> C["modo canonical<br/>fórmula + paridad"]
K -- no --> M{"¿Algún motor<br/>lo posee?"}
M -- no --> E0["422 INDICATOR_PARAMS_INVALID"]
M -- sí --> P{"¿Params válidos<br/>para ese motor?"}
P -- no --> E1["422 INDICATOR_PARAMS_INVALID<br/>details.accepted"]
P -- sí --> A{"¿Alimentable con<br/>barras OHLCV?"}
A -- no --> E2["501 LANE_UNSUPPORTED"]
A -- sí --> PT["200 engine_passthrough<br/>nivel sigue discovered"]
7.1 Ejemplo real: alma con VectorTA¶
Petición (examples/api/17_indicators_alma_passthrough.request.json, recortada):
{
"payload": {
"data": {"asset_id": "NVDA", "timeframe": "1d",
"window": {"start": null, "end": null, "mode": "reset_flat"}},
"indicator": {"indicator": "alma", "params": {"period": 9}, "source": "close"},
"engine": "vectorta",
"engine_options": {"vectorta": {"kernel": "scalar", "use_batch": true}}
}
}
Respuesta (17_indicators_alma_passthrough.response.json, recortada):
{
"payload": {
"status": "PASS",
"warnings": ["ENGINE_PASSTHROUGH: valores del motor sin fórmula canónica ni paridad; semilla de calentamiento y escala propias de cada motor."],
"execution_mode": "engine_passthrough",
"capability": {"level": "discovered", "computable_via_api": true,
"computable_engines": ["vectorta"]},
"guarantees": {"canonical_formula": false, "first_valid_rule": "observed",
"parity": "not_applicable"},
"results": [{
"engine": "vectorta", "adapter": "VTA_CPU_LEDGER",
"native": {"module": "vector_ta", "name": "alma", "lane": "batch"},
"n_bars_in": 1627, "n_valid": 1619, "first_valid_index": 8,
"first_valid_rule": "observed",
"outputs": [{"name": "value", "first_valid_index": 8, "n_valid": 1619}],
"params_resolved": {
"period": {"value": 9, "source": "request"},
"offset": {"value": 0.85, "source": "project_probe_default"},
"sigma": {"value": 6.0, "source": "project_probe_default"}
},
"values_tail": [{"index": 1626, "datetime": "2026-09-14T20:00:00Z",
"value": 218.0196459373903}]
}]
}
}
Qué hay que leer:
status: PASSsignifica «el motor calculó», no «coincide con una fórmula del proyecto».first_valid_index: 8es observado (primer valor finito), no una regla declarada.params_resolveddice de dónde sale cada parámetro:periodlo pediste tú;offsetysigmalos puso la sonda del proyecto.capability.levelsigue siendodiscovered: el paso directo no promueve el nivel.
Hay un segundo ejemplo real con Nautilus (18_indicators_aroonosc_nautilus_passthrough.*):
AroonOscillator con period=14, adaptador NT_ONLINE, first_valid_index 14 y tres salidas
(value, aroon_up, aroon_down). Y uno de error (93_error_indicator_passthrough_params_invalid.response.json):
pedir alma con periodo devuelve 422 INDICATOR_PARAMS_INVALID con
details.accepted: ["offset", "period", "sigma"].
7.2 Campos nuevos¶
| Campo | Dónde | Qué dice |
|---|---|---|
execution_mode |
catálogo, ayuda y respuesta | canonical o engine_passthrough |
computable_via_api |
catálogo y ayuda | si la API lo calcula de verdad (medido por la sonda) |
computable_engines |
capability |
qué motores lo calculan por paso directo |
not_computable_reason |
capability |
por qué no es ejecutable (solo en los 11 no ejecutables) |
capability_counts.computable_passthrough |
catálogo | entradas discovered calculables por paso directo (342); no es un nivel |
mode |
filtro de GET /v1/indicators |
canonical | passthrough | all |
params_resolved |
results[] |
valor y origen de cada parámetro: request, engine_default, engine_internal o project_probe_default |
outputs |
results[] |
todas las salidas del motor con su first_valid_index observado |
native |
results[] |
módulo, nombre y carril nativo que se ejecutó |
guarantees |
respuesta y capability |
canonical_formula: false, first_valid_rule: observed, parity: not_applicable |
7.3 Los 11 no ejecutables¶
| Indicador | Motivo | Código |
|---|---|---|
bandwidth, rolling_quantile, linreg_endpoint, sma_of, session_position, cross_sectional_rank |
primitivas registradas que leen series derivadas o paneles; solo se usan dentro de estrategias | 422 |
rsmk, spearman_correlation |
necesitan una serie de comparación | 501 |
decisionpoint_breadth_swenlin_trading_oscillator |
necesita datos de amplitud de mercado | 501 |
SpreadAnalyzer |
se alimenta de cotizaciones bid/ask, no de barras | 501 |
half_causal_estimator |
rechaza slots_per_day=1 en diario |
422 |
Calcular no es certificar
Una curva de paso directo sirve para explorar. Para usarla en un resultado publicable con paridad, el indicador tiene que promoverse (ver Niveles de capacidad).
8. Errores típicos¶
| Situación | Código | Pista en details |
|---|---|---|
| Nombre que no está en el catálogo de ningún motor | 422 INDICATOR_PARAMS_INVALID |
field: "indicator.indicator", value, params |
Paso directo con parámetros que el motor no admite (p. ej. periodo en alma) |
422 INDICATOR_PARAMS_INVALID |
unknown, accepted |
| Paso directo de un indicador que no se alimenta con barras, o motor que no lo posee | 501 LANE_UNSUPPORTED |
available |
source que la primitiva no consume (p. ej. source: "high" en rsi) |
422 INDICATOR_PARAMS_INVALID |
field: "indicator.source", accepted: ["close"] |
| Parámetros fuera de rango | 422 INDICATOR_PARAMS_INVALID |
campo y regla |
| Ventana sin barras | 409 INSUFFICIENT_HISTORY |
asset_id, timeframe |
| Activo o timeframe inexistente | 404 ASSET_NOT_FOUND |
available |
| Un motor no ofrece la primitiva | 501 STRATEGY_UNSUPPORTED_BY_ADAPTER |
indicator, engine |
kernel: "avx2" con el wheel PyPI |
422 ENGINE_OPTION_UNAVAILABLE |
accepted frente a available |
Cambiar source cambia la fórmula
Pedir un RSI sobre high no es «otro RSI»: es otra fórmula. Por eso la API lo rechaza en lugar de calcularlo en silencio. Si necesitas un indicador sobre hl2, usa una primitiva que lo declare en sus inputs.
Resumen¶
POST /v1/indicatorscalcula una curva (no una estrategia) confirst_valid_index, máscara, proveedor declarado y cola de valores.- 386 descubiertos; 375 ejecutables por la API: 33 con fórmula canónica y paridad verificada y 342 por paso directo al motor sin garantías canónicas; 11 no ejecutables con motivo.
- El paso directo devuelve los valores del motor con
first_validobservado y no promueve el nivel (discovered). sourcedebe pertenecer a lasinputsde la primitiva;periods_batchdevuelve una entrada por periodo y motor.- En el ejemplo real, RSI14 sobre 631 735 barras de NVDA 1min:
first_valid_index14 en VectorTA y 13 en Nautilus (semillas distintas) y valores de cola distintos (25,98 frente a 21,65) porque Nautilus suaviza con α = 2/(n+1) y no con el 1/n de Wilder. - En esta ruta el
adapterde Nautilus es siempreNT_FEATURES,stage_timingses global a la petición yparityes siemprenull. - Cada ficha trae un
example_curllisto para ejecutar.
Para practicar¶
- Calcula
bbandsconperiod=20, k=2.0sobre NVDA1d. ¿Cuántas salidas traevalues_tailpor fila (pista: sección 4.2) y cuál es elfirst_valid_index? - Pide
rsiconsource: "high". Leedetails.accepted. - Lanza
emaconperiods_batch: [10, 50, 200]yengine: "vectorta". Comprueba quefirst_valid_indexsigue la reglaperiod_minus_1. - Calcula
almapor paso directo. ¿Qué garantías declara la respuesta y qué dice supromotion_noteenGET /v1/help/alma? - Repite el ejemplo del RSI con
engine: "nautilus"ytail_rows: 20. ¿Se acercan los valores de la cola a los de VectorTA? Explica por qué no, con la sección 4.2.