Survivorship Bias: Waarom je backtest data van failliete bedrijven nodig heeft
Je denkt misschien dat je backtest-resultaten top zijn, maar wat als je database een gouden selectie is van bedrijven die het overleefden? Je bot draait soepel op historische data van Apple, Amazon en Microsoft, maar vergeet Enron, Lehman Brothers of Wirecard.
Dat is survivorship bias: je ziet alleen de winnaars en negeert de faillissementen, waardoor je strategie er in de simulatie veel beter uitziet dan in de echte markt.
Je bot presteert in de backtest fantastisch, maar zodra je hem live zet op een broker zoals Interactive Brokers of Alpaca via een Python script, stort je portfolio in. Dit gebeurt vaker dan je denkt, en het is een van de grootste valkuilen in algorithmic trading.
Wat is survivorship bias precies?
Survivorship bias is een denkfout waarbij je alleen naar de overlevers kijkt en degenen die het niet hebben gered, negeert. In trading betekent dit dat je backtest-data alleen aandelen bevat die nog steeds bestaan, zonder de bedrijven die failliet zijn gegaan of van de beurs zijn gehaald.
Stel je voor: je test een momentum-strategie op de S&P 500 van de afgelopen 10 jaar.
Je database bevat nu alleen de huidige 500 bedrijven, maar in 2014 waren er al andere bedrijven in die index die later verdwenen. Je bot ziet er winstgevend uit omdat die failliete bedrijven, die vaak grote verliezen hadden, uit de data zijn verwijderd. Het is alsof je een dieetplan test op alleen gezonde mensen en concludeert dat iedereen slank wordt.
Waarom doet dit pijn? Omdat je risicomanagement tekortschiet.
Je Python-bot, gebouwd met libraries als pandas en backtrader, berekent risico's op basis van incomplete data. Je denkt dat je drawdown maximaal 15% is, maar met faillissementen erbij kan dat oplopen tot 30% of meer. Brokers zoals Degiro of Saxo Bank bieden historische data aan, maar vaak zonder de 'dead' bedrijven. Je moet actief zoeken naar datasets die survivorship bias corrigeren, anders bouw je een bot die in de backtest een schot in de roos lijkt, maar in de praktijk faalt.
Waarom deze bias je trading bots saboteert
Je backtest is je proefrit voordat je geld inzet, maar met survivorship bias is het als rijden op een circuit zonder bochten: het voelt geweldig, maar in het echte verkeer crash je. In algorithmic trading gebruik je APIs van brokers zoals Interactive Brokers of Binance om data te halen, maar standaard datasets zijn vaak 'schoongeveegd'.
Neem een eenvoudige Python-script met de yfinance library: je haalt historische prijzen voor aandelen, maar als een bedrijf zoals Thomas Cook in 2019 failliet ging, is die data misschien niet meer beschikbaar of incomplete.
Je bot, getraind op deze data, denkt dat short-posities in luchtvaart aandelen altijd veilig zijn, maar vergeet de enorme verliezen van faillissementen. Het echte gevaar zit in de opties en futures. Als je een bot bouwt die opties verhandelt op aandelen, en je data bevat geen failliete bedrijven, mis je de extreme events die je risicomanagement moeten testen.
Stel je voor: je bot koopt put-opties op tech-aandelen met een API van Alpaca. In de backtest win je consistent, maar in 2008 zouden failliete banken zoals Lehman Brothers je portfolio hebben vernietigd.
Je risico-rendementsverhouding (Sharpe-ratio) ziet er fantastisch uit, maar in werkelijkheid is je maximum drawdown veel hoger. Dit leidt tot overmoed: je zet meer kapitaal in, gebruikt hefboom via je broker, en krijgt een klap als de markt draait. Statistisch gezien is het effect groot. Onderzoeken tonen aan dat strategieën die survivorship bias negeren, tot 2-3% per jaar te optimistisch presteren.
Voor een bot met €50.000 kapitaal betekent dat €1.000-€1.500 aan overschatte winst per jaar.
Je Python-backtesting omgeving, zoals vectorbt of zipline, moet deze bias expliciet aanpakken, anders bouw je op drijfzand.
Hoe survivorship bias werkt in je backtest-data
Stel je voor: je bouwt een mean-reversion bot in Python die aandelen koopt als ze onder hun 50-dagen moving average duiken. Je haalt data via de API van je broker, zoals de Historical Data endpoint van Interactive Brokers, en test het op de aandelen die nu in de S&P 500 zitten.
Je bot toont een jaarlijkse return van 12% met een drawdown van 10%. Mooi, toch? Maar als je een dataset gebruikt die faillissementen includeert, zie je dat bedrijven zoals General Motors in 2009 of Sears in 2018 enorme verliezen leden voordat ze failliet gingen. Je bot zou hebben doorgezet op deze aandelen, wat je totale verlies op 25% brengt.
De kern werkt zo: historische datasets zijn vaak 'point-in-time'. Dat betekent dat je alleen de data ziet die op dat moment beschikbaar was, maar veel tools verwijderen failliete bedrijven retroactief.
In Python kun je dit simuleren met libraries zoals pyfolio of backtrader, maar je hebt een dataset nodig die 'overlevingsgewogen' is. Een voorbeeld: gebruik een dataset van Quandl (nu Nasdaq Data Link) met de 'dead' companies erin. Voor €50-€100 per maand krijg je toegang tot datasets die tot 20% meer bedrijven bevatten dan standaard Yahoo Finance-data.
Je script laadt de data, filtert op datum, en test je strategie. Zonder deze filtering zie je alleen de overlevers, wat je bot vals optimistisch maakt.
Laten we een specifiek geval nemen: een momentum-bot die short gaat op dalende aandelen.
Op basis van data zonder faillissementen lijkt short-selling winstgevend, maar met faillissementen erbij ontdek je dat sommige aandelen naar nul gaan en je short squeeze risico's groter worden. Je risicomanagement, zoals stop-losses op 5%, faalt omdat faillissementen sneller gaan. In Python codeer je dit met een eenvoudige loop: laad de dataset, bereken returns, en voeg een 'survival flag' toe om bedrijven te markeren die failliet gingen. Je zult zien dat je winst met 15-20% daalt, wat je helpt realistischer te zijn.
Varianten en modellen met prijsindicaties
Er zijn verschillende manieren om survivorship bias te modelleren in je backtests, afhankelijk van je broker en data-provider. Omdat resultaten bij een broker vaak afwijken van je eigen code, is een basis-model de 'full universe' aanpak: neem een dataset die alle bedrijven in een index bevat, inclusief de failliete.
Voor de S&P 500 betekent dit een dataset vanaf 1926, zoals die van CRSP (Center for Research in Security Prices), beschikbaar via universiteiten of betaalde diensten voor €200-€500 per jaar. In je Python-script, bijvoorbeeld met pandas, laad je de CSV, filter je op datum, en voeg je een gewicht toe aan bedrijven op basis van hun overlevingskans. Een bot die hierop draait, toont een realistischere return van 8% in plaats van 12%, met een drawdown van 15-20%.
Een andere variant is de 'survival-adjusted' model, waarbij je de data aanpast met probabiliteiten.
Gebruik een library zoals scipy in Python om de overlevingskans van een bedrijf te berekenen op basis van historische faillissementen. Voor opties-trading bots, test je dit met datasets van €10-€20 per maand via OptionMetrics, die faillissementen in optieprijzen meenemen. Stel je voor: je bot verhandelt iron condors op tech-aandelen.
Zonder survivorship bias zie je een winst van €500 per trade, maar met de correctie daalt dit naar €350, omdat faillissementen zoals die van Wirecard (2020) je verliezen opdrijven. Deze modellen helpen je risicomanagement te verfijnen, zoals het instellen van trailing stops op 10% in plaats van 5%.
Voor futures en commodities, waar faillissementen minder voorkomen maar wel bestaan (bijv. grondstofbedrijven), gebruik je datasets van Bloomberg of Refinitiv, costing €1.000+ per jaar, maar je kunt cheaper alternatieven zoals de futures-data van Alpaca API (gratis tot bepaalde limits) combineren met faillissementstabellen.
Een specifiek prijsindicatie: als je een bot bouwt voor EUR/USD forex via MetaTrader API, voeg dan faillissementen van ECB-gerelateerde bedrijven toe voor een accurate backtest. Je zult merken dat je winstmarge met 5-10% daalt, wat je helpt betere posities te kiezen.
Praktische tips om survivorship bias te vermijden
Begin met het verzamelen van de juiste data. Zoek naar datasets die 'point-in-time' zijn en faillissementen includeren, zoals die van QuantConnect (gratis voor basisgebruik) of betaalde van Norgate Data (€30-€50 per maand). In Python, gebruik code zoals:
import pandas as pd
data = pd.read_csv('full_universe_dataset.csv')
data['survived'] = data['delisting_date'].isnull() # Markeer failliete bedrijven
Test je bot op deze data en vergelijk de resultaten met standaard datasets. Je zult snel zien of je strategie houdt.
Integreer dit in je risicomanagement. Gebruik libraries zoals pyfolio om drawdowns te berekenen en bepaal je risk of ruin. Stel je bot in op brokers zoals Interactive Brokers met API-toegang (kosten €0 voor data, maar commissies van €0,005 per aandeel).
Voeg een 'stress test' toe: simuleer faillissementen door random bedrijven uit je dataset te verwijderen en kijk hoe je bot reageert.
Als je drawdown meer dan 20% wordt, pas je position sizing aan, bijvoorbeeld tot 2% van je portfolio per trade. Varieer je data-bronnen voor diversiteit. Combineer Yahoo Finance (gratis) met faillissementstabellen van de SEC (gratis via EDGAR database). Voor opties, gebruik de API van Deribit of Binance Futures (kosten variëren, €0,01 per contract).
Test regelmatig: voer maandelijkse backtests uit met bijgewerkte data. Een tip: vermijd de valkuil van te korte backtest periodes; als je bot een Sharpe-ratio van 1.5 heeft in een backtest zonder faillissementen, eis er een van 1.0 in een volledige test.
Dit houdt je realistisch en beschermt je kapitaal. Tot slot, bouw een community of gebruik tools.
Sluit je aan bij forums zoals QuantNet of Reddit's r/algotrading voor datasets. Gebruik Python-tools zoals Backtrader met plugins voor survivorship bias. Onthoud: een goede bot is er een die overleeft in alle scenario's, niet alleen in de overlevingsdata. Je zult merken dat je vertrouwen toeneemt als je weet dat je strategie getest is op de volledige markt, inclusief de faillissementen die je helpen slimmer te handelen.
