این یک ردیف از فایل روزانه سهام است. NVDA، جمعه ۷ ژوئن ۲۰۲۴، آخرین نشست معاملاتی پیش از اجراییشدن تجزیه ۱۰ به ۱.
| ستون | مقدار |
|---|---|
| date | 2024-06-07 |
| close | 1208.88 |
| volume | 42,800,000 (گرد شده) |
| split_factor | 1.0 |
| dividend | 0.00 |
| adj_close | 120.8781 |
ستونهای OHLC را عمداً از این نما کنار گذاشتهام. نزدیک پایان دوباره سراغشان میرویم؛ همانهایی که بیسروصدا همهچیز را بههم میریزند.
هرچه در این ردیف جالب است، در فاصله بین ستون دوم و ستون ششم قرار دارد. نوار معاملات در ۷ ژوئن قیمت 1208.88 را ثبت کرد. دیگر هیچکس با آن قیمت معامله نخواهد کرد، چون سهمی که آن قیمت به آن اشاره داشت دیگر بهعنوان یک واحد وجود ندارد. عدد 120.8781 بازسازیشده است و صرفاً حاصل تقسیم 1208.88 بر ۱۰ نیست. بیایید ستونبهستون پیش برویم.
date: 2024-06-07، و دو تاریخ دیگری که اهمیت بیشتری دارند
تجزیه در ۲۲ مه ۲۰۲۴ همزمان با اعلام درآمدها اعلام شد. تاریخ ثبت سهامداران ۶
ژوئن بود. معاملات بر مبنای قیمتهای تعدیلشده بابت تجزیه از دوشنبه ۱۰ ژوئن
آغاز شد. سه تاریخ، اما ستون split_factor فروشنده داده شما فقط به
یکی از آنها مربوط است؛ معمولاً نخستین نشست معاملاتی پس از تجزیه. خطای یکروزه
در اینجا رایجترین باگ اقدام شرکتی است که میبینم و در آمار تجمیعی پنهان
میماند: منحنی ارزش پرتفوی در یک روز ۹۰٪ افت یا ۹۰۰٪ جهش میکند؛ چیزی که
Sharpe محاسبهشده روی 2,000 روز بهسختی نشان میدهد، اما حداکثر افت سرمایه یا
قاعده حد ضرر را بهوضوح تحتتأثیر قرار میدهد.
سود تقسیمی هم مسئله تاریخ خودش را دارد و در سال ۲۰۲۴، بدون آنکه کسی متوجه شود، قاعدهاش تغییر کرد. سود تقسیمی فصلی 0.01 دلاری NVDA پس از تجزیه، تاریخ ثبت سهامداران ۱۱ ژوئن داشت. تسویه معاملات آمریکا در ۲۸ مه ۲۰۲۴ به T+1 تغییر کرد؛ یعنی تاریخ بدون سود و تاریخ ثبت حالا یک روز هستند. هر بارگذاری که تاریخ بدون سود را «یک روز کاری پیش از تاریخ ثبت» حساب کند ــ روشی که دههها درست بود ــ از ژوئن ۲۰۲۴ تعدیل سود تقسیمی را بیسروصدا یک نشست زودتر ثبت میکند. هیچ خطایی رخ نمیدهد. ضریب فقط روی ردیف اشتباه میافتد.
شکست کد اقدامات شرکتی هیچوقت بهصورت استثنا ظاهر نمیشود. عددی است که یک روز جابهجا شده و کاملاً معقول به نظر میرسد.
close: 1208.88 — قیمتی که در فایل نیست
این قیمت خام ثبتشده در بازار است و در بیشتر خط لولههای پژوهشی فقط بهصورت
ستونی وجود دارد که کسی نمیخواند. سیگنالها بر مبنای
adj_close محاسبه میشوند. هر قاعدهای هم که به سطح قیمت هر سهم به
دلار ارجاع دهد، حالا به عددی اشاره میکند که هیچیک از فعالان بازار ندیدهاند.
صعود تدریجی NVDA بهسمت 1,000 دلار در بهار ۲۰۲۴ اتفاقی واقعی بود و جریان سفارش واقعی پشت آن قرار داشت: اعداد رُندِ جاذب قیمت، تمرکز قیمتهای اعمال اختیار معامله روی 950 و 1000، و ریسک خبر در هر بار نزدیکشدن. در دادههای تعدیلشده، کل این ماجرا در قیمت 100 دلار رخ میدهد. اگر رفتار پیرامون سطوح روانی، منطق پرشدن گپ نزدیک اعداد رُند یا ویژگی نزدیکی به قیمت اعمال را میآزمایید، دارید آن را با سری قیمتیای میسنجید که رویدادی در آینده هنوز مقیاسش را عوض نکرده بود.
همین موضوع درباره فیلترهای جهان سهام هم صدق میکند. «حذف سهام زیر 5 دلار» جانشین معتبری برای مجموعهای واقعی از مشکلات ریزساختار بازار است: فاصله نسبی زیاد بین قیمت خریدوفروش، قواعد قابلیت استفاده بهعنوان وثیقه و رژیمهای اندازه گام قیمت. اگر آن را روی تاریخچه تعدیلشده اجرا کنید، شرکتهایی را در دورههایی حذف میکنید که با قیمت 30 دلار معامله میشدند و بعدها تجزیه معکوس داشتند. اگر شرط «قیمت بالای 500 دلار» را اجرا کنید، NVDA را بیسروصدا از تمام سالهای پیش از ژوئن ۲۰۲۴ کنار میگذارید. فیلترهای قیمت باید روی قیمتهای خام اجرا شوند. همین و بس.
split_factor: 1.0 — و 0.1 در ردیف بعدی
این ضریب، حاصلضرب تجمعیای است که از امروز به عقب محاسبه میشود. هر ردیف پیش از ۱۰ ژوئن ۲۰۲۴ ضریب 0.1 این تجزیه را دارد که در ضریب 0.25 تجزیه ۴ به ۱ در سال ۲۰۲۱ و سپس ضرایب رویدادهای پیش از آن ضرب میشود. تاریخچه NVDA پیش از ۲۰۲۱ با 0.025 مقیاس میشود؛ بنابراین کندلی که در ۲۰۱۹ با قیمت 200 دلار ثبت شده، بهصورت 5.00 دلار دیده میشود.
دو پیامد را باید به خاطر سپرد. اول اینکه تاریخچه تعدیلشده هر بار که اقدام شرکتی جدیدی رخ میدهد، تغییر میکند. بکتستی که در مه ۲۰۲۴ اجرا کردید و بکتستی که امروز اجرا میکنید، با کد یکسان و روی تاریخهای یکسان، اعداد متفاوتی میدهند. اگر ویژگیها را با کلید نماد و تاریخ ذخیره کردهاید، بیآنکه نسخه داده را ثبت کنید، حالا حافظه نهانی دارید که دو مقیاس را با هم قاطی کرده است. دقیقاً به همین دلیل، دوره تعدیل را در کلید ویژگی نسخهبندی میکنیم؛ برای یادگرفتنش یک بعدازظهر بسیار گیجکننده هزینه کردیم.
دوم اینکه با ضریب مقیاس 0.025، سهمی که با گامهای 0.01 دلاری معامله میشد حالا با افزایشهای 0.00025 دلاری حرکت میکند. منطق گردکردن به گام قیمت، مقایسههای «آیا این سقف جدیدی است» و بررسی برابری ممیز شناور؛ همگی حالا در دقتی کار میکنند که بسیار فراتر از وضوح واقعی بازار بوده است.
dividend: 0.01 — عددی که شبکه قیمتی همه قیمتهای پیش از خودش را از بین میبرد
یک سنت. شبیه نویز به نظر میرسد، اما دلیل آن است که
adj_close بهجای عدد رُند 120.888، مقدار 120.8781 را نشان میدهد.
قیمت پایانی ۱۰ ژوئن 121.79 بود. ضریب بدون سود تقسیمی برابر است با (121.79 − 0.01) / 121.79 = 0.99991789. این ضریب در تمام قیمتهای پیش از ۱۱ ژوئن ضرب میشود؛ بنابراین 120.888 پس از تعدیل بابت تجزیه به 120.878074 تبدیل میشود. تغییری کوچک و دائمی که دوباره در هر یک از بیش از ۶۰ تاریخ بدون سود تقسیمی در تاریخچه NVDA اعمال میشود. اثر انباشته مهم است: وقتی به سال ۲۰۱۵ نگاه میکنید، قیمتی را میبینید که در دهها ضریب تقریباً نامعقول ضرب شده است. هیچ قیمت تاریخی تعدیلشدهای روی شبکه یکسنتی قرار ندارد.
یعنی هر مقایسه == با یک سطح رُند نادرست است، هر بررسی «آیا قیمت
به قیمت سفارش محدود رسید؟» به دامنه خطا نیاز دارد، و پس از گردکردن ساده به ۴
رقم اعشار، OHLC بازسازیشده دیگر شرط low ≤ open ≤ high را برآورده نمیکند.
همچنین یعنی adj_close سری بازده کل است، درحالیکه
close سری بازده قیمتی است؛ اگر بازده را از یکی و افت سرمایه را از
دیگری محاسبه کنید، دو تعریف متفاوت از آنچه رخ داده را با هم ترکیب کردهاید.
volume: 42,800,000 — ضریبی که هیچکس بهشکلی یکسان اعمال نمیکند
برای آنکه حجم سهام با نشستهای پس از تجزیه قابل مقایسه باشد، باید در ۱۰ ضرب شود. بعضی فروشندگان داده این کار را میکنند. بعضی نمیکنند. بعضی OHLC را تعدیل میکنند اما حجم را خام میگذارند؛ این بدترین حالت است، چون فایل تا پیش از ضرب قیمت در حجم، از درون سازگار به نظر میرسد.
راه درست این است که استفاده از حجم سهام بهعنوان ویژگی را کنار بگذاریم و از حجم دلاری استفاده کنیم که ذاتاً در برابر تجزیه ثابت میماند. فیلتر نقدشوندگی بر اساس میانگین حجم دلاری ۲۰روزه اصلاً به منطق تعدیل نیاز ندارد و اقدام شرکتی نمیتواند آن را خراب کند. ناوردایی ویژگی از کد تعدیل درست بهتر است، چون درستبودن کد تعدیل چیزی است که باید مدام حواستان به آن باشد.
سه شکل فایل فروشندگان داده، سه نوع شکست.
| آنچه ارائه میشود | آنچه خراب میشود |
|---|---|
| فقط قیمت پایانی تعدیلشده، OHLC خام | منطق گپ و درونروزی محاسبات را روی دو مقیاس قیمت انجام میدهد |
| OHLC تعدیلشده، حجم خام | حجم دلاری بهاندازه نسبت تجزیه خطا دارد؛ فیلترهای ADV اشتباه عمل میکنند |
| OHLCV خام بهعلاوه ستونهای ضریب | هیچچیز، اگر ضرایب را اعمال کنید. همهچیز، اگر روی ردیف اشتباه اعمالشان کنید |
ستونهایی که اینجا نیستند: adj_open، adj_high، adj_low
حالا OHLC را دوباره وارد کنید. اگر یک فید فقط قیمت پایانی را تعدیل کند و
استراتژی شما گپ شبانه را با فرمول
open / prev_adj_close − 1 محاسبه کند، در ۱۰ ژوئن ۲۰۲۴ مقدار
120.37 / 120.8781 − 1 را به دست میآورد؛ عددی قابل قبول، حدوداً −0.4%. اگر
همان کد را به ۷ ژوئن ۲۰۲۴ برگردانید، قیمت آغازین را از فایل خام (حدود 1207) در
برابر قیمت پایانیای میگذارید که با ضریب 0.025 حاصل از تجزیههای قدیمیتر
تعدیل شده است و گپی چند هزاردرصدی به دست میآید.
هر محاسبهای که ستون خامی را با ستون تعدیلشده ترکیب کند، روی دو دستگاه مختصات متفاوت انجام میشود. حالا خواندن دادههایی با تعدیلهای ترکیبی را در سطح بارگذار بهصورت یک شرط قطعی بررسی میکنم؛ نه چیزی که پژوهشگر باید به خاطر بسپارد، چون پژوهشگران یادشان نمیماند، از جمله خودم.
چیزی که هیچ ستونی به شما نمیگوید: واقعاً چند سهم میخریدید
این مورد در مدل هزینه بکتست پول واقعی هزینهتراشی میکند و دلیل اصلی نوشتن این مطلب درباره تجزیه سهام است.
کارمزد معاملات سهام آمریکا اغلب بهازای هر سهم محاسبه میشود. فرض کنید نرخ 0.005 دلار با حداقل کارمزد 1.00 دلار برای هر سفارش را در نظر بگیریم؛ این یک رده ثابت رایج در کارگزاریهای خرد است. حالا یک موقعیت 400,000 دلاری NVDA را یک سال پیش از تجزیه بکتست کنید؛ زمانی که قیمت خام نزدیک 400 دلار بود و قیمت تعدیلشده 40 دلار نشان داده میشد.
| تعداد سهم | کارمزد | |
|---|---|---|
| آنچه واقعاً رخ داد (قیمت خام 400 دلار) | 1,000 | $5.00 |
| آنچه بکتست میبیند (قیمت تعدیلشده 40 دلار) | 10,000 | $50.00 |
میزان سرمایه درگیر و معامله یکسان است، اما هزینه مدلشده ۱۰ برابر میشود. یعنی 45 دلار هزینه ساختگی برای هر سمت معامله، 90 دلار برای هر رفتوبرگشت، و اگر استراتژی هر روز گردش داشته باشد، حدود 22,000 دلار در سال هزینهای که هرگز وجود نداشته است. در پرتفویی به ارزش 400k، یعنی 5.6 واحد درصد از بازده سالانه که تماماً ساخته یک ضریب تقسیم است. در اینجا نتیجه این است که عملکردتان بدتر از واقعیت به نظر میرسد؛ این قابلتحمل است.
تجزیه معکوس اثر عکس دارد و این جهت خطرناک است. تجزیه معکوس ۱ به ۱۰ یعنی قیمتهای تاریخچه تعدیلشده ۱۰ برابر بالاتر و تعداد سهام ۱۰ برابر کمتر از چیزی است که معامله میکردید. مدل هزینه شما بیسروصدا کارمزد هر سهم را بر ۱۰ تقسیم میکند. تجزیههای معکوس در جهان سهام کوچک، زیر 5 دلار و با فاصله زیاد قیمت خریدوفروش رایجاند؛ جایی که کارمزد هر سهم بزرگترین قلم هزینه است. بکتست دقیقاً همان نمادهایی را جلوه میدهد که باید جریمه کند.
پس راهحل ساده و ساختاری است: موقعیتها را به دلار اندازهگیری کنید، با استفاده از قیمت تعدیلنشده همان تاریخ به تعداد سهم تبدیل کنید و کارمزد هر سهم را بر اساس آن تعداد بگیرید. ستون قیمت خام را برای همیشه در بارگذار نگه دارید؛ نه כاثر ممیزی، بلکه כورودی زنده موتور اجرا.
- سیگنالها و بازده: سری تعدیلشده.
- تعداد سهام، کارمزد هر سهم، گردکردن به گام قیمت، فیلترهای سطح قیمت: سری تعدیلنشده.
- نقدشوندگی و ظرفیت: حجم دلاری که به هیچکدام نیاز ندارد.
شش ستون، یک ردیف، یک اقدام شرکتی نسبتاً عادی که سه هفته زودتر اعلام شد و هیچکس را غافلگیر نکرد. بازار در یک صبح از پس آن برآمد. بازسازی دقیق آن در خط لوله پژوهشی بهمراتب دشوارتر است و نشانه خط لولهای که از پسش برنیامده، تقریباً هیچوقت پیام خطا نیست.
← همهٔ مطالب


