हमने ट्रेड के बीच में पेपर रणनीति रीस्टार्ट की और ऑर्डर का क्रम पहले से अलग पाया। बाज़ार का डेटा वही, रणनीति का संस्करण वही, खाते का बैलेंस वही। सिग्नल की गणना मेल खाती थी। लेकिन अपनी पोज़िशन और लंबित ऑर्डरों के बारे में रणनीति की याददाश्त मेल नहीं खाती थी।
एक दिन तक रीप्ले करके हमने इस अंतर का पता लगाया। काम की सीख सीधी थी: आपके सॉफ़्टवेयर के लिए रीस्टार्ट भी बाज़ार की एक घटना है। अगर आप यह नहीं परखते कि रणनीति अपनी स्थिति फिर से कैसे बनाती है, तो साफ़-सुथरा बैकटेस्ट उस पेपर सिस्टम की खामी छिपा सकता है जो भूल जाता है कि उसके पास क्या है।
09:10 — हमने एक साधारण पोज़िशन चुनी
परीक्षण रणनीति ने एक लिक्विड परपेचुअल में ट्रेड किया: जब छोटा मूविंग एवरेज बड़े मूविंग एवरेज से ऊपर जाता, तो लॉन्ग एंट्री; और क्रॉस उलटने पर एग्ज़िट। रीप्ले शुरू करते समय एक छोटी पोज़िशन पहले से खुली थी और उसे घटाने के लिए reduce-only लिमिट ऑर्डर लगा हुआ था। इससे रिकवरी को 2 बातें फिर से बनानी थीं: हमारे पास क्या था और हमने वेन्यू से पहले ही क्या करने को कहा था।
चेकपॉइंट पर खाते में 0.04 कॉन्ट्रैक्ट थे। 0.01 के लिए ऑर्डर खुला था। रणनीति की प्रक्रिया ने दोनों मान मेमोरी में कैश किए थे, लेकिन स्टार्टअप के दौरान उसने सिर्फ़ पोज़िशन हासिल की। उसने मान लिया कि कैश किया हुआ ऑर्डर अब नहीं है।
09:25 — पहला डुप्लिकेट ऑर्डर दिखा
रीस्टार्ट के बाद रणनीति ने मौजूदा लॉन्ग पोज़िशन देखी, सिग्नल लॉजिक चलाया और उसे घटाने के लिए एक और 0.01 का ऑर्डर भेज दिया। अब पेपर वेन्यू पर 2 ऑर्डर सक्रिय थे। अलग-अलग देखें तो दोनों में से कोई ऑर्डर गलत नहीं था। मगर दोनों भर जाते, तो इरादे से दोगुनी मात्रा बिक सकती थी।
शुरुआत में हमने सिग्नल लूप को दोष दिया। गड़बड़ी लूप में नहीं, अधूरे स्नैपशॉट में थी। रणनीति ने पूछा, “मेरी पोज़िशन क्या है?” लेकिन यह कभी नहीं पूछा, “कौन से ऑर्डर अब भी सक्रिय हैं?”
| रीस्टार्ट के बाद की स्थिति | प्रक्रिया के हिसाब से | खाते में मौजूद |
|---|---|---|
| पोज़िशन | लॉन्ग 0.04 | लॉन्ग 0.04 |
| पोज़िशन घटाने के खुले ऑर्डर | कोई नहीं | 0.01 के 2 ऑर्डर |
| एक ऑर्डर भरने के बाद तय एक्सपोज़र | लॉन्ग 0.03 | लॉन्ग 0.02 हो सकता है |
10:00 — हमने रिकवरी ठीक की, फिर समय से जुड़ी एक खामी मिली
हमने स्टार्टअप को बदलकर यह किया कि नए फैसले लेने से पहले वह खाते की पोज़िशनों और खुले ऑर्डरों से स्थिति फिर से बनाए। इससे डुप्लिकेट ऑर्डर नहीं आया। फिर हमने डिसकनेक्शन को कम व्यवस्थित बनाया: रणनीति ऑफ़लाइन थी तभी एक ऑर्डर भर गया, और री-कनेक्ट होने के बाद उसका फ़िल नोटिफ़िकेशन आया।
खाते के स्नैपशॉट में ऑर्डर का भरना पहले ही दर्ज था। फिर देर से आए नोटिफ़िकेशन ने स्थानीय पोज़िशन को दूसरी बार घटा दिया। कुछ सेकंड तक रणनीति को लगा कि उसके पास 0.02 कॉन्ट्रैक्ट हैं, जबकि खाते में 0.03 थे। उसका अगला रीबैलेंस एक काल्पनिक कमी पर आधारित था।
हमने मिलान के नियम जोड़े: खाते के स्नैपशॉट को शुरुआती स्थिति मानें, वहाँ पहले से दर्ज फ़िल को इवेंट आइडेंटिफ़ायर से पहचानकर अनदेखा करें, और शुरुआती सिंक पूरा होने तक ऑर्डर न भेजें। नोटिफ़िकेशन देर से या 2 बार आ सकता है। रिकवरी को दोनों स्थितियाँ संभालनी होंगी।
13:40 — रीप्ले में एक छिपा हुआ अंतर पकड़ में आया
हमने मूल रन और रीस्टार्ट किए गए रन में कीमतों का वही उतार-चढ़ाव फिर से चलाया। सिर्फ़ अंतिम P&L की तुलना करने पर समस्या नहीं दिखती: बाज़ार के पलटने के बाद दोनों संस्करणों में पोज़िशन एक जैसी थी। ऑर्डर इवेंट की तुलना से गड़बड़ी सामने आई।
हमने हर फैसले के साथ वह स्थिति लॉग की जिसे उसने पढ़ा था: पोज़िशन, खुले ऑर्डर, आख़िरी प्रोसेस किए गए फ़िल का आइडेंटिफ़ायर, सिग्नल वैल्यू और रणनीति का संस्करण। इससे पहले अलग हुए इवेंट की वजह पता चली। एक रन में सक्रिय ऑर्डर दिखा, दूसरे में सूची खाली थी। बाद में एक रन ने फ़िल को 2 बार लागू किया।
अंतिम बैलेंस का मेल खाना यह साबित नहीं करता कि व्यवहार भी मेल खाता था। फैसलों और ऑर्डरों के पूरे क्रम की तुलना करें, खासकर रिकवरी के दौरान।
16:20 — अगली बार हम क्या अलग करेंगे
खाते की स्थिति में बदलाव जाँचने से पहले हमने कीमतों का डेटा रीप्ले करने में बहुत समय लगा दिया। अगली बार हम पहले विफलता की स्थितियाँ डालेंगे और बाज़ार की चाल लगभग सपाट रखेंगे। इससे उतार-चढ़ाव के कारण निदान उलझे बिना सॉफ़्टवेयर की गलती साफ़ दिखेगी।
- पोज़िशन और आंशिक रूप से भरे ऑर्डर के साथ रीस्टार्ट करें।
- ऑर्डर भेजने के बाद डिसकनेक्ट करें, फिर फ़िल नोटिफ़िकेशन आने से पहले री-कनेक्ट करें।
- एक ही फ़िल इवेंट 2 बार भेजें और जाँचें कि उससे स्थिति सिर्फ़ 1 बार बदलती है।
- पोज़िशन और खुले ऑर्डर, दोनों का मिलान होने तक नए ऑर्डर रोकें।
- बिना रुकावट चले और रीस्टार्ट किए गए रन के फैसलों और ऑर्डरों के लॉग की तुलना करें।
हमने यह भी सीखा कि रिकवरी स्नैपशॉट को रणनीति के संस्करण और इवेंट लॉग के साथ सहेजना चाहिए। इससे सटीक री-कनेक्ट क्रम याद रखने के लिए किसी पर निर्भर रहने के बजाय, कुछ ही मिनटों में विफलता को फिर से दोहराया जा सका।
जो पेपर रणनीति सिर्फ़ तब सही काम करती है जब उसकी प्रक्रिया चलती रहे, उसने पूरा अभ्यास पास नहीं किया है। पोज़िशन के बीच में उसे रीस्टार्ट करें, फ़िल देर से आने दें और उसके बाद भेजे गए हर ऑर्डर की जाँच करें। मकसद यह साबित करना नहीं कि उसमें कभी गड़बड़ी नहीं होगी। मकसद यह है कि रिकवरी में क्या होता है, यह आपको पहले से दिखे, ताकि पेपर खाते को आपको वही सबक अचानक न सिखाना पड़े।
← सभी पोस्ट


