Golden SkyGolden SkyGuía Técnica

Referencia técnica · Paso 3 · Calibración TP/SL

Escala y R-múltiple

Formalización de la calibración: la escala de volatilidad característica que dimensiona la grilla, el Monte Carlo de entradas al azar que caracteriza el activo, y el ranking por Sharpe del R-múltiple por celda.

§0Notación

scale_hescala de vol al horizonte
Hhorizonte (candle_exhibition)
RiR-múltiple de la entrada i
pnliP&L señalizado de la entrada
mmultiplicador de scale_h
WRwin rate
σdesvío estándar verdadero
Piprecio (entry/exit)

§1Escala de volatilidad característica

Una medida robusta de "cuánto se mueve el activo por barra", escalada al horizonte del trade con la regla de la raíz del tiempo. Se calcula sobre el IS, nunca sobre el OOS.

compute_scale_h log_reti = ln(closei) − ln(closei−1)  // finitos
scalebarra = mediana( |log_ret| )  // mediana, no std → robusta a outliers
scale_h = scalebarra · √H

Precisión — scale_h ≠ σ, y es deliberado. Bajo normalidad mediana(|X|) ≈ 0.6745·σscale_h ≈ 0.67·σ; con colas gruesas (típico en financieros) la brecha crece → scale_h < 0.67σ. El nombre "escala" (no "sigma") evita razonar mal sobre el risk-of-ruin. Corre sobre df_development (IS) para no filtrar el OOS al TP/SL sugerido.

§2Grilla vol-adaptada

Cada eje de la grilla son múltiplos de scale_h — así la grilla se adapta sola a cada activo. Los multiplicadores son asimétricos por decisión de riesgo.

tp_grid = { m · scale_h : m ∈ TPmult }   ·   sl_grid = { m · scale_h : m ∈ SLmult }
EjeMultiplicadores (× scale_h)Cap
TP · 90.5 · 0.75 · 1 · 1.5 · 2 · 3 · 4 · 6 · 8
SL · 80.25 · 0.5 · 0.75 · 1 · 1.5 · 2 · 3 · 4

9 × 8 = 72 celdas. Asimetría por risk management: el TP llega a (recompensa, sin implicación de solvencia); el SL se topa en — un SL > 4×scale_h ≈ 2.7σ real ≈ "no tener SL", expone a patrones tipo martingala/blow-up.

§3Monte Carlo — entradas al azar

Para caracterizar el activo (no una estrategia), se entra en 1000 puntos al azar y se resuelve cada trade con la misma mecánica del target. El resultado señalizado por entrada alimenta el R-múltiple.

Selección de entradas · select_random_entries

entradas ⊂ [0, nbarras − H)  // excluye las últimas H barras → ventana futura completa
|entradas| = 1000  (default) · sin reposición · seed = 42

Resolución por entrada · simulate_outcomes

long tppx = entry·(1 + tp)  ·  slpx = entry·(1 − sl)  // short: invertido
scan j = 1..H (primer toque gana):
  toca TP  → pnli = +tp
  toca SL  → pnli = −sl
  ambos en la misma vela → desempate por color (close ≥ open → SL en long)
sin toque → timeout: pnlfinal = closei+H − entryentry ; pnli = pnlfinal
Ri = pnlisl  // sl nominal fijo de la celda (requiere sl > 0)

El R_i se computa sobre las n entradas completas (no condicional a ganar/perder). Eso es lo que permite medir dispersión y penalizar celdas cuyo edge lo sostiene una cola delgada.

§4Estadísticos por celda

La distribución de outcomes por celda produce las métricas. Solo una decide el ranking; el resto son contexto.

WR = pcttp + pcttimeout_gain
expectancy = WR·avg_win − (1−WR)·avg_loss  // INFORMATIVA — ya no rankea
mean_r = media(Ri)  ·  std_r = stdmuestral(Ri, ddof=1)  // 0.0 si n ≤ 1
sharpe_cell = mean_rstd_r  // None si std_r no finito o ≤ 0

Por qué el expectancy ya no rankea (rediseño 2026-08-14): sesgaba hacia SL grande y hacia celdas cuyo edge dependía de una cola delgada de entradas. sharpe_cell = mean_r/std_r exige mean_r alto Y std_r bajo a la vez, penalizando esa cola de forma natural.

§5Selección de la celda recomendada

La recomendada es simplemente la de mayor Sharpe del R-múltiple, con un único filtro que no es de negocio.

_pick_recommended viable = { filas : std_r finito y > 0 }  // precondición de existencia del cociente
recomendada = argmaxviable ( sharpe_cell )

El único guard es std_r > 0no hay umbral de negocio. Los criterios viejos (health_score > 0, timeout_rate < 80%, active_rate > 10%) fueron eliminados. Si ninguna fila tiene std_r válido → None (activo+horizonte sin varianza).

§6Salidas y redondeo

Además del ranking, se computa la línea base exacta del usuario y se redondea el valor final preservando la proporción.

user_baseline = simulate_outcomes( TP/SL exacto del data_config )  // no la celda más cercana
valor final = round2 cifras sig.( tpcelda , slcelda )

El redondeo por cifras significativas (no decimales fijos) preserva el R:R: 0.526/0.263 → 0.53/0.26 mantiene R:R ≈ 2.0, mientras que a 1 decimal daría 0.5/0.3 = 1.67. La user_baseline marca out_of_grid si el TP/SL del usuario cae fuera del rango evaluado.

Naturaleza de este paso

La calibración es opcional y caracteriza el activo (entradas al azar), no descubre ninguna ventaja. Ajusta el marco de TP/SL que después consumirán el target y el backtest — no dice nada sobre si las reglas funcionan.

Fuentes:
· domain/tpsl_calibration/calibrator.py — compute_scale_h, build_vol_adapted_grid, TP/SL_MULTIPLIERS, run, _pick_recommended, _round_sig
· domain/tpsl_calibration/monte_carlo.py — select_random_entries, simulate_outcomes, SimulationStats (win_rate, expectancy, sharpe_cell, R-múltiple)