यह रहा एक बार। Binance USDⓈ-M पर्पेचुअल, BTCUSDT, 13:46:00 UTC से शुरू होने वाला मिनट। यह klines एंडपॉइंट से बारह वैल्यूज़ के एक सादे ऐरे के रूप में आया, और यह रिटेल-और-उससे जुड़े क्वांट रिसर्च में इनपुट की सबसे आम इकाई है। हम जो लगभग हर स्ट्रैटेजी जनरेट करते हैं, वह किसी न किसी रूप में इसी जैसी किसी चीज़ को छूती है।
तो चलिए इसे इंडेक्स-दर-इंडेक्स खोलते हैं, और देखते हैं कि बैकटेस्ट इसमें से कितना गलत समझता है।
| इंडेक्स | वैल्यू | नाम |
|---|---|---|
| 0 | 1773495960000 | ओपन टाइम (ms) |
| 1 | "84120.50" | ओपन |
| 2 | "84177.90" | हाई |
| 3 | "84098.10" | लो |
| 4 | "84163.40" | क्लोज़ |
| 5 | "38.417" | बेस वॉल्यूम (BTC) |
| 6 | 1773496019999 | क्लोज़ टाइम (ms) |
| 7 | "3232108.94" | कोट वॉल्यूम (USDT) |
| 8 | 1204 | ट्रेड्स की संख्या |
| 9 | "21.883" | टेकर बाय बेस वॉल्यूम |
| 10 | "1841203.55" | टेकर बाय कोट वॉल्यूम |
| 11 | "0" | इग्नोर |
[0] और [6]: यह कौन सा मिनट है, और यह किस घड़ी के अनुसार है
ओपन टाइम 1773495960000, क्लोज़ टाइम 1773496019999। दूसरे पर ध्यान दें: यह 19999 पर खत्म होता है, अगले बार के ओपन से ठीक एक मिलीसेकंड पहले। यह विंडो हाफ-ओपन है, और एक्सचेंज आपको यह साफ़ तौर पर बता रहा है। जिन डेटा बग्स का मैंने पीछा किया है, उनमें से आधे तब शुरू हुए जब किसी ने दोनों एंडपॉइंट्स को इंक्लूसिव मानकर बाउंड्री पर किसी ट्रेड को दोबारा गिन लिया, या रीसैंपल को इस तरह अलाइन किया कि हर 5-मिनट का बार अपने पड़ोसी से एक मिलीसेकंड उधार ले बैठा।
ये टाइमस्टैम्प एक्सचेंज के मैचिंग-इंजन टाइम हैं। न आपकी घड़ी, न आपके वेंडर की इंजेशन घड़ी, और न वह घड़ी जो फंडिंग स्नैपशॉट इस्तेमाल करता है। जब आप किसी klines सीरीज़ को किसी अलग एंडपॉइंट से खींची गई फंडिंग-रेट सीरीज़ या ओपन-इंटरेस्ट सीरीज़ के साथ जॉइन करते हैं, तो आप ऐसे सोर्सेज़ को जॉइन कर रहे होते हैं जो ज़्यादातर समय लगभग एक सेकंड के भीतर आपस में मेल खाते हैं। 1-मिनट की स्ट्रैटेजी के लिए यह हर जॉइन की गई रो पर 1.7% की टाइमिंग एरर है। सब-मिनट किसी भी चीज़ के लिए यह घातक है।
और यह बार अपने ओपन पर स्टैम्प किया गया है। इसमें मौजूद जानकारी 13:46:59.999 तक जानी ही नहीं जा सकती। इंडेक्सिंग कन्वेंशन का हर सवाल — क्या मैं एक से शिफ्ट करूँ, क्या मैं अपने इवेंट टाइम के रूप में बार-क्लोज़ या बार-ओपन टाइमस्टैम्प इस्तेमाल करूँ — असल में वही लुकअहेड सवाल है, बस भेस बदलकर।
[1] "84120.50": वह ओपन जिस पर आप ट्रेड नहीं कर सकते
ओपन उस पहले ट्रेड की कीमत है जो विंडो के अंदर प्रिंट हुआ। यह दो अन्य लोगों के बीच हो चुका एक पूरा ट्रांज़ैक्शन है। जब तक यह बार आपके डेटाफ्रेम में एक रो के रूप में मौजूद होता है, तब तक वह कीमत साठ सेकंड पुरानी हो चुकी होती है।
पिछला बार 84109.80 पर बंद हुआ था, तो दो आसन्न 1-मिनट बार्स के बीच के गैप में $10.70 का प्राइस मूवमेंट बैठा है। यह 1.3 बेसिस पॉइंट्स है, चार्ट पर अदृश्य, और लगभग टेकर फीस का एक चौथाई। ठीक है। लेकिन किसी US CPI प्रिंट के दौरान किसी ऑल्ट पर्प पर वही सीरीज़ देखिए और वे इंटर-बार गैप्स 15 से 40 bps तक चले जाते हैं। जो बैकटेस्ट बार-क्लोज़ पर सिग्नल देता है और अगले बार के ओपन पर फिल करता है, वह चुपचाप यह मान लेता है कि गैप शून्य है, और यह ठीक तभी शून्य होता है जब इससे कोई फर्क नहीं पड़ता।
[2] और [3]: "84177.90" हाई, "84098.10" लो
यहीं पर ज़्यादातर फिल इंजन दम तोड़ देते हैं, इसलिए यह सेक्शन सबसे लंबा है।
हाई और लो चरम छुई गई कीमतें हैं। इनमें न कोई साइज़ है, न कोई अवधि। इसी मिनट के कच्चे ट्रेड टेप से पता चलता है कि 84100.00 पर या उससे नीचे सिर्फ़ 0.62 BTC ट्रेड हुआ, वह भी 1.4-सेकंड की विंडो में नौ प्रिंट्स में। तो 84100 पर एक बैकटेस्ट स्टॉप "फिल" हो जाता है — और अगर आपकी पोज़िशन 3 BTC की है, तो आपने नीचे जाते वक्त पूरी दिखने वाली बुक खा ली और बाकी साइज़ कहीं 84105–84130 के वॉक-बैक में पूरा हुआ। बार कहता है कि लो 84098.10 था। बार यह नहीं बताता कि वहाँ सिर्फ़ $52,000 का नोशनल ट्रेड हुआ।
दूसरी दिशा और भी बुरी है, क्योंकि यह आपको बहला देती है। मान लीजिए आपके पास 84175 पर एक रेस्टिंग लिमिट सेल थी। बार की हाई 84177.90 है, तो एक भोला-भाला इंजन आपको 84175 पर फिल कर देता है और टेकर कॉस्ट की बजाय मेकर रिबेट बुक कर लेता है। क्या वह फिल वाकई हुआ, यह उस प्राइस लेवल पर क्यू पोज़िशन पर निर्भर करता है, जिसे बार नहीं जान सकता और जिसे आपने शायद कभी रिकॉर्ड ही नहीं किया। छू जाना, फिल होना नहीं है।
हमारे फिल इंजन में हमने जो नियम तय किया वह यह है: एक रेस्टिंग लिमिट तभी फिल होती है जब बार उस लेवल तक सिर्फ़ पहुँचे नहीं बल्कि उसके आर-पार ट्रेड करे। बिल्कुल एक्ट्रीम टिक पर होने वाले फिल्स के लिए ट्रेड टेप से वॉल्यूम-एट-प्राइस सबूत ज़रूरी है, वरना उन्हें रिजेक्ट कर दिया जाता है। इससे एक सामान्य मीन-रिवर्ज़न बुक से लगभग 6% ट्रेड्स हट गए और एक कैंडिडेट का बैकटेस्टेड Sharpe 1.9 से घटकर 1.1 रह गया। वह कैंडिडेट कभी असली था ही नहीं; फिल नियम बस इतना ईमानदार पहली चीज़ थी जिसने यह बात कह दी।
एक जुड़ा हुआ जाल है: इंट्राबार पाथ। अगर किसी बार की रेंज में आपका स्टॉप और आपका टेक-प्रॉफिट दोनों आ जाते हैं, तो OHLCV आपको यह नहीं बता सकता कि पहले कौन-सा हुआ। हर इंजन को एक कन्वेंशन चुनना पड़ता है। हमारा इंजन हमेशा स्टॉप-फर्स्ट मानता है, जो निराशावादी है और कभी-कभी गलत भी, लेकिन यह कभी भी नकली जीत पैदा नहीं करता। अगर आपका इंजन टेक-प्रॉफिट-फर्स्ट मानता है, तो चौड़ी-रेंज वाले बार्स अस्पष्टता से मुनाफ़ा गढ़ लेंगे, और चौड़ी-रेंज वाले बार्स ही वे होते हैं जो आपके PnL डिस्ट्रिब्यूशन पर हावी रहते हैं।
[4] "84163.40": बार में सबसे कम भरोसेमंद नंबर
क्लोज़ विंडो का आखिरी प्रिंट है। बस इतना ही। यह 13:46:59.8 पर किसी बॉट द्वारा अपनी पोज़िशन राउंड ऑफ करते हुए किए गए 0.002 BTC के ऑड-लॉट ट्रेड जितना भी हो सकता है। यही एक अकेला, संरचनात्मक रूप से मनमाना टिक है जिसे ज़्यादातर रिसर्च पाइपलाइन हर सिग्नल कैलकुलेट करने, हर पोज़िशन मार्क करने, और हर एग्ज़िट का मूल्यांकन करने के लिए इस्तेमाल करती हैं।
BTC पर्प्स पर इससे मुश्किल से कोई फर्क पड़ता है; लेकिन 04:00 UTC पर किसी पतले ऑल्टकॉइन पर्प पर यह बहुत मायने रखता है, और उसी मिनट के लिए दो वेन्यूज़ के क्लोज़ के बीच का अंतर आपके पूरे पर-ट्रेड एज से भी ज़्यादा हो सकता है। जब किसी स्ट्रैटेजी का PnL खासतौर से क्लोज़ पर निर्भर करता है, तो हम उसे दोबारा एक्सचेंज मार्क प्राइस पर मार्क करके चलाते हैं, जो इंडेक्स-डिराइव्ड है और जिसे छेड़ना कहीं ज़्यादा मुश्किल है। अगर नतीजे अलग निकलते हैं, तो समझ लीजिए स्ट्रैटेजी उस आर्टिफैक्ट को ट्रेड कर रही थी।
[5] और [7]: "38.417" और "3232108.94", वॉल्यूम किस यूनिट में
बेस वॉल्यूम BTC में है; कोट वॉल्यूम USDT में। यहाँ दोनों मौजूद हैं, जो एक शिष्टाचार है जो सभी वेन्यूज़ नहीं दिखाते। इसकी परवाह करने की वजह है वेन्यूज़ के आर-पार एग्रीगेशन। कॉइन-मार्जिन्ड कॉन्ट्रैक्ट्स $100 नोशनल के कॉन्ट्रैक्ट्स में कोट होते हैं। कुछ इक्विटी फीड्स राउंड लॉट्स रिपोर्ट करते हैं। प्रेडिक्शन मार्केट वेन्यूज़ शेयर काउंट रिपोर्ट करते हैं, जहाँ एक शेयर डॉलर-डिनॉमिनेटेड बाइनरी क्लेम होता है। किसी मिक्स्ड यूनिवर्स में "वॉल्यूम" को एक ही नोशनल यूनिट में नॉर्मलाइज़ किए बिना जोड़ देना एक ऐसी लिक्विडिटी रैंकिंग बना देता है जो निरा बकवास है, और यह बकवास इतने स्थिर दिखने वाले तरीके से होगी कि रिव्यू में भी पकड़ में नहीं आएगी।
इंजेशन के समय हर चीज़ को कोट नोशनल में नॉर्मलाइज़ करें। रॉ फील्ड को भी स्टोर करें, लेकिन उसे कभी किसी स्ट्रैटेजी को देखने न दें।
[8] 1204: वह फील्ड जिसे आपका इम्पैक्ट मॉडल तय करना चाहिए
ट्रेड काउंट को बेस वॉल्यूम से भाग देने पर औसत प्रिंट 0.032 BTC, यानी लगभग $2,700 निकलता है। अगर आपकी कैंडिडेट स्ट्रैटेजी एक साथ $250,000 एंटर करना चाहती है, तो वह उस मिनट के सामान्य ट्रांज़ैक्शन के आकार से लगभग 92 गुना बड़ी मांग कर रही है। वह नंबर, न कि कोई सामान्य 5-bps स्लिपेज कॉन्स्टेंट, वह होना चाहिए जो आपके स्क्वायर-रूट इम्पैक्ट टर्म को तय करे। हम प्रति-बार पार्टिसिपेशन रेट को एक फर्स्ट-क्लास कॉलम के रूप में कैलकुलेट करते हैं, और उन स्ट्रैटेजीज़ को रिजेक्ट कर देते हैं जिनकी मीडियन एंट्री बार नोशनल के कुछ प्रतिशत से ज़्यादा होती है, क्योंकि उसके आगे जो कुछ भी है वह काल्पनिक है।
ट्रेड काउंट अजीब मिनटों को भी सस्ते में पकड़ लेता है। वॉल्यूम सामान्य, लेकिन ट्रेड काउंट गिरकर 11 रह गया? किसी ने ब्लॉक ट्रेड किया। वॉल्यूम सामान्य, लेकिन ट्रेड काउंट 9,000 पर? यह एक लिक्विडेशन कैस्केड है जो छोटे-छोटे टुकड़ों में चबाया जा रहा है।
[9] और [10]: "21.883", वह फील्ड जिसे सब फेंक देते हैं
टेकर बाय बेस वॉल्यूम। इस बार में 38.417 BTC में से 21.883 BTC बायर-इनिशिएटेड था, तो साइन्ड वॉल्यूम डेल्टा +5.349 BTC है और एग्रेसर स्प्लिट बायर्स की ओर 57/43 है। एक्सचेंज आपको ऑर्डर फ्लो इम्बैलेंस मुफ़्त में सौंप रहा है, एक ऐसी फील्ड में जिसे ज़्यादातर लोग कभी पढ़ते ही नहीं, क्योंकि pandas ने उनके लिए वह कॉलम नाम नहीं दिया।
मैं यह दावा नहीं कर रहा कि यह अकेले रिटर्न्स प्रेडिक्ट करता है; भोली डेल्टा स्ट्रैटेजीज़ फीस लेजर में दान देने के सबसे भरोसेमंद तरीकों में से हैं। लेकिन यह प्राइस से सचमुच एक अलग नाप है, यह उसी रिक्वेस्ट में उपलब्ध है जो आप पहले से कर रहे थे, और यह आपको उस रैली में फ़र्क करने देता है जो खरीदी गई थी बनाम उस रैली में जो इसलिए हुई क्योंकि सेलर्स पीछे हट गए। ये दोनों OHLC में एक जैसी दिखती हैं और दस मिनट बाद अलग व्यवहार करती हैं। हमारा रिसर्च एजेंट किसी ऐसी हाइपोथिसिस को, जो किसी ऐसे वेन्यू पर टेकर स्प्लिट को नज़रअंदाज़ करती है जो इसे पब्लिश करता है, सबूत मेज़ पर छोड़ देना मानता है।
[11] "0": इग्नोर — और वह सब कुछ जो यहाँ नहीं है
इंडेक्स 11 एक डिप्रिकेटेड फील्ड है, जो हमेशा शून्य रहता है। इससे ज़्यादा दिलचस्प उन चीज़ों की सूची है जो इस बार में नहीं हैं: न बिड, न आस्क, न स्प्रेड, न बुक डेप्थ, न फंडिंग रेट, न ओपन इंटरेस्ट, न लिक्विडेशन, न मार्क प्राइस, न इंडेक्स प्राइस। और सबसे अहम, यह जानने का कोई तरीका नहीं कि आपका ऑर्डर मेकर होता या टेकर, जो इस वेन्यू पर 0.045% चुकाने और 0.01% कमाने के बीच का फ़र्क है।
तो सिर्फ़ klines पर बना कोई भी फी मॉडल एक अनुमान है जो नंबर का लिबास पहने हुए है। हम इसे हल करते हैं हर स्ट्रैटेजी को पहले से अपनी एग्ज़िक्यूशन स्टाइल घोषित करने पर मजबूर करके, और फिर हर उस चीज़ पर टेकर चार्ज करके जो इसके उलट साबित नहीं कर सकती।
वह बार जो कभी दिखा ही नहीं
आखिरी टुकड़ा, और वह जो मेजर्स के बाहर सबसे ज़्यादा काटता है। जिस मिनट में शून्य ट्रेड होते हैं, उसमें कोई klines बनता ही नहीं। वेंडर्स और लाइब्रेरीज़ आमतौर पर इसे फॉरवर्ड-फिल कर देते हैं: open = high = low = close = पिछला क्लोज़, वॉल्यूम 0। आपका इंडिकेटर खुशी-खुशी कैलकुलेट कर लेता है। आपकी स्ट्रैटेजी को एक वैध रो दिखती है और वह उस मिनट पर सिग्नल जनरेट कर सकती है जिसमें दुनिया में किसी ने भी वह इंस्ट्रूमेंट ट्रेड नहीं किया।
हमने जो एक मिड-कैप पर्प इंजेस्ट किया था, उसमें बारह महीने की विंडो में 1-मिनट बार्स का 4.1% शून्य ट्रेड्स वाला था। उस सिंबल पर एक मीन-रिवर्ज़न कैंडिडेट अपनी 38% एंट्रीज़ सिंथेटिक बार्स पर रख रहा था, क्योंकि फ्लैट सिंथेटिक प्राइस, मूविंग एवरेज से डेविएशन नापने वाली किसी भी चीज़ के लिए किसी नशे से कम नहीं होतीं। यह बैकटेस्ट में शानदार दिखा। असल में यह डेटा के गैप्स को ट्रेड कर रहा था।
यही वजह है कि इंजेस्ट लेयर अब प्रति बार एक synthetic बूलियन साथ रखती है, जो हर रीसैंपल में आगे बढ़ता है, और वेरिफिकेशन गॉन्टलेट किसी भी ऐसी स्ट्रैटेजी को फेल कर देता है जिसके ट्रेड्स इस पर क्लस्टर करते हैं। सस्ता-सा कॉलम है। लेकिन इसने हमारे लिखे किसी भी इंडिकेटर से ज़्यादा कैंडिडेट्स को मार गिराया है।
बारह वैल्यूज़। इनमें से चार को अक्सर गलत समझा जाता है, दो को अक्सर फेंक दिया जाता है, और इनकी एक पूरी कैटेगरी रो में मौजूद ही नहीं होती और इंजन उसे खुद गढ़ लेता है। अपने अगले बैकटेस्ट से पहले, अपने स्टोर से एक रॉ बार निकालिए और हर फील्ड को ज़ोर से पढ़िए, यह देखते हुए कि आपका फिल लॉजिक उसके बारे में क्या मान लेता है। यह बीस मिनट की एक कसरत है, और मैंने आज तक किसी को यह करते देखा है जिसे कुछ न मिला हो — ऐसा हुआ ही नहीं।
← सभी पोस्ट