P14 · Parabolic SAR¶
| Campo | Valor |
|---|---|
| Familia | Tendencia · stop-and-reverse (siempre largo o corto tras el warmup, como P06 y P19) |
| Features requeridas | psar (primitiva nueva de fase B, entradas high, low, close; salidas sar, direction, ep, af) + la columna close de la barra |
| Parámetros y defaults | acceleration = 0.02, maximum = 0.2 |
| Rejilla del catálogo | acceleration ∈ {0.01, 0.02, 0.03, 0.04}, maximum ∈ {0.1, 0.2, 0.3} → 12 candidatos válidos, 12 curvas PSAR distintas |
variant_keys |
acceleration, maximum |
| Restricciones | 0 < acceleration <= maximum (si no, PolicyParamError) |
first_decision_index |
1, con cualquier pareja de parámetros (el calentamiento más corto del catálogo) |
| Activos y timeframes | NVDA y KO en los 7 TF (1min … 1d); AMZN, INTC, MSFT, TSLA en 1d; BME y FX en 1d con los calendarios de WP-01b |
| Paridad en la matriz | PASS en NT_FEATURES, NT_INTENT_REPLAY y NT_ONLINE(vectorta) (12/12 cada una). UNSUPPORTED en NT_ONLINE(native) (12/12): "nautilus_trader 1.231.0 no ofrece un indicador nativo para 'psar'". No es un fallo: no hay nada nativo con qué comparar, y el carril no se rellena con un cálculo propio disfrazado de nativo |
Fuentes: docs/estrategias/P14.md (especificación), catalog/strategy_catalog.json, docs/DATOS_POR_ESTRATEGIA.md, runs/parity/summary.json.
Qué vas a aprender¶
- Cómo se construye el Parabolic SAR: un "suelo" que sube cada vez más deprisa mientras el precio marca máximos nuevos, y que salta al otro lado cuando el precio lo perfora.
- Por qué en el banco de backtesting el SAR no es una orden stop: se decide en el cierre y se ejecuta en la apertura siguiente.
- Las cuatro piezas de la recursión (SAR, dirección, EP, AF) y los dos detalles que más implementaciones hacen mal: la semilla en el índice 1 y la limitación por los dos extremos previos.
- A seguir en el fixture una entrada, la aceleración del AF y dos reversiones con delta 2.
- Por qué P14 es el peor caso de factorización del catálogo: 12 candidatos, 12 curvas.
La idea en una frase¶
Si el cierre queda por encima del punto parabólico, estar largo; si queda por debajo, estar corto; el punto parabólico persigue al precio y, cuando lo alcanza, cambia de lado.
Intuición de mercado¶
El PSAR de Welles Wilder es un trailing stop con prisa. En una tendencia alcista coloca un nivel por debajo del precio y lo va subiendo cada barra una fracción (AF) de la distancia al máximo del tramo (EP, extreme point). Cada máximo nuevo aumenta esa fracción, así que cuanto más dura la tendencia, más deprisa se acerca el nivel. Cuando el precio lo perfora, se asume que la tendencia ha terminado y se da la vuelta: el nivel salta al máximo del tramo anterior y empieza a perseguir desde arriba.
Analogía. Un perro pastor que sigue al rebaño: al principio camina lejos y despacio; a medida que el rebaño avanza en la misma dirección, se acerca cada vez más rápido. Si el rebaño da media vuelta y se topa con él, el perro se cambia al otro lado y vuelve a empezar despacio.
Por qué podría funcionar. Recoge el mismo momentum de medio plazo que P01, pero con una salida que se aprieta con el tiempo: protege más ganancia en tendencias largas que una media fija.
Cuándo falla.
- Mercados laterales: el SAR se sitúa cerca del precio muy pronto y cualquier oscilación lo perfora. Cada perforación es una reversión de 2 unidades, con doble comisión.
- Intradía (1min): el ruido acelera el AF y las reversiones se disparan; la especificación pide reportar las reversiones por sesión, no esconderlas.
- Gaps de apertura: la parábola cruza el hueco nocturno sin reiniciarse y un gap produce reversiones sistemáticas en la primera barra de la sesión.
Sesgos típicos al evaluarla.
- Leerla como stop intrabar: si en tu hoja de cálculo sales "al tocar el SAR" dentro de la barra, estás midiendo otra estrategia (sería SIM-R, con su propio id).
- Elegir el AF a posteriori: la rejilla tiene 12 combinaciones y ninguna comparte curva con otra; es fácil encontrar una "buena" por azar.
- Semilla distinta: dos PSAR con la misma pareja de parámetros pero semilla distinta invierten en barras distintas. No es ruido numérico: son estrategias distintas.
Las reglas exactas¶
La regla canónica del catálogo: "Calcular PSAR causal con acceleration y maximum. Objetivo +1 cuando SAR
Situación en el cierre de t |
Objetivo target[t] |
Motivo (reason) |
|---|---|---|
t = 0 (el SAR aún es NaN) |
0 | WARMUP |
sar[t] < close[t] (estricto) |
+1 | ENTRY / REVERSAL / HOLD |
sar[t] > close[t] (estricto) |
−1 | ENTRY / REVERSAL / HOLD |
sar[t] == close[t] |
el anterior | HOLD |
sar[t] NaN tardío |
el anterior (y el proveedor debería haber rechazado la serie) | HOLD |
barra no operable (is_tradable = False) |
se congela el publicado; la parábola sigue calculándose | NOT_TRADABLE |
- Entrada: en la barra 1 ya hay SAR y la comparación con el cierre da ±1.
- Salida: no existe salida a plano; salir de un largo es invertir a corto.
- Reversión: permitida y habitual; una sola orden de 2 unidades.
- Filtros: ninguno.
La feature, según la convención canónica de engineering_notes:
Semilla (t = 1):
direction = +1 si close[1] >= close[0], si no -1 # el empate va a alcista
alcista: sar = min(L0, L1); ep = max(H0, H1)
bajista: sar = max(H0, H1); ep = min(L0, L1)
af = acceleration
Recursión (t >= 2), con los valores de t-1:
raw = sar_prev + af_prev * (ep_prev - sar_prev)
proj = min(raw, L[t-1], L[t-2]) si alcista # dos extremos PREVIOS
= max(raw, H[t-1], H[t-2]) si bajista
si alcista y L[t] < proj (o bajista y H[t] > proj): # estricto
direction = -direction; sar = ep_prev
ep = extremo actual de la nueva dirección; af = acceleration
si no:
sar = proj
si hay extremo ESTRICTO nuevo: ep = ese extremo; af = min(af_prev + acceleration, maximum)
Y la política:
# decisión en el cierre de t, fill en el open de t+1
target_prev = 0
para cada barra t:
si t < 1: target = 0 # WARMUP
si no, si sar[t] < close[t]: target = +1
si no, si sar[t] > close[t]: target = -1
si no: target = target_prev # empate o NaN
si target != target_prev:
delta = target - target_prev # +1 al entrar, ±2 al invertir
orden(delta) -> fill a open[t+1]
target_prev = target
El objetivo sale de comparar con el cierre, no de direction
Casi siempre target[t] == direction[t], pero la regla canónica compara sar[t] con close[t]. En la barra de inversión, sar[t] = ep_prev, y si el cierre quedara al otro lado de ese nivel, el objetivo seguiría a la comparación. La especificación lo registra en §11 como diferencia deliberada frente a P06 y P19, cuyo objetivo sí es la dirección del indicador.
Los indicadores que usa¶
| Feature | Fórmula | first_valid |
|---|---|---|
psar.sar |
recursión de arriba; sar[0] = NaN |
1 (regla fixed_index, independiente de los parámetros) |
psar.direction, psar.ep, psar.af |
estado de la parábola tras la barra t |
1 |
first_decision_index = 1. Solo la barra 0 es calentamiento. Las tres salidas de estado no las consume la política: existen porque son el checkpoint mínimo para reanudar en modo continue sin recalcular la serie.
La recursión es causal y no vectorizable: sar[t] depende de sar, ep, af y direction de t−1, y la rama de inversión cambia las cuatro a la vez. La política, en cambio, es enteramente vectorial (dos comparaciones y un arrastre del último evento). Detalle de la primitiva en Las 23 primitivas de fase B; contexto general en Indicadores y features.
Ejemplo barra a barra¶
Fixture §6 de docs/estrategias/P14.md: 16 barras, acceleration = 0.02, maximum = 0.2 (los defaults, dentro de rejilla), cash_inicial = 1.000,00, tick 0,01, sin costes. first_decision_index = 1.
Se muestran 14 de las 16 barras; las barras 11 y 12 (corto mantenido, HOLD) se omiten: sar 12,1696 y 12,0274, ep 9,80, af 0,06.
| t | O | H | L | C | sar | ep | af | target | orden | fill | pos. | PnL acum. sin costes | equity con 5 bps* |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 10,05 | 10,20 | 10,00 | 10,15 | NaN | NaN | NaN | 0 WARMUP | — | — | 0 | 0,00 | 1.000,00 |
| 1 | 10,25 | 10,50 | 10,20 | 10,45 | 10,0000 | 10,5000 | 0,02 | +1 ENTRY | BUY 1 | — | 0 | 0,00 | 1.000,00 |
| 2 | 10,60 | 10,90 | 10,55 | 10,85 | 10,0000 | 10,9000 | 0,04 | +1 | — | 10,60 | +1 | 0,25 | 1.000,24 |
| 3 | 11,00 | 11,40 | 10,95 | 11,35 | 10,0360 | 11,4000 | 0,06 | +1 | — | — | +1 | 0,75 | 1.000,74 |
| 4 | 11,20 | 11,30 | 10,90 | 11,00 | 10,1178 | 11,4000 | 0,06 | +1 | — | — | +1 | 0,40 | 1.000,39 |
| 5 | 11,35 | 11,80 | 11,30 | 11,75 | 10,1948 | 11,8000 | 0,08 | +1 | — | — | +1 | 1,15 | 1.001,14 |
| 6 | 11,90 | 12,30 | 11,85 | 12,25 | 10,3232 | 12,3000 | 0,10 | +1 | — | — | +1 | 1,65 | 1.001,64 |
| 7 | 12,00 | 12,10 | 11,40 | 11,50 | 10,5209 | 12,3000 | 0,10 | +1 | — | — | +1 | 0,90 | 1.000,89 |
| 8 | 11,50 | 11,60 | 10,90 | 11,00 | 10,6988 | 12,3000 | 0,10 | +1 | — | — | +1 | 0,40 | 1.000,39 |
| 9 | 10,95 | 11,00 | 10,30 | 10,40 | 12,3000 | 10,3000 | 0,02 | −1 REVERSAL | SELL 2 | — | +1 | −0,20 | 999,79 |
| 10 | 10,55 | 10,60 | 10,00 | 10,10 | 12,2600 | 10,0000 | 0,04 | −1 | — | 10,55 | −1 | 0,40 | 1.000,38 |
| 13 | 10,45 | 10,90 | 10,40 | 10,85 | 11,8938 | 9,8000 | 0,06 | −1 | — | — | −1 | −0,35 | 999,63 |
| 14 | 11,05 | 11,50 | 11,00 | 11,45 | 11,7682 | 9,8000 | 0,06 | −1 | — | — | −1 | −0,95 | 999,03 |
| 15 | 11,50 | 11,90 | 11,45 | 11,85 | 9,8000 | 11,9000 | 0,02 | +1 REVERSAL | BUY 2 | sin fill | −1 | −1,35 | 998,63 |
OHLC, sar, ep, af, objetivos y fills son literales del fixture (§6.1, §6.2 y §6.4). El fixture da la equity en las barras 2 (1.000,25), 10 (1.000,40) y 15 (998,65); en el resto de barras el PnL es cálculo de este manual con la regla trivial equity = cash + posición · close[t]. *"Equity con 5 bps" es también cálculo de este manual: escenario hypothetical_5bps (fee_rate = 0,0005, sin spread ni deslizamiento), comisión por fill = |delta| · precio · 0,0005 redondeada al céntimo half-even y restada de la caja en la barra del fill: fill 1 → 10,60 · 0,0005 = 0,0053 → 0,01; fill 2 → 2 · 10,55 · 0,0005 = 0,01055 → 0,01.
Lo que hay que ver en la tabla:
- Barra 1: con una sola barra de historia ya hay SAR (10,00) y la política entra. La orden se decide al cierre de 1 (10,45) y se llena al open de 2 (10,60).
- Barras 2–6: el AF sube 0,02 → 0,04 → 0,06 → 0,08 → 0,10 solo cuando hay máximo estricto nuevo. En la barra 4 no sube:
H4 = 11,30 < EP = 11,40. - Barras 7–8: el precio cae, pero el mínimo (11,40; 10,90) sigue por encima del SAR proyectado. El SAR sigue subiendo sin acelerar.
- Barra 9:
L9 = 10,30 < 10,8589perfora la proyección. El SAR salta a 12,30 (el EP del tramo alcista), el EP pasa a ser el mínimo actual y el AF se reinicia a 0,02. Orden de 2 unidades llenada al open de 10 (10,55). - Barra 15:
H15 = 11,90 > 11,6501invierte otra vez, pero no hay barra 16: la señal queda sin fill y el corto se valora al último cierre. No hay liquidación automática.
Las cuentas de las barras clave¶
Semilla (t=1): C1 = 10,45 >= C0 = 10,15 -> alcista
sar[1] = min(L0, L1) = min(10,00; 10,20) = 10,0000
ep[1] = max(H0, H1) = max(10,20; 10,50) = 10,5000 ; af[1] = 0,02
10,0000 < C1 = 10,45 -> +1 ENTRY
Dos extremos (t=2): raw = 10,0000 + 0,02·(10,5000 - 10,0000) = 10,0100
proj = min(10,0100; L1=10,20; L0=10,00) = 10,0000 <- muerde L0
L2 = 10,55 < 10,0000? No -> sin inversión
H2 = 10,90 > ep 10,50 -> ep = 10,90 ; af = 0,04
Reversión (t=9): sar_prev = 10,698782305920 (sin redondear), af_prev = 0,10, ep_prev = 12,30
raw = 10,698782305920 + 0,10·(12,30 - 10,698782305920) = 10,858904075328
proj = min(10,858904; L8=10,90; L7=11,40) = 10,858904
L9 = 10,30 < 10,858904 -> invierte: sar = 12,30 ; ep = 10,30 ; af = 0,02
12,30 > C9 = 10,40 -> -1 REVERSAL
Caja: 1.000,00 - 10,60 = 989,40 (fill 1, open[2])
989,40 + 2·10,55 = 1.010,50 (fill 2, open[10])
Equity final: 1.010,50 + (-1)·11,85 = 998,65
Encadenar sin redondear
Si en la barra 9 usas el sar_prev ya redondeado a cuatro decimales (10,6988), obtienes raw = 10,85892, que difiere en la sexta cifra. La recursión se encadena en float64; las cifras de las tablas son presentación. Por eso los tests comparan con la cadena completa y no con la tabla impresa.
Qué pasaría con un solo extremo previo. En la barra 2, min(10,0100; L1 = 10,20) = 10,0100 en lugar de 10,0000. La curva ya sería otra desde la tercera barra y, arrastrada, movería las reversiones. Es la variante vta_sar_single_clamp que la especificación pide verificar en VectorTA.
Diagrama¶
flowchart LR
W(["WARMUP: t = 0"]) -->|"t = 1 · SAR < C · BUY 1"| L["Largo +1"]
W -->|"t = 1 · SAR > C · SELL 1"| S["Corto -1"]
L -->|"SAR > C · SELL 2"| S
S -->|"SAR < C · BUY 2"| L
L -->|"SAR <= C"| L
S -->|"SAR >= C"| S
Tras la barra 1, P14 nunca está plana: solo alterna entre largo y corto. Un 0 posterior con decision_index_valid = True sería un fallo.
Cómo lanzarla¶
Backtest con ambos motores sobre NVDA diario (2015–2024), con los defaults. La estrategia se referencia por plantilla y parámetros (forma "inline" de la API de backtesting, docs/API.md §3.2); el resto del payload sigue examples/api/01_backtest_p01_both.request.json:
BASE=http://localhost:8000
SID=$(curl -sS -X POST "$BASE/v1/backtest" -H 'Content-Type: application/json' -d '{
"request_id": "manual-p14-0001",
"correlation_id": null,
"schema_version": "v1",
"payload": {
"strategy": {"template_id": "P14", "params": {"acceleration": 0.02, "maximum": 0.2},
"name": "PSAR 0.02/0.2 base", "register": true},
"data": {"asset_id": "NVDA", "timeframe": "1d",
"window": {"start": "2015-01-01T00:00:00Z", "end": "2025-01-01T00:00:00Z",
"mode": "reset_flat"}},
"execution": {"lane": "SIM-S", "contract_version": "1", "initial_cash": 100000,
"target_lots": [-1, 0, 1], "cost_scenario": "hypothetical_5bps"},
"engine": "both",
"cache": {"cache_mode": "WARM_FEATURES", "write_through": true},
"output": {"output_mode": "metrics", "include_timings": true,
"include_parity": true, "tail_rows": 5},
"engine_options": {"vectorta": {"kernel": "scalar", "use_batch": true},
"nautilus": {"adapter": "NT_FEATURES"}}
}}' | jq -r '.payload.signature.strategy_id')
echo "$SID"
import uuid, requests
BASE = "http://localhost:8000"
env = lambda payload: {"request_id": str(uuid.uuid4()), "correlation_id": None,
"schema_version": "v1", "payload": payload}
payload = {
"strategy": {"template_id": "P14", "params": {"acceleration": 0.02, "maximum": 0.2},
"register": True},
"data": {"asset_id": "NVDA", "timeframe": "1d",
"window": {"start": "2015-01-01T00:00:00Z",
"end": "2025-01-01T00:00:00Z", "mode": "reset_flat"}},
"execution": {"lane": "SIM-S", "contract_version": "1", "initial_cash": 100000,
"target_lots": [-1, 0, 1], "cost_scenario": "hypothetical_5bps"},
"engine": "both",
"output": {"output_mode": "metrics", "include_parity": True},
"engine_options": {"vectorta": {"kernel": "scalar", "use_batch": True},
"nautilus": {"adapter": "NT_FEATURES"}},
}
r = requests.post(f"{BASE}/v1/backtest", json=env(payload)).json()["payload"]
SID = r["signature"]["strategy_id"] # "P14-xxxxxx": hash de plantilla + parámetros
print(SID, r["parity"]["verdict"])
for res in r["results"]:
print(res["adapter"], res["run_metrics"]["final_equity"], res["run_metrics"]["n_fills"])
No pidas indicator_provider: "native" con NT_ONLINE: la matriz lo marca UNSUPPORTED porque Nautilus 1.231.0 no trae PSAR.
Derivar una variante con un AF inicial mayor:
curl -sS -X POST "$BASE/v1/strategies/$SID/derive" -H 'Content-Type: application/json' -d '{
"request_id": "manual-p14-derive", "correlation_id": null, "schema_version": "v1",
"payload": {"param_overrides": {"acceleration": 0.03}, "name": "PSAR 0.03/0.2",
"slug": "psar-0-03-0-2", "tags": ["sensibilidad"]}}' | jq '.payload.strategy_id, .payload.cache_forecast'
acceleration es parámetro de feature: según la tabla de invalidación (§5.3 de la especificación) hay que rehacer la curva psar entera, la política y el ledger; solo se reutilizan datos, manifiesto y calendario. El cache_forecast debe anunciar la curva psar como fallo esperado y ninguna feature reutilizable. Lo mismo vale para maximum.
Sweep de sus variant_keys (rejilla completa del catálogo, con la forma de 03_sweep_p01_4x4.request.json):
curl -sS -X POST "$BASE/v1/sweep" -H 'Content-Type: application/json' -d '{
"request_id": "manual-p14-sweep", "correlation_id": null, "schema_version": "v1",
"payload": {"base_strategy_id": "'"$SID"'",
"grid": {"acceleration": [0.01, 0.02, 0.03, 0.04], "maximum": [0.1, 0.2, 0.3]},
"candidate_policy": {"drop_invalid": true, "drop_duplicates": true,
"register_strategies": true,
"name_template": "{template_name} {acceleration}/{maximum}"},
"data": {"asset_id": "NVDA", "timeframe": "1d",
"window": {"start": "2015-01-01T00:00:00Z", "end": "2025-01-01T00:00:00Z", "mode": "reset_flat"}},
"execution": {"lane": "SIM-S", "contract_version": "1", "initial_cash": 100000,
"cost_scenario": "hypothetical_5bps"},
"engine": "vectorta", "cache": {"cache_mode": "OPT_FULL"},
"output": {"output_mode": "metrics"},
"engine_options": {"vectorta": {"kernel": "scalar", "use_batch": true}}}}' | jq '.payload.job_id, .payload.factorization_plan'
Según §5.4 de la especificación: 12 candidatos cartesianos, 12 válidos, 12 curvas psar distintas. El resultado se consulta en GET /v1/jobs/{job_id}.
Cuánto cuesta la rejilla¶
| Concepto | Cuenta |
|---|---|
| Candidatos cartesianos | 4 acceleration × 3 maximum = 12 |
Inválidos por acceleration <= maximum |
0 (el mayor acceleration, 0,04, es menor que el menor maximum, 0,1) |
Curvas psar distintas |
12: los dos parámetros entran en la recursión |
| Ahorro de caché en features | ninguno (factor ≈ 1,0) |
| Memoria, rejilla completa en 1min (N = 632.000) | 12 curvas × 4 salidas × N × 8 B ≈ 242,7 MB; con bloques de 4 candidatos el pico baja a ≈ 109 MB |
Compárese con P15 (20 candidatos válidos → 4 curvas) o P16 (36 → 6). acceleration actúa en la semilla, en cada incremento y en cada reinicio; maximum en el tope. Dos recursiones que difieren en uno de ellos divergen desde la primera barra en que actúa. Lo único que se reutiliza entre candidatos es la lectura del activo, y un cambio de comisión reutiliza curva y decisiones y solo rehace el ledger.
Qué mirar en los resultados¶
parity.verdictenNT_FEATURES: la matriz da PASS en features, señales, fills y equity. Los cuatro carriles consumen la misma curva canónica; el microbenchmark devector_ta.sarse reporta aparte con la etiquetano_equivalentesi su curva difiere, y los trades no se ajustan.- Número de reversiones y reversiones por sesión: es la métrica que distingue un PSAR utilizable de uno ahogado en ruido.
- Duración media del tramo direccional (barras entre reversiones), por candidato: es la lectura directa de
acceleration. - Fracción de barras con
af == maximum: dice si el tope actúa o es decorativo. - Distancia media
|close − sar| / close: cuán cerca va el "stop". - Exposición neta: ±1 en el 100 % de las barras operables desde la barra 1. Un 0 es un fallo.
costs_total: cada reversión paga 2 unidades de comisión.DATA_GAP_SESSIONSsi usas KO (271 sesiones ausentes): la parábola cruza el hueco con el mismo AF y el mismo EP.
Causalidad comprobada¶
Las fugas típicas del PSAR son sutiles porque dan curvas "razonables":
- Limitar con el mínimo de la barra actual (
min(raw, L[t], L[t−1])): la barratnunca podría perforar un nivel que ya incluye su propio mínimo, así que el SAR no invertiría nunca. En el fixture desaparecería la reversión de la barra 9. - Comparar con el cierre de la barra de fill (
sar[t] < close[t+1]): la mejora sistemática clásica. - Reiniciar el AF una barra tarde: el fixture lo caza en la barra 9 (AF 0,02, no 0,12).
El test de "futuros alterados" de la especificación multiplica por 3 high, low y close desde la barra 150 y exige igualdad bit a bit de sar, direction, ep, af, objetivos y fills hasta la barra 120. Un complemento perturba solo la barra 150 y comprueba que sar[149] no cambia y sar[151] sí, porque la limitación de 151 usa low[150].
Para reanudar en modo continue basta un checkpoint con los cuatro escalares de estado (sar, direction, ep, af en T), los dos extremos previos (low[T], low[T−1], high[T], high[T−1]), el objetivo vigente y el ledger. Guardar solo sar[T] no basta.
Errores típicos¶
| Error | Consecuencia | Cómo evitarlo |
|---|---|---|
acceleration > maximum o acceleration = 0 |
PolicyParamError (el tope se violaría ya en la semilla; con 0 la parábola es una recta) |
Respeta 0 < acceleration <= maximum; en un sweep cuenta como inválido |
| Sembrar en el índice 0 | Toda la parábola desplazada; reversiones en otras barras | La semilla canónica está en el índice 1; si otro motor siembra en 0, es otra variante |
| Limitar con un solo extremo previo | Curva distinta desde la barra 2 del fixture | min(raw, L[t−1], L[t−2]) en alcista, max(raw, H[t−1], H[t−2]) en bajista |
Invertir con <= en vez de < |
Reversiones de más en toques exactos | L[t] == proj no invierte |
| Acelerar con un empate de máximo | AF inflado sin máximo nuevo | Solo H[t] > ep_prev estricto acelera |
| Llenar "al tocar el SAR" | Otra estrategia (stop intrabar) | En SIM-S la señal es de cierre y el fill es open[t+1] |
| Redondear el SAR entre barras | Deriva en la sexta cifra que puede mover una reversión | Encadena en float64 |
| Usar el PSAR de 1min submuestreado para 5min | Curva incorrecta | Recalcula la recursión sobre la serie agregada |
Variantes y extensiones¶
- PSAR como stop real (SIM-R): salir intrabar al tocar el nivel. Es otra estrategia con su propio id; no se mezcla con P14.
- Solo largos:
target_lots = [0, 1]y la reversión a corto se convierte en salida a plano. - Filtro de fuerza: operar solo cuando el ADX de P15 indica tendencia, para evitar el whipsaw lateral.
- Reinicio por sesión: reiniciar la parábola en cada apertura intradía. No es la convención canónica y cambiaría la identidad de la estrategia.
- Parientes stop-and-reverse: P06 Supertrend (bandas de ATR) y P19 Chandelier (stop desde el extremo con ATR).
Resumen¶
- P14 compara el SAR con el cierre: +1 si el SAR queda debajo, −1 si queda encima; el empate conserva.
- La parábola se siembra en la barra 1, acelera solo con extremos estrictos nuevos y se limita con los dos extremos previos.
- Siempre en mercado desde la barra 1; cada reversión mueve 2 unidades. En el fixture: entrada a 10,60, reversión a 10,55 y una última señal sin fill.
- 12 candidatos son 12 curvas: nada que factorizar.
- Paridad PASS en los tres carriles comparables; el carril nativo de Nautilus es
UNSUPPORTEDporque no hay PSAR nativo.
Para practicar¶
- Con el fixture, calcula a mano la barra 10: parte de
sar[9] = 12,30,ep[9] = 10,30,af[9] = 0,02, obténraw = 12,2600, limita conH9 = 11,00yH8 = 11,60, y comprueba queL10 = 10,00 < 10,30actualiza el EP y sube el AF a 0,04. - Rehaz la columna "equity con 5 bps" con 20 bps. ¿Cuáles son las comisiones de los dos fills y la equity final? (Pista:
10,60 · 0,002 = 0,0212y21,10 · 0,002 = 0,0422.) - Lanza el sweep de 12 candidatos sobre NVDA 1d y KO 1d. Compara el número de reversiones de
0.01/0.1frente a0.04/0.3y comprueba enfactorization_planque no hay curvas compartidas.