एक उपयोगी बैकटेस्ट जांच का बेहतर पैरामीटर खोजने से कोई लेना-देना नहीं है: प्रोसेस को बीच में रोकें, उसे रीस्टोर करें और वही रीप्ले पूरा करें। समान इनपुट और नियंत्रित एक्ज़ीक्यूशन सिम्युलेटर के साथ, उसके फैसले, ऑर्डर और इक्विटी बिना रुके चले रन से मेल खाने चाहिए।
अगर ऐसा नहीं होता, तो आपको स्टेट मैनेजमेंट की समस्या मिल गई है। स्ट्रैटेजी किसी ऐसी चीज़ पर निर्भर है जिसे आपने सेव नहीं किया या दोबारा बना नहीं सके। यह निर्भरता तब मायने रखती है जब रिसर्च रन फिर से शुरू किए जाते हैं, वर्कर बदले जाते हैं या पेपर ट्रेडिंग सर्विस में नया कोड डिप्लॉय होता है।
मुझे यह टेस्ट पसंद है, क्योंकि इसका अपेक्षित जवाब असामान्य रूप से साफ़ है। इस बात पर बहस नहीं कि मार्केट बदल गया था या नहीं। दोनों रन को वही मार्केट मिलता है।
रीस्टार्ट करने के 3 गलत तरीके ये हैं। संख्याएं उदाहरण के लिए हैं; ये गड़बड़ियां किसी अन्यथा नियतात्मक सिस्टम में भी हो सकती हैं।
1. कुछ बार फिर से लोड करें और इंडिकेटर को वार्म मान लें
मान लें कि स्ट्रैटेजी 100-अवधि की एक्सपोनेंशियल मूविंग एवरेज इस्तेमाल करती है। इसका अपडेट यह है:
alpha = 2 / 101
ema_next = alpha * close + (1 - alpha) * ema_previous
बिना रुका प्रोसेस जमा हुआ EMA आगे लेकर चलता है। रीस्टार्ट हुआ प्रोसेस 100 बार लाता है, पहले क्लोज़ को बीज बनाकर EMA शुरू करता है और मान लेता है कि 100-अवधि वाले इंडिकेटर के लिए 100 ऑब्ज़र्वेशन चाहिए।
यह मान्यता इंडिकेटर के स्मूदिंग पैरामीटर को सीमित मेमोरी विंडो समझने की भूल करती है। EMA अपनी शुरुआती स्थिति का घटता हुआ योगदान बनाए रखता है। अगर दो वर्ज़न की शुरुआत में EMA का अंतर 10 कीमत इकाई हो, तो बाद की समान कीमतें उस अंतर को इस तरह कम करती हैं:
| इनिशियलाइज़ेशन के बाद अपडेट | बाकी अंतर | शुरुआती त्रुटि का अंश |
|---|---|---|
| 100 | 1.353 | 13.53% |
| 250 | 0.0674 | 0.674% |
| 500 | 0.000454 | 0.00454% |
गणना 10 * (99 / 101)^k है। अगर पहला ऑब्ज़र्वेशन बीज का काम करता है, तो 100 बार लाने पर आपको सिर्फ़ 99 अपडेट मिलते हैं।
गड़बड़ी आम तौर पर फैसले की सीमा के पास दिखती है। एक रन में कीमत EMA से ऊपर दिखती है, दूसरे में नीचे। संख्याओं का छोटा-सा अंतर एक अतिरिक्त ट्रेड करा देता है। ऐसा होते ही कूलडाउन, उपलब्ध नकदी और बाद के फैसले भी अलग हो सकते हैं।
रिकर्सिव इंडिकेटर की स्थिति, उसका इनिशियलाइज़ेशन स्टेटस और आखिरी प्रोसेस किया गया इवेंट सेव करें। या फिर किसी ज्ञात शुरुआती स्थिति से रीप्ले करें। लंबा वार्म-अप स्वीकार्य अनुमान दे सकता है, लेकिन उसकी अवधि स्पष्ट त्रुटि-सहनशीलता के आधार पर चुनें और जांचें कि क्या वह सहनशीलता फैसले बदल सकती है। “अवधि का 5 गुना” एक परंपरा है, प्रमाण नहीं।
और पूरा इतिहास सिर्फ़ इंडिकेटर तक सीमित नहीं है। रोलिंग पर्सेंटाइल को अपनी विंडो चाहिए। ऑनलाइन मॉडल को ऑप्टिमाइज़र स्टेट की ज़रूरत हो सकती है। नुकसान के बाद 3 बार इंतज़ार करने वाले नियम को नुकसान और काउंटर याद रखना होगा।
2. पोज़िशन सेव करें और बीच में चल रहे ऑर्डर भूल जाएं
आपकी लक्ष्य पोज़िशन 10 इकाई है। 10 खरीदने का ऑर्डर 4 भर चुका है, और 6 अभी बाकी हैं। आप चेकपॉइंट में पोज़िशन 4 सेव करते हैं, रीस्टार्ट करते हैं और बाकी 6 के लिए एक और खरीद ऑर्डर भेजते हैं।
अगर मूल ऑर्डर का बचा हिस्सा और नया ऑर्डर, दोनों भर जाएं, तो आपके पास 16 इकाई होंगी।
बैकटेस्ट में इस बग का पता अक्सर नहीं चलता, क्योंकि फिल इंजन रीस्टार्ट होने पर चालू ऑर्डर चुपचाप मिट जाते हैं। पेपर ट्रेडिंग में सिम्युलेटर या बाहरी सर्विस उन्हें बनाए रख सकती है। तब वही रिकवरी कोड अलग एक्सपोज़र देता है, इस पर निर्भर कि कौन-सा हिस्सा बचा रहा।
| रीस्टार्ट के समय | वास्तविक स्थिति | सिर्फ़ पोज़िशन से रिकवरी में दिखता है |
|---|---|---|
| लक्ष्य पोज़िशन | 10 | 10 |
| भरी हुई पोज़िशन | 4 | 4 |
| बाकी खरीद मात्रा | 6 | 0 |
| अतिरिक्त ज़रूरी मात्रा | 0 | 6 |
गड़बड़ी के बाद रिकवरी होते ही ऑर्डर अचानक बढ़ जाते हैं, और उनकी कोई वजह समझ नहीं आती। कभी एक्सपोज़र दोगुना हो जाता है। कभी ऐसी पोज़िशन बंद हो जाती है जिसका सुरक्षा ऑर्डर अब भी चालू है; बाद में वही ऑर्डर एक नई पोज़िशन खोल सकता है।
चेकपॉइंट में पोज़िशन के साथ ऑर्डर की पहचान और उसके लाइफसाइकल की स्थिति भी होनी चाहिए। नए एक्शन बनाने से पहले रिकवरी को इन रिकॉर्ड का एक्ज़ीक्यूशन सिस्टम से मिलान करना होगा। जिस ऑर्डर का नतीजा पता न हो, उसकी जांच ज़रूरी है; “कोई पावती सेव नहीं हुई” को “ऑर्डर कभी भेजा ही नहीं गया” मानने से डुप्लिकेट ऑर्डर बनते हैं।
स्थिर क्लाइंट ऑर्डर ID से यह पता लगाने में मदद मिलती है कि क्या हुआ। वे डुप्लिकेट तभी रोकते हैं जब ऑर्डर पाने वाला सिस्टम ज़रूरी विशिष्टता या इडेम्पोटेंसी नियम सचमुच लागू करता हो। प्रोसेस किए गए एक्ज़ीक्यूशन ID भी सेव करें, ताकि दोबारा चलाया गया फिल पोज़िशन को दो बार न बढ़ाए।
मुझे उस साधारण-सी ऑर्डर-स्टेटस स्क्रीन से कुछ खास लगाव है। रीस्टार्ट वाले दिन उसकी छोटी-छोटी पंक्तियां अचानक पूरी इमारत का सबसे दिलचस्प इंटरफ़ेस बन जाती हैं।
3. पोज़िशन रीस्टोर करें और P&L का नया लेजर शुरू करें
बिना लीवरेज का स्पॉट उदाहरण लें, जिसमें कोई फीस नहीं है। शुरुआत $10,000 नकदी से करें, $100 पर 10 इकाई खरीदें और मार्क $110 पहुंचने पर चेकपॉइंट बनाएं।
सही स्थिति है $9,000 नकदी और $1,100 मूल्य की पोज़िशन: यानी $10,100 इक्विटी। अगर रिकवरी 10 इकाई तो रीस्टोर करे, लेकिन नकदी को मूल $10,000 पर रीसेट कर दे, तो यह $11,100 दिखाएगी। आपने प्रोसेस रीस्टार्ट करके $1,000 बना लिए।
कुछ और रूप कम नाटकीय होते हैं। रिकवरी इक्विटी तो जस की तस रखती है, लेकिन एंट्री कीमत को $110 पर रीसेट कर देती है। कुल इक्विटी सही रह सकती है, जबकि रियलाइज़्ड और अनरियलाइज़्ड का बंटवारा बदल जाता है। अगर स्टॉप या एग्ज़िट शर्त एंट्री कीमत पर निर्भर है, तो अकाउंटिंग का यह शॉर्टकट अब ट्रेडिंग व्यवहार बदल देता है।
या सिस्टम पिछली इक्विटी की ऊंचाई भूल जाता है। मान लें इक्विटी $10,600 तक पहुंची थी और फिर गिरकर $10,100 हो गई। इसका ड्रॉडाउन लगभग 4.72% है। रिकवरी के समय हाई-वॉटर मार्क रीसेट करें, तो स्ट्रैटेजी अचानक मानने लगती है कि ड्रॉडाउन शून्य है। ड्रॉडाउन पर आधारित हर जोखिम नियंत्रण अभी-अभी बिना अनुमति रीसेट हुआ है।
इसलिए गड़बड़ी इक्विटी में अचानक बदलाव, संदिग्ध रूप से बेहतर दिखता ड्रॉडाउन, या डिप्लॉयमेंट के बाद काम करना बंद कर देने वाला जोखिम नियम हो सकती है। लेजर और स्ट्रैटेजी की अकाउंटिंग पर निर्भर स्थिति सुरक्षित रखें: नकदी के लेनदेन, पोज़िशन, लागू लागत-आधार, जमा हुए शुल्क और जोखिम नियंत्रण की मेमोरी। रीस्टोर की गई इक्विटी का लेजर से उसी वैल्यूएशन समय पर मिलान करें।
चेकपॉइंट की सीमा एकसार होनी चाहिए। फिल के बाद नकदी सेव करना और उस फिल से पहले की पोज़िशन मात्रा सेव करना ऐसी स्थिति बनाता है जो कभी थी ही नहीं। संबंधित स्थिति को एक साथ कमिट करें, या इवेंट का टिकाऊ क्रम दर्ज करें जिससे इसे फिर बनाया जा सके। उसी स्थिति के साथ इवेंट कर्सर भी सेव करें, ताकि रिकवरी में फिल न छूटे और न दो बार लागू हो।
रिसर्च हार्नेस में मैं जो टेस्ट रखूंगा, उसमें पहले एक बिना रुका रेफरेंस रीप्ले चलेगा, फिर दूसरे रन को जान-बूझकर मुश्किल पलों पर रीस्टार्ट किया जाएगा: इंडिकेटर के इनिशियलाइज़ेशन के दौरान, आंशिक फिल के बाद और जोखिम सीमा सक्रिय रहते हुए। इवेंट का वही क्रम रखें और सिम्युलेटर की रैंडम स्थिति सुरक्षित रखें। रिकवरी के बाद का पहला फैसला, ऑर्डर और फिल रिकॉर्ड, और इक्विटी का क्रम मिलाएं। सिर्फ़ आखिरी बैलेंस का मेल खाना उन गलतियों को छिपा सकता है जो एक-दूसरे का असर काट देती हैं।
सबमिशन के बाद लेकिन पावती आने से पहले क्रैश हो, तो हार्नेस को एक्ज़ीक्यूशन सर्विस की स्थिति स्ट्रैटेजी प्रोसेस से अलग सुरक्षित रखनी होगी। वरना जिस अनिश्चितता को आप जांचना चाहते हैं, आप उसी को मिटा देंगे।
स्ट्रैटेजी की विशिष्टता में यह भी शामिल है कि उसे क्या याद रहता है। उस मेमोरी को इतना स्पष्ट बनाएं कि रीप्ले के बीच में प्रोसेस बंद करके आप दिखा सकें कि वह दोबारा काम कैसे शुरू करता है।
← सभी पोस्ट


