P10 · Ichimoku: Tenkan/Kijun y nube causal¶
| Campo | Valor |
|---|---|
| Familia | Tendencia · cruce de medias de rango con filtro de nube desplazada; alterna plano y posición (nunca invierte) |
| Features requeridas | ichimoku (salidas tenkan, kijun, senkou_a, senkou_b, estas dos ya desplazadas), construida sobre rolling_max(high) y rolling_min(low); la política lee además la columna close |
| Parámetros y defaults | tenkan = 9, kijun = 26, span_b = 52, displacement = 26 |
| Rejilla del catálogo | tenkan ∈ {7, 9, 12}, kijun ∈ {22, 26, 30}, span_b ∈ {44, 52, 60}; displacement fijo en 26 → 27 candidatos, todos válidos |
variant_keys |
tenkan, kijun, span_b |
| Restricciones | enteros ≥ 1, tenkan < kijun < span_b (estricto), displacement ≥ 1 (si no, PolicyParamError) |
first_decision_index |
span_b − 1 + displacement = 77 con defaults (85 en el peor punto de la rejilla) |
| Activos y timeframes | NVDA y KO en los 7 TF (1min … 1d); AMZN, INTC, MSFT, TSLA en 1d; BME con reserva; FX con reserva grave (los extremos high/low son la única entrada) |
| 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 'ichimoku'" en el registro del runner (ver nota en Qué mirar) |
Fuentes: docs/estrategias/P10.md (especificación), catalog/strategy_catalog.json, docs/DATOS_POR_ESTRATEGIA.md, runs/parity/summary.json.
Qué vas a aprender¶
- Qué son las cuatro líneas de Ichimoku y por qué todas se reducen a "punto medio del rango de las últimas
pbarras". - La diferencia entre la nube que dibuja una plataforma y la nube disponible en
t: es toda la causalidad de esta estrategia. - Por qué P10 entra con desigualdades estrictas y sale con no estrictas, y por qué nunca invierte de un golpe.
- A seguir en el fixture una entrada por cruce TK, una salida por nube sin cruce y una segunda entrada.
- Por qué 27 candidatos solo necesitan 9 ventanas móviles distintas.
La idea en una frase¶
Entrar cuando la línea rápida (Tenkan) cruza la lenta (Kijun) con el cierre por encima de ambas, y salir en cuanto el cierre toca la nube que se calculó hace displacement barras o el cruce se deshace.
Intuición de mercado¶
Tenkan y Kijun no son medias de cierres: son el centro del rango (máximo más mínimo, entre dos) de las últimas 9 y 26 barras. Cuando el centro del rango corto sube por encima del centro del rango largo, el mercado está haciendo máximos y mínimos más altos que antes: tendencia alcista naciente. La nube (Senkou A y B) es un soporte/resistencia de fondo calculado en el pasado; mientras el precio se mantenga por encima, la tendencia "no se ha roto".
Analogía. La nube es la marca de la marea alta de hace 26 días pintada en el muelle. Si el agua de hoy (el cierre) vuelve a tocar esa marca por arriba, la subida que te hizo entrar ya no se sostiene y sales. Lo que no puedes hacer es pintar la marca con el agua de hoy y fingir que estaba ahí de antes.
Por qué podría funcionar. Como todo seguimiento de tendencia, apuesta por el momentum de medio plazo, pero con un filtro de confirmación (el cierre sobre ambas líneas) y una salida asimétrica, rápida, por nube.
Cuándo falla.
- Rangos laterales: los cruces TK se multiplican y el cierre vive dentro de la nube; entradas que mueren a la barra siguiente.
- Intradía con los defaults: 9/26/52/26 vienen de semanas de seis sesiones; sobre 5min,
kijun = 26son 130 minutos. Calculable y perfectamente arbitrario. - Tras huecos de datos (KO, 271 sesiones ausentes): las ventanas no se reinician; la señal siguiente mezcla precios de años distintos.
Sesgos típicos al evaluarla.
- Fuga de nube: comparar
close[t]con la nube calculada con la propia barrat(la que el gráfico dibuja 26 barras adelante). Da salidas sistemáticamente "mejores". - Chikou: leer
close[t + 26]dibujado entes leer el futuro. P10 no lo calcula. - Ventanas distintas por candidato:
span_b = 44empieza en la barra 69 yspan_b = 60en la 85; compara desde un inicio común.
Las reglas exactas¶
La regla canónica del catálogo: "Tenkan=midpoint de n1, Kijun=midpoint de n2, A=(Tenkan+Kijun)/2, B=midpoint de n3. Nube disponible dibujada en t: A[t-displacement], B[t-displacement]. Desde plano, largo al cruce Tenkan sobre Kijun con C sobre ambas; corto simétrico bajo ambas. Salir largo si C<=max(nube) o hay cruce TK bajista; salir corto si C>=min(nube) o hay cruce TK alcista. Salida tiene prioridad y no se invierte en esa decisión."
Definiciones (spec §4.b):
tk_up[t] = tenkan[t] > kijun[t] and tenkan[t−1] <= kijun[t−1];tk_downsimétrico. Cualquier NaN los hace falsos.cloud_top[t] = max(senkou_a[t], senkou_b[t]),cloud_bottom[t] = min(...), con propagación de NaN (np.maximum, nonp.fmax).
Situación en el cierre de t |
Objetivo target[t] |
Motivo (reason) |
|---|---|---|
t < first_decision_index |
0 | WARMUP |
plano y tk_up y close > tenkan y close > kijun |
+1 | ENTRY |
plano y tk_down y close < tenkan y close < kijun |
−1 | ENTRY |
largo y (close <= cloud_top o tk_down) |
0 | EXIT |
corto y (close >= cloud_bottom o tk_up) |
0 | EXIT |
| ninguna de las anteriores, empate o NaN | el anterior | HOLD |
barra no operable (is_tradable = False) |
se congela el publicado | NOT_TRADABLE |
- Entrada: solo desde plano; desigualdades estrictas. "C sobre ambas" son las dos líneas (Tenkan y Kijun), no la nube: decisión declarada en la spec (§11, punto 2).
- Salida: desigualdades no estrictas; basta con que el cierre toque la nube por su lado, aunque la atraviese entera de un gap.
- Reversión: prohibida. Si una barra cumple a la vez
exit_longyenter_short, el objetivo es 0; la barra siguiente decide desde plano. El ledger nunca ve un delta de 2. - Filtros: la propia nube, solo en la salida.
# decisión en el cierre de t, fill en el open de t+1
target_prev = 0
para cada barra t:
si t < first_decision_index: target = 0 # WARMUP
si no, si target_prev == +1:
target = 0 si (close[t] <= cloud_top[t] o tk_down[t]) si no +1
si no, si target_prev == -1:
target = 0 si (close[t] >= cloud_bottom[t] o tk_up[t]) si no -1
si no: # plano
si tk_up[t] y close[t] > tenkan[t] y close[t] > kijun[t]: target = +1
si no, si tk_down[t] y close[t] < tenkan[t] y close[t] < kijun[t]: target = -1
si no: target = 0
si target != target_prev:
orden(target - target_prev) -> fill a open[t+1] # |delta| siempre 1
target_prev = target
La nube de t es la de hace displacement barras
senkou_a[t] = senkou_a_raw[t − displacement]. La primitiva ichimoku devuelve las spans ya desplazadas y no expone las _raw: quien quiera la fuga tiene que escribirla a propósito. Si programas el adaptador a mano, no calcules (tenkan + kijun)/2 en t y lo llames nube.
Los indicadores que usa¶
| Feature | Fórmula | first_valid (defaults) |
|---|---|---|
rolling_max(p), rolling_min(p) |
máximo de high / mínimo de low de las p barras incluida t |
p − 1 |
tenkan |
(rolling_max(tenkan) + rolling_min(tenkan)) / 2 |
tenkan − 1 = 8 |
kijun |
ídem con kijun |
kijun − 1 = 25 |
senkou_a |
((tenkan + kijun)/2)[t − displacement] |
kijun − 1 + displacement = 51 |
senkou_b |
midpoint(span_b)[t − displacement] |
span_b − 1 + displacement = 77 |
first_decision_index = max(first_valid) = span_b − 1 + displacement = 77, sin +1 aunque el cruce mire t−1 (en 77 Tenkan y Kijun llevan mucho tiempo válidas). La nube entra en el índice aunque la entrada no la use: así no se abre nunca una posición que no pueda cerrarse por nube.
Las ventanas son inclusivas; no confundir con el donchian de P11, que usa barras estrictamente anteriores. Más detalle en Las 23 primitivas de fase B y en Indicadores y features.
Ejemplo barra a barra¶
Fixture §6 de docs/estrategias/P10.md: tenkan = 2, kijun = 3, span_b = 4, displacement = 2 (fuera de rejilla a propósito; cumple 2 < 3 < 4), 18 barras, cash_inicial = 1.000,00, tick 0,01, sin costes. Construcción: open[t] = close[t−1], high = max(O,C) + 0,10, low = min(O,C) − 0,10. first_valid: tenkan 1, kijun 2, senkou_a 4, senkou_b 5 → first_decision_index = 5.
Las barras 0–3 (sin nube) se omiten; en la barra 3 ya existen tenkan 9,9500 y kijun 9,9500.
| t | O | H | L | C | tenkan | kijun | senkou_a | senkou_b | cruce | target | orden | fill | pos. | PnL acum. sin costes | equity con 5 bps* |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 4 | 9,70 | 9,80 | 9,50 | 9,60 | 9,7500 | 9,9000 | 10,0500 | — | TK↓ | 0 WARMUP | — | — | 0 | 0,00 | 1.000,00 |
| 5 | 9,60 | 9,70 | 9,20 | 9,30 | 9,5000 | 9,6000 | 9,9500 | 9,9500 | — | 0 HOLD | — | — | 0 | 0,00 | 1.000,00 |
| 6 | 9,30 | 9,70 | 9,20 | 9,60 | 9,4500 | 9,5000 | 9,8250 | 9,9000 | — | 0 HOLD | — | — | 0 | 0,00 | 1.000,00 |
| 7 | 9,60 | 9,80 | 9,50 | 9,70 | 9,5000 | 9,5000 | 9,5500 | 9,7500 | — | 0 HOLD | — | — | 0 | 0,00 | 1.000,00 |
| 8 | 9,70 | 10,10 | 9,60 | 10,00 | 9,8000 | 9,6500 | 9,4750 | 9,6000 | TK↑ | +1 ENTRY | BUY 1 | — | 0 | 0,00 | 1.000,00 |
| 9 | 10,00 | 10,40 | 9,90 | 10,30 | 10,0000 | 9,9500 | 9,5000 | 9,5000 | — | +1 | — | 10,00 | +1 | 0,30 | 1.000,30 |
| 10 | 10,30 | 10,40 | 10,10 | 10,20 | 10,1500 | 10,0000 | 9,7250 | 9,6500 | — | +1 | — | — | +1 | 0,20 | 1.000,20 |
| 11 | 10,20 | 10,50 | 10,10 | 10,40 | 10,3000 | 10,2000 | 9,9750 | 9,8000 | — | +1 | — | — | +1 | 0,40 | 1.000,40 |
| 12 | 10,40 | 10,50 | 10,20 | 10,30 | 10,3000 | 10,3000 | 10,0750 | 9,9500 | — | +1 | — | — | +1 | 0,30 | 1.000,30 |
| 13 | 10,30 | 10,40 | 9,90 | 10,00 | 10,2000 | 10,2000 | 10,2500 | 10,0500 | — | 0 EXIT (nube) | SELL 1 | — | +1 | 0,00 | 1.000,00 |
| 14 | 10,00 | 10,30 | 9,90 | 10,20 | 10,1500 | 10,2000 | 10,3000 | 10,2000 | TK↓ | 0 | — | 10,00 | 0 | 0,00 | 1.000,00 |
| 15 | 10,20 | 10,50 | 10,10 | 10,40 | 10,2000 | 10,2000 | 10,2000 | 10,2000 | — | 0 | — | — | 0 | 0,00 | 1.000,00 |
| 16 | 10,40 | 10,50 | 10,30 | 10,40 | 10,3000 | 10,2000 | 10,1750 | 10,2000 | TK↑ | +1 ENTRY | BUY 1 | — | 0 | 0,00 | 1.000,00 |
| 17 | 10,40 | 10,50 | 10,20 | 10,30 | 10,3500 | 10,3000 | 10,2000 | 10,2000 | — | +1 | — | 10,40 | +1 | −0,10 | 999,89 |
OHLC, líneas, cruces, objetivos, fills (8→9 a 10,00; 13→14 a 10,00; 16→17 a 10,40) y equity en las barras 9, 14 y 17 son literales del fixture. El PnL de las barras intermedias es caja + pos · close − 1.000,00 con la caja del fixture. *"Equity con 5 bps" es 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 en la barra del fill:
- fill 1 (barra 9):
10,00 · 0,0005 = 0,005 → 0,00(medio céntimo exacto, redondea al par); - fill 2 (barra 14):
10,00 · 0,0005 = 0,005 → 0,00; - fill 3 (barra 17):
10,40 · 0,0005 = 0,0052 → 0,01.
Con precios de 10 dólares y una unidad, la comisión de 5 bps casi desaparece por redondeo: es un efecto del fixture, no una propiedad de la estrategia. Sobre NVDA a cientos de dólares no ocurre.
Lo que hay que ver en la tabla:
- Barra 4:
senkou_aya existe,senkou_bno: la nube no está completa y es warmup. En la barra 5 (primera decisión) no hay cruce, así que el 0 es "no entrar", no calentamiento. - Barra 8: cruce TK alcista armado por igualdad en
t−1(9,50 <= 9,50), cierre 10,00 sobre ambas líneas → +1; fill al open de 9. - Barra 13: salida por nube sin cruce:
tenkan == kijun(10,20) no estk_down, peroclose = 10,00 <= cloud_top = 10,25. El cierre ha atravesado la nube entera (está bajo las dos bandas) y la regla cierra igual. - Barra 16: segunda entrada; la estrategia no se queda bloqueada tras salir.
- Barra 17: posición abierta al final, valorada a 10,30: equity 999,90 sin costes. No hay liquidación automática.
Las cuentas de las barras clave¶
Primera tenkan (t=1): (max(10,10;10,30) + min(9,90;9,90))/2 = (10,30+9,90)/2 = 10,100000
Primera B_raw (t=3): (max(high[0..3]) + min(low[0..3]))/2 = (10,30+9,60)/2 = 9,950000
Nube completa (t=5): senkou_a[5] = A_raw[3] = 9,95 ; senkou_b[5] = B_raw[3] = 9,95
Entrada (t=8):
tenkan[8] = (max(9,80;10,10) + min(9,50;9,60))/2 = 9,800000
kijun[8] = (max(9,70;9,80;10,10) + min(9,20;9,50;9,60))/2 = 9,650000
tenkan[7] = kijun[7] = 9,500000
tk_up[8] = (9,80 > 9,65) y (9,50 <= 9,50) = True
close[8] = 10,00 > 9,80 y > 9,65 -> +1
Salida (t=13):
senkou_a[13] = A_raw[11] = (10,30 + 10,20)/2 = 10,250000
senkou_b[13] = B_raw[11] = (max(high[8..11]) + min(low[8..11]))/2 = (10,50+9,60)/2 = 10,050000
cloud_top[13] = 10,25 ; close[13] = 10,00 <= 10,25 -> 0
Caja: 1.000,00 − 10,00 = 990,00 (fill 1) ; 990,00 + 10,00 = 1.000,00 (fill 2) ; 1.000,00 − 10,40 = 989,60 (fill 3)
Equity final: 989,60 + 1 · 10,30 = 999,90
Comprobación de causalidad sobre la propia tabla: senkou_a[8] = 9,4750 = A_raw[6], y el A_raw[8] = 9,7250 de la propia barra 8 no aparece en la columna senkou_a hasta la barra 10.
Diagrama¶
flowchart LR
W(["WARMUP: t < span_b-1+displacement"]) --> FLAT["Plano 0"]
FLAT -->|"tk_up y C > tenkan y C > kijun · BUY 1"| L["Largo +1"]
FLAT -->|"tk_down y C < tenkan y C < kijun · SELL 1"| S["Corto -1"]
L -->|"C <= max(nube) o tk_down · SELL 1"| FLAT
S -->|"C >= min(nube) o tk_up · BUY 1"| FLAT
L -->|"sin salida"| L
S -->|"sin salida"| S
FLAT -->|"sin entrada, empate o NaN"| FLAT
No hay flecha directa entre largo y corto: toda salida pasa por plano, y la entrada contraria, si procede, se decide en la barra siguiente.
Cómo lanzarla¶
Backtest con ambos motores sobre NVDA 1d (el régimen donde 9/26/52 tienen su lectura tradicional), con los defaults:
BASE=http://localhost:8000
SID=$(curl -sS -X POST "$BASE/v1/backtest" -H 'Content-Type: application/json' -d '{
"request_id": "manual-p10-0001",
"correlation_id": null,
"schema_version": "v1",
"payload": {
"strategy": {"template_id": "P10",
"params": {"tenkan": 9, "kijun": 26, "span_b": 52, "displacement": 26},
"name": "Ichimoku 9/26/52 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": "P10",
"params": {"tenkan": 9, "kijun": 26, "span_b": 52, "displacement": 26},
"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"]
print(SID, r["parity"]["verdict"])
Derivar una variante con una nube más lenta (span_b = 60):
curl -sS -X POST "$BASE/v1/strategies/$SID/derive" -H 'Content-Type: application/json' -d '{
"request_id": "manual-p10-derive", "correlation_id": null, "schema_version": "v1",
"payload": {"param_overrides": {"span_b": 60}, "name": "Ichimoku 9/26/60",
"slug": "ichimoku-9-26-60", "tags": ["sensibilidad"]}}' | jq '.payload.strategy_id, .payload.cache_forecast'
span_b es parámetro de feature: según la tabla de invalidación (§5.3 de la spec) cambia senkou_b y el first_decision_index (de 77 a 85). La especificación ichimoku(9,26,60,26) es otra entrada de caché; solo se reutilizan las ventanas de 9 y 26 si la caché guarda los eslabones rolling_max/rolling_min. Un cambio de fee_rate no toca ninguna feature: solo rehace el ledger.
Sweep de sus variant_keys (rejilla completa del catálogo):
curl -sS -X POST "$BASE/v1/sweep" -H 'Content-Type: application/json' -d '{
"request_id": "manual-p10-sweep", "correlation_id": null, "schema_version": "v1",
"payload": {"base_strategy_id": "'"$SID"'",
"grid": {"tenkan": [7, 9, 12], "kijun": [22, 26, 30], "span_b": [44, 52, 60]},
"candidate_policy": {"drop_invalid": true, "drop_duplicates": true,
"register_strategies": true,
"name_template": "{template_name} {tenkan}/{kijun}/{span_b}"},
"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'
El resultado se consulta en GET /v1/jobs/{job_id}.
Cuánto cuesta la rejilla¶
| Concepto | Cuenta (spec §5.4 y §9.2) |
|---|---|
| Candidatos cartesianos | 3 × 3 × 3 = 27 (displacement fijo no multiplica) |
Inválidos por tenkan < kijun < span_b |
0: max(tenkan) = 12 < min(kijun) = 22 y max(kijun) = 30 < min(span_b) = 44 |
Especificaciones ichimoku distintas |
27 |
| Periodos de ventana distintos | {7, 9, 12, 22, 26, 30, 44, 52, 60} = 9 pares rolling_max/rolling_min |
| Ventanas sin caché de eslabones | 27 × 3 = 81 |
senkou_a / senkou_b distintas |
9 (una por pareja tenkan, kijun) / 3 (una por span_b) |
| Memoria de features con N = 632.095 | ≈ 101 MiB con eslabones cacheados, ≈ 391 MiB sin ellos |
Que los 27 sean válidos es una suerte de esta rejilla, no una propiedad de la restricción: con tenkan = 25 ya se caerían candidatos.
Qué mirar en los resultados¶
parity.verdict: PASS esperado conNT_FEATURES,NT_INTENT_REPLAYyNT_ONLINEcon proveedor por defecto (ventanas incrementalescustom_reference).- Reparto de salidas por nube frente a por cruce TK (métrica de la spec §10.2): 0 % por nube significa que P10 es un cruce TK con pasos extra; 100 %, que el cruce nunca llega a tiempo.
- Fracción de cruces TK alcistas filtrados por "C sobre ambas" y distancia media de
closeacloud_topen las entradas: si es negativa, las entradas nacen dentro de la nube y mueren a la barra siguiente. fills = 2 × tradesmenos el trade abierto al final:|delta|siempre vale 1.- Arranque común en un sweep: 85 para la rejilla completa.
- Overnight permitido: P10 mantiene posición entre sesiones; no la compares con P12 o P13 sin decirlo.
- Nota sobre el carril nativo: la matriz marca
NT_ONLINE(native)como UNSUPPORTED porque el runner no registra un indicador nativo paraichimoku. La spec (§3.5) documenta, con una sonda, queIchimokuCloudde Nautilus existe y coincide en valores, pero devuelve 0,0 antes de ser válido y liberasenkou_atarde: sería una variante de máscara (nt_ichimoku_zero_masked_late_span_a), pendiente de test en contenedor.
Causalidad comprobada¶
El test de "futuros alterados" de la spec (§8.2) perturba las barras 14–17 del fixture y exige que tenkan, kijun, senkou_a, senkou_b y objetivos en 0..13 queden idénticos bit a bit; con span_b = 4 y displacement = 2, senkou_b[13] depende de las barras 8–11. Una variante más afilada perturba solo la barra 17 para cazar ventanas centradas (el origin por defecto de maximum_filter1d centra la ventana y mete high[t+1] en rolling_max[t]).
Para reanudar en modo continue no bastan target, tenkan_prev y kijun_prev: hacen falta los últimos displacement valores de senkou_a_raw y senkou_b_raw (416 B con 26) y las ventanas de high/low. Sin el búfer de nube, la posición heredada no podría salir por nube durante 26 barras, sin ninguna excepción que lo delate.
Errores típicos¶
| Error | Consecuencia | Cómo evitarlo |
|---|---|---|
tenkan >= kijun o kijun >= span_b |
PolicyParamError (Nautilus acepta >=; aquí es estricto a propósito) |
Respeta tenkan < kijun < span_b |
displacement = 0 |
PolicyParamError: sería la nube contemporánea, otra estrategia |
Déjalo en 26 salvo exploración explícita |
Usar la nube dibujada en t (senkou_a_raw[t]) |
Salidas tardías y favorables: fuga | Usa las spans desplazadas de la feature |
| Leer Chikou | Lees 26 barras de futuro | P10 no lo calcula ni lo expone |
Exigir close > cloud_top para entrar |
Otra estrategia más restrictiva | "Ambas" son las líneas |
| Esperar reversión directa | No cuadra con el motor | Salida a 0; la entrada contraria, en la barra siguiente |
np.fmax para la nube |
Nube "válida a medias" | np.maximum propaga NaN |
Leer initialized de Nautilus como fin de warmup |
Lee senkou_b = 0,0 y decide con basura |
Contador propio hasta first_decision_index |
Variantes y extensiones¶
- Entrada sobre la nube: exigir
close > cloud_top; es otra receta con otroid. - Barrer
displacement: barato (solo se multiplican losshift), aunque el catálogo lo fija. - Solo largos:
target_lots = [0, 1]. - Parientes: P11 Donchian (canal de rango, ventana desplazada), P01 EMA (cruce de medias de cierre) y P08 (usa las mismas
rolling_max/rolling_min).
Resumen¶
- Tenkan, Kijun y Senkou B son puntos medios de rango (
(máx + mín)/2) con ventana inclusiva; Senkou A es la media de las dos primeras. - La nube disponible en
tse calculódisplacementbarras antes; la feature la entrega ya desplazada. - Entrada desde plano por cruce TK con el cierre sobre (o bajo) ambas líneas; salida al tocar la nube o al cruce contrario; nunca invierte.
first_decision_index = span_b − 1 + displacement= 77; el fixture sale por nube en la barra 13 sin cruce TK.- 27 candidatos, 9 ventanas distintas; la caché de eslabones divide por nueve el trabajo.
Para practicar¶
- Con el fixture, calcula a mano
tenkan[16],kijun[16]y comprueba eltk_up[16](pista:tenkan[15] = kijun[15] = 10,20). ¿Por qué el cierre 10,40 cumple la condición de precio? - Cambia el fixture mentalmente: si en la barra 13 el cierre fuera 10,26, ¿saldría? ¿Y con 10,25 exacto? Justifícalo con la desigualdad no estricta.
- Lanza el sweep 3×3×3 sobre NVDA 1d y KO 1d y compara el reparto de salidas por nube frente a por cruce del mejor candidato en cada activo.