TickerLeague

Dividend capture — methodology

Formulas, data sources and known limitations behind TickerLeague’s dividend capture analytics.

Data sources

Two underlying tables drive every metric on this product:

  • Ex-dividend events — one row per declared cash dividend with ex-date, declaration date, record date, payment date, dividend amount, and frequency. Source: Financial Modeling Prep /stable/dividends.
  • End-of-day prices — raw OHLC + volume bars, not dividend-adjusted. We must use raw prices, not adjusted ones, because adjusted prices already “eat” the dividend gap and would make recovery look instant.

Event construction

For every qualifying ex-dividend event we precompute and store the following per-event values exactly once (see plan v7.6 «посчитать один раз»):

  • close_prev — the regular close on the last trading day strictly before the ex-date.
  • gap_open_pct = (open_ex − close_prev) / close_prev — expected to be negative (price drops by ~the dividend).
  • recovered_Nd primary recovery flag: did the post-ex intraday high ever reach close_prev within N trading days (N ∈ {1, 3, 5, 10, 30}). High-based because that is precisely when a GTC limit-order at the pre-ex close would actually fill. The companion stricter close-based flags recovered_close_Nd require an actual close above pre-ex (mark-to-MOC) and are exposed as secondary information.
  • days_to_recover_high primary time-to-recover: first trading day with high ≥ close_prev, capped at 30, null if never within 30. This is the column aggregated into the MV median / avg / best / worst days-to-recover stats and is consistent with recovered_Nd (no more “Recovered 30d: yes” alongside “Days to recover: >30” on the same row).
  • days_to_recover_close stricter alternative: first trading day with close ≥ close_prev, capped at 30. Stored for analytics and explored via the per-ticker simulator in Hold N days, exit MOC mode; the history table stays on the high-touch (limit-order) view only.
  • The per-ticker Pre-ex touch time distribution chart buckets days_to_recover_high into trading-day windows (≤1, 2–3, …, plus a final 30+ bucket for no touch within 30 sessions). The summary line above the chart reports the share of events whose intraday high touched the pre-ex close within 5 trading days.
  • drawdown_during_hold min(low / close_prev − 1) over the 10-day window after ex-date.
  • signal_to_noise = dividend / atr_14_pre — how big the dividend is versus typical daily price swing.

Why we measure recovery on intraday high, not close

A real-world dividend capture trade rarely waits for the closing bell. The textbook exit is a GTC limit-order at the pre-ex close: the moment the post-ex intraday high first touches that level, the order fills, the position is flat, and the trader pockets the dividend at break-even. Measuring recovery via intraday high directly answers the trader-facing question “would my limit have filled?” — and aligns the headline metrics on this product (30d touch rate, median touch days) with the same system of coordinates used in the per-event Recovered 5d / Recovered 30d badges.

The stricter close-based recovery (mark-to-MOC) is also computed and stored as days_to_recover_close. It answers a different question: “was I flat at the bell?” — relevant for a passive trader who exits at MOC rather than via limit. Compare it in the per-ticker simulator's Hold N days, exit MOC mode; the event history table shows only the high-touch path so the columns line up with the Recovered 5d / Recovered 30d badges. By design the close-based count is always ≥ the high-based count when both exist.

Aggregation window

Per-ticker headline numbers (success rate, median days, etc.) aggregate the most recent 20 events or 5 years, whichever yields fewer rows. This window balances statistical reliability against regime-shift risk: trading dynamics from a decade ago may no longer apply.

We require a minimum of 4 events to compute any aggregate. Tickers below this threshold have no row in the rankings materialised view and their per-ticker page renders an empty-state.

Confidence tiers

Every per-ticker row is tagged with a data-confidence label:

  • highevents_count ≥ 12
  • mediumevents_count ≥ 6
  • low — fewer than 6 events. These tickers still render their sub-page, but headline metrics are hidden behind a tooltip and the page is not indexed by search engines.

ATR calculation

We use a 14-day Average True Range with Wilder's smoothing, computed over the 14 trading days immediately before the ex-date. ATR captures typical intra-day price range; comparing the dividend amount to ATR (the “signal-to-noise” ratio) tells you whether the dividend is meaningful versus normal daily volatility.

Why no composite score

We deliberately do not publish a single “Capture Score”. Industry practice from Bloomberg, Schwab, Tastytrade and Interactive Brokers shows the primitives (success rate, median recovery days, dividend/ATR) separately — each user weights them according to their own strategy.

The academic literature on dividend capture (Boyd & Jagannathan, 1994; Frank & Jagannathan, 1998) similarly focuses on the price-drop ratio and recovery time as standalone metrics rather than composite indices. Any composite score is a subjective heuristic that requires out-of-sample validation against realised P&L; we have no such backtest at launch and will not introduce one without it.

Sort the rankings by whichever primitive matches your priority: reliability (30d touch rate), speed (median touch days), signal (dividend vs ATR), or yield.

How we estimate the next ex-date

The countdown on each per-ticker page resolves the next ex-date in three priority levels:

  1. Confirmed — the company has declared the dividend (the source row has a declaration_date and the ex-date is in the future). No uncertainty band.
  2. Estimated — we extrapolate from history. Base frequency is the modal value over the last 4 events; if there is no clear mode, the most recent frequency wins. The next ex-date equals last_ex_date + median_gap_days over the last 8 events of the same frequency. Uncertainty is min(7, round(stddev(gaps))) days. For quarterly payers we additionally pin the date to the historical day-of-quarter pattern when available.
  3. Awaiting announcement — if the estimated date falls outside the next 120 days, or fewer than 3 events are available, we suppress the countdown entirely.

Known limitations

  • Survivorship bias: aggregates exclude delisted tickers. Live numbers may therefore look more favourable than a true historical universe. We mitigate by reporting events_count on every metric so you can see the sample size.
  • Regime shifts: market behaviour around ex-dates can change over time (interest-rate cycles, tax-law changes). The 5-year window cushions this; a 5-year majority of the sample still outweighs any single recent event.
  • Universe scope: only currently active US-listed tickers in our curated universe (no penny stocks, no OTC). The volume floor is implicit via the universe definition.
  • No transaction-cost model: success rate measures whether the gap closes — not whether you made money after commissions, slippage, or short-term ordinary-income tax. The calculator and the per-ticker simulator let you layer those costs back in.