← Maqolalarga qaytish
July 8, 2026
5 daqiqa o'qish

Ko'p vaqt oralig'idagi bektestlarda kelajakka qarash yo'qligini isbotlash: kelajakni buzib, o'tmish uni ko'ra olmasligini isbotlash

Ko'p vaqt oralig'idagi bektestlarda kelajakka qarash yo'qligini isbotlash: kelajakni buzib, o'tmish uni ko'ra olmasligini isbotlash
#algotrading
#bektest
#kelajakka qarash bias
#ko'p vaqt oralig'i
#ma'lumot sizib chiqishi
#validatsiya
🎯
Part 2 of 9 · Collection
Backtesting Without Fooling Yourself

"Illyuziyasiz bektestlar" turkumining bir qismi.

Oldingi maqola diagnostika bilan tugadi: bir-bar siljitish testi. Har bir bajarilishni bir bar keyinga suring; agar natija qulasa, demak siz o'tmishda savdo qilgan edingiz. Bu test yagona vaqt oralig'idagi strategiya uchun yetarli, unda kelajakka qarash bajarilishda yashiringan — siz i barida qaror qabul qilib, i barida bajargansiz.

Ko'p vaqt oralig'idagi strategiyalarning sizib chiqish uchun ikkinchi, sokinroq joyi bor, va siljitish testi u yerga yetib bormaydi. 1 daqiqalik bardagi qaror 1 soatlik trendga murojaat qilganda, sizib chiqish endi bajarilishda emas — u indikatorda, ya'ni hali shakllanishi tugallanmagan yuqori vaqt oralig'idagi bardan hisoblangan indikatorda joylashadi. Ushbu maqola aynan shu sizib chiqish haqida va sizning dvigatelingizda uning yo'qligini — shunchaki kodga qarab emas, mexanik tarzda — qanday isbotlash haqida.

Oxirida biz qiladigan da'vo kuchli: bizning multi-TF dvigatelimiz haqiqiy ETHUSDT 1 daqiqalik ma'lumotlarining 86,400 barida 25 ta paritet va sizib chiqish tekshiruvining 25 tasidan o'tdi, jumladan kelajakdagi har bir barni buzadigan va o'tmishdagi bironta ham qarorning siljimasligini tasdiqlaydigan siljitilgan-kelajak tekshiruvi ham bor. Va dvigatel jonli botning kanonik yadrosi bilan bit darajasida bir xil bo'lgani uchun, isbot faqat bektestning emas, balki jonli tizimning xususiyati hisoblanadi.

Ko'p vaqt oralig'idagi minalar maydoni

Bir vaqtning o'zida uchta vaqt oralig'iga ko'tarilayotgan 1 daqiqalik qaror, eng yuqori vaqt oralig'idagi sham hali shakllanmoqda va uning yakuniy yopilish narxi vaqt chegarasi ortida yashiringan

Ko'p vaqt oralig'idagi (multi-TF) strategiya sekin soatlarga murojaat qilib turib, tez soat bo'yicha qaror qabul qiladi. Bizning dvigatelimiz aniq misol hisoblanadi: yuqori vaqt oralig'i (HTF) va o'rta vaqt oralig'i (MTF) trendlari kirishlarni cheklaydigan, quyi vaqt oralig'i (LTF) kesishuvi esa ularni ishga tushiradigan uch karrali TF impuls qoidasi. 1 daqiqalik asosiy soat bo'yicha kirish faqat 1 daqiqalik HMA/HMA3 kesishuvi 1 soatlik trend va 15 daqiqalik trend yo'nalishi bilan mos kelganda ishga tushadi; chiqish esa yuqori vaqt oralig'idagi trend pozitsiyaga qarshi burilganda yoki LTF orqaga kesishganda ishga tushadi.

Xavf tuzilmaviy xususiyatga ega. Ushbu yuqori vaqt oralig'idagi qiymatlarning har biriga har bir 1 daqiqalik barda javob berish kerak — soatiga 60 marta — va har bir javob faqat jonli bot o'sha lahzada bilishi mumkin bo'lgan narsadan foydalanishi kerak. Ushbu bar boshiga taxminan 180 ta o'qishning (uchta vaqt oralig'i, kirish va chiqish trendlari, ajratish chegaralari) bittasi hali chop etilmagan barga tegib ketgan zahoti, sizda kelajakka qarash mavjud bo'ladi. Off-by-one xatosining tarqalish maydoni ulkan, va bajarilishdagi sizib chiqishdan farqli o'laroq, u o'zini bajarilishni siljitish orqali bildirmaydi.

Shakllanayotgan barning hali yakuniy yopilish narxi yo'q

Mana aniq tuzoq. Faraz qiling, soat 10:37 va siz hozirgina yopilgan 1 daqiqalik bar bo'yicha qaror qabul qilyapsiz. Sizning qoidangizga 1 soatlik trend kerak. 10:00–11:00 oralig'ini qamrab oluvchi 1 soatlik sham hali shakllanmoqda — uning yakuniy yopilish narxi faqat soat 10:59:59 da ma'lum bo'ladi. Soat 10:37 da siz aslida nimani bilasiz? Faqat o'sha shamning shu vaqtgacha bo'lgan joriy yopilish narxini, ya'ni 10:37 barining yopilish narxini. Shamning yakuniy yopilish narxi 23 daqiqadan keyingi kelajakda.

Soddadil multi-TF bektest butunlay zararsiz ko'rinadigan narsani qiladi: u butun 1 daqiqalik seriyani oldindan, bir marta, 1 soatga qayta namunalaydi, so'ngra har bir 1 daqiqalik bar uchun "1 soatlik yopilish narxi"ni o'qiydi. Ammo u 10:00 va 11:00 orasidagi har bir 1 daqiqalik bar uchun o'qiydigan qiymat — real vaqtda soat tugagunga qadar mavjud bo'lmaydigan 10:00–11:00 oralig'ining yakuniy yopilish narxidir. Soat ichidagi har bir qaror sekinlik bilan 59 daqiqalik kelajakka topshirilmoqda. Va bu kichik sizib chiqish emas — yuqori vaqt oralig'idagi yopilish narxi siz savdo qilmoqchi bo'lgan yaqin kelajakdagi 1 daqiqalik daromadlarning eng kuchli mumkin bo'lgan bashoratchisi hisoblanadi, shuning uchun uni sizib chiqarish javob kalitini o'qishga yaqin. Bu taksonomiyadagi indikator-sizib chiqish kanali, faqat kuchaytirilgan: bu bitta barga qarash emas, butun HTF davrigacha bo'lgan qarash bo'lishi mumkin.

Oldingi maqoladagi bir-bar siljitish testi buni ushlab qolmaydi. Siz bajarilishni bir bar keyinga surishingiz mumkin, ammo qayta namunalangan 1 soatlik seriya hali ham ifloslangan bo'lib qoladi — sizib chiqish siz bitim tuzgan vaqtda emas, balki indikatorning qanday qurilganida yashiringan.

Jonli botning qoidasi, aynan takrorlangan: yopiq-bar semantikasi

i baridagi yuqori vaqt oralig'i buferi: tugallangan yopiq shamlarning yopilish narxlari qatori, undan keyin qiymati joriy asosiy yopilish narxi bo'lgan bitta shakllanayotgan sham, hali yashirin yakuniy yopilish narxi chizib tashlangan

To'g'ri qoida — jonli bot allaqachon ishlatayotgan qoidadir. Bizning kod bazamizda bu RunningCandleBuffer deb ataladigan kichik sinf bo'lib, jonli tik simulyatoridan so'zma-so'z ko'chirilgan. U asosiy barlarni belgilangan davrli shamlarga oqim tarzida yetkazadi va har bir asosiy barda HTF indikatorini aniq bir massivdan hisoblaydi:

all_closes = np.array(self.closes + [self.current_close], dtype=np.float64)

Buni so'zma-so'z o'qing. self.closes — bu allaqachon yopilgan shamlarning yakuniy yopilish narxlari — sham faqat yangi davr chegarasi kesib o'tganda qo'shiladi, va uning saqlangan qiymati davr ichidagi oxirgi asosiy barning yopilish narxidir (candle_buffer.py:39–44). Shakllanayotgan sham aynan bitta son qo'shadi, self.current_close — bu joriy yopilish narxi, ya'ni eng so'nggi asosiy barning yopilish narxi, base_close[i]. Bu i barida ta'rifi bo'yicha ma'lum bo'lgan kattalik. Shakllanayotgan shamning yakuniy yopilish narxi hech qachon ishlatilmaydi, chunki u hali mavjud emas.

Shunday qilib, soat 10:37 da HTF indikatori [..., close(9:00 shami), close(10:37 gacha)] ni ko'radi. Soat 10:38 chop etilganda, oxirgi katak close(10:38) ga yangilanadi. Soat 11:00 kesib o'tganda, close(10:59) yangi yopilgan shamning yakuniy qiymatiga aylanadi va yangi shakllanish katagi ochiladi. Soat ichidagi qaror hech qachon 10:00–11:00 oralig'ining yakuniy yopilish narxiga tegmaydi. Aynan shu — yopiq-bar semantikasi: yopiq shamlar tugallangan yopilish narxlarini beradi, shakllanayotgan sham esa faqat o'zining joriy yopilish narxini beradi.

Bizning tezkor dvigatelimiz (engine_multitf.py) shuning vektorlashtirilgan, numba bilan kompilyatsiya qilingan qayta amalga oshirilishi. O'sib boruvchi ro'yxatli Python siklidan farqli o'laroq, u har bir asosiy bar i uchun oldindan nechta sham to'liq yopilganini (n_closed[i]) hisoblaydi va HMA/HMA3 oynasini [yopiq sham yopilish narxlari…, base_close[i]] shaklida joylashtiradi — joriy yopilish narxi yakuniy katakka mahkamlangan (engine_multitf.py:168–169). Bu aynan o'sha matematika, tezlik uchun uchta vaqt oralig'ida yo'nalishli ajratish chegaralari bilan yoyilgan. Shartnoma aniq: i baridagi qiymat faqat base_close[0..i] ga bog'liq.

Bu — da'vo. Maqolaning qolgan qismi buni qanday isbotlaganimiz haqida, chunki docstringdagi da'voning hech qanday qiymati yo'q.

Paritet zarur, ammo yetarli emas

Oqim sinfini aniq sikllarga yoyadigan vektorlashtirilgan numba dvigateli aynan off-by-one xatolarining ko'payadigan joyidir. Shuning uchun birinchi darvoza — haqiqiy kesimda, ETHUSDT 1 daqiqalik, 2024 yil yanvar–fevral, 86,400 bar, kanonik ma'lumotnomaga qarshi bit-baytiga paritet testidir.

Biz ikkita mustaqil ma'lumotnomaga qarshi ikkita mustaqil narsani tekshiramiz:

  • Indikatorlar va kesishuvlar bar-bar bo'yicha ishga tushirilgan RunningCandleBuffer ga qarshi. Har bir vaqt oralig'i uchun biz jonli sinfni barcha 86,400 barda qayta ijro etamiz va kesishuv hodisalarini — barni, yo'nalishni, ajratishni — aniq mosligiga solishtiramiz, shuningdek HMA/HMA3 qiymatlarini suzuvchi nuqta aniqligiga qadar solishtiramiz (ma'lumotnoma np.dot dan foydalanadi, dvigatel esa aniq sikllardan, shuning uchun yig'indilash tartibi ~1e-15 darajasida farqlanadi). Kesishuvlar aniq mos keladi: HTF da (1 soat, HMA uzunligi 21) 408 kesishuv, MTF da (15 daqiqa/14) 2,792, LTF da (1 daqiqa/50) 3,691. Bironta ham kesishuv hodisasi barda yoki yo'nalishda farq qilmaydi.
  • Savdolar ma'lumotnomaning o'z kesishuvlari bilan boshqariladigan savdo qoidalarining mustaqil sof Python simulyatsiyasiga qarshi. Bu jonli bektest siklini takrorlaydi — kirish trendlari kirishlarni cheklaydi, chiqish-trend burilishi yoki qarama-qarshi LTF kesishuvi yopadi, bajarilish open[i+1] da, 0.09% ikki tomonlama komissiya, oxirgi barda majburiy yopish — dvigatelning numba mexanizmisiz. So'ngra biz savdo-savdo bo'yicha solishtiramiz: kirish/chiqish barlari, tomonlari, kirish/chiqish narxlari, PnL, chiqish sabablari va pozitsiyadagi umumiy faol vaqt.

Testdagi ajratish chegaralari beg'araz standart qiymatlar emas. Ular noqulay burchakka tegishi uchun tanlangan — MTF chiqish chegarasi mos keluvchi kirish chegarasidan yuqori o'rnatilgan — bu ma'lumotnoma burilish deb qaraydigan "pozitsiya ochiq bo'lgan paytda chiqish trendining birinchi ta'rifi" tarmog'ini majburlaydi. Paritet faqat oson yo'lda emas, burchak holatlarda ham saqlanishi kerak.

Maydon bo'yicha, savdolar bir xil: qo'sh konfiguratsiya uchun 466 savdo, uchlik uchun 211 savdo, umumiy PnL 1e-12 gacha mos keladi va har bir savdoning maydonlari aniqlikka qadar teng. Umumiy kod ulashmaydigan ikkita amalga oshirish — kompilyatsiya qilingan vektorlashtirilgan dvigatel va uchinchi amalga oshirishning kesishuvlariga asoslangan soddadil Python sikli — oxirgi o'nlik gacha bir xil savdolarni hosil qiladi.

Bu kuchli natija, va u kelajakka qarash yo'qligining isboti emas. Paritet tezkor dvigatel ma'lumotnomani sadoqat bilan takrorlashini aytadi. Agar ma'lumotnomaning o'zi sizib chiqqan bo'lsa — agar RunningCandleBuffer oldindan qaragan bo'lsa — paritet sizib chiqishni sadoqat bilan takrorlar va o'tar edi. Amalga oshirishlar orasidagi kelishuv ularning bir xil ekanini aytadi, sabab-oqibatli ekanini emas. Sabab-oqibat uchun boshqacha turdagi test kerak, u dvigateldan o'tmish kelajakni ko'ra olishini to'g'ridan-to'g'ri so'raydi.

Siljitilgan-kelajak tekshiruvi: haqiqiy isbot

Seriyaning 60 foizidagi tik kesim: o'ng tomondagi hamma narsa ko'paytirilgan va silkitilgan, chap tomondagi hamma narsa bit-baytiga o'zgarmas holda muzlatilgan

Kelajakka qarashning ta'rifi operatsion, shuning uchun uni operatsion tarzda sinab ko'ring. Kelajakka qarash — o'tmishdagi qaror kelajak ma'lumotlariga bog'liq degani. Uning teskarisi siz o'tkaza oladigan test: agar siz kelajakni o'zgartirsangiz va biror o'tmish qarori siljisa, demak o'tmish kelajakni o'qigan edi. Shuning uchun kelajakni — shafqatsizlarcha — o'zgartiring va o'tmishni kuzating.

Seriyaning 60% ida kesim nuqtasi j ni tanlang (86,400 dan 51,840-chi bar). j dan boshlab har bir barni buzing: barcha kelajakdagi yopilish va ochilish narxlarini 1.05 ga ko'paytiring. Buzilgan ma'lumotlar bo'yicha uchta vaqt oralig'ining barchasi uchun butun signal to'plamini qayta hisoblang. So'ngra j dan qat'iy oldingi hamma narsa buzilmagan ishga tushirishga bit-baytiga bir xil ekanini tasdiqlang:

j = int(n * 0.6)                       # bar 51,840
cl2 = cl.copy(); cl2[j:] *= 1.05       # shove the future up 5%
op2 = op.copy(); op2[j:] *= 1.05

base = [precompute_tf_signals(cl,  ts, p, L) for (p, L) in tf_params]
pert = [precompute_tf_signals(cl2, ts, p, L) for (p, L) in tf_params]

for s0, s1 in zip(base, pert):
    assert eq_nan(s0.hma[:j],  s1.hma[:j])      # HMA identical, NaNs included
    assert eq_nan(s0.hma3[:j], s1.hma3[:j])
    assert np.array_equal(s0.cross[:j], s1.cross[:j])   # every cross event
    assert np.array_equal(s0.sep[:j],   s1.sep[:j])     # every separation

"Yaqin" emas. "Aniqlik chegarasida" emas. np.array_equal, NaN lar NaN lar bilan mos kelishi talab qilinadi — 51,840 ta o'tmish barning har bir HMA qiymati, har bir HMA3 qiymati, har bir kesishuv bayrog'i va har bir ajratish bir xil suzuvchi son bo'lishi kerak. So'ngra savdolarga xuddi shunday tasdiq qo'llaniladi: chiqishi j dan oldin bo'lgan har bir savdo maydon-maydon bo'yicha o'zgarmagan bo'lishi kerak. Agar kelajakka 5% turtki bitta o'tmish HMA sini o'n ikkinchi o'nlik xonada siljitsa, demak o'tmish qarori kelajak bilan maslahatlashgan, va tekshiruv muvaffaqiyatsiz bo'ladi.

Bizning dvigatelimiz buni o'tadi — barcha uchta vaqt oralig'i uchun, va qo'sh hamda uchlik savdo simulyatsiyalari uchun ham. 34,560 ta kelajakdagi barni buzish 51,840 ta o'tmish barni va ular orasida yopilgan har bir savdoni aynan avvalgidek qoldiradi. Bu amalga oshirishlar orasidagi kelishuv emas — bu vaqtdagi axborot chegarasi saqlanishining to'g'ridan-to'g'ri isbotidir.

Muvaffaqiyatsiz bo'la olmaydigan test hech narsani isbotlamaydi

Yuqoridagi tekshiruvdan o'tishning bir yo'li bor, u umuman hech narsani isbotlamaydi: agar buzish hech narsa qilmaydigan amal bo'lsa — agar kelajakni 1.05 ga ko'paytirish hech qayerda hech narsani o'zgartirmasa — u holda "o'tmish o'zgarmagan" degan gap avtomatik ravishda to'g'ri bo'ladi va butunlay foydasiz bo'ladi. Muvaffaqiyatsiz bo'la olmaydigan testdagi yashil belgi testsizlikdan ham yomonroq, chunki u soxta ishonch yaratadi. Shuning uchun tekshiruvda unga tish beradigan yana ikkita tasdiq bor.

Kelajak haqiqatan ham o'zgarishi kerak. Biz buzishning [j, n) oralig'ida biron joyda kesishuvlarni haqiqatan o'zgartirganini tasdiqlaymiz:

assert not np.array_equal(s0.cross[j:], s1.cross[j:])   # probe has teeth

Endi natija ma'noli bo'ladi: kelajakni qayta yozgan xuddi shu 5% turtki o'tmishni bit-baytiga o'zgarmas holda qoldirdi. Buzish haqiqiy, u oldinga tarqaladi va j da to'liq to'xtaydi. Bir tomonlama sizib chiqish — o'tmish kelajakni o'qiydi — j orqali orqaga sizib chiqar edi; bu unday emas.

Chegara aynan joriy barda — bir erta emas, bir kech emas. Nozikroq muvaffaqiyatsizlik sabab-oqibatli, ammo eskirgan dvigatel bo'lishi mumkin edi: u joriy barning joriy yopilish narxini e'tiborsiz qoldirib, bir bar kech reaksiya beradi (sizib chiqish yo'q, ammo jonli savdoda bo'lmaydigan kechikish), yoki bir bar erta reaksiya beradi (bir-barlik sizib chiqish). Shuning uchun biz yagona j barini buzamiz (1.02 ga) va ikki narsani bir vaqtda tasdiqlaymiz: o'tmish [0, j) tegilmagan, va hma[j] darhol reaksiya beradi.

cl3 = cl.copy(); cl3[j] *= 1.02        # nudge exactly one bar
s3 = precompute_tf_signals(cl3, ts, p_ltf, L_ltf)
assert eq_nan(s0.hma[:j], s3.hma[:j])  # nothing before j moves
assert s0.hma[j] != s3.hma[j]          # bar j reacts on the same bar

Bu chegarani aniq belgilaydi. Shakllanayotgan shamning joriy yopilish narxi indikatorga j barida nol kechikish va nol oldindan bilish bilan kiradi: j bari o'z yopilish narxini zudlik bilan ko'radi, undan oldingi bar esa uni umuman ko'rmaydi. Bu — yopiq-bar semantikasi turishi kerak bo'lgan aynan o'sha pichoq tig'i, va test dvigatelning o'sha yerda turganini tasdiqlaydi.

Mana to'liq darvoza — ushbu dvigatel va soxtalashtirilgan bektest orasida turgan barcha 25 ta tekshiruv:

Guruh Har bir tekshiruv nimani tasdiqlaydi Soni
Indikatorlar va kesishuvlar (×3 vaqt oralig'i) kesishuv hodisalari RunningCandleBuffer ga qarshi aniq; kesishuvlardagi ajratish; HMA/HMA3 qiymatlari (rtol 1e-9) 9
Savdolar (qo'sh + uchlik) savdo soni; maydon-maydon bo'yicha bir xil; umumiy PnL 1e-12 gacha; pozitsiyadagi faol vaqt 8
Siljitilgan-kelajak tekshiruvi (qo'sh + uchlik) o'tmish signallari bit-baytiga o'zgarmagan; tekshiruvning tishi bor (kelajak haqiqatan o'zgardi); j dan oldingi savdolar o'zgarmagan; bir-barlik buzish lokallashtirilgan 8
Jami 25

Birinchi ikki guruh tezkor dvigatelning jonli ma'lumotnoma ekanini belgilaydi. Uchinchisi ma'lumotnomaning sabab-oqibatli ekanini belgilaydi. Sizga uchalasi ham kerak: sizib chiqadigan tezkor dvigatel, sabab-oqibatli bo'lgan sizib chiquvchi dvigatel va kechikadigan sabab-oqibatli dvigatel — uch xil muvaffaqiyatsizlik, va darvoza har birini istisno qiladi.

Nega tekshiruv vaqt oralig'idan mustaqil

Siljitilgan-kelajak tekshiruvining nafisligi shundaki, u sizib chiqish qayerda joylashishini bilmaydi va e'tiborga olmaydi. U hech qachon vaqt oralig'larini, qayta namunalashni yoki sham chegaralarini tilga olmaydi. U faqat: kelajakni buzish o'tmishni siljitadimi deb so'raydi. Bu uni bajarilishni-siljitish testi o'tkazib yuboradigan multi-TF sizib chiqishi uchun aynan to'g'ri vosita qiladi.

Soddadil butun-seriyani-qayta-namunalash xatosini to'g'ridan-to'g'ri ko'rib chiqaylik. Agar 1 soatlik oqim butun seriyani oldindan qayta namunalash orqali qurilgan bo'lsa, j-1000 barida (soat ichida, j dan keyin yopiladigan) o'qiladigan "1 soatlik yopilish narxi" j da va undan keyingi barlarga bog'liq bo'lgan yakuniy yopilish narxiga ega shamning yakuniy yopilish narxi bo'lar edi. Kelajakni 1.05 ga ko'paytiring, va o'sha yakuniy yopilish narxi o'zgaradi — shunda j-1000 dagi HTF indikatori o'zgaradi, j-1000 dagi chegara o'zgaradi va o'tmish qarori siljiydi. Tekshiruv HTF oqimida darhol, kesimdan ming qadam oldingi barda yonadi.

Bizning dvigatelimizning HTF oqimi siljimaydi, chunki j-1000 da shakllanayotgan sham faqat base_close[j-1000] — o'tmishdagi yopilish narxini — beradi, va shamning yakuniy yopilish narxi chegara o'tmaguncha umuman ko'rib chiqilmaydi. Tekshiruv mexanizmga ko'r, ammo baribir xatoni ushlaydi, bu esa haqiqiy isbotdan kutiladigan aynan narsa: u amalga oshirishni (qayta namunalashni to'g'ri indekslaganmizmi?) tekshirish o'rniga xatti-harakatni (hech qanday o'tmish qarori kelajak ma'lumotlariga bog'liq emas) cheklaydi. Xatti-harakat savdo qiladigan narsa; amalga oshirish esa siz uning mos kelishiga umid qiladigan narsa.

Bektest va jonli bot bitta haqiqatni baham ko'radi

RunningCandleBuffer deb nomlangan yagona ustunni baham ko'ruvchi ikkita panel: bir tomonda bektest qidiruvi, ikkinchi tomonda jonli bot, ikkalasi ham bir xil yadroga ulangan

Bu odatiy bektest auditidan ko'ra muhimroq bo'lishining yana bir sababi bor. Dvigatel unga qarshi isbotlangan ma'lumotnoma — RunningCandleBuffer — bektestni yaxshi ko'rsatish uchun yozilgan test uskunasi emas. Bu ishlab chiqarishda ishlaydigan tik simulyatoridan so'zma-so'z olingan jonli botning o'z sham mantig'i. Tekshiruv tasdiqlaydigan yopiq-bar qoidasi — jonli bot bar-bar bo'yicha bajaradigan qoidadir.

Shuning uchun paritet darvozasi ikki vazifani bajaradi. U tezkor dvigatelning ma'lumotnomaga mos kelishini isbotlaydi, va ma'lumotnoma jonli yadro bo'lgani uchun, u tezkor dvigatelning jonli botga mos kelishini isbotlaydi. Oldingi maqola sizib chiqish bektest-jonli paritet farqining eng aniq izohi ekanligini ogohlantirgan edi — jonli bot siz mexanik tarzda oldindan qarab bo'lmaydigan yagona joy, shuning uchun oldindan qaraydigan bektest jonli bo'lgan zahoti farqlanadi. Bu yerda bu farq tuzilish bo'yicha yopiladi: bektest va bot bitta sham buferini, bitta kesishuv qoidasini, "i barida ma'lum" degan bitta ta'rifni baham ko'radi. Qidiruv optimallashtiradigan raqam — bot haqiqatan savdo qila oladigan raqamdir.

Bu — kelajakka qarash yo'qligini taxmin qilish o'rniga isbotlashning butun mohiyati. Multi-TF qidiruvi minglab konfiguratsiyalarni ishga tushiradi; agar dvigatel sizib chiqqan bo'lsa, qidiruv sizib chiqishdan eng agressiv foydalanadigan konfiguratsiyani topib, sizga soxta g'olibni taqdim etar edi — bu taksonomiya sof shovqindan 15 Sharp koeffitsientida o'lchagan muvaffaqiyatsizlik rejimi. Tekshiruv esa kapitalga ulanishdan oldin g'olibning haqiqiy ekaniga ishonch hosil qilishga imkon beradigan narsadir.

Tekshiruv nimani isbotlaydi va nimani isbotlamaydi

Test haqidagi qat'iylik ikki tomonga ham tegishli, shuning uchun uning qamrovi haqida aniq bo'ling. Siljitilgan-kelajak tekshiruvi yagona, aniq xususiyatni isbotlaydi: ushbu ma'lumotlarda, j barida yoki undan oldin hech qanday signal yoki savdo qarori j dan keyingi biron barga bog'liq emas — vaqtdagi axborot chegarasi indikator, kesishuv va savdo yo'li orqali saqlanadi. Bu aynan biz yo'qotmoqchi bo'lgan multi-TF sizib chiqishi, va bu kodni ko'rib chiqish orqali aniqlab bo'lmaydigan xususiyatdir.

U strategiyaning ustunligi borligini isbotlamaydi. Mukammal darajada sabab-oqibatli dvigatel halol tarzda pul yo'qotishi mumkin, va tekshiruv bu haqda jim — shunday bo'lishi kerak ham; sizib chiqish yo'qligini isbotlash va haqiqiy ustunlikni topish alohida vazifalar, va ularni aralashtirish sizib chiqqan bektestlarning qanday joylashtirilishining sababidir. U vaqtga bog'liq bo'lmagan bias larni qamrab olmaydi: vositadagi omon qolish biasi, dvigatel yaxshi ko'ringandan keyingina tekshiruvni ishga tushirishdan kelib chiqadigan tanlov biasi, yoki juda yumshoq komissiya modeli. Va u o'z-o'zidan jonli bajarilishlarning bektest bajarilishlariga mos kelishini isbotlamaydi — sirpanish va kechikish tekshiruv ko'ra olmaydigan haqiqiy farqlardir, chunki u bajarilish maydonida emas, qaror yo'lida ishlaydi. Shu farqni yopadigan narsa — dvigatelning sham yadrosi jonli botning yadrosi bilan bit darajasida bir xil ekanligining alohida haqiqatidir.

Tekshiruvning o'z tuzilishi haqida bir halol eslatma: u yagona j da kesiladi (seriyaning 60% i). U tekshiradigan xususiyat j bo'yicha bir xil — 51,840-bar da alohida hech narsa yo'q — shuning uchun bitta kesim tuzilmaviy xususiyatning adolatli testi, ammo shubhali versiya j ni butun seriya bo'yicha sipqarib chiqar edi. Biz bitta yaxshi tanlangan kesim va bir-barlik lokalizatsiya tekshiruvini yetarli deb hisoblaymiz, chunki 34,560-barlik kelajak buzilishidan yashiringan, ammo boshqa bir kesimda paydo bo'ladigan sizib chiqish juda g'alati xato bo'lishi kerak edi. Masala — dalillarning chegarasini bilish, bitta testni universal kvantor sifatida tasavvur qilish emas.

Asosiy xulosalar

  1. Ko'p vaqt oralig'idagi strategiyalar bajarilish orqali emas, shakllanayotgan bar orqali sizib chiqadi. Tugallanmagan HTF davri ichidagi qaror faqat o'sha shamning joriy yopilish narxidan (eng so'nggi asosiy yopilish narxidan) foydalanishi kerak, hech qachon uning yakuniy yopilish narxidan emas. Butun-seriyani-qayta-namunalash bektestlari davr ichidagi har bir qarorni butun HTF davrigacha bo'lgan kelajakka topshiradi.
  2. Bir-bar siljitish testi bu sizib chiqishga yetib bormaydi. U bajarilishdagi kelajakka qarashni ushlaydi; multi-TF sizib chiqishi indikatorning qanday qurilganida yashiringan. Sizga boshqacha tekshiruv kerak.
  3. Jonli qoidani aynan takrorlang, so'ngra uni isbotlang. Biz botning RunningCandleBuffer yopiq-bar semantikasini vektorlashtirilgan dvigatel sifatida qayta qurdik va uni 25 ta tekshiruv orqasiga qo'ydik: ma'lumotnomaga qarshi aniq kesishuvlar (408 / 2,792 / 3,691), maydon-maydon bo'yicha bir xil savdolar (466 qo'sh, 211 uchlik), PnL 1e-12 gacha.
  4. Paritet zarur, ammo yetarli emas. Ma'lumotnomaga mos kelish siz bir xil ekaningizni isbotlaydi, sabab-oqibatli ekaningizni emas. Sadoqat bilan takrorlangan sizib chiqqan ma'lumotnoma baribir sizib chiqadi.
  5. Siljitilgan-kelajak tekshiruvi — haqiqiy isbotdir. j da yoki undan keyin har bir barni buzing; j dan oldingi har bir signal va savdoning bit-baytiga o'zgarmaganini tasdiqlang. Agar kelajak o'tmishni siljita olsa, sizda kelajakka qarash mavjud.
  6. Tekshiruvga tish bering. Kelajakning haqiqatan o'zgarganini (buzish hech narsa qilmaydigan amal emas) va bir-barlik turtki xuddi shu barda reaksiya berishini (sizib chiqish yo'q, kechikish yo'q) tasdiqlang. Muvaffaqiyatsiz bo'la olmaydigan test hech narsani isbotlamaydi.
  7. Bektest va jonli bot bitta yadroni baham ko'rganda, isbot ko'chadi. Dvigatel jonli botning sham mantig'i bilan bit darajasida bir xil bo'lgani uchun, kelajakka qarash yo'qligi jonli tizimning ham xususiyati hisoblanadi — va bektest-jonli paritet farqi tuzilish bo'yicha yopiladi.

Oldingi maqola bir qatorli sizib chiqish qanday qilib 15 Sharp koeffitsientini soxta ravishda yaratishini ko'rsatdi. Bu maqola qarama-qarshi intizomni ko'rsatadi: "sizib chiqishlar sizni qanday aldaydi" emas, balki aniq dvigatelning sizib chiqmasligini haqiqiy ma'lumotlar asosida, mexanik tarzda qanday isbotlash kerakligini. Kelajakni buzing. Agar o'tmish qalt etmasa, demak siz hozirgi zamonda savdo qilyapsiz.

blog.disclaimer

Authors

Eugen Soloviov
Eugen Soloviov

Trading-systems engineer

Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.

Newsletter

Bozordan bir qadam oldinda bo'ling

Sun'iy intellekt savdo tahlillari, bozor tahlili va platforma yangiliklari uchun bizning xabarnomaga obuna bo'ling.

Biz sizning maxfiyligingizni hurmat qilamiz. Istalgan vaqtda obunadan chiqishingiz mumkin.