Strasmore Research
Deep Dives · Matt ConnorBy Matt Connor ·

Wanneer presteert gelijke weging beter dan optimalisatie?

Gelijke weging presteert beter dan geoptimaliseerde positiegrootte bij korte steekproeven. Een Python simulatie toont hoe dit voordeel verdwijnt naarmate de steekproef groeit.

Gelijke weging versus geoptimaliseerde allocatie

Equal weight presteert beter dan geoptimaliseerde positiegrootte wanneer de steekproef te kort is om verwachte rendementen nauwkeurig vast te stellen, en korte steekproeven zijn eerder de norm dan de uitzondering. Een optimizer is correcte rekenkunde toegepast op input die niemand goed kan meten. De 1/N-portefeuille, oftewel gelijke weging, schat helemaal niets in, en dat is de reden waarom deze standhoudt wanneer de schattingen onbetrouwbaar zijn.

Presteert gelijke weging werkelijk beter dan optimalisatie?

Onder één specifieke voorwaarde wel. Laten we de termen één voor één bekijken. Gelijke weging, geschreven als 1/N, verdeelt het kapitaal gelijkmatig over N posities en vereist geen enkele prognose. Mean-variance-optimalisatie berekent de wegingen met het beste verwachte rendement per eenheid geschatte variantie. Het Kelly-criterium berekent de wegingen die de samengestelde groei op lange termijn maximaliseren; bij ongecorreleerde activa resulteert dit in een weging die evenredig is aan het verwachte excess return van elk actief gedeeld door de variantie ervan. Onze gids voor positiebepaling volgens het Kelly-criterium behandelt die formule in detail.

Beide optimalisatiemodellen hebben dezelfde input nodig: een verwacht rendement per actief. Dat is de grootheid die een steekproef het slechtst schat. Volatiliteit kan uit een kort tijdsbestek met werkbare precisie worden afgeleid. Het gemiddelde niet, en het verschil tussen beide is groot genoeg om in elke prijshistorie zichtbaar te zijn. Het onderstaande overzicht neemt zes veelgehouden namen, meet elk kalenderjaar van tweeduizendvijftien tot en met tweeduizendvierentwintig afzonderlijk, en rapporteert hoe ver de hoogste en laagste jaarlijkse schatting uiteenlopen. Dit gebeurt tweemaal per naam: één keer voor het geannualiseerde gemiddelde dagrendement en één keer voor de geannualiseerde volatiliteit.

QueryTien jaar aan jaarlijkse estimates: het gemiddelde fluctueert sterker dan de volatility
De exacte SQL achter elk getal
WITH prices AS
(
    SELECT
        ticker,
        date,
        toFloat64(max(close)) AS c
    FROM global_markets.stocks_daily_aggs
    WHERE ticker IN ('AAPL', 'MSFT', 'NVDA', 'SPY', 'KO', 'JNJ')
      AND date >= '2015-01-01'
      AND date <  '2025-01-01'
    GROUP BY ticker, date
),
rets AS
(
    SELECT
        ticker,
        date,
        c / lagInFrame(c, 1) OVER (PARTITION BY ticker ORDER BY date ASC ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) - 1 AS ret
    FROM prices
),
yearly AS
(
    SELECT
        ticker,
        toYear(date)                     AS yr,
        avg(ret) * 252 * 100             AS mean_pct,
        stddevPop(ret) * sqrt(252) * 100 AS vol_pct
    FROM rets
    WHERE isFinite(ret)
    GROUP BY ticker, yr
    HAVING count() >= 200
)
SELECT
    ticker,
    round(max(mean_pct) - min(mean_pct), 1) AS mean_estimate_range_pct,
    round(max(vol_pct) - min(vol_pct), 1)   AS vol_estimate_range_pct
FROM yearly
GROUP BY ticker
ORDER BY mean_estimate_range_pct DESC
Run this yourself

Voor NVDA beslaat de jaarlijkse gemiddelde schatting 184.7 procentpunt over die tien jaar, tegenover 28.6 punten spreiding in de volatiliteitsschatting voor dezelfde naam over dezelfde jaren. De meest stabiele naam in het overzicht, KO, zag zijn jaarlijkse gemiddelde schatting nog steeds met 23.9 punten bewegen. Elk model dat het gemiddelde rendement van vorig jaar aan een optimizer voert als het verwachte rendement voor dit jaar, voert het een getal met een dergelijke foutmarge.

Hoe lang moet een steekproef zijn om een verwacht rendement te schatten?

De standaardfout van een geschat gemiddeld rendement is de volatiliteit van het activum gedeeld door de wortel uit de lengte van de steekproef in jaren. In jaren, niet in observaties: dezelfde twaalf maanden per uur in plaats van per dag bemonsteren levert niets op. Pas die formule toe op een activum met een volatiliteit van twintig procent en één jaar aan historie geeft een standaardfout van twintig procentpunt per jaar. Vier jaar halveert dit tot tien. Om dit terug te brengen tot één punt, de precisie die u zou wensen voordat u twee activa rangschikt waarvan de werkelijke gemiddelden twee punten verschillen, is vier eeuwen aan data nodig.

Volatieliteit is een ander verhaal. De precisie daarvan verbetert met het aantal observaties in plaats van met de kalenderduur, waardoor een paar maanden aan dagelijkse data de schatting al binnen enkele punten plaatst. Het onderstaande overzicht verdeelt twintig jaar aan dagelijkse rendementen van één indexfonds in niet-overlappende blokken van een vaste lengte, berekent beide schattingen binnen elk blok en rapporteert hoe ver de schattingen per blok uiteenlopen.

QuerySpreiding van gemiddelde en volatility estimates per sample length
De exacte SQL achter elk getal
WITH prices AS
(
    SELECT
        date,
        toFloat64(max(close)) AS c
    FROM global_markets.stocks_daily_aggs
    WHERE ticker = 'SPY'
      AND date >= '2005-01-01'
      AND date <  '2025-01-01'
    GROUP BY date
),
rets AS
(
    SELECT
        date,
        c / lagInFrame(c, 1) OVER (ORDER BY date ASC ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) - 1 AS ret
    FROM prices
),
numbered AS
(
    SELECT
        ret,
        row_number() OVER (ORDER BY date ASC) AS i
    FROM rets
    WHERE isFinite(ret)
),
sweep AS
(
    SELECT
        arrayJoin([21, 63, 126, 252, 504]) AS n,
        i,
        ret
    FROM numbered
),
blocks AS
(
    SELECT
        n,
        intDiv(i - 1, n)                 AS blk,
        avg(ret) * 252 * 100             AS mean_pct,
        stddevPop(ret) * sqrt(252) * 100 AS vol_pct
    FROM sweep
    GROUP BY n, blk
    HAVING count() = n
)
SELECT
    concat(toString(n), ' sessions') AS sample_length,
    round(stddevPop(mean_pct), 1)    AS mean_estimate_spread_pct,
    round(stddevPop(vol_pct), 1)     AS vol_estimate_spread_pct,
    count()                          AS window_count
FROM blocks
GROUP BY n
ORDER BY n ASC
Run this yourself

Bij blokken van 21 sessions loopt de gemiddelde schatting uiteen over 53.7 procentpunt, tegenover 10.9 punten voor de volatiliteitsschatting gemeten over dezelfde blokken. Rek het blok uit tot 504 sessions en de spreiding van het gemiddelde vernauwt tot 10.6 punten. Dit vernauwt volgens een wortelfunctie: elke halvering van de fout kost vier keer zoveel data.

Een gesimuleerde test die u zelf kunt uitvoeren

Niets hiervan bewijst dat de schattingsfout groot genoeg is om de overwinning aan 1/N te schenken. Dit bewijst het wel. Het recept vereist enkel een Python-installatie: geen databestanden, geen downloads, geen externe pakketten. Het genereert zijn eigen rendementen op basis van door u gekozen parameters, waardoor het werkelijke antwoord bekend is en beide allocaties hiertegen kunnen worden getoetst.

  1. Importeer twee modules, import random en import statistics, plus from math import log. Stel de seed in op de volgende regel met random.seed(20260816).
  2. Definieer vijf activa met werkelijke verwachte jaarrendementen van vijf, zes, zeven, acht en negen procent, elk met een werkelijke jaarlijkse volatiliteit van twintig procent, zonder onderlinge correlatie. Reken om naar een dagelijkse stap met mu_d = mu_a / 252 en sd_d = sd_a / (252 ** 0.5).
  3. Kies een steekproeflengte T uit de reeks [60, 125, 250, 500, 1000, 2500, 5000].
  4. Trek T dagelijkse rendementen voor elk actief met random.gauss(mu_d, sd_d). Die trekking vormt de volledige historie die de beheerder te zien krijgt.
  5. Schat het gemiddelde van elk actief met statistics.mean en de volatiliteit ervan met statistics.stdev. Deze twee schattingen zijn alles wat de optimizer weet.
  6. Bouw de equal weight portefeuille door 0,2 toe te wijzen aan elk van de vijf. Deze maakt geen gebruik van de schattingen.
  7. Bouw de geoptimaliseerde portefeuille door elk ruw gewicht in te stellen op mu_hat / (sd_hat ** 2), en deel vervolgens elk gewicht door de som van de absolute ruwe gewichten, waardoor beide portefeuilles op dezelfde bruto exposure uitkomen.
  8. Trek een nieuw out-of-sample pad van 2520 dagelijkse rendementen per actief op basis van de werkelijke parameters. Geen van beide allocaties heeft dit pad eerder gezien.
  9. Beoordeel beide op dat pad met het gemiddelde van log(1 + r), waarbij r de gewogen som is van de vijf activarendementen op die dag.
  10. Herhaal stap 4 tot en met 9 voor tweeduizend onafhankelijke trials bij elke T, en noteer het aandeel trials waarin equal weight beter presteert dan de geoptimaliseerde gewichten.

Lees de reeks van korte T naar lange T. Aan de korte kant wint equal weight de duidelijke meerderheid van de trials. Het aandeel daalt gestaag naarmate T groeit, en aan de lange kant winnen de geoptimaliseerde gewichten het merendeel. Ergens in het midden kruisen de twee elkaar. Het kruispunt verschuift met de seed en met de spread tussen de werkelijke gemiddelden. De richting verandert niet: meer data bevoordeelt de optimizer, minder data bevoordeelt 1/N. Om dit te repliceren, wijzigt u het gehele getal in random.seed(20260816) en voert u de reeks opnieuw uit.

Waarom de optimizer een onjuiste gemiddelde-schatting versterkt

Kijk naar de wijze waarop de schattingen de weging beïnvloeden. Het geschatte gemiddelde staat in de teller, de geschatte variantie in de noemer. Verdubbel de schatting van het gemiddelde en de weging verdubbelt. Haal een kwart van de variantieschatting af en de weging stijgt met een derde. In een gelukkige steekproef wijzen beide fouten dezelfde kant op: een reeks goede resultaten verhoogt het gemeten gemiddelde en dempt vaak de gemeten variantie over dezelfde periode. De optimizer ziet dat activum als de uitblinker van de groep en bepaalt de omvang dienovereenkomstig. Buiten de steekproef is het weer een gewoon lid van de groep. Equal weight heeft die gelukkige steekproef nooit gezien.

De simulatie is de milde versie van dit probleem. Vijf ongecorreleerde activa resulteren in een diagonale covariantie-matrix waar niets in te inverteren valt. Echte portefeuilles zijn gecorreleerd en een steekproef-covariantie-matrix die is opgebouwd uit nauwelijks meer observaties dan activa, bevindt zich dicht bij een singuliere matrix. Het inverteren ervan vermenigvuldigt kleine invoerfouten tot zeer grote wegingen; dit is hoe een optimizer tot een positie komt die vele malen het kapitaal in één naam waard is, afgezet tegen een compenserende short in een nauw verwant substituut. Onze notitie over concentratierisico in een portefeuille behandelt wat dat soort weging doet met een drawdown.

De invoer staat bovendien niet stil. Het onderstaande paneel volgt een voortschrijdend gemiddeld dagelijks rendement over één jaar, geannualiseerd en maandelijks bemonsterd, voor een breed indexfonds naast een grote naam in consumentengoederen.

QueryVoortschrijdend gemiddeld jaarrendement, de input voor een optimizer
De exacte SQL achter elk getal
WITH prices AS
(
    SELECT
        ticker,
        date,
        toFloat64(max(close)) AS c
    FROM global_markets.stocks_daily_aggs
    WHERE ticker IN ('SPY', 'KO')
      AND date >= '2015-10-01'
      AND date <  '2025-01-01'
    GROUP BY ticker, date
),
rets AS
(
    SELECT
        ticker,
        date,
        c / lagInFrame(c, 1) OVER (PARTITION BY ticker ORDER BY date ASC ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) - 1 AS ret
    FROM prices
),
trailing AS
(
    SELECT
        ticker,
        date,
        avg(ret) OVER (PARTITION BY ticker ORDER BY date ASC ROWS BETWEEN 251 PRECEDING AND CURRENT ROW) * 252 * 100 AS trailing_mean_pct,
        row_number() OVER (PARTITION BY ticker ORDER BY date ASC) AS i
    FROM rets
    WHERE isFinite(ret)
)
SELECT
    toString(toStartOfMonth(date))                     AS month,
    round(avgIf(trailing_mean_pct, ticker = 'SPY'), 1) AS spy_trailing_mean_pct,
    round(avgIf(trailing_mean_pct, ticker = 'KO'), 1)  AS ko_trailing_mean_pct
FROM trailing
WHERE i >= 252
  AND date >= '2017-01-01'
GROUP BY month
ORDER BY month ASC
Run this yourself

Elk punt op die twee lijnen is een getal dat een optimizer op die datum als verwacht rendement zou hebben geaccepteerd. De eerste maandelijkse meting voor SPY is 17.7% en de laatste is 25.8%, met 96 metingen daartussen. KO opent hetzelfde venster op -0.4%. Een wegingsschema dat deze reeks maand na maand verwerkt, neemt elke schommeling daarin over.

Bieden half-Kelly en shrinkage een oplossing?

Zij verzachten het probleem. In de praktijk komen vier correcties naar voren, waarbij elke methode een deel van het theoretische optimum inruilt voor een lagere gevoeligheid voor de schatting.

  • Half-Kelly halveert elke weging. De Kelly-groeicurve is vlak nabij het hoogtepunt en steil daaronder; een halve inzet levert dus slechts een klein deel van de theoretische groei in, terwijl de schade van een overschatte edge aanzienlijk sterker wordt beperkt. Volatility targeting hanteert hetzelfde principe voor de noemer, waarbij de omvang wordt bepaald op basis van de enige input die een korte steekproef betrouwbaar kan leveren.
  • Shrinkage trekt elk geschat gemiddelde naar het cross-sectionele gemiddelde van de schattingen, met een factor die toeneemt naarmate de steekproef kleiner wordt. Wordt dit tot het uiterste doorgevoerd, dan krijgt elk actief hetzelfde verwachte rendement; bij gelijke volatiliteiten geeft de optimizer dan vanzelf een gelijke weging. Een gelijke weging is de volledig 'geshrinkte' portefeuille.
  • Beperkingen, zoals een verbod op short gaan en een maximum per positie, begrenzen in hoeverre één gelukkige schatting een individuele weging kan opdrijven. Dit is eerder schadebeperking dan een verbetering van de schatting.
  • Het volledig weglaten van verwachte rendementen leidt tot minimum variance en risk parity, die uitsluitend gebruikmaken van de covariantie. Dat is de input die de steekproef daadwerkelijk kan leveren.

Geen van deze vier methoden creëert informatie die niet in de steekproef aanwezig is. Wat zij veranderen, is de mate waarin de portefeuille afhankelijk is van informatie die u mogelijk niet bezit.

Wanneer optimalisatie zijn waarde bewijst

De crossover werkt in beide richtingen. Zodra T groot wordt ten opzichte van de spread tussen de werkelijke gemiddelden, neemt de geoptimaliseerde allocatie de leiding en behoudt deze; hoe groter die spread, des te eerder dit gebeurt. Optimalisatie is ook het juiste instrument wanneer de input afkomstig is uit de data zelf: covariantie en hedge ratios laten zich veel beter schatten dan verwachte rendementen.

Equal weight brengt zijn eigen kosten met zich mee. Het negeert informatie waarover u daadwerkelijk beschikt en in een klein universum concentreert het net zo sterk als elke optimizer zou doen. Beschouw het als de baseline die elke kandidaat-weging moet verslaan op data die de gewichten niet eerder hebben gezien. Het fitten van gewichten en deze vervolgens scoren op dezelfde steekproef is look-ahead bias in backtesting in een ander jasje, en het flatteert de optimizer telkens weer. Voor een betrouwbare bandbreedte rondom een gemeten edge in plaats van een enkele puntschatting, zijn bootstrapped confidence intervals het standaardinstrument.

Veelgestelde vragen

Presteert equal weight werkelijk beter dan mean-variance optimization?

In korte steekproeven is dat vaak het geval. Een optimizer heeft een schatting nodig van het verwachte rendement van elk actief, en die schatting bevat een standaardfout van ruwweg de volatiliteit van het actief gedeeld door de wortel van de lengte van de steekproef in jaren. Zolang die fout groter blijft dan de werkelijke verschillen tussen de activa, sorteert de optimizer ruis. Equal weight heeft geen schatting die fout kan zijn.

Hoeveel observaties zijn er nodig om een verwacht rendement te schatten?

Meer dan bijna iedereen heeft. Voor een actief met twintig procent volatiliteit laat één jaar aan dagelijkse data een standaardfout zien van bijna twintig procentpunt per jaar, en het halveren van die fout kost vier keer de kalenderduur. Het toevoegen van intraday-observaties binnen hetzelfde jaar helpt niet. Volatiliteit daarentegen is bruikbaar op basis van enkele maanden aan data.

Is half Kelly simpelweg een kleinere inzet?

Het is een kleinere inzet onder gunstige voorwaarden. De Kelly-groeicurve is vlak nabij het hoogtepunt, dus het halveren van de inzet levert een klein deel van de theoretische groei op, terwijl de volatiliteit van het traject ruwweg wordt gehalveerd en de kosten van een overschatte edge worden verkleind.

Wat is de 1/N-portefeuille?

Dit is de portefeuille die een gelijk deel van het kapitaal in elk van de N posities belegt en volgens een vast schema herbalanceert. Deze methode vereist geen rendementsverwachting en geen covariantieschatting, wat het de standaardbenchmark maakt voor elk wegingsschema dat deze wel vereist.

Hoe de panelen zijn opgebouwd

Alle drie de panelen lezen dagelijkse slotkoersen en berekenen eenvoudige rendementen van slot tot slot, waarbij dubbele rijen worden samengevoegd tot één slotkoers per ticker per datum. Gemiddelden worden geannualiseerd door het gemiddelde dagelijkse rendement te vermenigvuldigen met 252 sessies; volatiliteiten worden geannualiseerd door de dagelijkse standaarddeviatie te vermenigvuldigen met de wortel van 252. Het jaarlijkse paneel behoudt alleen een kalenderjaar als er ten minste 200 sessies aanwezig zijn. Het blokpaneel gebruikt niet-overlappende blokken en verwerpt het laatste gedeeltelijke blok bij elke lengte; de kolom met het aantal vensters toont hoeveel blokken elke lengte heeft opgeleverd. Er zijn nergens dividenden opgenomen, dus dit zijn koersrendementen en het niveau van elk gemiddelde is voor dividendbetalers lager dan in werkelijkheid. De spreiding van de schattingen is het doel van de panelen, niet het niveau.


Elk paneel hier bevat de exacte SQL onder de grafiek, en de simulatie bevat de bijbehorende seed. Om dezelfde stabiliteitscontrole voor schattingen uit te voeren voor uw eigen lijst met namen, kunt u hierom vragen in begrijpelijk Engels op de Strasmore-terminal.

#quant#position sizing#portfolio construction#estimation error#kelly