اگر بکتست استراتژیات نتایج درخشانی نشان میدهد، احتمال زیادی وجود دارد که مشکل داری. نه به این خاطر که استراتژی بد است — بلکه به این خاطر که بکتست دروغ میگوید.
لوکاهد بایاس (Look-Ahead Bias) یکی از پنهانترین خطاهای سیستمهای کوانتی است. بر خلاف overfitting که حداقل میتوانی روی نمودار ببینیش، این خطا در لایههای پایینتر — در pipeline داده، در نحوه محاسبه اندیکاتور، در ساختار خود کد — پنهان میماند. سیستم میگوید کار کرده. داده میگوید کار کرده. اما در live trading، همه چیز خراب میشود.
مشکل واقعی چیست
ایدهی بکتستینگ ساده است: شبیهسازی کن که استراتژیات در گذشته چطور عمل میکرد. اما این شبیهسازی یک فرض اساسی دارد: در هر لحظهی تاریخی، فقط از اطلاعاتی استفاده میکنی که آن لحظه در دسترس بوده.
لوکاهد بایاس زمانی اتفاق میافتد که این فرض نقض شود. سیستم بدون اینکه متوجه شوی، به دادههایی دسترسی پیدا میکند که در آن لحظه وجود نداشتند. نتیجه؟ عملکرد تاریخی بهشدت خوشبینانه، و شکست مطمئن در بازار واقعی.
اکثر مقالات این موضوع را با یک مثال ساده توضیح میدهند و تمام میکنند. اما مسئله این است که Look-Ahead Bias در عمل چندین شکل مختلف دارد، و برخی از آنها حتی برای کوانتهای باتجربه هم غیرواضح هستند.
چهار مسیر اصلی که دادههای آینده وارد تست میشوند
۱. استفاده از قیمت Close در سیگنال همان کندل: اگر سیگنال خرید روی close کندل ۱۴:۰۰ تولید شود و اجرا هم روی همان قیمت باشد، در واقعیت این قیمت تا ۱۵:۰۰ مشخص نیست. یعنی با اطلاعات آینده تصمیم گرفتهای.
۲. نرمالسازی با اطلاعات کل دوره: اگر feature engineering با استفاده از min/max یا mean/std کل dataset انجام شود، مدل بهطور ضمنی اطلاعات آینده را در featureهای گذشته جاسازی میکند. این یکی از رایجترین اشتباهات در ML-based strategy است.
۳. rebalancing بر اساس دادههای تجدیدنظرشده: دادههای اقتصادی — مانند GDP، تولید صنعتی، یا حتی برخی fundamentalهای شرکتها — پس از انتشار اولیه اصلاح میشوند. اگر از نسخه فعلی این دادهها در بکتست استفاده کنی، نه نسخهای که در آن تاریخ موجود بود، داری با اطلاعات آینده کار میکنی.
۴. فیلتر universe بر اساس اطلاعات امروز: اگر universe سهام را بر اساس سهامهایی که امروز در بازار هستند انتخاب کنی، survivorship bias ایجاد میکنی — که نوع خاصی از Look-Ahead Bias است. شرکتهایی که ورشکست شدند یا از بورس خارج شدند از تست حذف شدهاند، در حالی که در آن زمان جزو universe بودند.
یک مثال عملیاتی از pipeline واقعی
فرض کن یک مدل LSTM برای پیشبینی جهت بازار طراحی میکنی. دادهها را لود میکنی، normalization میکنی، سپس train/test split میزنی.
اگر normalization قبل از split انجام شود — که در اکثر tutorials اینطوری نشان داده میشود — مدل در مرحله آموزش به اطلاعات آماری بخش test دسترسی داشته. Sharpe ratio در بکتست ممکن است دو برابر عملکرد واقعی نشان دهد. نه به خاطر استراتژی خوب، بلکه به خاطر یک خط کد اشتباه.
راهحل؟ Pipeline باید به این ترتیب باشد: split اول، سپس normalization روی train set، سپس اعمال همان پارامترها روی test set. این ترتیب ساده است اما نقض آن رایج است.
چطور سیستم را در برابر این خطا مقاوم کنی
Point-in-Time Database اساسیترین ابزار است. این نوع دیتابیس هر بار که دادهای منتشر یا اصلاح میشود، نسخه قبلی را نگه میدارد — نه اینکه override کند. وقتی بکتست میزنی، به نسخهای از داده دسترسی داری که دقیقاً در آن تاریخ موجود بود.
Walk-Forward Testing لایه دیگری از اعتبارسنجی است. به جای یک train/test split ثابت، دورههای rolling داری: روی ۱۲ ماه train میکنی، روی ماه ۱۳ تست میکنی، پنجره را جلو میبری. این ساختار بهطور طبیعی از نشت اطلاعات جلوگیری میکند.
اما مهمترین اقدام این است: هر بار که سیگنالی در سیستم تولید میشود، یک سوال ساده بپرس — آیا در آن لحظه تاریخی، این اطلاعات واقعاً در دسترس بود؟ اگر جواب مشخص نیست، فرض کن نبوده.
بکتست خوب آن نیست که بهترین نتیجه را نشان دهد. بکتست خوب آن است که واقعاً شبیهسازی کند — با همه محدودیتهای اطلاعاتی که یک معاملهگر در آن لحظه داشت. هر چیزی کمتر از این، فقط یک داستان است که با داده روایت میشود.
نظرات (0)
اولین نفری باشید که نظر میدهد.
برای ثبت نظر باید وارد حساب کاربری خود شوید.
ورود / ثبتنام