Lesson 1.2.1 · 60 min

Stocks: splits, dividends and corporate actions

The price of a stock does not change only because the market has an opinion: it also changes because the company pays out cash, multiplies its shares or issues new ones. This lesson explains the economics of each corporate action, measures it on eight years of unadjusted NOVA prices and ends with the three ways of weighting an index.

Fig. — NOVA weekly unadjusted close, 2018–2025: the 2021 split cuts the series in two
Level 1 lessons
  1. 1.1 · How markets work

    1. 1.1.1 Market participants and trading venues
    2. 1.1.2 Sessions, auctions, holidays and calendars
    3. 1.1.3 Order book: bid, ask, spread and depth
    4. 1.1.4 Order types
    5. 1.1.5 Costs, settlement, leverage and margin
  2. 1.2 · Asset classes

    1. 1.2.1 Stocks: splits, dividends and corporate actions
    2. 1.2.2 ETFs: replication, tracking error, leveraged ETFs and UCITS
    3. 1.2.3 Futures: specifications, margin, roll and contango
    4. 1.2.4 Forex: pairs, pips, lots, rollover and CFDs
    5. 1.2.5 Options: calls, puts, intrinsic value and time value
    6. 1.2.6 Crypto: spot, perpetuals, funding and custody
    7. 1.2.7 Fixed income and interest rates; CFDs and leveraged products
  3. 1.3 · Market data sources

    1. 1.3.1 Types of market data: EOD, bars, ticks, order book and reference
    2. 1.3.2 Free market data sources
    3. 1.3.3 Retail and prosumer market data APIs
    4. 1.3.4 Professional market data providers
    5. 1.3.5 Crypto and on-chain data
    6. 1.3.6 Brokers as market data sources
    7. 1.3.7 Market data licensing and terms of use
    8. 1.3.8 How to choose a market data provider
  4. 1.4 · Financial data engineering

    1. 1.4.1 Downloading over REST and websockets: pagination, rate limits and retries
    2. 1.4.2 Data cleaning: missing values, bad ticks, gaps and time zones
    3. 1.4.3 Adjusting for splits and dividends: adjusted and unadjusted prices
    4. 1.4.4 Universes without survivorship bias: delistings, mergers and symbol changes
    5. 1.4.5 Building bars: time, tick, volume, dollar and imbalance
    6. 1.4.6 Continuous futures series: roll rules, difference adjustment and ratio adjustment
    7. 1.4.7 Storage: CSV, Parquet, partitioning, DuckDB, TimescaleDB and ArcticDB
    8. 1.4.8 Reproducible pipeline: download, validation, incremental updates and quality tests
  5. 1.5 · Fundamental and macro data

    1. 1.5.1 Financial statements, ratios, XBRL and SEC EDGAR
    2. 1.5.2 Macro data, economic calendars, estimates and transcripts
  6. 1.6 · Financial exploratory analysis

    1. 1.6.1 Returns, volatility, rolling correlations and drawdown
    2. 1.6.2 Stylized facts: fat tails, clustering, autocorrelation and leverage
    3. 1.6.3 Seasonality: day of the week, month, turn of the month and intraday sessions
  7. 1.7 · Programmed technical analysis

    1. 1.7.1 Technical indicators in Python
    2. 1.7.2 Your own implementation versus TA-Lib: validating results
    3. 1.7.3 Candlestick patterns and support and resistance
    4. 1.7.4 Multi-timeframe analysis without look-ahead

What a share is

A share is a proportional part of a company's capital. It gives two kinds of rights: economic (a part of the profits that are distributed, in the form of dividends, and of the assets if the company is wound up) and voting (voting at the general meeting). Many companies also grant a pre-emptive subscription right: when they issue new shares, current shareholders can buy them first, in proportion to what they already hold.

Three quantities are best not confused:

  • Price: what is paid for one share in the market.
  • Shares outstanding: how many have been issued (minus those the company itself holds as treasury stock).
  • Market capitalization: price × shares outstanding. It is what the whole company is worth to the market. Indexes usually use the free-float capitalization: only the shares that actually trade, without those of controlling shareholders.

The price of a share, on its own, does not say whether a company is large or expensive: a 1,600 USD share can belong to a smaller company than an 18 USD one with many more shares. This idea comes back at the end of the lesson, with indexes.

Corporate actions are the company's decisions that change the number of shares, the price or both. Each one has different economics and a different footprint in the data:

EventSharesPriceValue for the shareholder
N-for-1 split× N÷ NUnchanged
1-for-N reverse split÷ N× NUnchanged
Cash dividendUnchangedFalls by the amount on the ex-dateUnchanged: receives the cash
Stock dividend (scrip)RisesFalls proportionallyUnchanged if the rights are not sold
Rights issue below marketRisesFalls to the theoretical priceUnchanged if they exercise or sell the rights
Issue without rights (placement)RisesMay fallDiluted
Share buybackFallsNo mechanical adjustmentUnchanged for those who do not sell
Spin-offReceives shares of the subsidiaryFalls by the subsidiary's valueUnchanged: the sum of the two
Merger or takeover bidExchanged or paid outConverges to the offer priceDepends on the premium
DelistingDisappearsLast traded priceWhatever is left (lesson 1.4.4)

The right-hand column says “unchanged” in almost every row. That is the central idea: most corporate actions change the unit of measurement, not the value. But the raw price does change, and a trading system that reads raw prices sees moves that do not exist. The way to correct it, adjusted prices, is lesson 1.4.3; here the point is to understand why they jump.

The split: the price changes and the value does not

In a 4-for-1 split, each old share becomes four new ones. The price is divided by four, the market capitalization does not change. Companies do it mostly so that the share has a “manageable” price: at 240 USD per share, a lot of 100 costs 24,000 USD.

The header figure is NOVA's unadjusted weekly close since 2018. On August 23, 2021 the series breaks in two. The daily data shows it without smoothing:

IN [01]python
import pandas as pd

d = pd.read_csv("nova_diario_sin_ajustar.csv", parse_dates=["fecha"],
                index_col="fecha")
d.loc["2021-08-18":"2021-08-25"]
OUT [01]The split in raw prices
            apertura  maximo  minimo  cierre   volumen
fecha
2021-08-18    241.43  247.29  233.13  245.16   1747289
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

On Friday, August 20 NOVA closes at 240.00 USD; on Monday the 23rd it opens at 60.28. It is the effective day of the split (the split's ex-date): the new shares are already trading. Volume in shares goes from about 2 million to more than 13 million. None of this is news about the company. A return calculation that does not know about it reads it like this:

IN [02]python
r = d["cierre"].pct_change()
print(r.nsmallest(3).round(4))

antes = d.loc["2021-05-24":"2021-08-20", "volumen"].mean()
despues = d.loc["2021-08-23":"2021-11-19", "volumen"].mean()
print(f"Average volume: {antes:,.0f} before, {despues:,.0f} after"
      f" (x{despues / antes:.2f})")
OUT [02]What a naive calculation sees
fecha
2021-08-23   -0.7519
2021-06-02   -0.1221
2025-03-26   -0.1210
Name: cierre, dtype: float64
Average volume: 3,331,806 before, 11,516,047 after (x3.46)

The worst session in NOVA's history, according to this calculation, is −75.19%: the day of the split. The next two, of about −12%, are real moves. A backtest on this series would buy “the dip”, trigger a stop or produce an absurd volatility for 2021. Average volume over the following three months is 3.46 times that of the previous three: almost the split factor of 4, because each new share is a quarter of the old one. A liquidity filter based on shares traded thinks NOVA has become four times more liquid; in dollars traded (price × volume), almost nothing has changed.

Checking that the value does not change needs the number of shares, which is not in the data. With an assumed figure of 100 million shares before the split:

IN [03]python
acciones = pd.Series(100e6, index=d.index)
acciones.loc["2021-08-23":] *= 4  # 4-for-1 split

cap = d["cierre"] * acciones / 1e9
cap.loc["2021-08-19":"2021-08-24"].round(2)
OUT [03]Market capitalization before and after
fecha
2021-08-19    24.10
2021-08-20    24.00
2021-08-23    23.82
2021-08-24    23.82
dtype: float64

24.00 billion on Friday and 23.82 on Monday: a change of −0.75%, which is what the market moved that day. The practical rule for the data is twofold: returns are calculated on adjusted prices (lesson 1.4.3) and volumes are compared in dollars or adjusted by the same factor.

The reverse split is the opposite: 1 new share for every N old ones. It is usually done by a company whose price has fallen a lot. In the data, the raw price is multiplied from one day to the next: it is not a rally, and it almost always comes after a long decline.

Dividends: four dates and a drop

A cash dividend takes cash out of the company and hands it to the shareholders. The company is worth less by exactly what it pays, and the price discounts it. The calendar has four dates:

DeclarationEx-dateRecordPayment
Mermaid source
flowchart LR
  A[Declaration] --> E[Ex-date]
  E --> R[Record]
  R --> P[Payment]
  • Declaration date: the general meeting or the board approves the amount and the dates.
  • Record date: whoever is listed as a shareholder in the records that day receives the dividend.
  • Ex-dividend date: the first session in which the share trades without the right to the dividend. Whoever buys on that day or later no longer receives it; whoever sells on that day still receives it.
  • Payment date: the cash reaches the account.

The ex-date depends on settlement. To appear on the register the purchase has to have settled; with T+1 settlement (the US, since May 2024), a purchase made on the record date no longer arrives in time. That is why, according to the SEC, the ex-date is set on the record date (or the previous business day if the record date is not one). With T+2 settlement, as in the EU, the same reasoning gives one business day before the record date. For a very large dividend, 25% of the price or more, the US rule is different: the ex-date is deferred to the business day after the payment.

nova_eventos.csv lists NOVA's 34 events: 32 quarterly dividends, one special dividend and the split. Amounts before the split are per old share:

IN [04]python
ev = pd.read_csv("nova_eventos.csv",
                 parse_dates=["fecha_ex", "fecha_pago"])
print(ev["tipo"].value_counts())
ev.iloc[13:17]
OUT [04]NOVA corporate actions
tipo
dividendo                   32
split                        1
dividendo_extraordinario     1
Name: count, dtype: int64
     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

The dividend goes from 0.60 USD to 0.15 USD right after the split. It is not a cut: 0.60 / 4 = 0.15. Whoever had one share and received 0.60 now has four and receives 4 × 0.15. A “dividend growth” analysis that does not adjust for the split would see a 75% cut.

At the open of the ex-date, the price should, in theory, fall by the amount of the dividend. This can be checked by comparing the gap between the previous close and the open with the drop the dividend explains:

IN [05]python
d["cierre_ant"] = d["cierre"].shift()
div = ev[ev["tipo"] != "split"].merge(
    d[["apertura", "cierre_ant"]], left_on="fecha_ex",
    right_index=True)
div["esperado_pct"] = -100 * div["importe"] / div["cierre_ant"]
div["hueco_pct"] = 100 * (div["apertura"] / div["cierre_ant"] - 1)

cols = ["fecha_ex", "tipo", "importe", "esperado_pct", "hueco_pct"]
div[cols].iloc[23:27].round({"esperado_pct": 2, "hueco_pct": 2})
OUT [05]Expected drop versus observed gap
     fecha_ex                      tipo  importe  esperado_pct  hueco_pct
24 2023-11-10                 dividendo     0.17         -0.44      -0.95
25 2023-12-14  dividendo_extraordinario     1.50         -3.51      -3.20
26 2024-02-12                 dividendo     0.18         -0.37      -0.68
27 2024-05-10                 dividendo     0.18         -0.31       0.17

The special dividend of December 14, 2023, 1.50 USD on a close of 42.75, explains a 3.51% drop, and the open falls 3.20%: it is visible to the naked eye. The surrounding quarterly dividends explain drops of between 0.31% and 0.44%, and the observed gaps are −0.95%, −0.68% and +0.17%: the dividend is there, but it is covered up by everything else that happened that night. On May 10, 2024 the stock even opened above the previous close.

Fig. — Expected dividend drop against the observed opening gap on each NOVA ex-date, 2018–2025

The figure plots the two quantities against each other on the 33 ex-dates. If the gap were only the dividend, all the points would lie on the diagonal. The special dividend is almost on it; the quarterly ones form a column that is narrow (they all explain between −0.17% and −0.44%) and very tall. How much noise is there in a normal night?

IN [06]python
ordinarios = div[div["tipo"] == "dividendo"]
print(ordinarios[["esperado_pct", "hueco_pct"]].mean().round(2))
print("Positive gaps on ex-date:",
      (ordinarios["hueco_pct"] > 0).sum(), "of", len(ordinarios))

hueco = 100 * (d["apertura"] / d["cierre_ant"] - 1)
sin_evento = hueco.drop(ev["fecha_ex"])
print(f"Standard deviation of the gap without events: "
      f"{sin_evento.std():.2f} %")
OUT [06]The noise of a night
esperado_pct   -0.29
hueco_pct      -0.55
dtype: float64
Positive gaps on ex-date: 9 of 32
Standard deviation of the gap without events: 0.97 %

On average, the quarterly dividends explain −0.29% and the observed gap is −0.55%: the sign and the order of magnitude match, but on 9 of the 32 ex-dates the stock opened above the previous close. The standard deviation of the gap on a night without events is 0.97%, three times the dividend drop. Not being visible does not mean it does not matter: it is money the shareholder receives and the price series does not capture.

IN [07]python
div["rpd"] = div["importe"] / div["cierre_ant"]
anual = 100 * div.groupby(div["fecha_ex"].dt.year)["rpd"].sum()
anual.round(2)
OUT [07]Dividend yield for each year
fecha_ex
2018    0.85
2019    1.08
2020    1.13
2021    1.11
2022    1.13
2023    4.98
2024    1.30
2025    1.33
Name: rpd, dtype: float64

A little over 1% a year, and almost 5% in 2023 because of the special dividend. Over eight years, a strategy that measures its return with prices only misses nine or ten points that the investor did receive. It is the difference between a price index and a total return index (lesson 1.2.2), and the reason for dividend-adjusted prices (lesson 1.4.3).

Capital increases and subscription rights

A capital increase issues new shares to raise money. If the new shares are sold below the market price, the old shareholders lose value unless they have the right to buy them in proportion. That is the pre-emptive subscription right: each old share receives one right, and a fixed number of rights subscribes one new share at the issue price.

With NN old shares for every nn new ones, market price PP and issue price EE, the theoretical price after the issue (TERP, theoretical ex-rights price) is the weighted average of what the company is worth plus the new money:

Pex=N⋅P+n⋅EN+n,D=P−Pex=n (P−E)N+nP_{\text{ex}} = \frac{N \cdot P + n \cdot E}{N + n}, \qquad D = P - P_{\text{ex}} = \frac{n\,(P - E)}{N + n}

where DD is the theoretical value of one right (one per old share). On the day the rights are detached from the shares, the share trades “ex-rights” and its price falls, in theory, to PexP_{\text{ex}}; the rights trade separately during the subscription period.

IN [08]python
def ampliacion(P, E, N, n):
    """Theoretical ex-rights price and theoretical value of one right."""
    p_ex = (N * P + n * E) / (N + n)
    return p_ex, P - p_ex

p_ex, derecho = ampliacion(P=60.0, E=40.0, N=4, n=1)
print(f"Theoretical price: {p_ex:.2f}  right: {derecho:.2f}")

tengo = 400
print("Before:", tengo * 60.0)
print("Exercises (pays 100 x 40):", (tengo + 100) * p_ex - 100 * 40)
print("Sells the rights:", tengo * p_ex + tengo * derecho)
print("Does nothing:", tengo * p_ex)
OUT [08]Theoretical price and value of the right
Theoretical price: 56.00  right: 4.00
Before: 24000.0
Exercises (pays 100 x 40): 24000.0
Sells the rights: 24000.0
Does nothing: 22400.0

With one new share for every four at 40 USD on a price of 60, the theoretical price is 56 USD and each right is worth 4 USD. Whoever exercises or sells the rights keeps their 24,000 USD; whoever does nothing and lets them lapse loses 1,600 USD, 6.7%. In practice the market does not hit the theoretical price exactly, but this is the order of magnitude.

Rights issueReceives rightsExercisesSells rightsDoes nothingValue intactLoses the right
Mermaid source
flowchart TB
  A[Rights issue] --> D[Receives rights]
  D --> X[Exercises]
  D --> V[Sells rights]
  D --> N[Does nothing]
  X --> I[Value intact]
  V --> I
  N --> L[Loses the right]

In the data, a rights issue is a drop in the price on the ex-rights date that providers adjust with a factor Pex/PP_{\text{ex}} / P, just like a dividend. Two other variants are common in Spain:

  • Stock dividend or scrip (“flexible dividend”): the company grants free allotment rights; the shareholder chooses between receiving new shares or selling the rights (to the company itself at a fixed price or in the market). For the data it resembles a bonus issue: more shares and an adjusted price.
  • Accelerated placement without rights: the company sells new shares to institutional investors within a few hours, at a discount. There is no right to compensate, so the shareholder who does not take part is diluted. In the data it appears as a real drop, not as an adjustment.

Buybacks, spin-offs, mergers and delistings

  • Buyback: the company buys its own shares in the market. It is another way of returning money: shares outstanding fall and earnings per share rise. There is no price adjustment, because there is no day on which the value changes all at once. For fundamental analysis it does matter: the number of shares changes from one quarter to the next (lesson 1.5.1).
  • Spin-off: the company distributes shares of a subsidiary. The parent's price falls by what the subsidiary is worth, and the shareholder receives new shares. A provider that does not adjust for it shows a drop the shareholder did not suffer.
  • Merger or takeover bid: the price of the acquired company converges to the offer price and stops trading. If the deal is a share exchange, the shareholder ends up holding shares of the acquirer.
  • Delisting: the share stops trading, because of a merger, a bankruptcy or a decision of the company itself. If the data only has the companies listed today, all those that left are missing, and they are precisely the ones that ended badly: survivorship bias (lesson 1.4.4).
  • Ticker change: the ticker changes and the company is the same. A database indexed by ticker splits it into two unrelated series.

Indexes: how a basket is weighted

An index summarizes the price of a basket of stocks in one number. What changes from one to another is how much each stock weighs. The three basic weightings are:

  • Price-weighted: the index is the sum of the prices divided by a divisor. A 1,600 USD share weighs a hundred times more than a 16 USD one, whatever the size of the company. The Dow Jones Industrial Average works this way, according to its methodology.
  • Capitalization-weighted: each stock weighs as much as its market capitalization, usually free-float. It is the weighting of most S&P Dow Jones Indices indexes and, among others, of the S&P 500 and the IBEX 35.1Note 1 · According to the S&P Dow Jones Indices index mathematics methodology (in the resources), most of its equity indexes are weighted by free-float market capitalization; chapter 358 of the CME rulebook describes the S&P 500 as a value-weighted composite index, and the MEFF factsheet for the IBEX 35 future describes the IBEX 35 as “a capitalization-weighted index”.
  • Equal-weighted: they all weigh the same and the index is rebalanced periodically. It gives more weight to the small ones than capitalization weighting does.

The course universe data (lesson 1.4.4) says which stocks were members of a fictitious 40-stock index each day. On June 2, 2025:

IN [09]python
miembros = pd.read_csv("universo_miembros.csv",
                       parse_dates=["alta", "baja"])
dia = pd.Timestamp("2025-06-02")
vivos = miembros[(miembros["alta"] <= dia)
                 & (miembros["baja"].isna() | (miembros["baja"] > dia))]
print(len(vivos), "members on", dia.date())

precios = pd.read_parquet("universo_precios.parquet")
p = precios[precios["fecha"] == dia].set_index("ticker")["cierre"]
p[vivos["ticker"]].describe().round(2)
OUT [09]Index members on a date
40 members on 2025-06-02
count      40.00
mean      229.40
std       302.12
min        17.70
25%        51.24
50%       108.38
75%       309.10
max      1607.97
Name: cierre, dtype: float64

The 40 members trade between about 18 USD and about 1,600 USD. To compare weightings five are enough, with an assumed number of shares outstanding (the data does not include it). The closes in universo_precios.parquet are adjusted; for a single date close to the end of the series, that does not change the example.

IN [10]python
acciones = pd.Series({"ZXQZ": 50, "ZXLZ": 300, "ZXGM": 900,
                      "ZXAD": 2500, "ZXHW": 6000})  # millions
cesta = pd.DataFrame({"precio": p[acciones.index],
                      "acciones_m": acciones})
cesta["cap_m"] = cesta["precio"] * cesta["acciones_m"]

pesos = pd.DataFrame({
    "precio": cesta["precio"] / cesta["precio"].sum(),
    "capitalizacion": cesta["cap_m"] / cesta["cap_m"].sum(),
    "igual": 1 / len(cesta),
})
print(cesta.round(2))
(100 * pesos).round(1)
OUT [10]Three ways of weighting
       precio  acciones_m     cap_m
ZXQZ  1607.97          50   80398.5
ZXLZ   921.91         300  276573.0
ZXGM   171.20         900  154080.0
ZXAD    36.58        2500   91450.0
ZXHW    17.70        6000  106200.0
      precio  capitalizacion  igual
ZXQZ    58.4            11.3   20.0
ZXLZ    33.5            39.0   20.0
ZXGM     6.2            21.7   20.0
ZXAD     1.3            12.9   20.0
ZXHW     0.6            15.0   20.0
Fig. — Weight of five stocks in an index depending on the weighting: by price, by market capitalisation or equally

By price, ZXQZ is 58.4% of the index: its share is the most expensive, but with 50 million shares it is the smallest company of the five (80,398 million in market capitalization). By capitalization it weighs 11.3%, and the largest is ZXLZ, with 39.0%. The equal-weighted index gives 20% to each one. Three indexes with the same five stocks can have very different returns: the price-weighted one is, in practice, a bet on ZXQZ.

The divisor of a price-weighted index is what makes it continuous. If ZXQZ did a 10-for-1 split, its price would go from 1,607.97 to 160.80 and the index would fall because of an event that does not change the value of anything. The provider recalculates the divisor so that the level is the same just before and just after:

IN [11]python
divisor = 5.0
nivel = cesta["precio"].sum() / divisor
print(f"Index: {nivel:.2f}")

tras = cesta["precio"].copy()
tras["ZXQZ"] /= 10  # 10-for-1 split
print(f"Without adjusting the divisor: {tras.sum() / divisor:.2f}")

nuevo = tras.sum() / nivel
print(f"New divisor: {nuevo:.4f}, index {tras.sum() / nuevo:.2f}")
peso = 100 * tras["ZXQZ"] / tras.sum()
print(f"ZXQZ weight after the split: {peso:.1f} %")
OUT [11]A split in a price-weighted index
Index: 551.07
Without adjusting the divisor: 261.64
New divisor: 2.3739, index 551.07
ZXQZ weight after the split: 12.3 %

Without an adjustment, the index would go from 551.07 to 261.64, a fictitious −52.5%. With the new divisor (2.3739), the level stays at 551.07. But ZXQZ's weight falls from 58.4% to 12.3% without the company having changed: that is the oddity of price weighting. In a capitalization-weighted index, the same split changes nothing, because price × shares stays the same.

Capitalization-weighted indexes also have a divisor, and they adjust it for other events: additions and removals of members, share issues, large buybacks or changes in the free float. In all of them, the rule is the same: the index level only changes because of prices, never because of mechanics.

What this changes in your data

  • Unadjusted prices to trade, adjusted prices to measure. The price at which an order was executed is the raw one; the return of a position is measured with the adjusted one (lesson 1.4.3). Mixing them gives −75% returns or stops that trigger on their own.
  • Volume is adjusted too. After a split, volume in shares is multiplied; in dollars, it is not.
  • The date that counts is the ex-date. The dividend adjustment is applied on the ex-date; using the payment date shifts it.
  • Dividends are return. A little over 1% a year in NOVA, invisible on the chart, real in the account. A short strategy pays them.
  • The index is not the sum of its companies. Before comparing a strategy with an index, you have to know how it weights and whether it is a price or a total return index.
  • Events are stored separately. An events table (fecha_ex, type, ratio, amount) makes it possible to redo any adjustment; an already adjusted series cannot be undone.

Exercises

  1. Leaving out the split, which are NOVA's three largest opening gaps (in absolute value)? Do they coincide with any ex-dividend date?
Solution
IN [12]python
grandes = hueco.drop(pd.Timestamp("2021-08-23")).abs().nlargest(3)
print(hueco[grandes.index].round(2))
print("Is any of them an ex-date?",
      grandes.index.isin(ev["fecha_ex"]).any())
OUT [12]The largest gaps without the split
fecha
2018-04-27    13.49
2021-07-23    -9.39
2019-04-26    -7.55
dtype: float64
Is any of them an ex-date? False

None of them coincides with a dividend. NOVA's large gaps come on the day after an earnings release (after the close on the fourth Thursday of January, April, July and October, according to the data README). A 13% gap is not explained by any corporate action: it is new information. Telling a “mechanical” gap (split, dividend) from an informative one is the first step of any data cleaning (lesson 1.4.2).

  1. Calculate the weight of each index member on June 2, 2025 if the index were price-weighted. What weight does the largest have? And how much would it have in an equal-weighted one?
Solution
IN [13]python
p40 = p[vivos["ticker"]]
peso_precio = 100 * p40 / p40.sum()
print(peso_precio.nlargest(3).round(2))
print(f"Equal-weighted: {100 / len(p40):.2f} % each")
OUT [13]Price weights of the 40 members
ticker
ZXQZ    17.52
ZXLZ    10.05
ZXZE     7.80
Name: cierre, dtype: float64
Equal-weighted: 2.50 % each

ZXQZ, with the highest price, would weigh 17.52% in a price-weighted 40-stock index: seven times the 2.50% an equal-weighted one would give it. The three most expensive add up to more than a third of the index. That is why price-weighted indexes are a historical oddity today.

  1. A Spanish company announces a dividend and a record date on Thursday. With T+2 settlement, what is the last day to buy with the right to receive it? If instead of buying you want to sell and still receive the dividend, what is the first day you can sell?
Solution

With T+2, a purchase on Tuesday settles on Thursday and appears on the register: Tuesday is the last day with the right (last trading date) and Wednesday is the ex-date, one business day before the record date. Whoever wants to sell and keep the dividend can do so from Wednesday, the ex-date: on that day the share already sells “without” the dividend, which is still theirs. The reasoning is the same as in the US, with one more day of settlement (lesson 1.1.5).

Footnotes

  1. According to the S&P Dow Jones Indices index mathematics methodology (in the resources), most of its equity indexes are weighted by free-float market capitalization; chapter 358 of the CME rulebook describes the S&P 500 as a value-weighted composite index, and the MEFF factsheet for the IBEX 35 future describes the IBEX 35 as “a capitalization-weighted index”. ↩

Each answer is folded under its question

Self-assessment

  1. NOVA does a 4-for-1 split. An investor had 100 shares at 240 USD. What do they have the next day, not counting market moves?

    • A100 shares at 60 USD: they have lost 75%
    • B400 shares at 240 USD: they have quadrupled their investment
    • C400 shares at 60 USD: the same as before
    • D100 shares at 240 USD and 300 rights
    Show answer

    Answer C. 400 shares at 60 USD: the same as before

    A split multiplies the number of shares and divides the price by the same factor. The value of the position (100 × 240 = 400 × 60 = 24,000 USD) and the company's market capitalization do not change. Only the unit of measurement changes.

  2. In the US, with T+1 settlement, a company sets the record date of a dividend on Monday, March 16. What is the last day you have to buy to receive it?

    • AMonday the 16th itself
    • BFriday the 13th
    • CTuesday the 17th
    • DThe payment date
    Show answer

    Answer B. Friday the 13th

    With T+1, the ex-date coincides with the record date (Monday the 16th). Whoever buys on the 16th or later no longer receives it; whoever buys on Friday the 13th settles on Monday the 16th and appears on the register.

  3. Why are NOVA's quarterly dividends barely distinguishable in the opening gap of their ex-date?

    • ABecause dividends are paid later and do not affect the price
    • BBecause the provider has already adjusted the prices
    • CBecause dividends only affect the close, not the open
    • DBecause the drop they explain (0.3% on average) is small compared with the normal noise of a night (standard deviation of 0.97%)
    Show answer

    Answer D. Because the drop they explain (0.3% on average) is small compared with the normal noise of a night (standard deviation of 0.97%)

    The price falls by the dividend, but it also moves because of everything else. A 0.3% drop is buried in noise three times larger; the special dividend of 1.50 USD (3.5%) does show. Not being visible to the naked eye does not mean it does not matter: added up, it is a little over 1% a year.

  4. A stock trades at 60 USD and the company raises capital: 1 new share for every 4 old ones at 40 USD. What is the theoretical value of each right?

    • A4 USD
    • B20 USD
    • C5 USD
    • D0 USD: the rights are worthless
    Show answer

    Answer A. 4 USD

    The theoretical price after the issue is (4 × 60 + 1 × 40) / 5 = 56 USD, and each old share carries a right worth 60 − 56 = 4 USD. Whoever does nothing and lets the rights lapse loses those 4 USD per share.

  5. In a price-weighted index, one of its stocks does a 10-for-1 split. What does the index provider do?

    • ANothing: the index falls and recovers on its own
    • BMultiplies that stock's price by 10 forever
    • CRemoves the stock from the index
    • DChanges the divisor so that the index is worth the same just before and just after the split
    Show answer

    Answer D. Changes the divisor so that the index is worth the same just before and just after the split

    Without an adjustment, the index would fall because of an event that does not change the value of anything. The divisor is recalculated so that the level is continuous. The side effect is that, from then on, that stock weighs much less in the index.

Key points

  • Market capitalization = price × shares outstanding. A split changes both factors and leaves the product unchanged; a dividend takes cash out of the company and lowers the price by its amount.
  • In unadjusted NOVA prices, the 2021 split is a −75% jump and volume is multiplied by four; a return calculation that does not know about it sees the worst session in its history.
  • The ex-date decides who receives a dividend. In the US, with T+1, the ex-date coincides with the record date; the price drop comes at the open of the ex-date.
  • Ordinary dividends get lost in the noise of a night, but added up they are a little over 1% a year in NOVA: a price-only series understates the return.
  • A rights issue lowers the market price to the theoretical price; the right compensates the shareholder who sells or exercises it.
  • A price-weighted index gives more weight to the stock with the highest price, not to the largest company. After a split, the divisor is adjusted and that stock's weight collapses.

Resources

Data