2026 m. rugsėjo 4 d. · backtesting

Ir stopas, ir tikslas buvo tame pačiame bare. Kurį pasirinko jūsų backtestas?

Ir stopas, ir tikslas buvo tame pačiame bare. Kurį pasirinko jūsų backtestas?

Pozicija atidaryta ties 84,120. Stopas ties 84,036, tikslas – ties 84,271. Ateina kitos minutės baras: atidarymo kaina 84,118, aukščiausia – 84,290, žemiausia – 84,010, uždarymo – 84,240.

Abu lygiai yra tame bare. Stopas buvo pasiektas, ir tikslas buvo pasiektas, tačiau šie keturi OHLC skaičiai visiškai neatskleidžia, kas įvyko pirmiau. Jūsų backtestas vis tiek pateikė skaičių. Kažkur cikle viena eilutė nusprendė – tikriausiai tokia, kurios rašydami nelaikėte modeliavimo prielaida.

Tai didžiausias netikro pelningumo šaltinis, kurį matau trumpalaikėse strategijose – didesnis už mokesčius ir praslydimą, nes tai nė neatrodo kaip prielaida. Atrodo kaip techninė smulkmena.

Pirmas klaidingas būdas: leisti nuspręsti if grandinei

Įprasta struktūra:

if bar.high >= target:
    exit(target, "tp")
elif bar.low <= stop:
    exit(stop, "sl")

Niekas nepasirinko „pirmiausia įvykdomi tikslai“. Tikslo patikra tiesiog atsidūrė pirmiau, nes tai laimingas scenarijus ir apie jį galvojote. Sukeiskite šakas vietomis – nuosavo kapitalo kreivė pasikeis; vien to turėtų pakakti suprasti, kad strategijos P&L iš dalies priklauso nuo jūsų redaktoriaus.

Paleidau sąmoningai įprastą vidurkio grįžimo skalpavimo strategiją su BTCUSDT perp, naudodamas trijų mėnesių 1-minute barus: 4,812 sandorių, stopas 0.10%, tikslas 0.18% nuo įėjimo kainos. Tie patys signalai, tie patys mokesčiai, pasikeitė tik lygių sutapimo sprendimo taisyklė.

12.6%sandorių abu lygiai pasiekti tame pačiame bare
2.31Sharpe, pirmiausia įvykdomi tikslai
0.18Sharpe, pirmiausia įvykdomi stopai
0.94Sharpe, įvykdymas nustatytas pagal 1-second barus

Aštuntadalis sandorių lemia visą rezultatą. Taip veikia glausta stopo ir tikslo pora: dviprasmiški sandoriai yra tie, kuriuose kaina judėjo į abi puses – būtent įdomiausi, o kiekvienas jų, priklausomai nuo monetos metimo, vertas viso atstumo tarp stopo ir tikslo. 12.6% sandorių × 0.28% intervalo sudaro 3.5% bendrosios nominalios apyvartos vienam imties vienetui, gerokai daugiau už tikrąjį strategijos pranašumą.

Šis rodiklis priklauso nuo baro intervalo ir atstumo tarp lygių santykio; didinant barų intervalą, jis greitai blogėja. Tie patys stopas ir tikslas, tie patys signalai, tik pakeistas duomenų diskretizavimo dažnis:

Baro intervalasSandorių, kai abu lygiai yra viename bareSharpe (pirmiausia tikslas)
1s0.3%0.91
1m12.6%2.31
5m34%3.60
15m49%4.42
1h71%5.88

Pažiūrėkite, ką ši lentelė iš tikrųjų sako. Su stambesniais barais backtesto rezultatas pagerėjo. Kiekvienas tyrėjas instinktyviai manytų, kad valandiniai barai yra konservatyvus pasirinkimas: mažiau triukšmo, mažesnė mikrostruktūros perteklinio pritaikymo rizika. Tačiau kai baro vidaus įvykių tvarka nustatoma jums palankiai, stambesnis baras tėra didesnė dėžė, kurioje galite daryti prielaidą, kad jums pasisekė. Naudojant 1h barus, septyni iš dešimties sandorių priklauso vien nuo pasirinktos taisyklės. Toks backtestas strategijos netikrina – jis 3,400 kartų tikrina dviejų `if` sakinių eiliškumą.

Antras klaidingas būdas: manyti, kad stopas įvykdytas stopo kaina

Tarkime, sutvarkote eiliškumą. Pirmiausia suveikia stopas, užfiksuojate lygiai 0.10% nuostolį ir taker mokestį, ir jaučiatės kruopščiai padirbėję. Vis tiek lieka dvi atskiros klaidos.

Pirma, stopas yra trigeris, o ne įvykdymas. Binance USDⓈ-M sistemoje STOP_MARKET pavedimas, kai tik tenkinama trigerio sąlyga, tampa rinkos pavedimu ir tada sunaudoja pavedimų knygoje esančią likvidumo pasiūlą. Ramią minutę praslydimas siekia vieną ar du kainos žingsnius. Minutę, kai stopas iš tiesų suveikė – tą, kurios žvakės kūnas siekė 40 punktų, o po juo vyko likvidacijų kaskada, – pavedimų knyga plona būtent toje pusėje, kuria kertate. Mano imtyje, stopų suveikimus sulyginus su sandorių įrašais, medianinis įvykdymas buvo 1.4 bps už trigerio kainos, o 95-asis procentilis – 11 bps. Esant 10 bps stopui, kraštiniu atveju sumokate dar dešimtadalį rizikos, kurią manėte apibrėžę.

Antra klaida subtilesnė ir būdinga perp: kuri kaina suveikia pavedimą. Binance stop pavedimai pagal numatytuosius nustatymus suveikia pagal mark price, kuri apskaičiuojama remiantis indeksu ir išlyginta baze, o ne paskutiniu sandoriu toje biržoje. Jūsų OHLC seka rodo paskutinę kainą. Tai skirtingos sekos, labiausiai išsiskiriančios būtent per įvykius, kurie suveikina stopus.

Paskutinė kaina (jūsų kline duomenys)Mark price (numatytasis trigeris)
Šaltinissandoriai šioje biržojekelių biržų indeksas + bazė
Šešėlių elgsenavisas kainos svyravimasstipriai išlygintas
Įprastas nuokrypis1–3 bps ramiomis sąlygomis, 20–35 bps kaskados minutę
Pasekmė backtestuistopai, kurie suveikė, nors neturėjo, ir atvirkščiai

Taigi 25 bps šešėlis paskutinės kainos duomenyse išmuša jus iš pozicijos backteste, nors reali mark price nė nepriartėjo prie jūsų trigerio 10 bps atstumu. Arba nutinka priešingai – tą dieną, kai pasikeičia indeksas, o jūsų birža vėluoja. Nustačius workingType į CONTRACT_PRICE, bent jau reali pavedimų elgsena sutampa su jūsų duomenimis. Tyrėjams tai paprastai teisingas pasirinkimas, nes sąžiningam mark price trigerio modeliavimui reikėtų per visą įvykdymo variklį perduoti antrą kainų seką.

Geriausiai prisimenu tokį atvejį: vienas iš mūsų „pagerino“ strategiją, perkeldamas take-profit iš 0.18% į 0.21%. Sharpe pakilo nuo 2.3 iki 3.1. Jokio naujo pranašumo neatsirado. Tikslas tiesiog atsidūrė už tankiausios 1-minute šešėlių pasiskirstymo dalies, todėl mažiau sandorių pateko į dviprasmišką grupę, kurioje kodas tyliai priskirdavo jiems laimėjimą. Jie optimizavo lygių sutapimo sprendimo taisyklę.

Trečias klaidingas būdas: visada manyti blogiausia ir vadinti tai konservatyvumu

Įprasta greita pataisa – pesimizmas. Jei pasiekiami abu lygiai, fiksuokite stopą. Viskas, jokio optimizmo, galima leisti į apyvartą.

Anksčiau taip darydavau. Tai geriau už alternatyvą, bet vis tiek klaidinga dėl dviejų priežasčių.

Taip nužudomos ir geros strategijos. Pesimistinis sprendimas 12.6% sandorių šiai strategijai kainavo 2.1 Sharpe punkto, palyginti su 0.94, gautu nustačius įvykdymą pagal sandorių įrašus. Jei tikrasis skaičius yra 0.94, o pagal jūsų taisyklę gaunate 0.18, idėją išmetate ir imatės ko nors prastesnio. Konservatyvumas, apsirinkantis dviem Sharpe punktais, nėra konservatyvumas – tai triukšmas su moraline laikysena.

Dar blogiau, tai iškreipia optimizavimą. Pateikite parametrų paieškai pesimistinę sutapimo taisyklę, ir optimizatorius išmoks vengti dviprasmiškų situacijų, nes dviprasmiškumas dabar reiškia gryną baudą. Jis rinksis plačius stopus ir artimus tikslus arba lėtus barus, kuriuose abu lygiai retai sutampa, ir pateiks parametrus, atrinktus pagal jūsų įvykdymo taisyklę, o ne pagal rinką. Ta pati nesėkmė kaip ir pernelyg palankaus varianto atveju, tik priešingo ženklo, ir lygiai taip pat nematoma rezultatų ataskaitoje.

Mūsų praktinė taisyklė prieš pradedant bet kokį darbą: jei stop_distance + target_distance mažesnis už jūsų baro intervalo amplitudės 75-ąjį procentilį, prielaida apie baro viduje vykusią kainos eigą P&L veikia labiau nei signalas. Apskaičiuokite abu skaičius. Tai užtrunka keturias kodo eilutes ir užbaigė daugiau strategijų peržiūrų nei bet kuri kita pavienė patikra.

Kas iš tikrųjų veikia

Kainos kelias baro viduje yra duomenys. Gaukite juos arba įvertinkite tai, ko negalite gauti.

  1. Nustatykite įvykdymą pagal tiksliausią turimą seką. Binance aggTrades atitinkamoms minutėms duoda kelis šimtus eilučių ir atsako į klausimą tiesiogiai: kuris lygis pasiektas pirmas ir kokia kaina įvykdytas prasiveržiantis pavedimas. Visam backtestui nereikia sandorių duomenų, pakanka jų dviprasmiškiems barams. Mano imtyje tai buvo 606 minutės iš 129,600. Tai nedidelis atsisiuntimas, o ne infrastruktūros projektas.
  2. Jei sandorių duomenų nėra, įvykdymui nustatyti pasirinkite 1 arba 2 žemesnius laiko intervalus. Signalai pagal 15m, išėjimai nustatomi pagal 1s arba 1m barus. Dviprasmiškų atvejų sumažėja nuo 49% iki procento dalies, o likutis pakankamai mažas, kad jį būtų galima sąžiningai ignoruoti.
  3. Visada pateikite intervalą. Kiekvieną backtestą atlikite du kartus – su optimistiniu ir pesimistiniu sprendimu – ir šalia pagal faktinius duomenis nustatyto Sharpe pateikite abu variantus. Šis skirtumas rodo neapibrėžtumą dėl įvykių tvarkos baro viduje; jį reikia įtraukti į rezultatų ataskaitą greta Sharpe rodiklio pasikliautinojo intervalo. Kai intervalas yra nuo 0.2 iki 2.3, jokia jame esanti išvada nėra tikra.
  4. Dviprasmiškų atvejų dalį stebėkite kaip pagrindinį rodiklį. Mūsiškis rodomas kiekvienos strategijos kortelės viršuje, šalia sandorių skaičiaus ir apyvartos. Didesnė nei maždaug 5% dalis reiškia, kad tikrinama išėjimo, o ne įėjimo logika.
  5. Trigerį modeliuokite atskirai nuo įvykdymo. Trigerį nustatykite pagal biržos naudojamą kainų seką, o įvykdymą – pagal trigerio kainą, pridėję pagal sandorių įrašus kalibruotą praslydimo atsitiktinę reikšmę, o ne pagal pačią trigerio kainą.

Akcijoms kyla ta pati problema, tik kitaip atrodo. Jei akcijos stopas nustatytas ties 62.00, o per naktį kaina krenta iki 58.40, pavedimas neįvykdomas ties 62.00 – jo kaina bus žemesnė už atidarymo sandorio kainą. Dienos barais paremtas backtestas, kuris kainos praslydimą per kainos tarpą prilygina −$0.00, mielai įtikins, kad apsauginis stop-loss sumažino nuosmukį. Taip nebuvo. Tiesiog strategija nebuvo išbandyta svarbiomis dienomis. Tą patį sukelia ir prekybos sustabdymai: pavedimas iš tikrųjų įvykdomas per atnaujinimo aukcioną, tokia kaina, kurios baro žemiausia reikšmė nerodo.

Čia nėra nieko egzotiško. Tiesiog reikia pripažinti, kad baras yra santrauka, o strategija su stopu ir tikslu – statymas dėl įvykių eiliškumo, kurį ši santrauka praleido. Kai popierinės prekybos variklis galiausiai paleidžia strategiją pagal realią sandorių seką, ši seka jau turi savo atsakymą apie įvykių tvarką, ir jai nė karto nerūpėjo, kurį if sakinį pirmą įvedėte.

užpildymai baro vidujestop pavedimaibacktestingkriptovaliutų ateities sandoriairinkos mikrostruktūra
← Visi įrašai