Setyembre 1, 2026 · corporate actions

Hinimay ang split-adjusted data: epekto ng 10-for-1 ng NVDA sa bawat row sa likod nito

Hinimay ang split-adjusted data: epekto ng 10-for-1 ng NVDA sa bawat row sa likod nito

Narito ang isang row mula sa daily equities file. NVDA, Biyernes 7 June 2024, ang huling session bago magkabisa ang 10-for-1 split.

ColumnValue
date2024-06-07
close1208.88
volume42,800,000 (rounded)
split_factor1.0
dividend0.00
adj_close120.8781

Sadyang hindi ko isinama sa view na ito ang mga OHLC column. Babalikan natin ang mga iyon malapit sa dulo, at tahimik nilang sinisira ang mga kalkulasyon.

Nasa pagitan ng ikalawa at ikaanim na column ang lahat ng kawili-wili sa row na ito. 1208.88 ang naitala sa tape noong 7 June. Wala nang makikipagtransaksyon sa presyong iyon, dahil wala na ang share unit na tinutukoy nito. Muling binuo ang halagang 120.8781; hindi lang ito basta 1208.88 na hinati sa 10. Himayin natin ang bawat column.

10:1divisor na inilapat sa bawat naunang row
0.99991789dividend factor na inilagay makalipas ang 1 araw
$45huwad na commission sa bawat round trip
2.8pptaunang drag na likha ng divisor

date: 2024-06-07, at ang 2 iba pang petsang mas mahalaga

Inanunsyo ang split noong 22 May 2024 kasabay ng earnings. 6 June ang record date. Nagsimula ang trading sa split-adjusted na batayan noong Lunes, 10 June. Tatlong petsa ito, pero eksaktong isa lang sa mga ito ang itinuturo ng split_factor column ng data vendor mo, karaniwan ay ang unang split-adjusted session. Ang pagkakamali sa petsa rito ang pinakakaraniwang corporate-action bug na nakikita ko, at hindi ito halata sa pinagsama-samang resulta: magkakaroon ang equity curve mo ng isang 90% gap-down o isang 900% gap-up sa iisang araw. Halos hindi ito makikita sa Sharpe na kinuwenta sa loob ng 2,000 araw, pero tiyak na makaaapekto ito sa max-drawdown o stop-loss rule.

May sarili ring problema sa petsa ang dividend, at nagbago ito para sa lahat noong 2024. 11 June ang record date ng $0.01 quarterly dividend ng NVDA pagkatapos ng split. Lumipat sa T+1 ang settlement sa US noong 28 May 2024, kaya pareho na ngayon ang ex-date at record date. Simula June 2024, tahimik nang naglalagay ng dividend adjustments nang 1 session mas maaga ang anumang loader na kumukuwenta ng ex-date bilang "record date minus one business day"—na tama sa loob ng ilang dekada. Walang error na lumalabas. Nailalagay lang ang factor sa maling row.

Hindi kailanman exception ang paraan ng pagkasira ng corporate-action code. Numero itong mali nang 1 araw, pero mukhang lubos na kapani-paniwala.

close: 1208.88 — ang presyong wala sa file

Ito ang raw print, at sa karamihan ng research pipeline, column lang ito na walang bumabasa. Sa adj_close kinukuwenta ang mga signal. At anumang rule na tumutukoy sa per-share price level sa dolyar ay gumagamit na ngayon ng numerong hindi kailanman nakita ng sinumang kalahok sa merkado.

Totoong umakyat ang NVDA papalapit sa $1,000 noong tagsibol ng 2024, at may totoong order flow sa likod nito: nahihila ang presyo sa mga bilog na numero, nagsisiksikan ang mga options strike sa 950 at 1000, at may panganib sa headline sa tuwing lumalapit ito. Sa adjusted data, sa $100 nagaganap ang buong yugtong iyon. Kung sinusubok mo ang galaw sa mga sikolohikal na antas, gap-fill logic malapit sa mga bilog na numero, o strike-proximity feature, sinusubok mo ito gamit ang price series na binago ang sukat dahil sa isang pangyayaring hindi pa nagaganap noon.

Ganoon din sa mga universe filter. Lehitimong proxy ang "Exclude stocks under $5" para sa mga totoong problema sa microstructure na madalas magkakasama: malalawak na relative spread, mga tuntunin sa marginability, at mga tick regime. Patakbuhin ito sa adjusted history at maaalis mo ang mga kumpanya sa mga panahong $30 ang presyo ng mga ito at saka lang nagkaroon ng reverse split. Patakbuhin ang "price over $500" at tahimik na maaalis ang NVDA sa bawat taon bago ang June 2024. Dapat sa unadjusted prints gamitin ang mga price filter. Wala nang iba.

split_factor: 1.0 — at ang 0.1 sa kasunod na row

Pabalik mula sa araw na ito ang takbo ng cumulative product ng factor. May 0.1 mula sa split na ito ang bawat row bago ang 10 June 2024, na minumultiply sa 0.25 mula sa 4-for-1 noong 2021, at minumultiply pa sa anumang nauna rito. Minultiply sa 0.025 ang pre-2021 history ng NVDA, kaya nagiging $5.00 ang bar na nagtala noon ng $200 noong 2019.

Tandaan ang 2 kahihinatnan. Una, nagbabago ang adjusted history sa tuwing may bagong corporate action. Magkaiba ang mga numerong makukuha sa backtest na pinatakbo mo noong May 2024 at sa pinapatakbo mo ngayon, kahit pareho ang code at mga petsa. Kung nag-cache ka ng mga feature gamit ang symbol at date bilang key nang walang data-version stamp, magkahalong 2 scale na ngayon ang laman ng cache mo. Isinasama namin ang adjustment epoch sa feature key dahil dito; natuto kami nito matapos ang isang hapon ng kalituhan.

Ikalawa, sa 0.025 scaling, nagiging 0.00025 ang galaw ng stock na nagte-trade noon sa 0.01 ticks. Ang tick-rounding logic mo, ang paghahambing mo kung "bagong high ba ito," at ang mga float equality check mo: lahat ng ito ay gumagana na ngayon sa mas pinong antas kaysa sa aktuwal na resolution ng merkado.

dividend: 0.01 — ang halagang sumisira sa penny grid ng bawat presyong nauna rito

Isang sentimo lang. Mukha itong ingay, pero ito ang dahilan kung bakit adj_close ay 120.8781 sa halip na eksaktong 120.888.

121.79 ang close noong 10 June. Ganito ang ex-dividend factor: (121.79 − 0.01) / 121.79 = 0.99991789. Minumultiply ang bawat presyong nauna sa 11 June sa factor na iyon, kaya nagiging 120.878074 ang split-adjusted na 120.888. Maliit ito, permanente, at muling inilalapat sa bawat isa sa mahigit 60 ex-date sa kasaysayan ng NVDA. Ang mahalaga ay ang pinagsama-samang epekto: pagsapit ng 2015, presyo na itong minultiply sa dose-dosenang factor na halos walang makatwirang batayan. Walang adjusted historical price na tumatama sa penny grid.

Ibig sabihin, mali ang bawat == paghahambing sa bilog na antas, kailangan ng tolerance ang bawat "umabot ba tayo sa limit price" check, at hindi na natutupad ng reconstructed OHLC ang invariant na low ≤ open ≤ high matapos itong basta i-round sa 4 na decimal place. Ibig sabihin din nito na total-return series ang adj_close, habang price-return series naman ang close; kung sa una ka kumukuwenta ng returns at sa ikalawa naman ng drawdowns, pinaghahalo mo ang 2 magkaibang depinisyon ng nangyari.

volume: 42,800,000 — ang divisor na hindi palaging inilalapat nang pare-pareho

Dapat imultiply sa 10 ang share volume para maikumpara ito sa mga session pagkatapos ng split. May mga vendor na gumagawa nito. May hindi. Ina-adjust naman ng iba ang OHLC pero iniiwang raw ang volume. Ito ang pinakamasama sa 3 dahil mukhang magkakatugma ang mga column sa file hanggang sa imultiply mo ang presyo sa volume.

Mas mainam na huwag nang gamitin ang share volume bilang feature at dollar volume na lang ang gamitin, dahil hindi ito naaapektuhan ng split. Hindi nangangailangan ng anumang adjustment logic ang 20-day average dollar volume liquidity filter, at hindi ito masisira ng corporate action. Mas mainam ang feature invariance kaysa sa tamang adjustment code, dahil kailangan mong patuloy na tiyaking tama ang adjustment code.

3 uri ng vendor file, 3 paraan ng pagkasira.

Laman ng fileProblema
Adjusted close lang, raw OHLCKuwenta ang gap at intrabar logic gamit ang 2 magkaibang price scale
Adjusted OHLC, raw volumeMali nang split ratio ang dollar volume; mali ang resulta ng mga ADV filter
Raw OHLCV at mga factor columnWalang problema kung ilalapat mo ang mga ito. Lahat magiging problema kung sa maling row mo ilalapat

Ang mga column na wala rito: adj_open, adj_high, adj_low

Ibalik natin ngayon ang OHLC. Kung close lang ang ina-adjust ng feed mo at kinukuwenta ng strategy mo ang overnight gap bilang open / prev_adj_close − 1, kukuwentahin nito sa 10 June 2024 ang 120.37 / 120.8781 − 1, na maayos na numero, humigit-kumulang −0.4%. Patakbuhin ang parehong code pabalik sa 7 June 2024 at kukunin nito ang open mula sa raw file (mga 1207) at itatapat iyon sa close na in-adjust ng 0.025 mula sa mga naunang split; maglalabas ito ng gap na ilang libong porsiyento.

Ang anumang pagkukuwenta na naghahalo ng raw column at adjusted column ay gumagamit ng arithmetic sa 2 magkaibang coordinate system. Itinuturing ko na ngayon na kailangang patunayan ng loader na walang magkahalong adjustment ang mga nababasang column; hindi dapat umasa sa researcher na maalala ito, dahil hindi nila maaalala—pati ako.

Ang hindi sinasabi ng anumang column: ilang share ba talaga ang nabili mo

Ito ang nagkakahalaga ng pera sa cost model ng backtest, at ito ang dahilan kung bakit nagsusulat ako tungkol sa stock split.

Madalas na per share ang commission sa US equities. Ipagpalagay na $0.005 ito, na may minimum na $1.00 bawat order; karaniwang fixed tier ito ng retail broker. Ngayon, mag-backtest ng $400,000 na posisyon sa NVDA 1 taon bago ang split, nang malapit sa $400 ang raw price pero $40 ang ipinapakita ng adjusted price.

SharesCommission
Ang aktuwal na nangyari (raw $400)1,000$5.00
Ang nakikita ng backtest (adjusted $40)10,000$50.00

Parehong exposure, parehong trade, pero 10x ang modelong gastos. Kathang-isip na $45 ito sa bawat leg, $90 sa bawat round trip, at aabot sa humigit-kumulang $22,000 kada taon ang mga gastusing hindi naman nangyari sa strategy na araw-araw ang turnover. Sa $400k na portfolio, 5.6 percentage point ng taunang return ang gawa-gawa lang ng divisor. Dito, pinagmumukha ka nitong mas mahina kaysa sa aktuwal, at kaya pa itong tiisin.

Kabaligtaran ang epekto ng reverse split, at dito nagiging mapanganib. Sa 1-for-10 reverse split, ipinapakita ng adjusted history ang mga presyong 10x na mas mataas at share count na 10x na mas mababa kaysa sa aktuwal na naitrade mo. Tahimik na hinahati sa 10 ng cost model mo ang per-share commission. Karaniwan ang reverse split sa mga kumpanyang maliit ang market cap, mas mababa sa $5 ang presyo, at malawak ang spread; dito pinakamalaking bahagi ng kabuuang gastos ang per-share fee. Pinapaganda ng backtest ang resulta para mismo sa mga pangalang dapat nitong parusahan.

Simple at pangmatagalan ang solusyon: magtakda ng laki ng posisyon sa dolyar, at kunin ang bilang ng shares gamit ang unadjusted na presyo sa petsang iyon; doon ibatay ang per-share fee. Panatilihin ang raw price column sa loader, hindi lang bilang audit artifact kundi bilang aktuwal na input sa fill engine.

  1. Mga signal at return: adjusted series.
  2. Share count, per-share fee, tick rounding, price-level filter: unadjusted series.
  3. Liquidity at kapasidad: dollar volume, na hindi nangangailangan ng alinman sa dalawa.

6 na column, 1 row, at 1 karaniwang corporate action na inanunsyo 3 linggo bago mangyari at hindi ikinagulat ninuman. Natapos ito ng merkado sa loob ng 1 umaga. Mas mahirap nang malaki rito ang tapat na muling pagbuo nito sa isang research pipeline; at ang palatandaan na hindi ito nagawa ng pipeline ay halos hindi kailanman error message.

corporate actionssplit adjustmentus equitiesdata engineeringbacktesting
← Lahat ng post