2026. augusztus 26. · piaci adatok

Egy 1 perces gyertya anatómiája: amit az OHLCV nem árul el a backtesztedről

Egy 1 perces gyertya anatómiája: amit az OHLCV nem árul el a backtesztedről

Íme egy gyertya. Binance USDⓈ-M perpetual, BTCUSDT, a 13:46:00 UTC-kor kezdődő perc. A klines endpointból tizenkét értékből álló, csupasz tömbként érkezett, és ez a retail, illetve az ahhoz közeli kvantitatív kutatás leggyakoribb bemeneti egysége. Szinte minden általunk generált stratégia érint valami ehhez hasonlót.

Szóval szedjük szét indexenként, és nézzük meg, mennyit értelmez félre belőle egy backteszt.

IndexÉrtékNév
01773495960000nyitási idő (ms)
1\"84120.50\"nyitó
2\"84177.90\"maximum
3\"84098.10\"minimum
4\"84163.40\"záró
5\"38.417\"base volume (BTC)
61773496019999zárási idő (ms)
7\"3232108.94\"quote volume (USDT)
81204kötések száma
9\"21.883\"taker vételi base volume
10\"1841203.55\"taker vételi quote volume
11\"0\"figyelmen kívül hagyandó

[0] és [6]: melyik percről van szó, és kinek az órája szerint

Nyitási idő: 1773495960000, zárási idő: 1773496019999. Figyeld meg a másodikat: 19999-re végződik, vagyis egy milliszekundummal a következő gyertya nyitása előtt ér véget. Az ablak balról zárt, jobbról nyílt, és a tőzsde ezt teljesen egyértelműen jelzi. Az adathibák fele, amelyekkel találkoztam, abból indult, hogy valaki mindkét végpontot zártnak tekintette, és kétszer számolt egy határon lévő kötést, vagy úgy igazított egy újramintavételezést, hogy minden 5 perces gyertya kölcsönvett egy milliszekundumot a szomszédjától.

Az időbélyegek a tőzsde matching engine-ének idejét mutatják. Nem a te órádét, nem a szolgáltatód adatbeolvasási idejét, és nem ugyanazt az órát, amelyet a funding snapshot használ. Amikor egy kline-sorozatot egy másik endpointból lekért funding-rate- vagy open-interest-sorozattal kapcsolsz össze, olyan forrásokat illesztesz össze, amelyek többnyire nagyjából egy másodpercen belül egyeznek. Egy 1 perces stratégia esetében ez minden összekapcsolt soron 1,7%-os időzítési hiba. Percen belüli idősíkon ez végzetes.

És ez a gyertya a nyitásakor kap időbélyeget. A benne lévő információ 13:46:59.999-ig nem ismerhető. Minden indexelési konvencióval kapcsolatos kérdés — eltoljam-e eggyel, a gyertya zárási vagy nyitási időbélyegét használjam-e eseményidőként — valójában ugyanaz a lookahead-kérdés, csak más jelmezben.

[1] \"84120.50\": a nyitóár, amelyen nem tudsz kereskedni

A nyitóár az ablakon belül létrejött első kötés ára. Egy befejezett tranzakció két másik szereplő között. Mire a gyertya sorként megjelenik a dataframe-edben, ez az ár már hatvan másodperces.

Az előző gyertya 84109.80-on zárt, így két egymás melletti 1 perces gyertya között $10.70 ármozgás húzódik. Ez 1,3 bázispont, grafikonon láthatatlan, és nagyjából a taker díj negyede. Rendben. De nézd meg ugyanezt a sort egy alt perpön egy amerikai CPI-közlés idején, és ezek a gyertyák közötti rések 15–40 bázispontra nőnek. A bar-close-on jelet adó, majd next-bar openön töltő backteszt csendben azt feltételezi, hogy a rés nulla — és éppen akkor nulla, amikor ennek a legkevésbé kellene így lennie.

[2] és [3]: \"84177.90\" maximum, \"84098.10\" minimum

A legtöbb fill engine itt pusztul el, ezért ez lesz a hosszabbik rész.

A maximum és a minimum szélsőérték: a megérintett árak. Nem tartozik hozzájuk sem mennyiség, sem időtartam. Ugyanennek a percnek a nyers kötési naplója szerint minden 84100.00 vagy az alatti kötés összesen 0.62 BTC volt, kilenc kötésben, egy 1,4 másodperces ablakon belül. Vagyis egy 84100-on elhelyezett backteszt-stop „teljesül” — és ha a pozíciód 3 BTC, lefelé menet felzabáltad a teljes látható könyvet, a maradék mennyiséged pedig valahol a 84105–84130 közötti visszakapaszkodásban teljesült. A gyertya szerint a minimum 84098.10 volt. Azt viszont nem mondja meg, hogy ott mindössze $52,000 névérték cserélt gazdát.

1204kötés a percben
0.032 BTCátlagos kötésméret (~$2.7k)
0.62 BTCa minimum ticknél vagy az alatt kötött összmennyiség
57%a volumenből vevői kezdeményezésű volt

A másik irány rosszabb, mert hízelgő képet fest rólad. Tegyük fel, hogy 84175-ön álló limit eladási megbízásod volt. A gyertya maximuma 84177.90, így egy naiv engine 84175-ön teljesít, és taker költség helyett maker rebate-et könyvel. Hogy ez a teljesülés tényleg megtörtént-e, az az adott árszinten elfoglalt queue-pozíciódtól függ, amit a gyertya nem tudhat, te pedig valószínűleg sosem rögzítettél. A megérintés nem teljesülés.

A fill engine-ünkben végül ezt a szabályt vezettük be: egy álló limit csak akkor teljesül, ha a gyertya áthalad a szinten, nem pusztán eléri azt. A pontos szélső ticknél csak akkor fogadunk el teljesülést, ha a kötési napló árhoz tartozó volumenre utaló bizonyítékot ad; különben elutasítjuk. Ez egy tipikus mean-reversion könyv ügyleteinek mintegy 6%-át eltávolította, és az egyik jelölt backtesztelt Sharpe-mutatóját 1.9-ről 1.1-re csökkentette. Az a jelölt sosem volt valódi; a fill szabály volt az első dolog, amely elég őszinte volt ahhoz, hogy ezt kimondja.

Kapcsolódó csapda: az intrabar útvonal. Ha egy gyertya tartománya a stopodat és a take-profitodat is átfogja, az OHLCV nem tudja megmondani, melyik teljesült előbb. Minden engine-nek választania kell egy konvenciót. A miénk mindig stop-first feltételezést használ, ami pesszimista, néha téves, de soha nem generál hamis nyereséget. Ha a te engine-ed take-profit-first feltételezést használ, a nagy tartományú gyertyák az ambiguitásból fognak profitot gyártani, miközben éppen ezek a gyertyák uralják a PnL-eloszlásodat.

[4] \"84163.40\": a gyertya legkevésbé robusztus száma

A záróár az ablak utolsó kötése. Ennyi. Lehet, hogy egy 0.002 BTC-s, páratlan kötés egy bottól, amely 13:46:59.8-kor kerekítette le a pozícióját. Ezt az egyetlen, szerkezetileg önkényes tick-et használja a legtöbb kutatási pipeline minden jel kiszámítására, minden pozíció árazására és minden kilépés kiértékelésére.

BTC perpökön ez alig számít; egy vékony altcoin perpnél 04:00 UTC-kor viszont óriási jelentősége lehet, és ugyanazon perc két venue-ja közötti záróárkülönbség meghaladhatja a teljes ügyletenkénti edge-edet. Ha egy stratégia PnL-je kifejezetten a záróártól függ, újrafuttatjuk a tőzsdei mark price-szal árazva, amely indexből származik, és sokkal nehezebb manipulálni. Ha az eredmények eltérnek, a stratégia az adatterméket kereskedte.

[5] és [7]: \"38.417\" és \"3232108.94\", milyen egységben van a volumen

A base volume BTC; a quote volume USDT. Itt mindkettő rendelkezésre áll, ami olyan gesztus, amellyel nem minden venue él. Azért fontos, mert venue-k között aggregálunk. A coin-margined kontraktusokat $100 névértékű kontraktusokban jegyzik. Egyes részvényadat-feedek round lotokat jelentenek. A prediction market venue-k részvényszámot közölnek, ahol egy részvény egy dollárban denominált bináris követelés. Ha egy vegyes univerzumban a „volume” értékeket egyetlen névértékegységre normalizálás nélkül adjuk össze, tiszta értelmetlenség lesz a likviditási rangsor — ráadásul stabilnak látszó értelmetlenség, amely a felülvizsgálaton is átmegy.

A beolvasáskor mindent normalizálj quote notionalra. A nyers mezőt is tárold el, de stratégiának soha ne tedd láthatóvá.

[8] 1204: a mező, amelynek meg kellene határoznia az impact modelledet

A base volume és a kötésszám hányadosa 0.032 BTC, vagyis körülbelül $2,700 átlagos kötést ad. Ha a jelölt stratégiád egyszerre $250,000 értékben akar belépni, az adott perc tipikus tranzakcióméretének nagyjából 92-szeresét kéri. Ezt a számot — nem valamiféle általános 5 bázispontos slippage-konstanst — kellene használnod a négyzetgyökös impact-tag meghatározására. Baronként első osztályú oszlopként számítjuk a participation rate-et, és elutasítjuk azokat a stratégiákat, amelyek medián belépése meghaladja a bar notional néhány százalékát, mert ami ezután következik, az már mind fikció.

A kötésszám olcsón jelzi a furcsa perceket is. Normális volumen, de a kötésszám 11-re esett? Valaki blokkot kötött. Normális volumen, de a kötésszám 9,000? Ez egy likvidációs kaszkád, amelyet apró darabokban rágnak át.

[9] és [10]: \"21.883\", a mező, amelyet mindenki eldob

Taker buy base volume. Ebben a gyertyában a 38.417 BTC-ből 21.883 vevői kezdeményezésű volt, így a signed volume delta +5.349 BTC, az aggressor-megoszlás pedig 57/43 a vevők javára. A tőzsde ingyen átadja neked az order flow imbalance-et egy olyan mezőben, amelyet a legtöbben sosem olvasnak, mert a pandas nem nevezte el helyettük az oszlopot.

Nem állítom, hogy ez önmagában előre jelzi a hozamokat; a naiv delta-stratégiák a díjkönyvbe történő adományozás megbízhatóbb módszerei közé tartoznak. De ez valóban más mérés, mint az ár, ugyanabban a kérésben elérhető, amelyet amúgy is elküldtél, és lehetővé teszi, hogy megkülönböztesd a vásárlások által hajtott ralit attól, amely azért történt, mert az eladók hátraléptek. Ez a kettő OHLC-ben azonosnak látszik, tíz perccel később mégis máshogy viselkedik. A kutatási agentünk úgy kezeli azt a hipotézist, amely figyelmen kívül hagyja a taker-megoszlást egy ezt publikáló venue-n, mintha bizonyítékot hagyna az asztalon.

[11] \"0\": figyelmen kívül hagyandó — és minden más, ami nincs itt

A 11-es index elavult mező, értéke véglegesen nulla. Érdekesebb azoknak a dolgoknak a listája, amelyeket ez a gyertya nem tartalmaz: nincs bid, nincs ask, nincs spread, nincs könyvmélység, nincs funding rate, nincs open interest, nincs likvidáció, nincs mark price, nincs index price. És ami a legfontosabb: nincs mód megtudni, hogy a te megbízásod maker vagy taker lett volna-e — ez a különbség aközött, hogy 0.045%-ot fizetsz, vagy 0.01%-ot keresel ezen a venue-n.

Vagyis minden, kizárólag kline-okra épülő díjmodell számnak öltöztetett feltételezés. Ezt úgy oldjuk fel, hogy minden stratégiát előre kötelezünk a végrehajtási stílusa deklarálására, majd minden olyan ügyletre taker díjat számítunk, amelynél nincs ellenkező bizonyíték.

A gyertya, amely sosem jelent meg

Az utolsó rész, és ez harap a legnagyobbat a majorokon kívül. Ha egy percben nincs kötés, egyáltalán nem keletkezik kline. A szolgáltatók és könyvtárak gyakran forward-fillt alkalmaznak: open = high = low = close = előző záróár, volume 0. Az indikátorod gond nélkül számol. A stratégiád érvényes sort lát, és jelet generálhat egy olyan percre, amelyben a világon senki nem kereskedett az adott instrumentummal.

Az egyik általunk beolvasott mid-cap perpnél egy tizenkét hónapos időablak 1 perces gyertyáinak 4.1%-ában nem volt kötés. Az adott szimbólumon futó mean-reversion jelölt a belépéseinek 38%-át szintetikus gyertyákon helyezte el, mert a lapos, szintetikus árak mágnesként vonzzák mindazt, ami a mozgóátlagtól való eltérést méri. Backtesztben gyönyörűen teljesített. Az adatok réseivel kereskedett.

Ezért hordoz az ingest layer mostantól minden gyertyához egy synthetic boolean értéket, amely minden újramintavételezésen átöröklődik, és az ellenőrzési gauntlet megbuktat minden olyan stratégiát, amelynek kötései erre sűrűsödnek. Olcsó oszlop. Több jelöltet ölt meg, mint bármelyik indikátor, amelyet valaha írtunk.

Tizenkét érték. Négyet rendszeresen félreértelmeznek, kettőt rendszeresen eldobnak, egy egész kategória pedig hiányzik a sorból, mégis az engine képzeli oda. A következő backteszted előtt kérj le egy nyers gyertyát a saját tárolódból, és olvasd fel hangosan minden mezőjét ahhoz képest, amit a fill logikád feltételez róla. Húszperces gyakorlat, és még soha nem láttam olyat, hogy valaki ezt elvégezte, és semmi problémásat nem talált.

ohlcvpiaci mikrostruktúraadatmérnökségbackteszteléskripto futures
← Összes bejegyzés