Meillä oli ongelma. Automatisoidulla kaupankäyntijärjestelmällämme oli positiivinen odotettu arvo: matematiikka tarkistettiin, taustakokeet näyttivät hyviltä, ja aluksi se teki rahaa. Tämä ei ollut koodin vika.Se oli perustavanlaatuinen väärinkäsitys siitä, mikä on tärkeää tuotannossa. Odotetun arvon ansa Useimmat kaupankäynnin opetusohjelmat, akateemiset paperit ja online-kurssit opettavat maksimoimaan odotetun arvon. E[profit] = Σ(probability_i × outcome_i) Jos tämä numero on positiivinen, sinun pitäisi ottaa kauppa. Jos voit tehdä tämän numeron suuremmaksi, sinun pitäisi optimoida sitä varten. Lukuun ottamatta tuotantoa, tällä optimointistrategialla on kohtalokas puute: . it doesn't account for the path you take to reach that expected value Näytän teille, mitä tarkoitan todellisella skenaariolla järjestelmästämme. Verenvuotojärjestelmä Strategiamme tarkoituksena oli kaapata hinnankorotuksia epävakailla markkinoilla. Analysoi mahdolliset hintojen suuntaukset jokaiselle kaupankäynnin ikkunalle Optimoi sijaintikokoa käyttämällä neliöohjelmointia Suorita kauppoja kaappaamaan leviämismahdollisuuksia Paperilla odotettu arvo oli vakaasti myönteinen. Päivä 1-3: Pistettiin suuri kärki, teki 15 000 dollaria Päivä 4-12: Pienet tappiot joka päivä, yhteensä -8,000 dollaria Päivä 13-14: Toinen kärki, tehnyt 12 000 dollaria Päivä 15-28: asteittainen verenvuoto, yhteensä -11 000 dollaria Ongelma? Optimisaattorimme oli kehittänyt rakenteellisen ennakkoluuloisuuden. Se oli järjestelmällisesti ottamassa positioita, jotka voittavat suuria ajoittain, mutta menettävät pieniä määriä usein. Odotettu arvo laskelma sanoi, että tämä oli kunnossa: suuret voitot lopulta kompensoivat. Meillä ei ollut kumpaakaan. Nähdä ero: Simulaatio Jotta voimme havainnollistaa, miksi nämä riskienhallinnat ovat tärkeitä, verrataan kahta strategiaa, joilla käydään kauppaa samalla markkinoilla vuoden aikana: Aggressiivinen aseman mitoitus, joka perustuu pelkästään odotettuun arvoon ja käyttää 150 prosentin vipuvaikutusta, kun mahdollisuudet näyttävät hyviltä. Strategy A (EV Maximization) Samat markkinasignaalit, mutta osittainen Kelly-koko (40% aggressiivinen) ja CVaR-pohjainen aseman väheneminen korkean hännän riskikausien aikana. Strategy B (Risk-Controlled) Tulokset kertovat ratkaisevan tarinan. Katso tarkasti vasemmalle kaavalle - useimmat EV-maksimointireitit eivät ole katastrofaalisesti epäonnistuneet. Ne ovat vain... eivät kompensoivia. Näet savenhampaiden kuvion: satunnaiset huiput ylöspäin, jota seuraa hidas eroosio. Tämä on salakavala verenvuoto, jonka positiivinen odotettu arvo puuttuu. Huomaa, miten muutamat polut saavuttivat 500 000 dollaria? Nämä ulkonäöt vetävät keskiarvon jopa 146 000 dollariin. Se on vain 136 000 dollaria, ja 29 100 reitistä päättyy alkupääoman alapuolelle. mediaani In a backtest, you might have gotten lucky and seen one of those winner paths. In production, you get one random draw. Oikea kaavio on "tyylikäs", ja se on täsmälleen se juttu. Ei kuunkuvia 500 000 dollariin, mutta ei myöskään katastrofaalisia laskuja. Riskienhallittu strategia rypistyy tiukasti vaatimattoman kasvun ympärille. Se selviytyy yhdisteen tuottoihin useiden vuosien ajan. Tämä on tuotannon todellisuus: strategia, joka selviytyy, muuttuu monimutkaiseksi. strategia, joka vuotaa verta, ei tee mitään, riippumatta siitä, mitä odotettu arvo laskenta lupasi. Mitä odotettu arvo ei kerää 1. Ruumiin tuhoutumisen vaara Tämä on klassisen pelaajan ongelma, joka on muodollistettu Kelly-kriteerillä. Vaikka odotettu arvo olisi positiivinen, jos sijaintisi koko on väärä, Käy murtamassa tahtoo Harkitse: Sinulla on 100 000 dollaria pääomaa ja kauppa, jossa on 60 prosentin todennäköisyys voittaa, joka joko kaksinkertaistaa panoksesi tai menettää sen. Kelly kertoo sinulle optimaalisen panostuksen koon: kelly_fraction = (p * b - q) / b # where p = win probability, q = loss probability, b = odds Mutta tässä on se, mitä opimme tuotannossa: . even Kelly is too aggressive Miksi? koska Todennäköisyysarviosi ovat väärässä (aina) Markkinat muuttuvat (60 % edestäsi tulee 52 %) Korrelaatiot hajoavat stressin aikana (kun tarvitset niitä eniten) Et voi tasapainottaa välittömästi (slippage, latenssi, markkinoiden vaikutus) Päädyimme käyttämään osittaista Kellyä (25-50% teoreettisesta Kelly-panoksesta), koska reaalimaailman kustannukset, jotka aiheutuvat edun yliarvioinnista, ovat katastrofaalisia. 2. Määrällinen epävakaus äärimmäisissä tapahtumissa Eräänä aamuna järjestelmämme kaatui äärimmäisen sääilmiön aikana.Ei ohjelmiston kaatuminen, vaan matemaattinen. Optimisaattori ei löytänyt ratkaisua.Olemme jäädytetty, emme pystyneet kaupankäyntiin, täsmällisissä olosuhteissa, joissa strategiamme olisi pitänyt tehdä eniten rahaa. Ongelma: Olemme optimoineet odotetut skenaariot. Mutta äärimmäisillä tapahtumilla on erilaiset korrelaatiorakenteet. Tavallisesti itsenäisesti liikkuvat varat yhtäkkiä korreloivat täydellisesti. Tulos ei ollut odotettua parempi kuin laskelmissa. : regularization from sklearn.covariance import LedoitWolf # Instead of sample covariance cov_matrix = np.cov(returns.T) # Use shrinkage towards structured estimator lw = LedoitWolf() cov_matrix_robust = lw.fit(returns).covariance_ Tämä vähentää jonkin verran tarkkuutta normaaleina aikoina vakauden äärimmäisyyksiin. Odotetut arvonlaskelmat ovat hieman huonompia. Ajan horisontti epätasapaino Tässä on ongelma, joka ei näy bakktesteissä: odotetun arvon laskeminen olettaa, että voit odottaa tarpeeksi kauan, että suurten lukujen laki toimii. Tuotannossa ei voi. Löysimme tämän, kun järjestelmämme osoitti vahvan positiivisen odotetun arvon 90-päivän ikkunoissa, mutta menetti jatkuvasti rahaa 30-päivän ikkunoissa. Pääomasijoittajamme tarkastelivat suorituskykyä kuukausittain.Riskirajoituksemme tarkistettiin neljännesvuosittain viimeaikaisten tulosten perusteella.Jos meillä oli kolme huonoa kuukautta, positiorajoituksemme leikattiin riippumatta siitä, mitä pitkän aikavälin odotettu arvo sanoi. Teoreettinen strategia kesti 6-12 kuukautta, jotta voitto näytettiin luotettavasti. Meidän oli lisättävä optimointiimme nimenomaisia aikavyöhykkeen rajoituksia: def optimize_with_horizon_constraint(scenarios, max_horizon_days=30): """ Optimize not just for long-term EV, but for probability of positive returns within operational time horizon """ # Standard expected value ev = np.mean(scenarios) # But also: what'sthe probability we're profitable # within our actual time horizon? rolling_returns = pd.Series(scenarios).rolling(max_horizon_days).sum() prob_profitable_in_horizon = (rolling_returns > 0).mean() # Penalize strategies with low short-term win probability # even if long-term EV is great if prob_profitable_in_horizon < 0.6: return ev * 0.5 # Heavily discount return ev Tämä tarkoitti sellaisten strategioiden hyväksymistä, joiden teoreettinen odotusarvo on hieman alhaisempi, mutta joiden todennäköisyys näyttää voittoa toiminnallisten rajoituksiemme puitteissa on suurempi. Mitä optimoida sen sijaan Kivuliaiden oppituntien jälkeen tässä on, mitä opimme optimoimaan: 1. Riskin mukautettu tuotto CVaR:llä Sen sijaan, että maksimoisimme E[voittoa], minimoimme CVaR (Ehdollinen arvo riskissä): odotettu tappio pahimmissa 5 prosentissa skenaarioista import cvxpy as cp # Decision variable: position sizes positions = cp.Variable(n_assets) # Scenarios returns scenario_returns = get_price_scenarios() # shape: (n_scenarios, n_assets) portfolio_returns = scenario_returns @ positions # CVaR constraints alpha = 0.05 # 5% tail var = cp.Variable() u = cp.Variable(n_scenarios) constraints = [ u >= 0, u >= -(portfolio_returns - var), ] cvar = var + cp.sum(u) / (n_scenarios * alpha) # Optimize for return while constraining tail risk objective = cp.Maximize(cp.sum(portfolio_returns) / n_scenarios - lambda_risk * cvar) Tämä nimenomaisesti rankaisee strategioita, joilla on hyvä keskimääräinen tuotto, mutta katastrofaalinen hännän riski. 2. Vakaus mallin virheeseen Oletamme, että malli on väärä ja optimoimme sen kohtuullisen epävarmuuden rajoissa: Huonoin tapaus # Instead of single expected return estimate mu_estimated = historical_returns.mean() # Assume uncertainty mu_lower_bound = mu_estimated - 2 * historical_returns.std() / np.sqrt(len(historical_returns)) # Optimize for worst-case in uncertainty range # (Robust optimization / minmax approach) Tämä suojaa liian luotettavia parametriarvioita vastaan. 3. Kelly-rajoitettu aseman koko Rajoitamme nimenomaisesti aseman kokoja Kelly-kriteerin perusteella, vaikka optimoija haluaa enemmän: def kelly_position_limit(edge, volatility, capital, max_kelly_fraction=0.25): """ edge: expected return per unit risk volatility: standard deviation of returns max_kelly_fraction: fraction of theoretical Kelly to actually use """ kelly_full = edge / (volatility ** 2) kelly_fraction = capital * kelly_full * max_kelly_fraction return kelly_position Käytämme 25% Kellyä kovana rajoituksena. Kyllä, tämä vähentää odotettua arvoa. Tuotannon ajattelutapa Siirtyminen odotetusta arvonajattelusta tuotannon ajatteluun on filosofista: "Millä strategialla on korkein odotettu tuotto?" Research mindset "Mikä strategia selviytyy olettamuksistani väärin?" Production mindset Tässä käytännön muutokset, joita teimme: Backtests: Huonoin kuukauden analyysi, ei vain keskimääräisiä tuottoja Aseman koko: Konservatiivinen oletusarvoisesti, jossa on poikkeavuuksien tappaminen Riskimittarit: seurata CVaR päivittäin, ei vain P&L Mallivalidointi: Oletetaan, että kaikkien arvioiden parametrien epävarmuus on 30 % Katastrofisuunnittelu: Selkeät koodin polut "malli on täysin väärässä" skenaarioissa Oppitunnin Odotettu arvo on kaunis matemaattinen käsite.Se on puhdas, intuitiivinen ja teoriassa optimaalinen. Se ei myöskään riitä. Tuotannossa et kauppaa todennäköisyysjakelua vastaan. Omat epätäydelliset riskimallit Markkinat, jotka muuttuvat Toiminnalliset rajoitukset, jotka eivät ole backtestissäsi Psykologinen todellisuus nähdä pääoman lasku päivä päivältä, vaikka "odotettu arvo on positiivinen" Järjestelmät, jotka selviytyvät, eivät ole niitä, joilla on korkein odotettu arvo.Ne ovat niitä, jotka pysyvät vahvoina, kun malli on väärä, markkinat muuttuvat ja mustat swans näkyvät. Optimoi selviytymisen kannalta ensin. Kannattavuus toiseksi. Odotettu arvo on osa tätä laskelmaa, mutta se ei ole objektiivinen toiminto.