یک استراتژی کاغذی را در میانه یک معامله دوباره راهاندازی کردیم و توالی سفارشهای متفاوتی نسبت به اجرای پیش از راهاندازی مجدد گرفتیم. دادههای بازار یکسان، نسخه استراتژی یکسان و موجودی حساب یکسان بود. محاسبه سیگنال همخوانی داشت، اما حافظه استراتژی از موقعیت و سفارشهای در انتظار چنین نبود.
ناهمخوانی را طی یک روز کار بازپخش بررسی کردیم. درس مفید ساده بود: برای نرمافزار شما، راهاندازی مجدد خودش یک رویداد بازار است. اگر بازسازی وضعیت استراتژی را آزمایش نکنید، یک بکتست بینقص میتواند سیستمی کاغذی را پنهان کند که فراموش میکند چه چیزی در اختیار دارد.
09:10 — یک موقعیت ساده انتخاب کردیم
استراتژی آزمایشی ما روی یک قرارداد دائمی نقدشونده معامله میکرد: وقتی میانگین متحرک کوتاهمدت از میانگین بلندمدتتر رو به بالا عبور میکرد، وارد موقعیت خرید میشد و با تقاطع معکوس خارج میشد. بازپخش را با یک موقعیت کوچکِ ازپیشباز و یک سفارش محدودِ فقطکاهنده برای کمکردن آن آغاز کردیم. این کار به فرایند بازیابی دو چیز برای بازسازی میداد: چه چیزی در اختیار داشتیم و پیشتر از صرافی خواسته بودیم چه کاری انجام دهد.
در نقطه بررسی، حساب 0.04 قرارداد داشت. سفارش باز برای 0.01 بود. فرایند استراتژی هر دو مقدار را در حافظه ذخیره کرده بود، اما مسیر راهاندازی فقط موقعیت را دریافت میکرد. با سفارش ذخیرهشده طوری رفتار کرد که انگار دیگر وجود نداشت.
09:25 — نخستین سفارش تکراری ظاهر شد
پس از راهاندازی مجدد، استراتژی موقعیت خرید موجود را دید، منطق سیگنال را اجرا کرد و یک سفارش دیگر برای کاهش 0.01 ثبت کرد. حالا در بازار کاغذی دو سفارش فعال داشتیم. هیچکدام بهتنهایی سفارش بدی نبودند؛ اما اگر هر دو اجرا میشدند، مجموعاً میتوانستند دو برابر مقدار موردنظر را بفروشند.
ابتدا حلقه سیگنال را مقصر دانستیم. مشکل از حلقه نبود؛ تصویر وضعیت ناقص بود. استراتژی پرسید «چه موقعیتی دارم؟» اما هرگز نپرسید «کدام سفارشها هنوز در جریاناند؟»
| وضعیت پس از راهاندازی مجدد | برداشت فرایند | وضعیت حساب |
|---|---|---|
| موقعیت | خرید 0.04 | خرید 0.04 |
| سفارشهای باز برای کاهش موقعیت | هیچکدام | دو سفارش، هرکدام برای 0.01 |
| میزان مواجهه موردنظر پس از اجرای یک سفارش | خرید 0.03 | ممکن است به خرید 0.02 برسد |
10:00 — بازیابی را اصلاح کردیم و بعد به یک مسئله زمانبندی رسیدیم
راهاندازی را طوری تغییر دادیم که پیش از فعالشدن تصمیمهای جدید، وضعیت از موقعیتها و سفارشهای باز حساب بازسازی شود. این کار سفارش تکراری را برطرف کرد. بعد قطع ارتباط را پیچیدهتر کردیم: وقتی استراتژی آفلاین بود، یک سفارش اجرا شد و اعلان اجرا پس از اتصال مجدد رسید.
تصویر حساب از قبل اجرای سفارش را نشان میداد. سپس اعلان با تأخیر، موقعیت محلی را بار دوم کاهش داد. برای چند ثانیه، استراتژی گمان میکرد 0.02 قرارداد دارد، در حالی که حساب 0.03 داشت. متعادلسازی بعدی بر پایه کمبود خیالی انجام میشد.
قواعد تطبیق وضعیت را اضافه کردیم: تصویر حساب را نقطه شروع بگیریم، با شناسه رویدادها اجراهایی را که از قبل در آن منعکس شدهاند نادیده بگیریم و تا پایان همگامسازی اولیه سفارشی ثبت نکنیم. اعلان ممکن است دیر برسد یا دوبار ارسال شود؛ بازیابی باید هر دو حالت را تاب بیاورد.
13:40 — بازپخش یک ناهمخوانی نامحسوس را آشکار کرد
مسیر قیمت یکسانی را در اجرای اصلی و اجرای دوبارهراهاندازیشده بازپخش کردیم. مقایسه P&L نهایی مشکل را نشان نمیداد: پس از برگشت بازار، هر دو نسخه با موقعیت یکسانی تمام کردند. مقایسه رویدادهای سفارش آن را آشکار کرد.
هر تصمیم را همراه با وضعیتی که خوانده بود ثبت کردیم: موقعیت، سفارشهای باز، شناسه آخرین اجرای پردازششده، مقدار سیگنال و نسخه استراتژی. حالا نخستین رویداد متفاوت توضیح روشنی داشت. یک اجرا سفارش در جریان میدید؛ اجرای دیگر فهرستی خالی. بعدتر، یکی از آنها یک اجرا را دوبار اعمال کرد.
یکسانبودن موجودی نهایی، رفتار یکسان را ثابت نمیکند. توالی تصمیمها و سفارشها را مقایسه کنید، بهخصوص در حوالی نقاط بازیابی.
16:20 — دفعه بعد چه کار متفاوتی میکنیم
پیش از بررسی تغییرات وضعیت حساب، بیش از حد برای بازپخش دادههای قیمت وقت گذاشته بودیم. دفعه بعد ابتدا حالتهای خطا را شبیهسازی میکنیم و مسیر بازار را تقریباً ثابت نگه میداریم. این کار خطای نرمافزار را آشکار میکند و حرکت پرنوسان بازار تشخیص را دشوار نمیکند.
- با یک موقعیت و یک سفارش که بخشی از آن اجرا شده، راهاندازی مجدد کنید.
- پس از ثبت سفارش اتصال را قطع کنید و پیش از رسیدن اعلان اجرا دوباره وصل شوید.
- یک رویداد اجرا را دوبار ارسال کنید و مطمئن شوید فقط یکبار وضعیت را تغییر میدهد.
- تا زمانی که موقعیتها و سفارشهای باز هر دو تطبیق داده نشدهاند، سفارشهای جدید را مسدود کنید.
- گزارش تصمیمها و سفارشها را میان اجرای پیوسته و اجرای دارای راهاندازی مجدد مقایسه کنید.
همچنین یاد گرفتیم یک تصویر بازیابی را کنار نسخه استراتژی و گزارش رویداد ذخیره کنیم. با این کار، شکست را در چند دقیقه بازتولید میکردیم و لازم نبود کسی توالی دقیق اتصال مجدد را به خاطر بیاورد.
استراتژی کاغذیای که فقط تا وقتی درست کار میکند که فرایندش زنده بماند، تمرین کامل را پشت سر نگذاشته است. آن را در میانه موقعیت دوباره راهاندازی کنید، بگذارید اعلان اجراها با تأخیر برسند و همه سفارشهایی را که بعد از آن میفرستد بررسی کنید. هدف اثبات این نیست که هرگز خطا نمیکند؛ هدف این است که بازیابیاش را پیش از آن ببینید که حساب کاغذی همان درس را با غافلگیری به شما بیاموزد.
← همهٔ مطالب


