पूर्वदर्शी पूर्वाग्रह बैकटेस्ट परीक्षण
पूर्वदर्शी पूर्वाग्रह भविष्य के डेटा को बैकटेस्ट में लीक करता है। जानें कैसे सेम बार निर्णय, सर्वाइवरशिप और संशोधित आंकड़े नतीजों को बढ़ा-चढ़ाकर दिखाते हैं और इसकी जांच कैसे करें।
पूर्वदर्शी पूर्वाग्रह (Look-ahead bias) एक बैकटेस्ट में उस जानकारी का उपयोग है जो सिम्युलेटेड ट्रेड लगाए जाने के समय किसी के पास नहीं हो सकती थी। इक्विटी कर्व ऊपर चढ़ता है, आंकड़े शानदार दिखते हैं, और लाइव ऑर्डर के संपर्क में आने पर इनमें से कुछ भी टिकता नहीं है। यह पृष्ठ इस पूर्वाग्रह को परिभाषित करता है, तीन ऐसे तंत्रों पर चर्चा करता है जो इसे उत्पन्न करते हैं, और वास्तविक बाजार डेटा पर प्रत्येक को मापता है।
पूर्वदर्शी पूर्वाग्रह क्या है
एक बैकटेस्ट एक निर्णय के बारे में एक दावा है: इस टाइमस्टैम्प पर, इस जानकारी के साथ, नियम ने यह किया होता। यह दावा तभी सही होता है जब नियम द्वारा पढ़ा गया प्रत्येक इनपुट, अपने अंतिम रूप में, उस टाइमस्टैम्प से पहले पहले से मौजूद था। पूर्वदर्शी पूर्वाग्रह उस शर्त का कोई भी उल्लंघन है, और यह मूक होता है। किसी स्प्रेडशीट या स्क्रिप्ट में कुछ भी शिकायत नहीं करता जब कोई पंक्ति उस निर्णय को फीड करने वाले टाइमस्टैम्प से बाद में अंकित मान वापस करती है।
तीन उल्लंघन अधिकांश व्यावहारिक मामलों को कवर करते हैं। एक निर्णय जो एक प्राइस बार पढ़ता है जिसके अंदर वह ट्रेड भी करता है। एक ब्रह्मांड जो आज भी सूचीबद्ध नामों से इकट्ठा किया गया है। एक डेटा फ़ील्ड जो अपनी तारीख के बाद संशोधित की गई थी।
तंत्र एक: उस बार पर निर्णय लेना जिसमें आप ट्रेड भी करते हैं
एक ऐसे नियम से शुरू करें जो हानिरहित लगता है। ताकत पर खरीदें, यानी उन सत्रों पर जहां फंड अपने खुलने के स्तर से ऊपर बंद होता है। लापरवाही से कोड किए जाने पर, परीक्षण उस सत्र के खुलने पर प्रवेश करता है और उसी सत्र के बंद होने पर बाहर निकलता है, जबकि जिस स्थिति पर यह जांच करता है वह उसी बार का समापन मूल्य है। कोई भी व्यक्ति शुरुआती घंटी पर समापन मूल्य नहीं जानता है।
नीचे दिया गया पैनल दोनों संस्करणों को SPY, S&P 500 ट्रैकर, पर दस कैलेंडर वर्षों में चलाता है। पहला कॉलम असंभव वाला है। दूसरा समान स्थिति को एक ही सत्र से पीछे कर देता है, जो कि सबसे पहला समय है जब कोई फंडेड खाता उस पर कार्य कर सकता था।
हर आंकड़े के पीछे का पूरा SQL
WITH bars AS (
SELECT date,
toFloat64(open) AS o,
toFloat64(close) AS c,
toFloat64(close) > toFloat64(open) AS up_day
FROM global_markets.stocks_daily_aggs
WHERE ticker = 'SPY'
AND date >= toDate('2015-12-01')
AND date <= toDate('2025-12-31')
),
lagged AS (
SELECT date, o, c, up_day,
any(up_day) OVER (ORDER BY date ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS prior_up
FROM bars
)
SELECT toYear(date) AS year,
countIf(up_day) AS signal_days,
round(100 * avgIf(c / o - 1, up_day), 3) AS same_bar_avg_pct,
round(100 * avgIf(c / o - 1, prior_up), 3) AS lagged_avg_pct,
round(100 * (avgIf(c / o - 1, up_day) - avgIf(c / o - 1, prior_up)), 3) AS gap_pp
FROM lagged
WHERE date >= toDate('2016-01-01')
GROUP BY year
ORDER BY yearअंतर सूक्ष्म नहीं है। 2016 में, एक ही बार वाले संस्करण ने प्रति योग्य सत्र औसतन 0.447% प्राप्त किया, जबकि लैग्ड संस्करण ने -0.008% प्राप्त किया, जो 0.455 प्रतिशत अंक प्रति दिन का अंतर है। 2025 में, दोनों ने 0.636% और -0.03% पढ़ा। एक वर्ष में लगभग 140 योग्य सत्रों के साथ, आधे प्रतिशत अंक प्रति सत्र का अंतर एक इक्विटी कर्व में बदल जाता है जो किसी भी लाइव खाते ने कभी नहीं छापा है।
पूरा लाभ परिभाषा के अनुसार है। उन सत्रों का चयन करना जो अपने खुलने से ऊपर बंद हुए, फिर उन्हीं सत्रों पर खुले-से-बंद को मापना, एक ऐसी मात्रा मापता है जो गारंटीशुदा सकारात्मक है। नियम ने अपना स्वयं का फ़िल्टर खोज लिया।
इसके प्रकार दैनिक डेटा में हर समय छिपे रहते हैं: एक मूविंग एवरेज जिसमें आज का क्लोज़ शामिल है और जिसका उपयोग आज ट्रेड करने के लिए किया जाता है, एक सिग्नल जो पहले से एक स्प्लिट के लिए समायोजित कीमतों पर गणना किया गया है जो अभी तक हुआ नहीं था, एक इंट्राडे स्टॉप जो एक सत्र के उच्च स्तर पर रखा गया है जो अभी तक नहीं बना था। सामान्य आकार एक निर्णय टाइमस्टैम्प है जो अपने स्वयं के इनपुट में से एक से पहले बैठा है।
तंत्र दो: आज के उत्तरजीवियों से बना एक ब्रह्मांड
दूसरा तंत्र कभी भी नियम को स्पर्श नहीं करता। यह उन नामों की सूची में बैठता है जिन्हें नियम देखने की अनुमति है।
किसी वर्तमान डेटा प्रदाता से एक टिकर सूची खींचें, इसे दस साल पीछे चलाएं, और नमूना चुपचाप उन सभी कंपनियों को बाहर कर देता है जो रास्ते में दिवालिया हो गईं, अधिग्रहित कर ली गईं, या डीलिस्ट कर दी गईं। नियम को कभी भी हारने वालों की पेशकश नहीं की गई। पैनल उस चूक के आकार को मापता है: प्रत्येक कैलेंडर वर्ष में कम से कम 200 सत्रों के लिए $1 से ऊपर कारोबार करने वाला प्रत्येक यूएस-सूचीबद्ध नाम, उस समूह का वह हिस्सा जो जुलाई 2026 में अभी भी कीमतें छाप रहा है, और पूरे समूह का माध्य कैलेंडर-वर्ष रिटर्न, केवल उत्तरजीवियों के माध्य के बगल में।
हर आंकड़े के पीछे का पूरा SQL
WITH recent AS (
SELECT DISTINCT ticker
FROM global_markets.stocks_daily_aggs
WHERE date >= toDate('2026-06-15')
AND date <= toDate('2026-07-28')
),
per_name AS (
SELECT toYear(date) AS year,
ticker,
argMin(toFloat64(close), date) AS first_close,
argMax(toFloat64(close), date) AS last_close,
count() AS sessions
FROM global_markets.stocks_daily_aggs
WHERE date >= toDate('2015-01-01')
AND date <= toDate('2024-12-31')
AND close > 1
GROUP BY year, ticker
HAVING sessions >= 200
)
SELECT year,
uniqExact(ticker) AS names_trading,
round(100 * uniqExactIf(ticker, ticker IN (SELECT ticker FROM recent)) / uniqExact(ticker), 1) AS still_listed_pct,
round(100 * quantileDeterministic(0.5)(last_close / first_close - 1, cityHash64(ticker)), 2) AS median_return_all_pct,
round(100 * quantileDeterministicIf(0.5)(last_close / first_close - 1, cityHash64(ticker), ticker IN (SELECT ticker FROM recent)), 2) AS median_return_survivors_pct,
round(100 * (quantileDeterministicIf(0.5)(last_close / first_close - 1, cityHash64(ticker), ticker IN (SELECT ticker FROM recent))
- quantileDeterministic(0.5)(last_close / first_close - 1, cityHash64(ticker))), 2) AS survivor_gap_pp
FROM per_name
GROUP BY year
ORDER BY year2015 में बार पार करने वाले 7063 नामों में से, 52.5% जुलाई 2026 में अभी भी कारोबार कर रहे थे। 2024 समूह के लिए यह आंकड़ा 87.5% है, जो अधिकतर बीते समय का मामला है: 2024 के एक नाम के पास गायब होने के लिए दो साल हैं और 2015 के एक नाम के पास ग्यारह साल हैं।
रिटर्न कॉलम में स्वयं पूर्वाग्रह है। 2017 में, माध्य नाम ने 7.51% लौटाया जबकि माध्य उत्तरजीवी ने 11.32% लौटाया, जो 3.81 प्रतिशत अंक का अंतर है जो मुफ्त में दिया गया। चार्ट में दिखाए गए 10 वर्षों में से प्रत्येक में अंतर सकारात्मक है। उत्तरजीवियों पर परीक्षण की गई एक रणनीति एक भी निर्णय लेने से पहले इसे विरासत में ले लेती है, और जो नियम कमजोरी की जांच करते हैं वे माध्य से अधिक विरासत में लेते हैं, क्योंकि जो नाम गायब हो गए वे असमान रूप से उस बाल्टी में बैठते हैं।
सुधार एक पॉइंट-इन-टाइम ब्रह्मांड है: प्रत्येक रीबैलेंस तिथि पर मौजूद नामों की सूची, जिसमें डीलिस्टिंग शामिल हैं, जिसमें एक डीलिस्टेड पोजीशन को रिकॉर्ड से हटाए जाने के बजाय उसके अंतिम प्रिंट पर बंद किया जाता है।
तंत्र तीन: डेटा जो अपनी तारीख के बाद संशोधित किया गया
कीमतें एक बार अंकित की जाती हैं। मूल सिद्धांत (Fundamentals) नहीं हैं। एक तिमाही आंकड़ा तिमाही की समाप्ति तिथि रखता है, बाद में एक फाइलिंग द्वारा संशोधित किया जाता है, और एक डेटाबेस जो केवल वर्तमान संस्करण संग्रहीत करता है, मूल तिथि के विरुद्ध संशोधित संख्या को खुशी-खुशी परोस देगा। उस संख्या पर जांच करने वाला एक नियम एक सुधार पढ़ रहा है जिसे आने में महीनों लग गए।
यही पैटर्न इंडेक्स सदस्यता सूचियों के माध्यम से चलता है जो वर्तमान घटकों के लिए पुनर्निर्मित की गई हैं, विश्लेषक अनुमान इतिहास जो अंतिम सर्वसम्मति से अधिलेखित कर दिए गए हैं, और कॉर्पोरेट कार्रवाई समायोजन जो पूरे मूल्य श्रृंखला में पीछे की ओर लागू किए गए हैं। प्रत्येक मामले में, संग्रहीत रिकॉर्ड एक वर्तमान-काल का स्नैपशॉट है जो भूतकाल की तारीख पहने हुए है।
दो प्रथाएं इसे रोकती हैं। एक स्रोत का उपयोग करें जो विंटेज रखता है, जिसका अर्थ है प्रत्येक तिथि पर ज्ञात मान, न कि वह मान जो अब ज्ञात है। जहां विंटेज उपलब्ध नहीं हैं, वहां एक रिपोर्टिंग अंतराल लागू करें जो वास्तविक को कवर करने के लिए पर्याप्त उदार हो, और उस अंतराल की लंबाई को अनुमान लगाने के लायक विवरण के बजाय परीक्षण करने योग्य पैरामीटर के रूप में मानें।
जब भविष्य अंदर लीक होता है तो कर्व कैसा दिखता है
पूर्वदर्शी पूर्वाग्रह का एक हस्ताक्षर है: प्रदर्शन जो अंतर्निहित बाजार द्वारा दी गई पेशकश से कहीं ऊपर बैठता है। एक उपयोगी संदर्भ बिंदु पूर्वदर्शी छत (hindsight ceiling) है, वह वृद्धि जो एक आदर्श एक-दिन-आगे का पूर्वानुमान एक एकल इंस्ट्रूमेंट पर उत्पन्न करता।
हर आंकड़े के पीछे का पूरा SQL
WITH bars AS (
SELECT date,
toFloat64(close) AS c,
any(toFloat64(close)) OVER (ORDER BY date ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS prev_c
FROM global_markets.stocks_daily_aggs
WHERE ticker = 'SPY'
AND date >= toDate('2015-12-01')
AND date <= toDate('2025-12-31')
),
rets AS (
SELECT toYear(date) AS year,
c / prev_c - 1 AS r
FROM bars
WHERE date >= toDate('2016-01-01')
AND prev_c > 0
)
SELECT year,
count() AS sessions,
round(100 * (exp(sum(log(1 + r))) - 1), 1) AS buy_and_hold_pct,
round(100 * (exp(sumIf(log(1 + r), r < 0.02)) - 1), 1) AS without_big_up_days_pct,
round(exp(sum(log(1 + abs(r)))), 1) AS hindsight_ceiling_multiple
FROM rets
GROUP BY year
ORDER BY yearछत बहुत बड़ी है। 2020 में, SPY पर एक-दिवसीय पूर्ण पूर्वज्ञान ने 253 सत्रों में पूंजी को 27.7 गुना बढ़ा दिया, जबकि केवल फंड को धारण करने पर 16.2% था। दस वर्षों के सबसे शांत वर्ष, 2017, में, उसी पूर्ण पूर्वानुमान ने पूंजी पर 2.2 गुना रिटर्न दिया।
मध्य कॉलम दिखाता है कि वह छत कितनी केंद्रित है। उन सत्रों को हटा दें जिन्होंने 2% से अधिक लाभ प्राप्त किया, और 2020 16.2% से -44.9% में बदल जाता है। एक वर्ष में उन सत्रों में से केवल मुट्ठी भर के लायक एक लीक एक बैकटेस्ट को बहुत दूर ले जाता है। उथले ड्रॉडाउन, एक उच्च हिट रेट, और बाजार के सबसे हिंसक सत्रों पर केंद्रित अपने सर्वोत्तम दिनों वाला एक कर्व एक ऑडिट का हकदार है।
अंशांकन (Calibration) किसी एकल सीमा से अधिक मायने रखता है। एक दशक में 40% प्रति वर्ष की एक सहज दर का दावा करने वाला नियम पूर्वदर्शी छत के एक बड़े अंश का दावा कर रहा है, और ईमानदार प्रश्न यह है कि किस इनपुट ने इसे बताया कि क्या होने वाला है।
पूर्वदर्शी पूर्वाग्रह के लिए बैकटेस्ट का परीक्षण कैसे करें
- हर चीज़ को एक बार पीछे करें (Lag everything by one bar)। प्रत्येक सिग्नल को एक पूर्ण अवधि बाद में शिफ्ट करें और फिर से चलाएं। वास्तविक बढ़त थोड़ी कम हो जाती है। लीक ढह जाते हैं, अक्सर कुछ भी नहीं बचता।
- भविष्य को गड़बड़ करें (Perturb the future)। प्रत्येक निर्णय टाइमस्टैम्प के बाद का डेटा लें, इसे शोर या पुनर्व्यवस्था से बदलें, और निर्णय तर्क को फिर से चलाएं। प्रत्येक निर्णय समान आना चाहिए। कोई भी निर्णय जो बदलता है, उसने कुछ ऐसा पढ़ा है जो वह नहीं जान सकता था।
- टाइमस्टैम्प को डेटा के रूप में मानें (Treat timestamps as data)। प्रत्येक इनपुट के लिए, वह क्षण संग्रहीत करें जब कोई मान उपलब्ध हुआ, उस क्षण के बगल में जिसका वह वर्णन करता है। एक जॉइन जो कभी उन दो कॉलमों की तुलना नहीं करता, नियम को लागू नहीं कर सकता।
- तिथि के अनुसार ब्रह्मांड का पुनर्निर्माण करें (Rebuild the universe as of the date)। डीलिस्टेड और अधिग्रहित नामों को शामिल करें, उन्हें उनके अंतिम प्रिंट पर बंद करें, और उत्तरजीविता योगदान के आकार का पता लगाने के लिए दोनों ब्रह्मांडों पर समान नियम चलाएं।
- छत के मुकाबले मापें (Measure against the ceiling)। रणनीति के रिटर्न को उसी विंडो के लिए खरीद-और-धारण आंकड़े और एक पूर्ण-पूर्वदर्शी आंकड़े के बगल में रखें। छत से दूरी एक ऐसा संदर्भ है जो अकेला शार्प अनुपात नहीं देता।
पोजीशन साइज़िंग इन सबके बाद आता है। एक बढ़ी हुई जीत दर एक बढ़े हुए बेट आकार को बढ़ावा देती है, जो वह जगह है जहां केली मानदंड पोजीशन साइज़िंग एक लेखांकन त्रुटि को ड्रॉडाउन में बदल देता है। वास्तविक पूंजी चलने से पहले वही अनुशासन लागू होता है: वास्तविक धन से पहले पेपर ट्रेडिंग ऑर्डर मैकेनिक्स का परीक्षण करती है, और स्वचालित स्टैक मशीन की गति पर समान खतरा रखते हैं, जैसा कि मल्टी एजेंट AI ट्रेडिंग सिस्टम में शामिल है। जो प्रभाव सावधानीपूर्वक पॉइंट-इन-टाइम परीक्षण से बच जाते हैं, जैसे कि कम अस्थिरता विसंगति, ठीक उसी कारण से दिलचस्प हैं।
सामान्य प्रश्न
बैकटेस्टिंग में पूर्वदर्शी पूर्वाग्रह क्या है?
यह एक सिम्युलेटेड ट्रेड में उस डेटा का उपयोग है जो ट्रेड लगाए जाने के समय उपलब्ध नहीं था। सामान्य रूप हैं: एक प्राइस बार पर निर्णय लेना जिसके अंदर ट्रेड भी निष्पादित होता है, उन कंपनियों के ब्रह्मांड की जांच करना जो आज भी सूचीबद्ध हैं, और एक वित्तीय आंकड़ा पढ़ना जो उससे जुड़ी तारीख के बाद संशोधित किया गया था।
आप पूर्वदर्शी पूर्वाग्रह का पता कैसे लगा सकते हैं?
प्रत्येक सिग्नल को एक पूर्ण अवधि पीछे करें और फिर से चलाएं: एक लीक आमतौर पर ढह जाता है जबकि एक वास्तविक बढ़त धीरे-धीरे कम होती है। एक मजबूत परीक्षण प्रत्येक निर्णय टाइमस्टैम्प के बाद के सभी डेटा को शोर से बदल देता है और पुष्टि करता है कि प्रत्येक निर्णय अपरिवर्तित रहता है।
क्या उत्तरजीविता पूर्वाग्रह (Survivorship bias) पूर्वदर्शी पूर्वाग्रह के समान है?
वे अलग हैं लेकिन वे एक साथ चलते हैं। उत्तरजीविता पूर्वाग्रह उन नामों से बना एक नमूना है जो टिक गए, और यह जानना कि कौन से नाम टिके, स्वयं भविष्य की जानकारी है, इसलिए केवल उत्तरजीवियों का एक ब्रह्मांड नियम के बजाय डेटा में स्थित एक पूर्वदर्शी लीक है।
पूर्वदर्शी पूर्वाग्रह वाले बैकटेस्ट इतने अच्छे क्यों दिखते हैं?
लीक परिणामों का चयन करता है, उनकी भविष्यवाणी नहीं करता। ऊपर दिए गए पैनल में, सत्रों को उनके स्वयं के समापन मूल्य पर जांचने से 2016 में लैग्ड संस्करण की तुलना में लगभग 0.455 प्रतिशत अंक अधिक औसत सत्र लाभ उत्पन्न हुआ, जो एक परिभाषा के अनुसार लाभ है न कि अर्जित।
पॉइंट-इन-टाइम डेटा क्या है?
पॉइंट-इन-टाइम डेटा प्रत्येक मान को उस रूप में संग्रहीत करता है जैसा वह प्रत्येक ऐतिहासिक तिथि पर ज्ञात था, जिसमें मूल आंकड़ा और प्रत्येक बाद का संशोधन शामिल है, साथ ही उस दिन मौजूद प्रतिभूतियों का ब्रह्मांड भी शामिल है। यह वह संदर्भ है जिसकी एक बैकटेस्ट को यह दिखाने के लिए आवश्यकता होती है कि उसके इनपुट उसके निर्णयों से पहले मौजूद थे।
ऊपर दिया गया प्रत्येक आंकड़ा वास्तविक दैनिक बार पर एक संग्रहीत, संस्करणित क्वेरी है। किसी भी पैनल का SQL विस्तृत करें, या Strasmore टर्मिनल पर अपने स्वयं के नियम पर लैग टेस्ट चलाएं।