Narito ang isang bar. Binance USDⓈ-M perpetual, BTCUSDT, ang minutong nagsisimula sa 13:46:00 UTC. Galing ito sa klines endpoint bilang isang payak na array ng labindalawang value, at ito ang pinakakaraniwang unit ng input sa retail at kaugnay na quant research. Halos bawat strategy na ginagawa namin ay humahawak ng isang bagay na ganito ang hugis.
Kaya himayin natin ito, index kada index, at tingnan kung gaano karami rito ang mali ang binabasa ng isang backtest.
| Index | Value | Pangalan |
|---|---|---|
| 0 | 1773495960000 | oras ng pagbukas (ms) |
| 1 | \"84120.50\" | pagbukas |
| 2 | \"84177.90\" | pinakamataas |
| 3 | \"84098.10\" | pinakamababa |
| 4 | \"84163.40\" | pagsasara |
| 5 | \"38.417\" | base volume (BTC) |
| 6 | 1773496019999 | oras ng pagsasara (ms) |
| 7 | \"3232108.94\" | quote volume (USDT) |
| 8 | 1204 | bilang ng trades |
| 9 | \"21.883\" | base volume ng taker buy |
| 10 | \"1841203.55\" | quote volume ng taker buy |
| 11 | \"0\" | ignore |
[0] at [6]: aling minuto ito, at kaninong orasan ang batayan
Oras ng pagbukas 1773495960000, oras ng pagsasara 1773496019999. Pansinin ang pangalawa: nagtatapos ito sa 19999, isang millisecond bago ang pagbukas ng susunod na bar. Half-open ang window, at tahasang sinasabi iyon ng exchange. Nagsimula ang kalahati ng mga data bug na hinabol ko sa pagtrato ng isang tao sa parehong endpoint bilang inclusive at sa pagdodoble ng bilang sa trade sa boundary, o sa pag-align ng resample na kumukuha ang bawat 5-minutong bar ng isang millisecond mula sa katabing bar.
Oras ito ng matching engine ng exchange. Hindi ng orasan mo, hindi ng ingestion clock ng vendor mo, at hindi rin ng orasan na ginagamit ng funding snapshot. Kapag pinagdugtong mo ang kline series sa funding-rate series o open-interest series na kinuha mula sa ibang endpoint, pinagdurugtong mo ang mga source na kadalasang nagkakasundo sa loob ng humigit-kumulang isang segundo. Para sa 1-minutong strategy, 1.7% itong timing error sa bawat pinagdikit na row. Para sa anumang sub-minute, nakamamatay ito.
At ang timestamp ng bar na ito ay nasa pagbukas nito. Hindi malalaman ang impormasyong nasa loob nito hanggang 13:46:59.999. Ang bawat tanong tungkol sa indexing convention — magshi-shift ba ako ng isa, gagamit ba ako ng bar-close o bar-open timestamp bilang event time — ay pareho lang na tanong tungkol sa lookahead na nagpalit ng anyo.
[1] \"84120.50\": ang open na hindi mo maaaring i-trade
Ang open ay ang presyo ng unang trade na nag-print sa loob ng window. Isa itong nakumpletong transaksyon sa pagitan ng dalawang ibang tao. Sa oras na maging row na ito sa dataframe mo, animnapung segundo na ang tanda ng presyong iyon.
Nagsara ang nakaraang bar sa 84109.80, kaya may $10.70 na galaw ng presyo sa pagitan ng dalawang magkatabing 1-minutong bar. Iyon ay 1.3 basis points, hindi nakikita sa chart, at humigit-kumulang sangkapat ng taker fee. Ayos lang. Pero tingnan mo ang parehong series sa isang alt perp habang may US CPI print at ang mga gap sa pagitan ng bar ay umaabot ng 15 hanggang 40 bps. Ang backtest na nagsi-signal sa bar close at pumupuno sa next-bar open ay tahimik na ipinapalagay na zero ang gap, at nagiging zero ito mismo kapag hindi iyon dapat mangyari.
[2] at [3]: \"84177.90\" high, \"84098.10\" low
Dito namamatay ang karamihan ng fill engine, kaya ito ang pinakamahabang seksyon.
Ang high at low ay mga sukdulang presyong nahawakan. Wala silang dalang size o tagal. Sa raw trade tape ng kaparehong minutong ito, lahat ng nasa 84100.00 pababa ay 0.62 BTC sa siyam na print sa loob ng 1.4-segundong window. Kaya ang stop ng backtest sa 84100 ay \"napupunan\" — at kung 3 BTC ang posisyon mo, naubos mo ang buong nakikitang book habang pababa at ang natitirang size mo ay naisagawa kung saan-saan sa 84105–84130 na pagbalik. Sinasabi ng bar na 84098.10 ang low. Hindi nito sinasabing $52,000 lang na notional ang na-trade roon.
Mas masama ang kabilang direksiyon dahil pinapaganda nito ang resulta para sa iyo. Ipagpalagay na mayroon kang resting limit sell sa 84175. Ang high ng bar ay 84177.90, kaya pupunan ka ng isang walang-ingat na engine sa 84175 at magbubukod ng maker rebate sa halip na taker cost. Kung talagang nangyari ang fill ay nakadepende sa queue position sa presyong iyon, na hindi malalaman ng bar at malamang ay hindi mo naitala. Ang nahawakan ay hindi katumbas ng napunan.
Ang panuntunang napagkasunduan namin sa fill engine: ang resting limit ay mapupunan lamang kung tatawirin ng trade ang level, hindi kapag naabot lang ito. Ang fill sa eksaktong extreme tick ay nangangailangan ng volume-at-price na ebidensiya mula sa trade tape; kung wala iyon, tinatanggihan ang mga ito. Inalis nito ang humigit-kumulang 6% ng trades mula sa karaniwang mean-reversion book at ibinaba ang backtested Sharpe ng isang candidate mula 1.9 tungong 1.1. Hindi talaga totoo ang candidate na iyon; ang fill rule lang ang unang naging sapat na tapat para sabihin iyon.
Kaugnay na patibong: intrabar path. Kung sakop ng range ng isang bar ang stop at take-profit mo, hindi masasabi ng OHLCV kung alin ang nauna. Kailangang pumili ng convention ang bawat engine. Sa amin, laging nauuna ang stop, na pesimistiko at paminsan-minsang mali ngunit hindi kailanman lumilikha ng pekeng panalo. Kung take-profit-first ang palagay ng engine mo, gagawa ng tubo ang malalawak na range bar mula sa kalabuan, at ang malalawak na range bar mismo ang nangingibabaw sa distribusyon ng PnL mo.
[4] \"84163.40\": ang pinakakaunting matibay na numero sa bar
Ang close ang huling print sa window. Iyon lang. Maaaring isa itong 0.002 BTC na odd-lot mula sa bot na nagtatapos ng posisyon sa 13:46:59.8. Ang iisang structurally arbitrary na tick na ito ang ginagamit ng karamihan ng research pipeline para kalkulahin ang bawat signal, i-mark ang bawat posisyon, at suriin ang bawat exit.
Sa BTC perps, halos walang epekto; sa manipis na altcoin perp sa 04:00 UTC, napakalaki ng epekto, at maaaring lumampas ang agwat ng close ng dalawang venue para sa parehong minuto sa buong edge mo kada trade. Kapag partikular na nakadepende ang PnL ng strategy sa close, inuulit namin ito gamit ang exchange mark price, na hinango sa index at mas mahirap galawin. Kung magkaiba ang resulta, ang strategy ay nakikipag-trade sa artifact.
[5] at [7]: \"38.417\" at \"3232108.94\", volume sa anong unit
Ang base volume ay BTC; ang quote volume ay USDT. Parehong narito, isang kagandahang-loob na hindi ibinibigay ng lahat ng venue. Mahalaga ito dahil sa pag-aaggregate sa mga venue. Ang coin-margined contracts ay naka-quote sa mga contract na may $100 notional. May mga equity feed na nag-uulat ng round lots. Ang mga prediction market venue ay nag-uulat ng share count kung saan ang isang share ay binary claim na nakadenomina sa dolyar. Ang pagsasama ng \"volume\" sa magkakahalong universe nang hindi nino-normalize sa iisang notional unit ay lumilikha ng liquidity ranking na purong kalokohan, at magiging kalokohan ito sa isang matatag na anyo na nakakalusot sa review.
I-normalize ang lahat sa quote notional sa ingest. Itago rin ang raw field, pero huwag itong ipakita kailanman sa isang strategy.
[8] 1204: ang field na dapat magtakda ng iyong impact model
Ang base volume na hinati sa bilang ng trades ay nagbibigay ng average print na 0.032 BTC, o humigit-kumulang $2,700. Kung gustong pumasok ng candidate strategy mo ng $250,000 nang sabay-sabay, hinihiling nitong maging humigit-kumulang 92 beses ang laki nito kaysa sa karaniwang transaksyon sa minutong iyon. Ang numerong iyon, hindi ang generic na 5-bps slippage constant, ang dapat magtakda sa iyong square-root impact term. Kinakalkula namin ang participation rate kada bar bilang first-class column at tinatanggihan ang mga strategy na ang median entry ay lumalampas sa ilang porsiyento ng bar notional, dahil kathang-isip ang lahat ng kasunod nito.
Mura ring pananda ang bilang ng trades para sa mga kakaibang minuto. Normal ang volume, pero bumagsak sa 11 ang bilang ng trades? May gumawa ng block. Normal ang volume, pero umabot sa 9,000 ang trade count? Isa itong liquidation cascade na kinakain sa maliliit na piraso.
[9] at [10]: \"21.883\", ang field na itinatapon ng lahat
Taker buy base volume. Buyer-initiated ang 21.883 sa 38.417 BTC sa bar na ito, kaya +5.349 BTC ang signed volume delta at 57/43 pabor sa buyers ang aggressor split. Ibinibigay sa iyo ng exchange ang order flow imbalance nang libre, sa isang field na hindi binabasa ng karamihan dahil hindi pinangalanan ni pandas ang column para sa kanila.
Hindi ko sinasabing hinuhulaan nito nang mag-isa ang returns; kabilang ang mga walang-ingat na delta strategy sa mas maaasahang paraan ng pag-aabuloy sa fee ledger. Pero tunay itong ibang sukat kumpara sa presyo, available ito sa parehong request na ginagawa mo na, at hinahayaan ka nitong makilala ang rally na binili kumpara sa rally na nangyari dahil umatras ang sellers. Magkamukha ang dalawang iyon sa OHLC at magkaiba ang kilos makalipas ang sampung minuto. Itinuturing ng research agent namin na ang hypothesis na binabalewala ang taker split sa venue na naglalathala nito ay nag-iiwan ng ebidensiya sa mesa.
[11] \"0\": ignore — at lahat ng iba pang wala rito
Deprecated na field ang index 11, at permanenteng zero. Mas kawili-wili ang listahan ng mga bagay na wala sa bar na ito: walang bid, ask, spread, book depth, funding rate, open interest, liquidations, mark price, o index price. At higit sa lahat, walang paraan para malaman kung ang order mo ay magiging maker o taker, na siyang kaibahan ng pagbabayad ng 0.045% at pagkita ng 0.01% sa venue na ito.
Kaya ang anumang fee model na nakabatay lamang sa klines ay isang palagay na nakadamit na parang numero. Nilulutas namin ito sa pag-aatas sa bawat strategy na ideklara nang maaga ang execution style nito, at pagkatapos ay paniningil ng taker sa anumang hindi makapagpapatunay ng iba.
Ang bar na hindi kailanman lumitaw
Huling bahagi, at ito ang pinakamasakit sa labas ng majors. Ang minutong walang trade ay hindi gumagawa ng kline. Karaniwang bina-forward-fill ito ng mga vendor at library: open = high = low = close = nakaraang close, volume 0. Masayang kinakalkula ng indicator mo. Nakikita ng strategy mo ang isang valid na row at maaaring bumuo ng signal sa minutong walang sinuman sa mundo ang nag-trade ng instrumentong iyon.
Sa isang mid-cap perp na in-ingest namin, 4.1% ng 1-minutong bar sa loob ng labindalawang-buwang window ay walang trades. Naglalagay ng 38% ng entries nito sa synthetic bars ang isang mean-reversion candidate sa symbol na iyon, dahil paboritong-paborito ng anumang sumusukat ng paglihis mula sa moving average ang patag na synthetic prices. Napakaganda ng backtest nito. Tina-trade nito ang mga puwang sa datos.
Kaya may synthetic boolean na ngayon ang ingest layer kada bar, ipinapasa sa bawat resample, at bumabagsak sa verification gauntlet ang anumang strategy na nagkakumpol dito ang mga trade. Murang column. Mas marami na itong pinatay na candidate kaysa sa alinmang indicator na naisulat namin.
Labindalawang value. Apat ang regular na mali ang basa, dalawa ang regular na itinatapon, at isang buong kategorya ang wala sa row ngunit iniimbento ng engine. Bago ang susunod mong backtest, kumuha ng isang raw bar mula sa sarili mong store at basahin nang malakas ang bawat field laban sa ipinapalagay ng fill logic mo tungkol dito. Dalawampung minutong ehersisyo lang ito, at wala pa akong nakitang gumawa nito nang walang nadiskubre.
← Lahat ng post