Lección 1.6.3 · 60 min

Estacionalidad: día de la semana, mes, cambio de mes y sesiones intradía

Los efectos calendario son la forma más fácil de encontrar un patrón en los datos y una de las más fáciles de engañarse. Esta lección mide los clásicos con estadísticos t e intervalos bootstrap, enseña cuántos «significativos» salen por azar cuando se prueban muchos a la vez y separa lo que sí es estable: el perfil intradía de la volatilidad y el volumen.

Fig. — NOVA, 2024–2025: volatilidad (arriba) y volumen medio (abajo) de cada barra de 5 minutos de la sesión, en hora de Nueva York
Lecciones del nivel 1
  1. 1.1 · Cómo funcionan los mercados

    1. 1.1.1 Participantes y centros de negociación
    2. 1.1.2 Sesiones, subastas, festivos y calendarios
    3. 1.1.3 Libro de órdenes: bid, ask, spread y profundidad
    4. 1.1.4 Tipos de órdenes
    5. 1.1.5 Costes, liquidación, apalancamiento y margen
  2. 1.2 · Clases de activos

    1. 1.2.1 Acciones: splits, dividendos y eventos corporativos
    2. 1.2.2 ETFs: réplica, tracking error, apalancados y UCITS
    3. 1.2.3 Futuros: especificaciones, margen, roll y contango
    4. 1.2.4 Forex: pares, pips, lotes, rollover y CFD
    5. 1.2.5 Opciones: call, put, valor intrínseco y valor temporal
    6. 1.2.6 Cripto: spot, perpetuos, funding y custodia
    7. 1.2.7 Renta fija y tipos de interés; CFDs y productos apalancados
  3. 1.3 · Fuentes de datos de mercado

    1. 1.3.1 Tipos de datos de mercado: EOD, barras, ticks, libro y referencia
    2. 1.3.2 Fuentes de datos gratuitas
    3. 1.3.3 APIs de datos retail y prosumer
    4. 1.3.4 Proveedores de datos profesionales
    5. 1.3.5 Datos de cripto y on-chain
    6. 1.3.6 Brókeres como fuente de datos
    7. 1.3.7 Licencias y términos de uso de datos
    8. 1.3.8 Cómo elegir proveedor de datos
  4. 1.4 · Ingeniería de datos financieros

    1. 1.4.1 Descarga por REST y websockets: paginación, límites y reintentos
    2. 1.4.2 Limpieza de datos: faltantes, ticks erróneos, huecos y zonas horarias
    3. 1.4.3 Ajustes por splits y dividendos: precios ajustados y sin ajustar
    4. 1.4.4 Universos sin sesgo de supervivencia: deslistados, fusiones y cambios de símbolo
    5. 1.4.5 Construcción de barras: tiempo, ticks, volumen, dólar y desequilibrio
    6. 1.4.6 Series continuas de futuros: reglas de roll, ajuste por diferencia y ajuste por ratio
    7. 1.4.7 Almacenamiento: CSV, Parquet, particionado, DuckDB, TimescaleDB y ArcticDB
    8. 1.4.8 Pipeline reproducible: descarga, validación, actualización incremental y tests de calidad
  5. 1.5 · Datos fundamentales y macro

    1. 1.5.1 Estados financieros, ratios, XBRL y SEC EDGAR
    2. 1.5.2 Datos macro, calendarios económicos, estimaciones y transcripciones
  6. 1.6 · Análisis exploratorio financiero

    1. 1.6.1 Rentabilidades, volatilidad, correlaciones móviles y drawdown
    2. 1.6.2 Hechos estilizados: colas gruesas, agrupamiento, autocorrelación y apalancamiento
    3. 1.6.3 Estacionalidad: día de la semana, mes, cambio de mes y sesiones intradía
  7. 1.7 · Análisis técnico programado

    1. 1.7.1 Indicadores técnicos en Python
    2. 1.7.2 Implementación propia frente a TA-Lib: validar resultados
    3. 1.7.3 Patrones de velas y soportes y resistencias
    4. 1.7.4 Multi-timeframe sin anticipación

Patrones en el calendario

Un efecto calendario es una diferencia sistemática de rentabilidad o de volatilidad ligada a una fecha: el día de la semana, el mes, los días alrededor del cambio de mes, la hora del día, los días antes de un festivo. Son atractivos porque son fáciles de programar y de explicar. También son la forma más sencilla de encontrar en los datos un patrón que no existe: hay muchos calendarios posibles, cada uno con pocos datos, y basta con probar suficientes para que alguno salga «significativo».

Esta lección sigue siempre el mismo flujo:

Hipótesis previaDatos y calendarioContraste t o bootstrapCorrección múltipleFuera de muestraCostes y decisión
Fuente Mermaid
flowchart TB
  H[Hipótesis previa] --> D[Datos y calendario]
  D --> T[Contraste t o bootstrap]
  T --> M[Corrección múltiple]
  M --> F[Fuera de muestra]
  F --> C[Costes y decisión]

Los datos son ISX y FIX, los dos índices diarios del nivel 1 (2019-2025), los 57 valores del universo de la lección 1.4.4 y las barras de 5 minutos de NOVA de 2024 y 2025. Una advertencia previa, como en la lección 1.6.2: son datos sintéticos y su generador no incluye efectos de día de la semana, mes ni cambio de mes. Lo que salga en esas pruebas es azar o un efecto lateral del modelo, y por eso son un buen banco de pruebas: sabemos la respuesta correcta. El perfil intradía de la volatilidad y del volumen, en cambio, sí está en el generador.

Día de la semana

El estadístico t de una media es la media dividida por su error típico:

t=r‾s/nt = \frac{\overline{r}}{s / \sqrt{n}}

Con unos cientos de datos, |t| > 1,96 corresponde a p < 0,05 (dos colas).

IN [01]python
import numpy as np
import pandas as pd
from scipy import stats

isx = pd.read_csv("etf_indice_diario.csv", parse_dates=["fecha"],
                  index_col="fecha")["indice"]
fix = pd.read_csv("fix_indice_diario.csv", parse_dates=["fecha"],
                  index_col="fecha")["indice"]
px = pd.DataFrame({"ISX": isx, "FIX": fix})
r = np.log(px).diff().dropna()
DIAS = ["lun", "mar", "mié", "jue", "vie"]

def por_grupo(x, grupos):
    g = x.groupby(grupos)
    out = pd.DataFrame({"n": g.size(), "media_%": 100 * g.mean()})
    out["t"] = g.mean() / (g.std() / np.sqrt(g.size()))
    return out

tablas = {c: por_grupo(r[c], r.index.dayofweek) for c in r}
dia = pd.concat(tablas, axis=1)
dia.index = DIAS
dia.round(3)
OUT [01]Rentabilidad media por día de la semana
     ISX                 FIX
       n media_%      t    n media_%      t
lun  329   0.040  0.527  329   0.082  1.212
mar  364   0.032  0.414  364  -0.017 -0.231
mié  360   0.101  1.505  360   0.173  2.669
jue  353   0.044  0.645  353   0.005  0.080
vie  353   0.037  0.595  353   0.047  0.725

Todas las medias son pequeñas y casi todos los t, menores que 2 en valor absoluto. La excepción es el miércoles de FIX: 0,17 % de media y t = 2,67. Antes de celebrarlo, dos cuentas. Son diez contrastes (dos índices por cinco días): con diez contrastes independientes al 5 %, la probabilidad de que al menos uno salga significativo por azar es 1 − 0,95¹⁰ ≈ 40 %. Y el contraste está mal planteado.

Contra el resto, no contra cero

El t de la tabla contrasta «la media del miércoles es cero». Pero un índice que sube un 14 % al año tiene una media diaria positiva todos los días: la pregunta de un efecto calendario es si el miércoles se diferencia de los demás días. Con un contraste de Welch (medias de dos grupos con varianzas distintas):

IN [02]python
def frente_al_resto(x, grupos):
    filas = {}
    for g in np.unique(grupos):
        dentro, fuera = x[grupos == g], x[grupos != g]
        t, p = stats.ttest_ind(dentro, fuera, equal_var=False)
        filas[g] = {"dif_%": 100 * (dentro.mean() - fuera.mean()),
                    "t": t, "p": p}
    return pd.DataFrame(filas).T

res = frente_al_resto(r["FIX"], r.index.dayofweek)
res.index = DIAS
res.round(3)
OUT [02]Cada día frente al resto
     dif_%      t      p
lun  0.030  0.393  0.695
mar -0.094 -1.173  0.241
mié  0.145  1.981  0.048
jue -0.066 -0.890  0.374
vie -0.013 -0.181  0.856

Frente al resto de días, el miércoles de FIX se queda en t = 1,98 y p = 0,048: justo por debajo de 0,05 y el único de los cinco. Con la hipótesis bien planteada el resultado se debilita pero no desaparece, así que la pregunta pasa a ser la otra: ¿es esperable un resultado así entre todos los que hemos mirado? Se responde más abajo, con muchos más contrastes.

Mes del año: un dato por año

Para el efecto mes, cada observación es la rentabilidad de un mes completo: con siete años hay siete eneros, siete febreros… Un intervalo bootstrap (remuestrear con reemplazo los siete valores y recalcular la media miles de veces) enseña lo poco que dicen:

IN [03]python
mens = np.log(px.resample("ME").last()).diff().dropna()["ISX"]
rng = np.random.default_rng(42)
filas = {}
for mes, x in mens.groupby(mens.index.month):
    ic = stats.bootstrap((x.to_numpy(),), np.mean, n_resamples=4000,
                         method="percentile", rng=rng)
    filas[mes] = {"n": len(x), "media_%": 100 * x.mean(),
                  "ic_bajo_%": 100 * ic.confidence_interval.low,
                  "ic_alto_%": 100 * ic.confidence_interval.high,
                  "t": x.mean() / (x.std() / np.sqrt(len(x)))}
meses = pd.DataFrame(filas).T
meses.round(2)
OUT [03]Rentabilidad mensual de ISX por mes, con intervalo bootstrap
      n  media_%  ic_bajo_%  ic_alto_%     t
1   6.0     2.84      -0.21       5.60  1.73
2   7.0     0.34      -0.87       1.71  0.46
3   7.0    -5.53     -18.92       6.68 -0.74
4   7.0     0.45      -4.68       5.86  0.15
5   7.0     5.19      -0.04      10.90  1.65
6   7.0     5.97       1.82      10.61  2.45
7   7.0     0.16      -4.76       4.91  0.06
8   7.0    -0.88      -3.68       2.03 -0.56
9   7.0    -0.44      -3.83       2.52 -0.26
10  7.0     2.90       0.69       5.40  2.21
11  7.0     1.01      -0.73       2.97  0.99
12  7.0     1.10      -0.84       3.06  1.02
Fig. — ISX, 2019–2025: rentabilidad media de cada mes del año con su intervalo bootstrap del 95 % (siete años, seis eneros)

Las medias van del −5,5 % de marzo al +6,0 % de junio y los intervalos son enormes: el de marzo va del −18,9 % al +6,7 %. Marzo es negativo por el desplome de 2020, un solo año. Junio y octubre salen con t mayor que 2 y con intervalos que no incluyen el cero, pero con siete datos cada uno y doce meses probados. En estos datos, además, se sabe por qué: el generador fija las grandes subidas y caídas en fechas concretas (marzo de 2020, la primavera de 2025), y eso deja huella en los meses en que cayeron. Es un efecto de la historia, no del calendario. Con datos reales pasa lo mismo: la mayoría de los «efectos mes» de un activo con diez o veinte años de historia son la huella de unos pocos acontecimientos.

El cambio de mes

El efecto cambio de mes (turn of the month) dice que las rentabilidades se concentran en el último día de negociación de un mes y los primeros días del siguiente. Una definición habitual: el último día y los tres primeros.

IN [04]python
mes = r.index.to_period("M")
orden = pd.Series(1, index=r.index).groupby(mes).cumsum()
total = pd.Series(1, index=r.index).groupby(mes).transform("sum")
cambio = (orden <= 3) | (orden == total)
print(f"Sesiones de cambio de mes: {cambio.sum()} de {len(r)}")
for c in r:
    a, b = r.loc[cambio, c], r.loc[~cambio, c]
    t, p = stats.ttest_ind(a, b, equal_var=False)
    print(f"{c}: {100 * a.mean():.3f} % frente a "
          f"{100 * b.mean():.3f} %  (t = {t:.2f}, p = {p:.3f})")
OUT [04]Cambio de mes frente al resto
Sesiones de cambio de mes: 336 de 1759
ISX: 0.096 % frente a 0.040 %  (t = 0.78, p = 0.434)
FIX: 0.054 % frente a 0.059 %  (t = -0.07, p = 0.947)

En ISX las sesiones de cambio de mes rinden más de media que el resto, pero con t = 0,78; en FIX, prácticamente lo mismo. Nada. Fíjate en la definición: «último día y tres primeros» es una de muchas posibles (dos y dos, uno y cuatro…). Probar varias y quedarse con la mejor es otra forma de multiplicar los contrastes, aunque no se vea en el código final.

Pruebas múltiples: cuántos «significativos» da el azar

Si no hay ningún efecto, el p-valor de un contraste bien hecho se distribuye de forma uniforme entre 0 y 1: un 5 % de los contrastes sale por debajo de 0,05 por puro azar. Con los 57 valores del universo y cinco días de la semana hay 285 contrastes:

IN [05]python
from statsmodels.stats.multitest import multipletests

uni = pd.read_parquet("universo_precios.parquet").pivot(
    index="fecha", columns="ticker", values="cierre")
ru = np.log(uni).diff()
filas = []
for tk in ru:
    s = ru[tk].dropna()
    dias = s.index.dayofweek
    for d in range(5):
        t, p = stats.ttest_ind(s[dias == d], s[dias != d],
                               equal_var=False)
        filas.append({"ticker": tk, "dia": DIAS[d], "t": t, "p": p})
pr = pd.DataFrame(filas)
print(f"Contrastes: {len(pr)}; esperados con p < 0,05: "
      f"{0.05 * len(pr):.1f}; observados: {(pr['p'] < 0.05).sum()}")
for metodo in ["bonferroni", "holm", "fdr_bh"]:
    rechaza = multipletests(pr["p"], alpha=0.05, method=metodo)[0]
    print(f"{metodo:>10}: {rechaza.sum()} significativos")
pr.sort_values("p").head(3).round(4)
OUT [05]285 contrastes de día de la semana en el universo
Contrastes: 285; esperados con p < 0,05: 14.2; observados: 10
bonferroni: 0 significativos
      holm: 0 significativos
    fdr_bh: 0 significativos
    ticker  dia       t       p
127   ZXLC  mié  2.9605  0.0032
20    ZXBI  lun  2.7957  0.0055
93    ZXHX  jue -2.7190  0.0067
Fig. — Histograma de los p-valores de 285 contrastes de día de la semana (57 valores × 5 días, cada día frente al resto)

Diez contrastes por debajo de 0,05, menos de los catorce que daría el azar, y ninguno sobrevive a una corrección. El histograma de los 285 p-valores es plano: la firma de que no hay nada. Las tres correcciones responden a preguntas distintas:

MétodoQué controlaUmbral efectivo aquí
BonferroniProbabilidad de algún falso positivop < 0,05 / 285 ≈ 0,00018
HolmLo mismo, de forma escalonada y algo menos estrictaDe 0,05 / 285 a 0,05
Benjamini-Hochberg (FDR)Proporción esperada de falsos positivos entre los rechazosDepende de cuántos p-valores pequeños haya

Si los miércoles de FIX formaran parte de una búsqueda así, su p = 0,048 no pasaría ninguna. La lección 2.1.8 vuelve sobre esto con el «zoo de factores»: la literatura de efectos calendario y de anomalías tiene el mismo problema a escala de miles de artículos.

Sesiones intradía

El calendario más fino es el del reloj. Con las barras de 5 minutos de NOVA (502 sesiones de 2024 y 2025), en hora de Nueva York, se puede calcular por franja la rentabilidad media, su t, la volatilidad y el volumen:

IN [06]python
b = pd.read_parquet("nova_barras_5min.parquet")
ny = b["ts"].dt.tz_convert("America/New_York")
b["franja"] = ny.dt.strftime("%H:%M")
b["r"] = np.log(b["cierre"] / b["apertura"])
g = b.groupby("franja")
perfil = pd.DataFrame({
    "n": g.size(), "media_pb": 1e4 * g["r"].mean(),
    "vol_pb": 1e4 * g["r"].std(),
    "volumen_miles": g["volumen"].mean() / 1e3})
perfil["t"] = perfil["media_pb"] / (perfil["vol_pb"]
                                    / np.sqrt(perfil["n"]))
print(f"Franjas: {len(perfil)}; |t| > 1,96: "
      f"{(perfil['t'].abs() > 1.96).sum()}")
perfil.iloc[[0, 1, 2, 30, 31, 76, 77]].round(1)
OUT [06]Perfil intradía de NOVA por franja de 5 minutos
Franjas: 78; |t| > 1,96: 2
          n  media_pb  vol_pb  volumen_miles    t
franja
09:30   502       2.1    47.8          351.6  1.0
09:35   502       2.1    42.2          282.4  1.1
09:40   502      -0.1    36.3          236.8 -0.0
12:00   502      -0.4    14.9          115.5 -0.6
12:05   502      -0.1    15.8          118.3 -0.2
15:50   496       0.5    29.2          205.2  0.4
15:55   496       2.2    33.2         1277.8  1.5

La figura de la cabecera dibuja las dos columnas que importan. La volatilidad de la primera barra (09:30) es unas tres veces la de mediodía y la de la última barra vuelve a subir; el volumen hace la misma U y en la barra de las 15:55 se dispara, porque incluye la subasta de cierre (lección 1.1.2). Las franjas desde las 13:00 tienen 496 sesiones en lugar de 502: en las seis medias sesiones del periodo el mercado cierra a esa hora.

Las rentabilidades medias, en cambio, son ruido: 2 franjas de 78 con |t| > 1,96, cuando el azar daría unas 4.

IN [07]python
perfil.loc[perfil["t"].abs() > 1.96, ["n", "media_pb", "t"]].round(2)
OUT [07]Las franjas «significativas»
          n  media_pb     t
franja
13:40   496      1.76  2.43
15:35   496     -2.56 -2.07
Fig. — NOVA, 2024–2025: estadístico t de la rentabilidad media de cada barra de 5 minutos; la banda marca |t| < 1,96

Una regla del tipo «comprar a las 13:40 y vender a las 13:45» sale de mirar 78 franjas y quedarse con la mejor. Con 1,8 puntos básicos de media en 5 minutos y una horquilla de un céntimo en una acción de unos 50 USD (2 puntos básicos de ida y vuelta solo en la horquilla), ni siquiera sería rentable si fuera real.

Lo que sí sirve del perfil intradía es su forma. ¿Qué parte de la varianza de un día se concentra en cada tramo?

IN [08]python
def tramo(h):
    if h < "10:00":
        return "1 apertura 9:30-10:00"
    if h >= "15:30":
        return "3 cierre 15:30-16:00"
    return "2 resto 10:00-15:30"

completas = b.groupby(ny.dt.date)["franja"].transform("size") == 78
bc = b[completas]
var = bc.groupby(bc["franja"].map(tramo))["r"].apply(
    lambda x: (x ** 2).sum())
reparto = pd.DataFrame({"barras": bc.groupby(
    bc["franja"].map(tramo)).size() / completas.sum() * 78,
    "varianza_%": 100 * var / var.sum()})
reparto.round(1)
OUT [08]Reparto de la varianza del día por tramos
                       barras  varianza_%
franja
1 apertura 9:30-10:00     6.0        23.9
2 resto 10:00-15:30      66.0        61.1
3 cierre 15:30-16:00      6.0        15.0

Las seis barras de la primera media hora y las seis de la última (un 15 % del tiempo de la sesión) concentran el 38,9 % de la varianza del día: el 23,9 % la apertura y el 15,0 % el cierre. Para un sistema tiene tres usos directos: repartir una orden grande siguiendo el perfil de volumen (como hace un algoritmo VWAP, lección 1.7.1), poner stops más amplios en la apertura que a mediodía y normalizar cualquier señal intradía por la volatilidad típica de su franja antes de compararla con otras horas.

Cómo no engañarse con el calendario

  • Hipótesis antes que datos. Escribe qué efecto vas a probar, con qué definición y en qué periodo, antes de mirar. La lección 2.2.4 propone un diario de investigación para eso.
  • El contraste correcto. Un día frente al resto, un mes frente al resto; no frente a cero.
  • Cuenta los contrastes. Los que hiciste y los que descartaste mentalmente (otras definiciones, otros activos, otros periodos). Corrige por todos.
  • Fuera de la muestra y con costes. Un efecto que sobrevive en un periodo que no usaste para encontrarlo y que paga la horquilla y las comisiones es otra cosa. Los research del sitio sobre estacionalidad intradía en futuros siguen ese camino hasta el backtest y sus estadísticas.

Ejercicios

  1. Repite los 285 contrastes del universo comparando la media de cada día con cero (stats.ttest_1samp) en lugar de con el resto de días. ¿Cuántos salen con p < 0,05 y cuántos sobreviven a Bonferroni? ¿Qué valores son?
Solución
IN [09]python
filas = []
for tk in ru:
    s = ru[tk].dropna()
    for d in range(5):
        x = s[s.index.dayofweek == d]
        t, p = stats.ttest_1samp(x, 0.0)
        filas.append({"ticker": tk, "dia": DIAS[d], "t": t, "p": p})
p0 = pd.DataFrame(filas)
bonf = multipletests(p0["p"], alpha=0.05, method="bonferroni")[0]
print(f"p < 0,05: {(p0['p'] < 0.05).sum()};"
      f" tras Bonferroni: {bonf.sum()}")
p0[bonf].round(5)
OUT [09]El contraste mal planteado
p < 0,05: 23; tras Bonferroni: 1
    ticker  dia        t        p
100   ZXIR  lun -4.27665  0.00006

Salen bastantes más que con el contraste correcto, porque los valores con una tendencia fuerte (al alza o a la baja) dan medias distintas de cero en todos los días. El que sobrevive a Bonferroni es ZXIR, el valor que quiebra en 2016, con un lunes muy negativo: refleja su caída continua, no un efecto del lunes.

  1. Calcula la volatilidad por franja de NOVA solo con 2024 y solo con 2025 y la correlación entre los dos perfiles. ¿Es estable la forma?
Solución
IN [10]python
ano = ny.dt.year
v24 = b[ano == 2024].groupby("franja")["r"].std()
v25 = b[ano == 2025].groupby("franja")["r"].std()
print(f"Correlación de los perfiles: {v24.corr(v25):.3f}")
print(f"Apertura/mediodía 2024: {v24['09:30'] / v24['12:00']:.2f}")
print(f"Apertura/mediodía 2025: {v25['09:30'] / v25['12:00']:.2f}")
OUT [10]Estabilidad del perfil de volatilidad
Correlación de los perfiles: 0.974
Apertura/mediodía 2024: 3.12
Apertura/mediodía 2025: 3.26

La forma se repite casi idéntica de un año a otro: la correlación entre los dos perfiles es muy alta y la relación entre la apertura y el mediodía se mantiene. Es la diferencia con las medias de rentabilidad por franja, que cambian de signo de un año a otro: la forma de la volatilidad es una propiedad del mercado; la media de una franja, una muestra.

  1. Un artículo afirma que «el mercado sube en diciembre» y lo apoya con 30 años de datos: 21 diciembres positivos de 30. ¿Qué más necesitas para tomarlo en serio?
Solución

Comparar con el resto de meses (si el mercado sube en el 65 % de los meses, 21 de 30 no es nada especial), el tamaño y la variabilidad de la diferencia (un t o un intervalo bootstrap), cuántos meses y definiciones se probaron antes de elegir diciembre, si el efecto aparece en un periodo distinto del que se usó para descubrirlo y en otros mercados, y si paga los costes de entrar y salir. Y una explicación económica plausible (flujos de fin de año, fiscalidad) que se pueda contrastar por separado.

Respuesta plegada en cada pregunta

Autoevaluación

  1. La rentabilidad media de FIX los miércoles tiene un estadístico t de 2,67. ¿Qué concluyes?

    • AQue hay un efecto miércoles en FIX y conviene comprar los martes al cierre
    • BNada todavía: es uno de diez contrastes (dos índices por cinco días), con uno o dos significativos esperables por azar, y en estos datos el generador no tiene efecto día de la semana
    • CQue el miércoles es el día más volátil
    • DQue los datos tienen un error
    Ver respuesta

    Respuesta B. Nada todavía: es uno de diez contrastes (dos índices por cinco días), con uno o dos significativos esperables por azar, y en estos datos el generador no tiene efecto día de la semana

    Con diez contrastes al 5 %, la probabilidad de que al menos uno salga significativo por azar es de un 40 %. Un efecto así hay que contrastarlo con una hipótesis previa, con corrección por pruebas múltiples y fuera de la muestra.

  2. Pruebas el efecto día de la semana en 57 valores: 285 contrastes. ¿Cuántos esperas con p < 0,05 si no hay ningún efecto?

    • ANinguno
    • BUnos 14
    • CUnos 57
    • DUnos 285
    Ver respuesta

    Respuesta B. Unos 14

    El 5 % de 285 son 14,25. En la lección salen 10: menos que los esperados por azar, y ninguno sobrevive a Bonferroni, Holm o FDR.

  3. Un valor que quiebra cae un 1 % de media cada día. Si contrastas «la rentabilidad media del lunes es cero», ¿qué pasa?

    • AEl lunes sale significativamente negativo, aunque no haya efecto lunes: el contraste detecta la tendencia del valor, no el día
    • BNo sale nada
    • CSale significativo el viernes
    • DEl contraste es correcto
    Ver respuesta

    Respuesta A. El lunes sale significativamente negativo, aunque no haya efecto lunes: el contraste detecta la tendencia del valor, no el día

    La hipótesis nula correcta para un efecto calendario es «el lunes no se diferencia del resto de días». Comparar con cero confunde la deriva del activo con el día de la semana.

  4. ¿Qué patrón intradía de NOVA es estable y útil para un sistema?

    • AQue la barra de las 13:40 sube
    • BQue la volatilidad y el volumen siguen una U: altos en la apertura y el cierre, bajos a mediodía
    • CQue el viernes por la tarde baja
    • DNinguno
    Ver respuesta

    Respuesta B. Que la volatilidad y el volumen siguen una U: altos en la apertura y el cierre, bajos a mediodía

    Las medias de rentabilidad por franja son ruido (2 de 78 franjas significativas, menos de las que daría el azar). La forma de la volatilidad y del volumen, en cambio, es enorme y persistente: sirve para repartir la ejecución, fijar stops y normalizar señales.

  5. ¿Por qué la rentabilidad media de marzo de ISX (−5,5 %) no es un efecto estacional?

    • APorque marzo tiene menos sesiones
    • BPorque con siete marzos, uno solo (el desplome de 2020) domina la media y el intervalo bootstrap incluye el cero
    • CPorque marzo siempre baja
    • DPorque es una media logarítmica
    Ver respuesta

    Respuesta B. Porque con siete marzos, uno solo (el desplome de 2020) domina la media y el intervalo bootstrap incluye el cero

    Un efecto mensual se mide con un dato por año. Con siete años, la media de un mes es la de siete números y un acontecimiento la mueve entera.

Ideas clave

  • Un efecto calendario se contrasta frente a los demás días o meses, no frente a cero, y con su estadístico t o un intervalo bootstrap.
  • Con muchos contrastes, los significativos por azar son la norma: 285 contrastes al 5 % dan unos 14. Corrige con Bonferroni, Holm o FDR y valida fuera de la muestra (lección 2.1.8).
  • Un efecto mensual tiene un dato por año: con siete años, un solo acontecimiento decide la media.
  • En estos datos ningún efecto de día de la semana, mes o cambio de mes resiste; el histograma de p-valores es plano, la firma de que no hay nada.
  • Lo que sí es estable es el perfil intradía de la volatilidad y del volumen: una U con la apertura y el cierre muy por encima del mediodía.

Recursos