Imali smo problem.Naš automatizirani sustav trgovanja imao je pozitivnu očekivanu vrijednost: matematika je provjerena, backtesti izgledali su sjajno, a u početku je zaradio novac. To nije bio bug u kodu, to je bilo temeljno pogrešno razumijevanje onoga što je važno u proizvodnji. Očekivana vrijednost zamke Većina trgovinskih vodiča, akademskih radova i online tečajeva uče vas kako maksimalno povećati očekivanu vrijednost. E[profit] = Σ(probability_i × outcome_i) Ako je ovaj broj pozitivan, trebali biste uzeti trgovinu. Ako možete učiniti ovaj broj većim, trebali biste optimizirati za to. Osim u proizvodnji, ova strategija optimizacije ima fatalni nedostatak: . it doesn't account for the path you take to reach that expected value Dozvolite mi da vam pokažem što mislim realnim scenarijem iz našeg sustava. Krvavi sustav Naša strategija bila je osmišljena kako bi uhvatila pike cijena na volatilnim tržištima. Analiza mogućih smjerova cijena za svaki trgovački prozor Optimizacija veličine položaja pomoću kvadratnog programiranja Izvršite trgovine kako biste uhvatili širenje prilika Na papiru, očekivana vrijednost bila je čvrsto pozitivna. Dan 1-3: Uhvatio veliki štap, napravio 15.000 dolara Dan 4-12: Mali gubici svaki dan, ukupno -8.000 dolara Dan 13-14: Još jedan vrhunac, napravio 12.000 dolara Dan 15-28: Postupno krvarenje, ukupno -11 tisuća dolara Problem? Naš optimizator je razvio strukturnu predrasudu. Sistematično je uzimao pozicije koje su povremeno osvojile velike, ali su često izgubile male iznose. Očekivani izračun vrijednosti rekao je da je to u redu: velike pobjede će na kraju nadoknaditi. Nismo imali ni jednog. Vidjeti razliku: Simulacija Da biste ilustrirali zašto su ove kontrole rizika važne, usporedimo dvije strategije trgovanja na istom tržištu tijekom jedne godine: Agresivna veličina pozicije temelji se isključivo na očekivanoj vrijednosti, koristeći 150% poluge kada prilike izgledaju dobro. Strategy A (EV Maximization) Isti tržišni signali, ali s frakcijskom veličinom Kellyja (40% agresivnog) i smanjenjem pozicije na temelju CVaR-a tijekom razdoblja visokog rizika. Strategy B (Risk-Controlled) Rezultati govore ključnu priču. Pogledajte na lijevom grafikonu pažljivo - većina putova EV-maksimiziranja nije katastrofalno neuspješna. Oni su samo... ne kompozit. Možete vidjeti uzorak šavova: povremeno se povećava, nakon čega slijedi spora erozija. Ovo je zavaravajuće krvarenje koje pozitivna očekivana vrijednost propušta. Primijetite kako je nekoliko staza dosegnulo 500 tisuća dolara?Ovi izlazi povlače prosjek do 146 tisuća dolara. To je samo 136 tisuća dolara, a 29 od 100 staza završava ispod početnog kapitala. Medija In a backtest, you might have gotten lucky and seen one of those winner paths. In production, you get one random draw. Pravi grafikon je "dosadan", i to je točno točka. Bez snimaka mjeseca do 500.000 dolara, ali i bez katastrofalnih povlačenja. Strategija pod kontrolom rizika čvrsto se skuplja oko skromnog rasta. To je stvarnost proizvodnje: strategija koja preživi postaje složena. Što očekivana vrijednost ne hvata 1. rizik od rušenja To je problem klasičnog kockarca, formaliziran Kelly Criterionom. Čak i uz pozitivnu očekivanu vrijednost, ako je veličina vaše pozicije pogrešna, Idite na razbijanje. Will Razmislite: Imate 100 tisuća dolara kapitala i trgovinu s 60% vjerojatnosti dobitka koja ili udvostručuje svoju ulogu ili je gubi.Očekivana vrijednost je pozitivna (+20%). Kelly vam kaže da je optimalna veličina stave: kelly_fraction = (p * b - q) / b # where p = win probability, q = loss probability, b = odds Evo što smo naučili u proizvodnji: . even Kelly is too aggressive Zašto? jer: Vaše procjene vjerojatnosti su pogrešne (uvijek) Tržišta se mijenjaju (vaša 60% prednost postaje 52%) Korelacije se raspadaju tijekom stresa (kada vam je najpotrebnije) Ne možete odmah ponovno uravnotežiti (slip, latentnost, utjecaj na tržište) Konačno smo upotrijebili frakcijski Kelly (25-50% teorijske Kelly stave) jer su stvarni troškovi pretjerivanja vaše granice katastrofalni. Numerička nestabilnost u ekstremnim događajima Jednog jutra, naš sustav se srušio tijekom ekstremnog vremenskog događaja, a ne softverski, već matematički. Optimizator nije mogao naći rješenje.Bili smo zamrznuti, nismo mogli trgovati, tijekom točnih uvjeta u kojima bi naša strategija trebala zaraditi najviše novca. Problem: bili smo optimizirani za očekivane scenarije. Ali ekstremni događaji imaju različite strukture korelacije. Sredstva koja se obično kreću neovisno odjednom postaju savršeno korelirana. Vaša pažljivo procijenjena matrika kovarijancije, izgrađena iz tisuća normalnih dana, postaje beskorisna. Izračun vrijednosti nije bio bolji od očekivanog. : 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_ To odbija određenu točnost u normalnim vremenima za stabilnost u ekstremima. Vaši očekivani izračuni vrijednosti bit će malo gore. Sljedeći članak Time Horizon Mismatch Evo problema koji se ne pojavljuje u backtestovima: vaše izračunavanje očekivane vrijednosti pretpostavlja da možete čekati dovoljno dugo da zakon velikih brojeva radi. U proizvodnji ne možete. Otkrili smo to kada je naš sustav pokazao snažnu pozitivnu očekivanu vrijednost preko 90-dnevnih prozora, ali je dosljedno izgubio novac preko 30-dnevnih prozora. Naši pružatelji kapitala pregledali su performanse mjesečno. Naše granice rizika su prilagođene tromjesečno na temelju nedavnih rezultata. Ako smo imali tri loša mjeseca, naše granice pozicija su se smanjile, bez obzira na to što je dugoročna očekivana vrijednost rekla. Teorijska strategija je trebala 6-12 mjeseci da pouzdano pokaže profit. Morali smo dodati eksplicitne vremenske ograničenja našoj optimizaciji: 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 To je značilo prihvaćanje strategija s nešto nižom teoretskom očekivanom vrijednošću, ali većom vjerojatnošću pokazivanja profita unutar naših operativnih ograničenja. Što optimizirati umjesto Nakon bolnih lekcija, evo što smo naučili optimizirati za: Povratak prilagođen riziku s CVaR-om Umjesto da maksimalno povećamo E[profit], minimiziramo CVaR (Conditional Value at Risk): očekivani gubitak u najgorem 5% scenarija 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) To izričito kažnjava strategije koje imaju dobre prosječne prinose, ali katastrofalan rizik repa. Robustnost do pogreške modela Pretpostavljamo da je naš model pogrešan i optimiziramo za U okviru razumne neizvjesnosti: Najgori slučaj # 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) To štiti od pretjerane procjene parametara. 3.Kelly-Ograničena veličina položaja Izričito ograničavamo veličine pozicija na temelju kriterija Kelly, čak i kada optimizator želi više: 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 Mi koristimo 25% Kelly kao tvrdo ograničenje. Da, to smanjuje očekivanu vrijednost. Razmišljanje o proizvodnji Prijelaz od očekivanog razmišljanja o vrijednosti prema razmišljanju o proizvodnji je filozofski: "Koja strategija ima najviši očekivani povrat?" Research mindset "Koja će strategija preživjeti pogrešno o mojim pretpostavkama?" Production mindset Evo praktičnih promjena koje smo napravili: Backtests: Dodana analiza najgoreg mjeseca, a ne samo prosječni prinosi Dimenzije položaja: konzervativno podrazumijevano, sa prekidačima za ubijanje anomalija Mjere rizika: Pratite CVaR dnevno, a ne samo P&L Validacija modela: pretpostavlja se 30% parametarske neizvjesnosti na svim procjenama Planiranje katastrofa: eksplicitne putove kodiranja za scenarije "model je potpuno pogrešan" Lekcija Očekivana vrijednost je lijep matematički koncept, čista je, intuitivna i teorijski optimalna. To također nije dovoljno. U proizvodnji, ne trgovate protiv distribucije vjerojatnosti. Vlastiti nesavršeni modeli rizika Tržišta koja se mijenjaju Operativne ograničenja koja nisu u vašem backtestu Psihološka stvarnost promatranja vašeg kapitala pada iz dana u dan, čak i ako je "očekivana vrijednost pozitivna" Sustavi koji preživljavaju nisu oni s najvišom očekivanom vrijednošću.To su oni koji ostaju robusni kada je model pogrešan, tržišta se mijenjaju i pojavljuju se crni šavovi. Optimizacija za preživljavanje prvo Profitabilnost drugo Očekivana vrijednost je sastavni dio tog izračuna, ali to nije objektivna funkcija.