---
title: "1.4.3 Ajustes por splits y dividendos"
description: "Factores de ajuste hacia atrás para un split 4 por 1 y 33 dividendos, rentabilidad total frente a la de precio, señales falsas y el problema point-in-time."
url: "https://pythonparatrading.com/curso-python-trading/nivel-1/ajustes-por-splits-y-dividendos/"
lang: "es"
image: "https://pythonparatrading.com/og/curso-python-trading/nivel-1/ajustes-por-splits-y-dividendos.png"
---

# 1.4.3 · Ajustes por splits y dividendos: precios ajustados y sin ajustar

> El 23 de agosto de 2021 NOVA «cayó» un 75 % y nadie perdió dinero: fue un split 4 por 1. Esta lección construye a mano los factores de ajuste de ocho años de eventos corporativos, comprueba el método contra el ejemplo publicado por un proveedor y enseña cuándo usar cada serie y qué rompe usar la equivocada.

- Curso: [Nivel 1: Datos financieros, mercados y análisis](https://pythonparatrading.com/curso-python-trading/nivel-1/)
- Módulo: 1.4 · Ingeniería de datos financieros
- Duración: 55 min
- Requisitos: [1.2.1 · Acciones: splits, dividendos y eventos corporativos](https://pythonparatrading.com/curso-python-trading/nivel-1/acciones-splits-dividendos-y-eventos-corporativos/), [1.4.2 · Limpieza de datos: faltantes, ticks erróneos, huecos y zonas horarias](https://pythonparatrading.com/curso-python-trading/nivel-1/limpieza-de-datos-financieros/)

## Al terminar esta lección

- Calcular el factor de cada split y de cada dividendo y el factor acumulado hacia atrás, y construir con ellos la serie ajustada.
- Comprobar que la serie ajustada no tiene saltos en las fechas ex y que su rentabilidad es la rentabilidad total.
- Distinguir rentabilidad de precio y rentabilidad total, y medir cuánto aportan los dividendos.
- Reconocer las señales falsas que producen los precios sin ajustar en un backtest.
- Explicar por qué un precio ajustado cambia cuando llega un dividendo nuevo y cómo guardar los datos para que eso no contamine un backtest.

## Un desplome que no lo fue

El diario de NOVA de esta lección tiene los precios **tal como se negociaron**: sin ajustar. Ocho años de sesiones de la
NYSE, de 2018 a 2025, con todos los eventos corporativos que la lección 1.2.1 describió: un split y 33 dividendos, uno
de ellos extraordinario. Basta mirar una semana de agosto de 2021:

```python
import numpy as np
import pandas as pd

bruto = pd.read_csv("nova_diario_sin_ajustar.csv",
                    parse_dates=["fecha"], index_col="fecha")
bruto.loc["2021-08-19":"2021-08-25"]
```
```output
            apertura  maximo  minimo  cierre   volumen
fecha
2021-08-19    239.60  251.84  238.19  241.05   2471611
2021-08-20    238.75  240.55  227.85  240.00   2203366
2021-08-23     60.28   60.41   58.11   59.55  13427377
2021-08-24     59.63   60.11   57.33   59.55  13974110
2021-08-25     59.17   62.40   58.71   60.18   6931159
```

El viernes 20 cierra en 240,00 y el lunes 23 abre en 60,28, con el volumen multiplicado por seis. No hubo pánico: desde
el lunes cada acción antigua son cuatro nuevas, y cada nueva vale la cuarta parte. Quien tenía 100 acciones a 240 USD
(24.000 USD) tiene 400 a 60 (24.000 USD). En la serie bruta, sin embargo, es la mayor caída de la historia:

```python
r_bruto = bruto["cierre"].pct_change()
(100 * r_bruto.nsmallest(4)).round(2)
```
```output
fecha
2021-08-23   -75.19
2021-06-02   -12.21
2025-03-26   -12.10
2020-06-23   -12.06
Name: cierre, dtype: float64
```

Un −75,19 % que no le costó nada a nadie, por delante de tres caídas reales de en torno al 12 %. Cualquier cálculo sobre
esta serie (volatilidad, drawdown, una señal) está contaminado por él. Y hay más saltos, más pequeños y más frecuentes:
en cada **fecha ex** de un dividendo, el precio abre más bajo porque quien compra ese día ya no cobra el dividendo. El
ajuste corrige las dos cosas.

## Los eventos y sus factores

La tabla de eventos tiene una fila por evento: la fecha ex, el tipo, el ratio del split o el importe del dividendo (en
las acciones que había en esa fecha: los dividendos anteriores al split son por acción antigua) y la fecha de pago.

```python
eventos = pd.read_csv("nova_eventos.csv",
                      parse_dates=["fecha_ex", "fecha_pago"])
print(eventos["tipo"].value_counts().to_dict())
eventos.iloc[13:18]
```
```output
{'dividendo': 32, 'split': 1, 'dividendo_extraordinario': 1}
     fecha_ex       tipo  ratio  importe fecha_pago
13 2021-05-10  dividendo    NaN     0.60 2021-06-01
14 2021-08-10  dividendo    NaN     0.60 2021-08-31
15 2021-08-23      split    4.0      NaN 2021-08-20
16 2021-11-10  dividendo    NaN     0.15 2021-12-01
17 2022-02-10  dividendo    NaN     0.16 2022-03-03
```

El dividendo trimestral pasa de 0,60 a 0,15 USD con el split: es el mismo dividendo por empresa, repartido entre cuatro
veces más acciones. Cada evento se convierte en un **factor**, el número por el que hay que multiplicar todos los
precios anteriores a su fecha ex para que la serie no salte:

$$
f_e = \begin{cases} \dfrac{1}{\text{ratio}_e} & \text{split} \\[6pt] 1 - \dfrac{D_e}{C_{e-1}} & \text{dividendo}
\end{cases} \qquad\qquad F_t = \prod_{e \,:\, t_e > t} f_e, \qquad\qquad \tilde{P}_t = F_t \cdot P_t
$$

donde $D_e$ es el dividendo, $C_{e-1}$ el cierre sin ajustar de la sesión anterior a la fecha ex, $F_t$ el factor
acumulado del día $t$ (el producto de los factores de todos los eventos **posteriores** a ese día) y $\tilde{P}_t$ el
precio ajustado. Es un ajuste **hacia atrás**: el último tramo de la serie queda con los precios reales y el pasado se
reescala. Es el método multiplicativo de CRSP, el que describe Yahoo para su cierre ajustado.

```mermaid
flowchart LR
  B[Precios brutos] --> F[Factor por evento]
  E[Eventos] --> F
  F --> A[Factor acumulado]
  A --> J[Serie ajustada]
  B --> J
```

```python
def factores(precios, eventos):
    cierre_ant = precios["cierre"].shift()
    ev = eventos.copy()
    es_split = ev["tipo"] == "split"
    ev["cierre_ant"] = cierre_ant.reindex(ev["fecha_ex"]).to_numpy()
    ev["factor"] = np.where(es_split, 1 / ev["ratio"],
                            1 - ev["importe"] / ev["cierre_ant"])
    return ev

ev = factores(bruto, eventos)
ev.loc[[14, 15, 25, 33],
       ["fecha_ex", "tipo", "importe", "cierre_ant", "factor"]]
```
```output
     fecha_ex                      tipo  importe  cierre_ant    factor
14 2021-08-10                 dividendo     0.60      213.21  0.997186
15 2021-08-23                     split      NaN      240.00  0.250000
25 2023-12-14  dividendo_extraordinario     1.50       42.75  0.964912
33 2025-11-10                 dividendo     0.19       66.13  0.997127
```

El split pesa 0,25; un dividendo trimestral, entre 0,9956 y 0,9983 según el precio de ese día; el extraordinario de 1,50
USD, 0,965. El factor acumulado de un día es el producto de todos los que vienen detrás. Se calcula recorriendo los
eventos: cada uno multiplica por su factor todos los días anteriores a su fecha ex.

```python
def ajustar(precios, ev):
    """F_t: producto de los factores de los eventos posteriores a t."""
    F = pd.Series(1.0, index=precios.index)
    for fecha_ex, f in zip(ev["fecha_ex"], ev["factor"]):
        F[F.index < fecha_ex] *= f
    return F

F = ajustar(bruto, ev)
precios = ["apertura", "maximo", "minimo", "cierre"]
ajustado = bruto[precios].mul(F, axis=0)
pd.DataFrame({"bruto": bruto["cierre"], "factor": F,
              "ajustado": ajustado["cierre"]}).loc[
    ["2018-01-02", "2021-08-20", "2021-08-23", "2025-12-31"]]
```
```output
             bruto    factor   ajustado
fecha
2018-01-02  192.00  0.219581  42.159572
2021-08-20  240.00  0.228378  54.810708
2021-08-23   59.55  0.913512  54.399628
2025-12-31   68.19  1.000000  68.190000
```

*Fig. — Factor de ajuste acumulado de NOVA: el producto de los factores de todos los eventos posteriores a cada día.* Escalera que sube de 0,22 en enero de 2018 a 1 en noviembre de 2025. Cada dividendo trimestral es un peldaño diminuto; el split 4 por 1 de agosto de 2021 (destacado) multiplica por cuatro el factor, de 0,23 a 0,91; el dividendo extraordinario de diciembre de 2023 es un peldaño algo mayor que los demás.

El factor acumulado es una escalera: vale 1 en el último tramo (después del último dividendo, el 10 de noviembre de
2025) y baja un peldaño en cada fecha ex, hacia atrás. El peldaño grande es el split. El 2 de enero de 2018, el factor
es 0,2196: el cierre de 192,00 USD de ese día equivale a 42,16 USD de hoy, contando el split y los 33 dividendos.

## La serie ajustada no salta

La prueba de que el ajuste está bien es que la rentabilidad de la serie ajustada sea la que obtuvo un accionista. En el
día del split, cero salto; en una fecha ex, la caída del precio compensada por el dividendo cobrado:

```python
r_aj = ajustado["cierre"].pct_change()
print(f"Split, bruto:    {r_bruto['2021-08-23']:+.2%}")
print(f"Split, ajustado: {r_aj['2021-08-23']:+.2%}")

dividendo = ev[ev["tipo"] != "split"].set_index("fecha_ex")["importe"]
c, c_ant = bruto["cierre"], bruto["cierre"].shift()
exd = dividendo.index
total = (c[exd] + dividendo) / c_ant[exd] - 1     # precio + dividendo
print("Mayor diferencia en fechas ex (pp):",
      round(100 * (r_aj[exd] - total).abs().max(), 3))
```
```output
Split, bruto:    -75.19%
Split, ajustado: -0.75%
Mayor diferencia en fechas ex (pp): 0.03
```

En el split, la serie ajustada se mueve lo que se movió el mercado ese día (−0,75 %), no un −75 %. En las fechas ex, la
rentabilidad ajustada y la rentabilidad total calculada a mano (precio más dividendo, sobre el cierre anterior)
coinciden a menos de tres milésimas de punto. La diferencia que queda es de definición: el factor multiplicativo
equivale a reinvertir el dividendo en la propia acción al precio de la fecha ex, $C_{e-1} - D_e$, mientras que la
fórmula a mano lo deja en efectivo ese día. Cualquiera de las dos es «rentabilidad total»; lo que no vale es mezclar las
dos sin saberlo.

La figura de la cabecera compara las dos series en escala logarítmica. La bruta tiene un escalón en
agosto de 2021 y una pendiente engañosa; la ajustada es continua y termina en el mismo precio, porque el último tramo no
se ajusta.

## Contra el ejemplo de un proveedor

El método no es una invención de la lección. La página de ayuda de Yahoo Finance sobre su cierre ajustado publica un
ejemplo con un split 2 por 1 y un dividendo de 0,08 USD, y dice que sigue el estándar de CRSP. Con las mismas dos
funciones, el resultado tiene que ser el suyo:

```python
dias = pd.to_datetime(["2001-02-16", "2001-02-17", "2001-02-18",
                       "2001-02-19", "2001-02-20", "2001-02-21",
                       "2001-02-22"])
ej = pd.DataFrame({"cierre": [46.99, 48.30, 24.96, 24.91, 24.95,
                              24.53, 24.54]}, index=dias)
ev_ej = pd.DataFrame({"fecha_ex": pd.to_datetime(["2001-02-18",
                                                  "2001-02-21"]),
                      "tipo": ["split", "dividendo"],
                      "ratio": [2.0, np.nan],
                      "importe": [np.nan, 0.08]})
ev_ej = factores(ej, ev_ej)
print(ev_ej[["tipo", "factor"]].round(4).to_string(index=False))
(ej["cierre"] * ajustar(ej, ev_ej)).round(2).to_list()
```
```output
     tipo  factor
    split  0.5000
dividendo  0.9968
[23.42, 24.07, 24.88, 24.83, 24.87, 24.53, 24.54]
```

Los siete cierres ajustados son los de la tabla de Yahoo (23,42; 24,07; 24,88; 24,83; 24,87; 24,53; 24,54), con el mismo
multiplicador de dividendo, 0,9968. El año y los días son de relleno: el ejemplo de Yahoo solo da día y mes, y para el
cálculo da igual que sean sesiones reales. Que la función reproduzca el ejemplo de un proveedor es una prueba mejor que
cualquier explicación: en un proyecto, este ejemplo iría a un test (lección 0.4.5).

No todos los proveedores ajustan igual. Unos ajustan solo por splits en el «cierre» y por splits y dividendos en el
«cierre ajustado»; otros ajustan toda la barra OHLC; algunos permiten elegir. Con `yfinance`, por ejemplo,
`auto_adjust=True` (el valor por defecto) devuelve las cuatro columnas ya ajustadas, y `actions=True` añade los
dividendos y los splits. El bloque no se ejecuta porque necesita red:

```python skip title="yfinance_ajustes.py"
import yfinance as yf

ajustada = yf.download("AAPL", start="2018-01-01", auto_adjust=True)
bruta = yf.download("AAPL", start="2018-01-01", auto_adjust=False,
                    actions=True)   # columnas Dividends y Stock Splits
```

Antes de usar la serie de un proveedor hay que saber cuál de ellas es. La forma rápida de averiguarlo es la de esta
sección: buscar un split conocido y ver si la serie salta.

## Rentabilidad de precio y rentabilidad total

Hay dos series ajustadas útiles, y responden a preguntas distintas. La ajustada **solo por splits** da la rentabilidad
de precio: cuánto ha subido la acción. La ajustada por splits y dividendos da la rentabilidad total: cuánto ha ganado
quien la tuvo y reinvirtió los dividendos. La diferencia es la rentabilidad por dividendo.

```python
F_split = ajustar(bruto, ev[ev["tipo"] == "split"])
precio = bruto["cierre"] * F_split
anos = (bruto.index[-1] - bruto.index[0]).days / 365.25

def tasa_anual(s):
    return (s.iloc[-1] / s.iloc[0]) ** (1 / anos) - 1

for nombre, s in [("sin ajustar", bruto["cierre"]),
                  ("solo splits (precio)", precio),
                  ("splits y dividendos (total)", ajustado["cierre"])]:
    print(f"{nombre:>28}: {tasa_anual(s):+.2%} anual")
```
```output
                 sin ajustar: -12.15% anual
        solo splits (precio): +4.49% anual
 splits y dividendos (total): +6.20% anual
```

*Fig. — 100 USD en NOVA desde enero de 2018: rentabilidad total, rentabilidad de precio y serie sin ajustar.* Tres líneas que empiezan en 100. La de rentabilidad total (destacada) termina en 161,7, un 6,2 % anual; la de precio, ajustada solo por el split, en 142,1, un 4,5 % anual; la serie sin ajustar cae a la cuarta parte en el split y termina en 35,5, como si se hubiera perdido un 12 % al año.

La serie sin ajustar dice que NOVA pierde un 12 % al año: el split, leído como una pérdida. La de precio, que gana un
4,5 %; la total, un 6,2 %. Los dividendos aportan 1,7 puntos al año, más de la cuarta parte de la rentabilidad total.
Para comparar una estrategia con «comprar y mantener», la referencia es la rentabilidad total: comparar contra la de
precio regala a la estrategia esos 1,7 puntos. Lo mismo vale para los índices: un índice de precio (como el FIX del
curso) no incluye los dividendos, y uno de rentabilidad total (como el ISX) sí (lecciones 1.2.2 y 1.2.3).

## Señales falsas en un backtest

Con la serie bruta, cualquier regla que mire variaciones o niveles se tropieza con los eventos. Dos ejemplos:

```python
caida = r_bruto[r_bruto < -0.20]
print("Días con caída > 20 % (bruto):", list(caida.index.date))
print("Días con caída > 20 % (ajustado):", (r_aj < -0.20).sum())

despues = slice("2021-08-23", "2022-06-10")
for nombre, s in [("bruto", bruto["cierre"]),
                  ("ajustado", ajustado["cierre"])]:
    bajo = (s < s.rolling(200).mean())[despues]
    print(f"Bajo su media de 200 sesiones ({nombre}): "
          f"{bajo.mean():.0%}")
```
```output
Días con caída > 20 % (bruto): [datetime.date(2021, 8, 23)]
Días con caída > 20 % (ajustado): 0
Bajo su media de 200 sesiones (bruto): 95%
Bajo su media de 200 sesiones (ajustado): 15%
```

Con la serie bruta, una regla de «comprar desplomes» compra el día del split; un filtro de tendencia (precio por debajo
de su media de 200 sesiones = mercado bajista) declara bajista a NOVA en el 95 % de las sesiones de los diez meses
siguientes, mientras la media arrastra los precios de antes del split. Con la serie ajustada, el mismo filtro solo ve
tendencia bajista en el 15 %. Son las señales falsas más visibles; las de los dividendos son pequeñas y repetidas:

```python
diferencia = (r_bruto[exd] - r_aj[exd]) * 100
print(f"Fechas ex: {len(exd)}")
print(f"Caída media que el accionista no sufrió: "
      f"{diferencia.mean():.2f} %")
print(f"Suma en ocho años: {diferencia.sum():.1f} puntos")
```
```output
Fechas ex: 33
Caída media que el accionista no sufrió: -0.39 %
Suma en ocho años: -12.9 puntos
```

Cada fecha ex, la serie bruta enseña una caída del orden del 0,4 % que el accionista no sufrió, porque cobró el
dividendo. Una estrategia que vendiera en corto la víspera de cada fecha ex parecería ganar ese 0,4 % con regularidad en
un backtest con datos brutos; en la realidad, quien está corto en la fecha ex **paga** el dividendo al prestamista de
las acciones y la ventaja desaparece.

<aside class="callout" data-kind="aviso">

Lo contrario también es un error: usar precios ajustados donde importa el precio real. Una orden limitada, un stop a un
precio, el tamaño de una posición en acciones, un filtro de «acciones de más de 5 USD» o una comisión por acción se
calculan con el precio que había en el mercado ese día, es decir, sin ajustar. Las rentabilidades, con la serie
ajustada; los niveles y las órdenes, con la bruta del día.

</aside>

El volumen también se ajusta, pero solo por splits y en sentido contrario: antes del split había cuatro veces menos
acciones, así que el volumen en acciones se multiplica por el ratio. Los dividendos no cambian el número de acciones:

```python
vol_aj = bruto["volumen"] / F_split
antes = slice("2021-07-23", "2021-08-20")
despues = slice("2021-08-23", "2021-09-21")
for nombre, v in [("bruto", bruto["volumen"]), ("ajustado", vol_aj)]:
    print(f"{nombre:>8}: mediana {v[antes].median():>11,.0f} antes, "
          f"{v[despues].median():>11,.0f} después")
```
```output
   bruto: mediana   2,578,329 antes,   9,953,681 después
ajustado: mediana  10,313,316 antes,   9,953,681 después
```

## El pasado cambia cada vez que llega un dividendo

El ajuste hacia atrás tiene una consecuencia incómoda: la serie ajustada de 2018 no es la misma si se descargó en
octubre de 2025 o en diciembre. El dividendo del 10 de noviembre de 2025 añade un factor más, y ese factor multiplica
toda la historia anterior. Se puede reconstruir lo que habría visto un sistema en cada fecha usando solo los eventos
conocidos entonces:

```python
def ajustado_a_fecha(precios, ev, fecha):
    conocidos = ev[ev["fecha_ex"] <= fecha]
    hasta = precios.loc[:fecha]
    return hasta["cierre"] * ajustar(hasta, conocidos)

oct25 = ajustado_a_fecha(bruto, ev, "2025-10-31")
dic25 = ajustado_a_fecha(bruto, ev, "2025-12-31")
print("Cierre ajustado del 2018-01-02:")
print(f"  visto el 2025-10-31: {oct25.iloc[0]:.4f}")
print(f"  visto el 2025-12-31: {dic25.iloc[0]:.4f}")
r_oct = oct25.pct_change().loc[:"2025-10-31"]
r_dic = dic25.pct_change().loc[:"2025-10-31"]
print("Rentabilidades hasta octubre iguales:",
      np.allclose(r_oct, r_dic, equal_nan=True))
```
```output
Cierre ajustado del 2018-01-02:
  visto el 2025-10-31: 42.2811
  visto el 2025-12-31: 42.1596
Rentabilidades hasta octubre iguales: True
```

Los precios ajustados de 2018 bajan un 0,29 % de una versión a la otra; las rentabilidades de los días anteriores al
evento no cambian ni en el último decimal. Un sistema que solo use rentabilidades o cocientes (medias móviles sobre la
misma serie, por ejemplo) no nota la diferencia. Uno que use niveles absolutos sí: «el máximo de 2018 fue 52,10» es una
frase que caduca cada trimestre. Y una base de datos que guarde la serie ajustada como si fuera un hecho mezclará, tras
unas cuantas actualizaciones incrementales, tramos ajustados con factores distintos.

```mermaid
flowchart LR
  G[Guardar brutos] --> T[Ajustar en t]
  E[Guardar eventos] --> T
  T --> R[Rentabilidades]
  G --> O[Órdenes y niveles]
```

La solución es la del diagrama: guardar los precios **sin ajustar** y la tabla de eventos, que no cambian, y calcular el
ajuste cuando se necesite, con los eventos conocidos en la fecha que interese. Es la idea de **point-in-time** que la
lección 1.4.4 aplica a los universos de valores y la 1.5.1 a los datos fundamentales: cada dato, tal como se conocía en
su momento.

## Ejercicios

1. Ajusta la serie con el método **aditivo**: en lugar de multiplicar por un factor, resta a todos los precios
   anteriores a cada fecha ex el dividendo (y divide por el ratio en el split). Compara la rentabilidad total anual con
   la del método multiplicativo y mira el precio ajustado más bajo de cada serie.

**Solución.**

```python
aditivo = bruto["cierre"] * F_split
for fecha_ex, d in dividendo.items():
    d_hoy = d * F_split[fecha_ex]     # en acciones de hoy
    aditivo[aditivo.index < fecha_ex] -= d_hoy
print(f"Aditivo:        {tasa_anual(aditivo):+.2%} anual, "
      f"mínimo {aditivo.min():.2f}")
print(f"Multiplicativo: {tasa_anual(ajustado['cierre']):+.2%} anual, "
      f"mínimo {ajustado['cierre'].min():.2f}")
```
```output
Aditivo:        +6.40% anual, mínimo 28.24
Multiplicativo: +6.20% anual, mínimo 30.12
```

El dividendo se pasa primero a acciones de hoy (los anteriores al split se dividen por 4) y después se resta de todo lo
anterior. El método aditivo conserva las diferencias de precio en dólares, pero no los cocientes: al restar una cantidad
fija, los precios antiguos, más bajos en proporción, bajan más en porcentaje, y la rentabilidad del principio de la
serie sale inflada. Con muchos dividendos y precios bajos puede dejar precios negativos en el pasado lejano. Por eso el
multiplicativo es el estándar para series de acciones; el aditivo solo tiene sentido cuando lo que importa son
diferencias en puntos, como en algunas series continuas de futuros (lección 1.4.6).

2. Comprueba, con `ajustado_a_fecha`, que el cierre ajustado del 2018-01-02 cambia exactamente en el factor del
   dividendo de noviembre de 2025. ¿Qué factor es?

**Solución.**

```python
f_nov = ev.loc[ev["fecha_ex"] == "2025-11-10", "factor"].item()
print(f"Factor del 2025-11-10: {f_nov:.6f}")
print(f"Cociente dic/oct: {dic25.iloc[0] / oct25.iloc[0]:.6f}")
```
```output
Factor del 2025-11-10: 0.997127
Cociente dic/oct: 0.997127
```

El cociente entre las dos versiones es justo el factor del dividendo nuevo, 1 − 0,19 / cierre del 7 de noviembre. Es la
forma de detectar, comparando dos descargas del mismo proveedor, que ha aparecido un evento: todo el pasado se mueve en
la misma proporción.

3. Un backtest de NOVA usa precios ajustados para decidir y coloca órdenes limitadas «a 50 USD» en 2019. ¿Qué problema
   tiene? ¿Cómo lo corregirías?

**Solución.**

En 2019 NOVA cotizaba sin ajustar en torno a 200 USD (antes del split) y su precio ajustado de hoy ronda los 45. Una
orden limitada a 50 USD calculada sobre la serie ajustada se ejecutaría en el backtest a un precio que nunca existió en
el mercado; colocada sobre el precio real, nunca se habría ejecutado. La regla puede decidir con la serie ajustada (o
con rentabilidades), pero el precio de la orden debe convertirse al precio real del día dividiendo por el factor
acumulado de ese día ($P_t = \tilde{P}_t / F_t$), y el tamaño en acciones se calcula también con el precio real.

## Autoevaluación

1. El cierre antes de la fecha ex es 50 USD y el dividendo, 0,50 USD. ¿Cuál es el factor multiplicativo de ese dividendo?

   - A. 0,50
   - B. 0,99
   - C. 1,01
   - D. 0,95

   *Respuesta B: 0,99.* f = 1 − D / C = 1 − 0,50 / 50 = 0,99. Todos los precios anteriores a la fecha ex se multiplican por 0,99, de modo que la caída mecánica del precio en la fecha ex desaparece de la serie.

2. Una acción hace un split 4 por 1. ¿Qué se hace con el volumen de las sesiones anteriores en la serie ajustada?

   - A. Se divide por 4
   - B. Se multiplica por 4
   - C. No se toca
   - D. Se pone a cero

   *Respuesta B: Se multiplica por 4.* Después del split hay cuatro veces más acciones y cada una vale la cuarta parte. Para que el volumen en acciones sea comparable, el anterior se multiplica por el ratio (igual que los precios se dividen por él). El volumen en dólares no cambia.

3. Un backtest con precios sin ajustar compra cuando el precio cae más de un 20 % en un día. ¿Qué pasa con NOVA el 23 de agosto de 2021?

   - A. Nada: ese día no hubo caída
   - B. Compra: la serie bruta cae un 75 %, aunque el valor de la posición no cambió
   - C. Vende
   - D. Da un error

   *Respuesta B: Compra: la serie bruta cae un 75 %, aunque el valor de la posición no cambió.* En la serie bruta el split aparece como una caída del 75 %. La regla lo interpreta como un desplome y opera. En la serie ajustada ese día es un día normal.

4. Llega un dividendo nuevo en noviembre de 2025. ¿Qué cambia en la serie ajustada de NOVA?

   - A. Solo el precio del día del dividendo
   - B. Todos los precios anteriores a la fecha ex, que se multiplican por el nuevo factor; las rentabilidades anteriores no cambian
   - C. Nada
   - D. Todas las rentabilidades de la historia

   *Respuesta B: Todos los precios anteriores a la fecha ex, que se multiplican por el nuevo factor; las rentabilidades anteriores no cambian.* El ajuste hacia atrás multiplica todo el pasado por el factor nuevo. Los niveles de precio de 2018 cambian; los cocientes entre dos días anteriores al evento, no. Por eso una regla que use niveles absolutos (un precio de 50 USD, una orden limitada) da resultados distintos según el día en que se descargó la serie.

5. ¿Qué conviene guardar en un data lake para no depender de cuándo se calculó el ajuste?

   - A. Solo la serie ajustada del proveedor
   - B. Los precios sin ajustar y la tabla de eventos, para calcular el ajuste en cada fecha con los eventos conocidos entonces
   - C. Solo las rentabilidades
   - D. Las dos series ajustadas, la de precio y la total

   *Respuesta B: Los precios sin ajustar y la tabla de eventos, para calcular el ajuste en cada fecha con los eventos conocidos entonces.* Con brutos y eventos se puede reconstruir cualquier versión del ajuste, incluida la que habría visto un sistema en una fecha concreta. Una serie ajustada guardada es una foto de un día: el siguiente dividendo la deja vieja.

## Ideas clave

- Los precios negociados (sin ajustar) tienen saltos que no son pérdidas ni ganancias: el split y la caída del precio en cada fecha ex.
- Factor de un split: 1 / ratio. Factor de un dividendo: 1 − D / C del cierre anterior a la fecha ex. El factor de cada día es el producto de los de todos los eventos posteriores.
- La serie ajustada da la rentabilidad total (precio más dividendos reinvertidos); la ajustada solo por splits, la de precio. En NOVA, 6,2 % frente a 4,5 % anual.
- Un backtest con precios sin ajustar ve desplomes falsos (el split) y caídas en cada fecha ex; con precios ajustados por splits pero no por dividendos, subestima la rentabilidad de mantener.
- El ajuste hacia atrás reescribe el pasado con cada evento nuevo: guarda brutos y eventos y ajusta al vuelo. Para órdenes y niveles absolutos se usa el precio sin ajustar.

## Recursos

### Research

- [Zipline, Backtesting en Python 2 : Mi primer Data Analisis](https://pythonparatrading.com/backtesting-python-zipline-bundle/) · Research-0012 · 3 min

### Documentación

- [Yahoo Help: What is the adjusted close? (multiplicadores de split y dividendo, estándar CRSP)](https://help.yahoo.com/kb/SLN28256.html) · help.yahoo.com
- [Investor.gov (SEC): Ex-Dividend Dates](https://www.investor.gov/introduction-investing/investing-basics/glossary/ex-dividend-dates-when-are-you-entitled-stock-and) · investor.gov
- [Investor.gov (SEC): Stock Split](https://www.investor.gov/introduction-investing/investing-basics/glossary/stock-split) · investor.gov
- [yfinance: download (auto_adjust, actions)](https://ranaroussi.github.io/yfinance/reference/api/yfinance.download.html) · ranaroussi.github.io

### Datos

- [Datos del nivel 1: diario de NOVA sin ajustar (CSV)](https://pythonparatrading.com/curso/datos/nivel-1/nova_diario_sin_ajustar.csv) · Descarga · nova_diario_sin_ajustar.csv
- [Datos del nivel 1: eventos corporativos de NOVA (CSV)](https://pythonparatrading.com/curso/datos/nivel-1/nova_eventos.csv) · Descarga · nova_eventos.csv

Lección anterior: [1.4.2 · Limpieza de datos: faltantes, ticks erróneos, huecos y zonas horarias](https://pythonparatrading.com/curso-python-trading/nivel-1/limpieza-de-datos-financieros/)

Lección siguiente: [1.4.4 · Universos sin sesgo de supervivencia: deslistados, fusiones y cambios de símbolo](https://pythonparatrading.com/curso-python-trading/nivel-1/sesgo-de-supervivencia-y-point-in-time/)
