Siin on üks küünal. Binance USDⓈ-M perpetual, BTCUSDT, minut, mis algab kell 13:46:00 UTC. See tuli klines endpoint'ist palja kaheteistkümnest väärtusest koosneva massiivina ning on jae- ja sellega külgnevas kvantitatiivses uurimistöös kõige tavalisem sisendühik. Peaaegu iga meie genereeritav strateegia puutub kokku millegagi, mis näeb välja selline.
Võtame selle siis indeks indeksilt lahti ja vaatame, kui palju sellest backtest valesti tõlgendab.
| Indeks | Väärtus | Nimi |
|---|---|---|
| 0 | 1773495960000 | avamisaeg (ms) |
| 1 | \"84120.50\" | avamine |
| 2 | \"84177.90\" | kõrgeim |
| 3 | \"84098.10\" | madalaim |
| 4 | \"84163.40\" | sulgemine |
| 5 | \"38.417\" | baasmaht (BTC) |
| 6 | 1773496019999 | sulgemisaeg (ms) |
| 7 | \"3232108.94\" | noteeritud maht (USDT) |
| 8 | 1204 | tehingute arv |
| 9 | \"21.883\" | taker-ostude baasmaht |
| 10 | \"1841203.55\" | taker-ostude noteeritud maht |
| 11 | \"0\" | ignoreeri |
[0] ja [6]: millise minutiga on tegu ja kelle kell seda ütleb
Avamisaeg 1773495960000, sulgemisaeg 1773496019999. Pane tähele teist: see lõpeb numbritega 19999, üks millisekund enne järgmise küünla avamist. Aken on poolavatud ja börs ütleb seda sulle täiesti otse. Pooled andmevead, mida olen taga ajanud, said alguse sellest, et keegi käsitles mõlemat otspunkti kaasavana ning luges piiril oleva tehingu kaks korda või joondas resample'i nii, et iga 5-minutiline küünal laenas naaberküünlalt ühe millisekundi.
Ajatemplid on börsi matching engine'i aeg. Mitte sinu kell, mitte teenusepakkuja ingestimise kell ega sama kell, mida kasutab funding snapshot. Kui ühendad kline-seeria teisest endpoint'ist tõmmatud funding-rate'i või open-interest'i seeriaga, ühendad allikaid, mis langevad enamasti kokku ligikaudu ühe sekundi täpsusega. 1-minutilise strateegia puhul tähendab see iga ühendatud rea kohta 1,7% ajastusviga. Kõik alla minuti pikkune muutub selle tõttu kasutuskõlbmatuks.
Ja sellele küünlale on märgitud selle avamisaeg. Selles sisalduv info ei ole teada enne 13:46:59.999. Iga indekseerimise konventsiooni küsimus — kas nihutan ühe võrra, kas kasutan sündmuse ajana küünla sulgemise või avamise ajatemplit — on tegelikult sama lookahead-küsimus, lihtsalt teises kostüümis.
[1] \"84120.50\": avamishind, millega sa kaubelda ei saa
Avamine on esimese akna sees toimunud tehingu hind. See on kahe teise inimese vahel lõpetatud tehing. Selleks ajaks, kui küünal sinu dataframe'is reana eksisteerib, on see hind juba kuuskümmend sekundit vana.
Eelmine küünal sulgus hinnal 84109.80, seega on kahe kõrvutise 1-minutilise küünla vahelises vahes 10.70 dollarit hinnaliikumist. See on 1.3 baaspunkti, graafikul nähtamatu ja ligikaudu veerand taker-tasust. Olgu. Aga vaata sama seeriat altcoin'i perp'i puhul USA CPI avaldamise ajal ja need küünaldevahelised vahed ulatuvad 15–40 baaspunktini. Backtest, mis genereerib signaali küünla sulgumisel ja täidab selle järgmise küünla avamisel, eeldab vaikselt, et vahe on null — ja see on null täpselt siis, kui see oluline on.
[2] ja [3]: \"84177.90\" kõrgeim, \"84098.10\" madalaim
Siin sureb enamik fill engine'e, mistõttu tuleb sellest pikk lõik.
Kõrgeim ja madalaim on äärmuslikud hinnad, mida puudutati. Need ei ütle midagi mahu ega kestuse kohta. Sama minuti toor-teibit näeme, et kõik hinnal 84100.00 või alla selle oli üheksa tehingu peale kokku 0.62 BTC, mis toimusid 1.4-sekundilise akna jooksul. Seega backtesti stop hinnal 84100 „täidetakse” — ja kui sinu positsioon on 3 BTC, sõid sa kogu nähtava order book'i allapoole liikudes ära ning ülejäänud kogus täideti kusagil 84105–84130 tagasiliikumise jooksul. Küünal ütleb, et madalaim hind oli 84098.10. Küünal ei ütle, et seal kaubeldi ainult $52,000 väärtuses notional'iga.
Teine suund on hullem, sest see meelitab sind ennast üle hindama. Oletame, et sul oli hinnal 84175 puhkav limit-müügikorraldus. Küünla kõrgeim hind on 84177.90, seega täidab naiivne engine su korralduse hinnal 84175 ja arvestab taker-kulu asemel maker-rebate'i. See, kas täitmine tegelikult toimus, sõltub järjekorrakohast sellel hinnatasemel — seda küünal teada ei saa ja tõenäoliselt ei salvestanud sina seda kunagi. Puudutamine ei tähenda täitmist.
Reegel, milles me oma fill engine'is kokku leppisime: puhkav limit täidetakse ainult siis, kui küünal kaupleb tasemest läbi, mitte lihtsalt selleni. Täpselt äärmuslikul tick'il toimunud täitmised vajavad trade tape'ist pärinevaid mahu-hinna tõendeid; vastasel juhul lükatakse need tagasi. See eemaldas tüüpilisest mean-reversion'i portfellist umbes 6% tehingutest ja vähendas ühe kandidaadi backtestitud Sharpe'i 1.9-lt 1.1-le. See kandidaat polnud kunagi päris; fill-reegel oli lihtsalt esimene asi, mis oli piisavalt aus, et seda öelda.
Seotud lõks: intrabar path. Kui küünla vahemik hõlmab nii sinu stoppi kui ka take-profit'i, ei saa OHLCV öelda, kumb neist esimesena saavutati. Iga engine peab valima konventsiooni. Meie eeldab alati, et stop saavutatakse esimesena — see on pessimistlik, aeg-ajalt vale ja ei tekita kunagi võltsvõitu. Kui sinu engine eeldab, et take-profit saavutatakse esimesena, toodavad laia vahemikuga küünlad ebaselgusest kasumit ning just need küünlad domineerivad sinu PnL-jaotuses.
[4] \"84163.40\": küünla kõige vähem robustne number
Sulgemine on akna viimane tick. See on kõik. See võib olla 0.002 BTC suurune odd-lot botilt, mis lõpetab kell 13:46:59.8 positsiooni täitmist. Seda üht struktuurilt suvalist tick'i kasutavad enamik uurimis-pipeline'e iga signaali arvutamiseks, iga positsiooni markeerimiseks ja iga väljumise hindamiseks.
BTC perp'ide puhul pole sellel peaaegu tähtsust; õhukese altcoin'i perp'i puhul kell 04:00 UTC on tähtsus tohutu ning sama minuti kahe venue'i sulgemishindade erinevus võib ületada kogu sinu tehingupõhise edge'i. Kui strateegia PnL sõltub konkreetselt sulgemishinnast, käivitame selle uuesti, kasutades markeerimiseks börsi mark price'i, mis tuleneb indeksist ja mida on palju raskem mõjutada. Kui tulemused erinevad, kauples strateegia artefaktiga.
[5] ja [7]: \"38.417\" ja \"3232108.94\", millistes ühikutes maht on
Baasmaht on BTC; noteeritud maht on USDT. Siin on mõlemad olemas, mis on vastutulelikkus, mida kõik venue'id ei paku. Põhjus, miks see oluline on, on venue'ideülene agregeerimine. Coin-margined lepingute noteering on $100 notional'iga lepingutes. Mõni aktsiafeed raporteerib round lot'e. Prediction market'i venue'id raporteerivad osakute arvu, kus üks osak on dollarites nomineeritud binaarne nõue. „Mahu” summeerimine segatud universumi lõikes ilma seda ühte notional'i ühikusse normaliseerimata annab likviidsusjärjestuse, mis on täielik jama — ja stabiilsena näiv jama, mis elab üle ka ülevaatuse.
Normaliseeri ingestimisel kõik noteeritud notional'iks. Salvesta ka toores väli, kuid ära lase strateegial seda kunagi näha.
[8] 1204: väli, mis peaks määrama sinu mõju mudeli
Tehingute arvuga jagatud baasvolüüm annab keskmiseks tehingu suuruseks 0.032 BTC ehk umbes $2,700. Kui sinu kandidaatstrateegia soovib korraga siseneda $250,000 väärtuses, palub see teha ligikaudu 92 korda suurema tehingu kui tolle minuti tüüpiline tehing. Seda arvu, mitte mingit üldist 5-bps libisemiskonstanti, peaks kasutama sinu square-root mõju-termin. Arvutame osalusmäära iga küünla kohta esmase klassi veeruna ja lükkame tagasi strateegiad, mille mediaanne sisenemine ületab mõne protsendi küünla notional'ist, sest kõik sellest allavoolu on väljamõeldis.
Tehingute arv märgib odavalt ära ka veidrad minutid. Maht on normaalne, tehingute arv kukkus 11-ni? Keegi tegi plokktehingu. Maht on normaalne, tehingute arv on 9,000? See on likvideerimiskaskaad, mida näritakse läbi väikeste tükkidena.
[9] ja [10]: \"21.883\", väli, mille kõik minema viskavad
Taker-ostude baasmaht. Selles küünlas oli 38.417 BTC-st 21.883 ostjate algatatud, seega on allkirjastatud mahu delta +5.349 BTC ja agressori jaotus ostjate poole 57/43. Börs annab sulle order flow imbalance'i tasuta väljana, mida enamik inimesi kunagi ei loe, sest pandas ei andnud sellele nende eest nime.
Ma ei väida, et see prognoosib iseseisvalt tootlust; naiivsed delta-strateegiad on üks kindlamaid viise fee ledger'isse annetamiseks. Kuid see on hinnast päriselt erinev mõõdik, see on saadaval samas päringus, mida sa niigi tegid, ning võimaldab eristada rallit, mida osteti, rallist, mis juhtus seetõttu, et müüjad astusid kõrvale. OHLC-s näevad need kaks ühesugused välja, kuid kümme minutit hiljem käituvad erinevalt. Meie research agent käsitleb strateegia hüpoteesi, mis ignoreerib seda taker-jaotust venue'il, kus see avaldatakse, tõenditest loobumisena.
[11] \"0\": ignore — ja kõik muu, mida siin pole
Indeks 11 on aegunud väli, püsivalt null. Huvitavam on nimekiri sellest, mida see küünal ei sisalda: pole bid'i, ask'i, spread'i, order book'i sügavust, funding rate'i, open interest'i, likvideerimisi, mark price'i ega index price'i. Ja mis kõige olulisem, pole võimalust teada, kas sinu korraldus oleks olnud maker või taker — see on erinevus 0.045% maksmise ja 0.01% teenimise vahel sellel venue'il.
Seega on iga ainult kline'idele ehitatud fee-mudel lihtsalt number-desse riietatud eeldus. Lahendame selle nii, et sunnime iga strateegia oma täitmisstiili ette deklareerima ja võtame seejärel taker-tasu kõige eest, mis ei suuda vastupidist tõendada.
Küünal, mida kunagi ei ilmunud
Viimane osa ja see, mis hammustab kõige valusamalt väljaspool suuremaid instrumente. Nulltehingutega minut ei tekita üldse kline'i. Teenusepakkujad ja teegid kannavad selle tavaliselt edasi: open = high = low = close = eelmine close, volume 0. Sinu indikaator arvutab rõõmsalt. Sinu strateegia näeb kehtivat rida ja võib genereerida signaali minutil, mil mitte keegi maailmas selle instrumendiga ei kaubelnud.
Ühe keskmise kapitalisatsiooniga perp'i puhul, mille sisse lugesime, oli 12-kuulises aknas 4.1% 1-minutilistest küünaldest nulltehingutega. Selle sümboli mean-reversion'i kandidaat paigutas 38% oma sisenemistest sünteetilistele küünaldele, sest lamedad sünteetilised hinnad on kõige ahvatlevam toit kõigele, mis mõõdab kõrvalekallet liikuvast keskmisest. Backtest nägi suurepärane välja. See kauples andmelünkadega.
Seetõttu kannab ingest-kiht nüüd iga küünla kohta synthetic boolean'i, mis liigub läbi iga resample'i, ning verifitseerimisgauntlet kukutab läbi iga strateegia, mille tehingud sellele koonduvad. Odav veerg. See on tapnud rohkem kandidaate kui ükski indikaator, mille oleme kunagi kirjutanud.
Kaksteist väärtust. Neli neist tõlgendatakse rutiinselt valesti, kaks visatakse rutiinselt minema ning terve kategooria puudub reast ja on engine'i kujutluses olemas. Enne järgmist backtesti tõmba oma andmehoidlast üks toores küünal ja loe iga väli valjusti läbi, võrreldes seda sellega, mida sinu fill-logic selle kohta eeldab. See on kahekümne minuti pikkune harjutus ja ma pole kunagi näinud, et keegi seda teeks ning mitte midagi ei leiaks.
← Kõik postitused