آیا الگوریتم‌های ژنتیک توانایی trade کردن سهام را دارند؟

شکل ۱: توانایی الگوریتم‌ها برای trade کردن
شکل ۱: توانایی الگوریتم‌ها برای trade کردن


منتشر‌شده در: towardsdatascience به تاریخ ۲۷ فوریه ۲۰۲۱
لینک منبع: What would happen if you gave genetic algorithms the ability to trade?

بیشتر کاربردهای یادگیری ماشینی، یا حداقل بیشتر محتوای موجود در رسانه‌ها، شامل آموزش یک الگوریتم یادگیری ماشینی برای پیش‌بینی قیمت آینده یا جهت آینده یک سهام است. ثابت شده است که این امر بی‌اثر است، زیرا داده‌های سهام برای روش‌های پیش‌بینی سری‌های زمانی مناسب نیستند. علت آن این است که هیچ همبستگی بین نقاط داده وجود ندارد. این امر باعث می‌شود که هر وزن آموخته‌شده توسط شبکه عصبی تنها نویز آماری در داده‌ها باشد.

این مرا به این فکر انداخت که شاید مشکل در حوزه راه‌حل باشد: شاید پیش‌بینی مستقیم بر اساس داده‌های تاریخی موفق نباشد، زیرا به طور مستقیم به هم مرتبط نبودند. یک ارتباط مستقیم بین پیش‌بینی‌ها و trade کردن سهام می‌تواند نتایج مختلفی به همراه داشته باشد. من شروع کردم به نظریه‌پردازی در مورد راه‌های اعمال این مفهوم.

این ایده که من به آن رسیدم، راه‌اندازی مشابهی با یادگیری تقویتی خواهد بود: یک عامل وجود خواهد داشت، که با یک شبکه عصبی نیرو می‌گیرد و با یک محیط در تعامل خواهد بود. محیط به عنوان یک واسطه برای داده‌های سهام گذشته عمل می‌کند.

به منظور مقابله با بیشتر مشکلاتی که با رگرسیون سری‌های زمانی ایجاد شدند، در عوض از یک الگوریتم ژنتیک استفاده کردم. این بدان معنی است که شبکه عصبی در واقع هرگز بر روی داده‌ها آموزش نخواهد دید، بنابراین احتمال تاخیر در داده‌های واقعی یا بیش از حد بر روی داده‌های trading را رد می‌کند. این به قیمت بهره‌وری است، زیرا الگوریتم‌های ژنتیک زمان زیادی را صرف هم‌گرایی می‌کنند اگر آن‌ها حتی این کار را مدیریت کنند.

برنامه‌ای که من ایجاد کردم شامل سه بخش است:

  1. ساخت کارگزار
  2. ایجاد محیط
  3. ساخت الگوریتم ژنتیک

قبل از برنامه واقعی، تمام کتابخانه‌هایی که من برای این پروژه استفاده کردم عبارتند از:

ساخت کارگزار:

ویژگی‌های کارگزار بسیار روشن هستند. باید قادر به ایجاد تعاملات موثر با محیط باشد و باید تناسب خود را ذخیره کند (یعنی سود حاصل شده). همانطور که می‌بینید، بسیار ساده است. به غیر از تابع _ init _، تنها دو تابع دیگر دارد. این امر به عنوان بیشتر ویژگی‌های مورد نیاز برای تعامل کارگزار با محیط در مدل keras گنجانده شده است.

تابع clone_model 3 ضروری است به طوری که هر عامل تولید شده دارای وزن‌های متفاوتی باشد، در حالی که معماری مدل مشابه را حفظ می‌کند. این معماری مدلی است که من برای این پروژه استفاده کردم. بسیار ساده است، چون این پروژه فقط یک اثبات مفهوم است. علاوه بر این، پیچیده‌تر کردن آن زمان محاسبه را به طور نمایی بزرگ‌تر می‌کند. شما می‌توانید زمان محاسبه را با نگاه کردن به تعداد پارامترها در هنگام فراخوانی مدل کنترل کنید.

یک مدل بهتر برای این پروژه می‌تواند شامل لایه‌های کانولوشن ۱ بعدی باشد، زیرا آن‌ها در انتخاب ویژگی از داده‌ها موثرتر خواهند بود.

شاید به مطالعه مقاله معرفی جستجو بر اساس مدل(Model Search): یک پلتفرم منبع باز برای یافتن مدل‌های ML بهینه علاقه داشته باشید.

ایجاد محیط:

محیط با کارگزار دست به دست می‌دهند. محیط باید قادر به رسیدگی به درخواست‌های کارگزار باشد و باید قادر به ارسال موثر داده‌ها به عقب و جلو باشد. همچنین باید قادر به محاسبه تناسب کارگزار باشد. با این حال، محیط پیچیده‌تر از عامل است، زیرا محیط باید از هر کارکردی که می‌تواند عامل را مستعد استفاده از تجهیزات اضافی کند یا فقط از داده‌های واقعی سهام عقب بماند، پاک باشد.

این عملکرد __init__ محیط است. این تابع شامل تمام متغیرهایی است که همه توابع دیگر برای عملکرد نیاز دارند. متغیرهای تاریخ شروع و تاریخ پایان برای کنترل زمانی که داده‌ها را می‌توان از آن استخراج کرد، استفاده می‌شوند. از این روش می‌توان برای مقایسه نتایج مدل در دوره‌های زمانی مختلف، برای تجزیه و تحلیل بهتر نتایج استفاده کرد.

این تابع راه‌اندازی می‌تواند محیط را راه‌اندازی و تنظیم مجدد کند. این روش تمام متغیرها را به مقادیر اصلی آن‌ها اعمال می‌کند و به داده‌ها دسترسی پیدا می‌کند. با تابع دریافت داده‌ها، کارگزار می‌تواند به داده‌ها دسترسی داشته باشد و از آن داده‌ها برای پیش‌بینی استفاده کند.

توجه داشته باشید که قیمت نزدیک تعدیل‌شده و ستون‌های حجمی افت می‌کنند. قیمت نزدیک مجاور برای شبکه عصبی خیلی مفید نیست، و مقادیر حجم بسیار بزرگ هستند. این یک مشکل است چرا که مقیاس‌گذاری استاندارد نباید بر روی داده‌هایی که تقسیم نشده‌اند استفاده شود، چرا که به نقاط داده آینده بینش می‌دهد.

این دو تابع وظایف کلیدی هستند که نماینده برای تعامل با محیط از آن‌ها استفاده می‌کند. تابع موقعیت بسته در واقع یک تابع فرعی از تابع موقعیت باز است. این به این دلیل است که خروجی مدل به طور مستقیم به تابع موقعیت باز منتقل می‌شود. تنها در صورتی که نقشه خروجی به [ ۰، ۰، ۱ ] برسد، تابع موقعیت بسته نامیده می‌شود.

تابع موقعیت باز قیمت یک سهم از دارایی را برمی‌گرداند، در حالی که تابع موقعیت بسته سود (یا زیان) ایجاد شده پس از بستن موقعیت را باز می‌گرداند. سپس می‌توان از این مقادیر برای محاسبه سود کلی ایجاد شده توسط عامل استفاده کرد.

ساخت الگوریتم ژنتیک:

الگوریتم ژنتیک به عنوان ابزار دیگری برای جلوگیری از مسائل ناشی از استفاده از طبقه‌بندی و رگرسیون مورد استفاده قرار گرفت. این به این دلیل است که هیچ چیزی به عنوان بیش از حد مناسب وجود ندارد، چرا که هیچ برچسبی برای داده‌ها وجود ندارد. شما می‌توانید سایر الگوریتم‌های بدون نظارت را اجرا کنید، که می‌تواند سرعت برنامه را بهبود بخشد.

ابتدا کد عامل خود را انتخاب می‌کنیم و آن را به الگوریتم ژنتیک اضافه می‌کنیم. این سند تعداد مشخصی از عوامل را با یک معماری مدل تعریف‌شده ایجاد می‌کند. این بخش اصلی الگوریتم ژنتیک است که برای تطبیق با این مساله تغییر کرده است. این سند اساسا محیط را تنظیم می‌کند، و به نماینده اجازه می‌دهد تا در هر گام زمانی با مدل تعامل داشته باشد. این فرآیند می‌تواند چندین بار براساس اپیزودهای متغیر لن اجرا شود. این به گونه‌ای است که ما نگاه جامع‌تری به تناسب هر کارگزار داریم.

مقداری که به عنوان تناسب تعیین خواهد شد، سود مدل، در طول تعداد گام‌های زمانی مجموعه خواهد بود. این تابع ۲۰٪ بالایی از عوامل را بر اساس تناسب آن‌ها انتخاب می‌کند. تمام عوامل دیگر دور ریخته می‌شوند. سعی کنید درصد عواملی که انتخاب شده‌اند را تغییر دهید: موازنه بین سرعت محاسباتی و هم‌گرایی است. هر چه نقطه قطع پایین‌تر باشد، سرعت محاسباتی بالاتر خواهد بود. با این حال، یک نقطه قطع بالاتر می‌تواند شانس هم‌گرایی را افزایش دهد.

این تابع انتخاب برای کار با مدل‌های keras اصلاح شده است. تابع تقاطع اصلی تنها با شبکه‌های عصبی سفارشی من کار می‌کند. این عملکرد کاملا پیچیده است. برای درک این که چرا این طور است، شما باید درک کنید که تابع تقاطع چگونه کار می‌کند: دو عامل «والد» تصادفی از ۲۰٪ بالای عوامل انتخاب می‌شوند. وزن هر دوی این عوامل مسطح شده است. یک نقطه تقسیم تصادفی یافت می‌شود. وزن‌های پدر و مادر اول تا آن نقطه استخراج می‌شوند، و وزن‌های پدر و مادر دوم پس از آن نقطه به وزن‌های پدر و مادر اول الحاق می‌شوند.

مشکل این است که وزن‌ها باید مسطح شوند. این امر زمانی دشوار می‌شود که وزن‌های داخل مدل keras، لیست‌های تودرتو با اشکال مختلف ایجاد کنند. بنابراین، من درک لیست، عملکرد مسطح‌سازی عددی، و همچنین یک عملکرد مسطح‌سازی جداگانه که نوشتم را با هم ترکیب کردم.

این تابع، تابع جهش است. برای هر نماینده، ۱۰درصد شانس کوچکی وجود دارد که یک وزن تصادفی به یک مقدار تصادفی تبدیل شود. این امر به یک الگوریتم ژنتیک اجازه می‌دهد تا به آرامی اما با اطمینان از حداقل محلی خارج شود. از آنجا که همه این موارد شامل یک تابع اجرایی است، این بخش از برنامه، تمام توابع تعریف‌شده قبلی را اجرا می‌کند. اولین نماینده لیست را برمی‌گرداند. این نماینده، در تئوری، بهترین نماینده ایجاد شده توسط الگوریتم ژنتیک خواهد بود. اتلاف از هر نسل نیز برگردانده شده است به طوری که اتلاف را می‌توان ترسیم کرد، تا ببینیم آیا الگوریتم ژنتیک در حال پیشرفت است یا خیر.

این تابع الگوریتم ژنتیک را اجرا می‌کند. من در نهایت مدل را به یک شبکه کانولوشن تبدیل کردم، اما واقعا تفاوت زیادی ایجاد نکرد.

نتایج:

هزینه محاسباتی برای این برنامه به قدری زیاد بود که من نیاز داشتم از Google Colab GPU برای اجرای این سند استفاده کنم. من متوجه شدم که نتایج کاملا متناقض بودند، عمدتا به این دلیل که مدل بسیار ساده بود. من سعی کردم پیچیدگی مدل را افزایش دهم، اما هزینه محاسباتی بسیار بالا بود.

من فکر می‌کنم که بهترین راه برای مبارزه با این کار بهبود هر یک از بخش‌های منحصر به فرد است، تا به آن سرعت ببخشد.

این متن با استفاده از ربات مترجم مقالات دیتاساینس ترجمه شده و به صورت محدود مورد بازبینی انسانی قرار گرفته است.در نتیجه می‌تواند دارای برخی اشکالات ترجمه باشد.
مقالات لینک‌شده در این متن می‌توانند به صورت رایگان با استفاده از مقاله‌خوان ترجمیار به فارسی مطالعه شوند.