27 अगस्त 2026 · डेटा इंजीनियरिंग

आपका सिम्बल यूनिवर्स एक टाइम मशीन है: क्रिप्टो परपेचुअल बैकटेस्ट में सर्वाइवरशिप बायस

आपका सिम्बल यूनिवर्स एक टाइम मशीन है: क्रिप्टो परपेचुअल बैकटेस्ट में सर्वाइवरशिप बायस

आपने रविवार रात मुझे नोटबुक भेजी थी, और तब से वह मेरे दूसरे मॉनिटर पर खुली है। क्रॉस-सेक्शनल मोमेंटम, 30-दिन के डॉलर वॉल्यूम के हिसाब से शीर्ष 150 Binance USDⓈ-M परपेचुअल, साप्ताहिक रीबैलेंस, शीर्ष डेसाइल में लॉन्ग और निचले डेसाइल में शॉर्ट, 2021-01 से 2026-06 तक। Sharpe 2.31, अधिकतम ड्रॉडाउन 14.2%, और लागत मॉडल भी मुझे ईमानदार लगा: taker पर एंट्री, taker पर एग्ज़िट, हर अंतराल के हिसाब से जमा होती फंडिंग, और ऑर्डर बुक के मुकाबले आपकी पोज़िशन के आकार के अनुसार बढ़ता स्लिपेज टर्म। आपने कठिन हिस्से सही किए। फिर आपने पूछा कि छह हफ़्तों की पेपर ट्रेडिंग सपाट क्यों रही, और क्या एज घट गया।

एज घटा नहीं। वह बैकटेस्ट में था ही नहीं। सेल 4 देखिए:

info = requests.get(BASE + "/fapi/v1/exchangeInfo").json()
symbols = [s["symbol"] for s in info["symbols"]
           if s["status"] == "TRADING" and s["quoteAsset"] == "USDT"]

आपने जून 2026 में उस endpoint को कॉल किया और उसके जवाब से तय किया कि मार्च 2021 में क्या ट्रेड किया जा सकता था। उस सूची का हर सिम्बल जून 2026 तक बचा रहा था—यह तो तय ही था। पूरी गड़बड़ी यही है, और इसकी कीमत आपके बाकी लागत मॉडल से भी ज़्यादा है।

2.31 → 0.74Sharpe, सर्वाइवर सूची बनाम पॉइंट-इन-टाइम
~5 में 1आपके 2021 यूनिवर्स में से अब मौजूद नहीं है
380 KBरोज़ाना exchangeInfo स्नैपशॉट, gzip किया हुआ

endpoint आपको क्या नहीं बताएगा

exchangeInfo में कोई इतिहास नहीं है। कोई asOf पैरामीटर नहीं, कोई आर्काइव नहीं, कोई चेंजलॉग नहीं। यह अभी की तस्वीर है, और Binance ने कभी इससे ज़्यादा का वादा भी नहीं किया। जब कोई कॉन्ट्रैक्ट डीलिस्ट होता है, तो उसका रिकॉर्ड जवाब से मिटा दिया जाता है और API की नज़र में उसका टिकर अस्तित्वहीन हो जाता है। Binance ने 2019 से अब तक 600 से ज़्यादा USDⓈ-M परपेचुअल सूचीबद्ध किए हैं और सौ से भी ज़्यादा रिटायर किए हैं। BTS, COCOS, TOMO, RAY, FTT, SC—2021 के ऑल्ट-सीज़न कॉन्ट्रैक्ट्स की लंबी कतार, जिनका एक शानदार क्वार्टर रहा और फिर वे धीरे-धीरे सिमट गए, जब तक एक्सचेंज ने उन्हें हटा नहीं दिया।

सोचिए, 30-दिन की मोमेंटम स्क्रीन को कौन-से नाम पसंद आते हैं। BTC नहीं। उसे वह चीज़ पसंद आती है जो लिस्टिंग पंप और Twitter के चर्चे से अभी-अभी तीन गुना हुई हो। उन नामों और आखिरकार डीलिस्ट होने वाले नामों में भारी ओवरलैप है, और आपके यूनिवर्स फ़िल्टर ने वही ओवरलैप हटा दिया।

मैंने आपके रन को हमारे स्नैपशॉट आर्काइव के साथ दोबारा बनाया: पॉइंट-इन-टाइम यूनिवर्स, वही सिग्नल, वही लागतें। Sharpe 0.74 और ड्रॉडाउन 31% आया। अंतर का लगभग दो-पाँचवाँ हिस्सा उन डीलिस्टेड नामों का है जिन्हें रखने की आपको अनुमति ही नहीं थी। एक और चौथाई इसका उलटा मामला है—जो थोड़ा पेचीदा है, और मुझे लगता है आपको शायद उससे भी कम पसंद आएगा।

टाइम मशीन का दूसरा सिरा: वे सिम्बल जो अभी अस्तित्व में ही नहीं आए थे

आपका फ़ीचर 90-दिन का रिटर्न है। आपकी रोलिंग विंडो में min_periods=20 है, क्योंकि आपने सैंपल की पहली तिमाही को वार्मअप से उड़ने से रोकने के लिए इसे एक बार सेट किया और फिर दोबारा देखा ही नहीं। इसलिए 21 दिन पहले ऑनबोर्ड हुआ कॉन्ट्रैक्ट तीन हफ़्तों की लिस्टिंग-पश्चात कीमतों से मोमेंटम स्कोर पाता है, लिस्टिंग अच्छी रहने पर लगभग हर बार शीर्ष डेसाइल में रैंक करता है और आपकी बुक में आ जाता है।

उस हिस्से को शायद जायज़ ठहराया जा सकता है। यह हिस्सा नहीं: आपके डेटा प्रोवाइडर ने कुछ सिम्बलों के लिए परपेचुअल के अस्तित्व में आने से पहले का spot या index डेटा बैकफ़िल किया है, इसलिए कुछ कॉन्ट्रैक्ट्स का kline इतिहास उनके अपने onboardDate से भी पुराना है। इसे जाँचने में करीब एक मिनट लगेगा। अपनी प्राइस टेबल को ऑनबोर्ड तारीखों से जोड़ें और लिस्टिंग से पहले की पंक्तियाँ गिनें। आपके डेटा में 41 सिम्बल्स के प्री-लिस्टिंग बार हैं, और उनमें से एक ने 2023 की गर्मियों में इक्विटी कर्व को एक ही हफ़्ते में 6% का लाभ दिया—ऐसी पोज़िशन से जो उस कॉन्ट्रैक्ट में थी जो अगले नौ दिनों तक अस्तित्व में ही नहीं आता।

टिकर स्ट्रिंग कोई पहचानकर्ता नहीं है। यह वह लेबल है जिसे एक्सचेंज किराये पर देता है—कभी-कभी दो बार।

इससे नाम बदलने का मामला सामने आता है। MATICUSDT, POLUSDT बना। FTMUSDT, 1:1 रूपांतरण के बाद SUSDT बना। मई 2022 के LUNA मामले में LUNCUSDT बना और बाद में एक नया LUNAUSDT आया, जिसका टिकर रूट उस चीज़ से मिलता है जिसने लगभग सब कुछ खो दिया था। अगर आपका लोडर सिम्बल स्ट्रिंग को key बनाता है और मिली हुई फ़ाइलों को जोड़ देता है, तो वहाँ कम-से-कम एक ऐसी सीरीज़ है जिसमें ऐसा उछाल है जो कीमत का उतार-चढ़ाव नहीं है। आपका मोमेंटम फ़ीचर उस उछाल को पूरे क्रॉस-सेक्शन का सबसे मज़बूत सिग्नल समझेगा।

बाकी सब चीज़ें जो आपके नीचे बदलती रहती हैं

एक बार मान लें कि सिम्बल सूची समय के साथ बदलती है, तो यही बात उस जवाब के हर दूसरे फ़ील्ड पर भी लागू होती है। आप उन सभी के लिए आज की वैल्यू इस्तेमाल कर रहे हैं।

फ़ील्डयह कैसे बदलता हैक्या बिगड़ता है
statusTRADING → SETTLING → गायबसर्वाइवरशिप; ऐसे क्लोज़ भाव पर नकली एग्ज़िट जो कभी ट्रेड ही नहीं हुआ
onboardDateहर हफ़्ते नई लिस्टिंग; बंद हो चुके सिम्बलों के लिए अनुपलब्धअस्तित्व में आने से पहले कॉन्ट्रैक्ट ट्रेड करना
tickSize / stepSizeकीमत के स्तर बदलने पर दोबारा तय होते हैंऑर्डर राउंडिंग, और ऐसी लिमिट कीमतें जिन्हें अस्वीकार कर दिया जाता
minNotionalकम गहराई वाली बुक पर समय के साथ बढ़ाया गयाछोटी पोज़िशन लेग्स जिन्हें आपका लाइव राउटर अस्वीकार कर देता
fundingIntervalHoursसालों तक 8h, फिर कई सिम्बलों पर 4h या 1hठीक उन्हीं ऑल्ट्स पर कैरी 2–3× गलत, जिन्हें आपकी स्क्रीन रखती है
leverage bracketsटियर और मेंटेनेंस मार्जिन संशोधित हुएलिक्विडेशन मॉडलिंग और मार्जिन क्षमता

आपके मामले में फंडिंग वाली बात सबसे ज़्यादा नुकसान करती है। आपका एक्रूअल लूप पूरे इतिहास के लिए मानता है कि हर दिन तीन भुगतान होते थे। ऑल्ट बुक का अच्छा-खासा हिस्सा चार घंटे वाली फंडिंग पर चला गया, और ऊँची फंडिंग वाले नामों में शॉर्ट लेग्स से ही आपका काफ़ी सिम्युलेटेड PnL आता है। यहाँ आप राउंडिंग की छोटी-सी गलती से नहीं चूक रहे। गलती कई गुना बड़ी है।

डीलिस्टिंग खुद एक घटना है, और आप उसका मॉडल नहीं बना रहे

आपके पॉइंट-इन-टाइम दोबारा रन में मैंने रणनीति को उदार एग्ज़िट दिया। असल डीलिस्टिंग एक तय क्रम में होती है: घोषणा, आम तौर पर सात से चौदह दिन पहले; फिर केवल पोज़िशन घटाने की अवधि; और उसके बाद मार्क कीमत पर अनिवार्य सेटलमेंट। घोषणा सार्वजनिक जानकारी है और आप उस पर कार्रवाई कर सकते हैं, इसलिए ईमानदार सिम्युलेशन में घोषणा वाले दिन के क्लोज़ पर एग्ज़िट होना चाहिए। लेकिन किसी सामान्य ऑल्ट डीलिस्टिंग में वह क्लोज़ पहले के हफ़्ते से पहले ही 10-20% नीचे होता है, बुक में कम गहराई होती है, और आपके स्लिपेज टर्म को पता होना चाहिए कि वह अब अलग माहौल में काम कर रहा है। अगर आपका फ़िल इंजन बिना किसी प्रभाव के सेटलमेंट कीमत दे देता है, तो आपने चुपचाप मरती हुई परिसंपत्तियों को उचित मूल्य पर ट्रेड करने लायक बना दिया है।

अगर आपने exchangeInfo को कभी आर्काइव नहीं किया, तो भी आप फँसे नहीं हैं। सार्वजनिक डंप में data.binance.vision/data/futures/um/monthly/klines/ डीलिस्टेड सिम्बलों की डायरेक्टरीज़ तब तक रखता है जब तक API उन्हें भूल न जाए। डायरेक्टरी सूची निकालें; हर सिम्बल की पहली और आख़िरी मासिक फ़ाइल से लिस्टिंग और डीलिस्टिंग की एक उपयोगी समय-सीमा मिल जाती है, किसी वेंडर की ज़रूरत के बिना। यह रिकॉर्ड नहीं, पुनर्निर्माण है, और इससे tick sizes या funding intervals वापस नहीं मिलेंगे। लेकिन इससे पता चल जाएगा कि कौन कब मौजूद था—सोमवार को आपको जिस जानकारी की ज़रूरत है, उसका 80% यही है।

सिग्नल को फिर छूने से पहले मैं आपसे क्या बनवाता

  1. एक cron जो आपके शोध वाले हर एक्सचेंज से रोज़ाना exchangeInfo खींचे और तारीख़ के हिसाब से object storage में लिखे। gzip करने पर यह आधे मेगाबाइट से भी कम है। दस साल का खर्च S3 में राउंडिंग की छोटी-सी गलती होगा, और बदले में आपको ऐसी शोध क्षमता मिलेगी जिसे बाद में खरीदा नहीं जा सकता।
  2. उन स्नैपशॉट्स से बना एक asset master: (venue, symbol, valid_from, valid_to) के हर संयोजन के लिए एक पंक्ति, जिसमें सभी फ़ील्ड हों। लगातार स्नैपशॉट्स का अंतर निकालकर इसे बनाएँ, और किसी भी फ़ील्ड के बदलने को नई पंक्ति मानें।
  3. एक universe फ़ंक्शन जिसमें timestamp देना अनिवार्य हो। universe(ts), कभी universe() नहीं। डिफ़ॉल्ट को इस तरह असंभव बनाएँ कि कोई भी—यहाँ तक कि रात 1 बजे वाला आपका भविष्य का रूप भी—गलती से सर्वाइवर सूची न चुन सके।
  4. डेटा लोडर में प्री-लिस्टिंग assertion: कोई बार onboard_ts से एक दिन पहले मौजूद नहीं होना चाहिए। रन विफल करें, चेतावनी न दें।
  5. एक स्थिर आंतरिक instrument ID जो नाम बदलने पर भी बना रहे, और टिकर को सिर्फ़ एक एट्रिब्यूट बना दें। POL और MATIC को एक ही ID पर मैप करें, और नाममात्र के रूपांतरणों को फ़्लैग करें ताकि continuity logic उन्हें जोड़ने से मना कर सके।

ये सब करें और फिर से रन करें। मेरा अनुमान है कि नतीजा मेरे 0.74 के करीब आएगा, और दिलचस्प सवाल यह होगा कि मृत नामों को शामिल करने के बाद बचे 0.74 में पेपर ट्रेडिंग लायक कुछ है या नहीं। हो सकता है। परपेचुअल में क्रॉस-सेक्शनल मोमेंटम कुछ तो है, और यूनिवर्स ठीक करने के बाद जो बचता है, उसका एक हिस्सा शॉर्ट साइड से मिलने वाला असली कैरी है। आप यह भी पाएँगे कि आपके पेपर नतीजे और बैकटेस्ट आपस में मेल खाने लगेंगे, क्योंकि पेपर ट्रेडिंग हमेशा पॉइंट-इन-टाइम यूनिवर्स पर चलती रही है। उसके पास दूसरा विकल्प था ही नहीं।

P.S. यह क्रिप्टो की अजीब बात नहीं, बस यहाँ ज़्यादा साफ़ दिखती है। CRSP ने डीलिस्टिंग रिटर्न और दोबारा इस्तेमाल हुए टिकर भेजने शुरू किए, तब से इक्विटी शोधकर्ता इनसे जूझ रहे हैं। प्रेडिक्शन मार्केट्स में यह बात चरम पर पहुँच जाती है: हर कॉन्ट्रैक्ट की अवधि तय है और वह ख़त्म होता ही है, इसलिए पूरा यूनिवर्स लिस्टिंग और समाप्ति से बना है। अगर आप यह स्क्रीन कभी Kalshi पर ले जाएँ, तो पहले asset master बनाएँ। वहाँ इतिहास का कोई दूसरा रूप है ही नहीं।

सर्वाइवरशिप बायसपॉइंट-इन-टाइम डेटाक्रिप्टो फ्यूचर्सबैकटेस्टिंगडेटा इंजीनियरिंग
साझा करेंXLinkedInFacebookRedditHacker NewsWhatsAppTelegramEmail
← सभी पोस्ट