در حالی که پایتون نسبت به بسیاری از زبانهای کامپایل کندتر است ، استفاده از آن آسان و بسیار متنوع است. برای بسیاری ، به ویژه در حوزه علوم داده ، عملی بودن زبان ملاحظات سرعت را مورد ضرب و شتم قرار می دهد - این مانند یک چاقوی ارتش سوئیس برای برنامه نویسان و محققان است.
متأسفانه برای Quants ، پایتون هنگام تکرار (مقدار زیادی از داده ها) به یک تنگنا واقعی تبدیل می شود. به همین دلیل ، یک اکوسیستم کامل از بسته های علمی مانند Numpy و Pandas وجود دارد که برای عملکرد بسیار بهینه شده اند ، با مسیرهای کد بحرانی که اغلب در Cython یا C. نوشته شده است. داده ها به روشی کارآمد.
این توانایی هنگام ساخت شاخص هایی که می توانند به مجموعه ای از عملیات بردار مانند OBB ترجمه شوند ، بسیار مورد استقبال قرار می گیرد. اما حتی عملیات غیر بردار ، مانند میانگین متحرک وزن نمایی (EMA) که دارای شاخص های بی شماری مانند MACD هستند ، به یک زبان کامپایل شده اجرا شده و به عنوان یک عملکرد آماده برای استفاده پایتون ارائه می شوند. اما گاهی اوقات ، یک شاخص صرفاً با استفاده از عملیات استاندارد آرایه دشوار یا حتی غیرممکن است زیرا این شاخص وابستگی به مسیر را معرفی می کند ، جایی که امروز یک تصمیم به تصمیمی که دیروز گرفته می شود بستگی دارد. یکی از اعضای چنین خانواده ای از شاخص ها فوق العاده است.
در این مقاله ، شما یاد می گیرید که چگونه یک شاخص Supertrend را طراحی و پیاده سازی کنید و به تدریج آن را به سمت عملکردی که هرگز دیده نشده با استفاده از TA-LIB و NUMBA بهینه کنید. ما همچنین نشانگر تازه ایجاد شده را در طیف وسیعی از پارامترها با استفاده از VectorBT Pro انجام خواهیم داد ( + نکات مربوط به نحوه اجرای قطعات مختلف را با استفاده از نسخه جامعه نیز مشاهده کنید).
اولین قدم همیشه گرفتن داده های (درست) است. به طور خاص ، ما به مقدار کافی داده برای معیار اجرای مختلف Supertrend نیاز داریم. بیایید 2 سال از داده های ساعتی بیت کوین و اتریوم را از Binance با استفاده از کلاس Binancedata VectorBT بکشیم:
نکته: از بارگیری در نسخه جامعه استفاده کنید.
عملیات واکشی برای هر دو نماد حدود 80 ثانیه طول کشید تا انجام شود. از آنجا که Binance ، مانند هر مبادله دیگر ، هرگز کل داده ها را به طور همزمان بازگرداند ، ابتدا VectorBT حداکثر مقدار داده را که از اول ژانویه 2020 شروع می شود ، درخواست کرد و سپس به تدریج داده های باقی مانده را با احترام به محدودیت نرخ API Binance جمع آوری کرد. در کل ، این منجر به 36 درخواست در هر نماد شد. سرانجام ، VectorBT در صورتی که شاخص ها یا ستون های آنها متفاوت باشد ، هر دو نماد را تراز کرد و شاخص نهایی آگاه-آگاه (در UTC) را ایجاد کرد.
برای جلوگیری از ضربه مکرر سرورهای Binance هر بار که یک جلسه جدید پایتون را شروع می کنیم ، باید داده های بارگیری شده را به صورت محلی با استفاده از داده های VectorBT. to_csv یا data. to_hdf ذخیره کنیم:
نکته: داده های محلی توسط نسخه جامعه پشتیبانی نمی شوند اما هنوز هم می توانید با استفاده از پاندا داده ها را به صورت دستی ذخیره و بازیابی کنید.
سپس می توانیم با استفاده از HDFDATA به راحتی به داده های ذخیره شده دسترسی پیدا کنیم:
پس از داده ، اجازه دهید نگاهی گذرا به آنچه در داخل است ، بیندازیم. برای به دست آوردن هر یک از DataFrames ذخیره شده ، از فرهنگ لغت Data. data با هر DataFrame که توسط نماد کلید است استفاده کنید:
ما همچنین می توانیم یک مرور کلی از همه نمادهای ضبط شده دریافت کنیم:
هر نماد 17514 نقطه داده بدون NANS دارد - خوب!
اگر تا به حال با VectorBT کار کرده اید ، می دانید که VectorBT عاشق داده هایی است که با نمادهایی به عنوان ستون - یکی در هر پشتی - تهیه می شود و نه ویژگی هایی به عنوان ستون. از آنجا که Supertrend به قیمت بالا ، پایین و نزدیک بستگی دارد ، اجازه دهید این سه ویژگی را به عنوان DataFrames جداگانه با استفاده از Data. get بدست آوریم:
همه ما تصمیم داریم اولین شاخص Supertrend خود را طراحی کنیم!
طرح
Supertrend یک شاخص دنبال کننده روند است که از میانگین محدوده واقعی (ATR) و قیمت متوسط برای تعریف مجموعه ای از باندهای فوقانی و پایین استفاده می کند. ایده بسیار ساده است: وقتی قیمت نزدیک از بالای باند بالا عبور می کند ، دارایی در نظر گرفته می شود که در حال صعود است ، از این رو یک سیگنال خرید است. هنگامی که قیمت نزدیک از زیر باند پایین عبور می کند ، دارایی در نظر گرفته می شود که از صعود خارج شده است ، از این رو یک سیگنال فروش است.
بر خلاف ایده ، روش محاسبه چیزی ساده است:
حتی اگر گروههای اصلی با استفاده از ابزارهای استاندارد بتوانند به خوبی محاسبه شوند ، مطمئناً هنگام تلاش برای انجام این کار برای گروههای نهایی ، سردرد خواهید گرفت. اجماع در بین بیشترین راه حل های منبع باز استفاده از یک حلقه اصلی پایتون و نوشتن عناصر آرایه یک بار است. اما آیا این مقیاس پذیر است؟ما اینجا هستیم تا دریابیم!
پاندا
پاندا یک ابزار سریع ، قدرتمند ، انعطاف پذیر و آسان برای استفاده از ابزار منبع باز و ابزار دستکاری است. از آنجا که این یک کتابخانه برای پردازش داده ها در پایتون است ، اجازه دهید اولین اجرای خود را با استفاده از پاندا به تنهایی بنویسیم. این یک ستون و یک ترکیبی از پارامترها خواهد بود و چهار آرایه را برمی گرداند: یکی برای Supertrend (Trend) ، دیگری برای جهت (dir_) ، دیگری برای صعود (طولانی) و دیگری برای پایین آمدن (کوتاه). ما همچنین برای خوانایی ، اجرای را به 5 قسمت تقسیم خواهیم کرد و می توانیم در هر زمان هر مؤلفه ای را بهینه کنیم:
- محاسبه قیمت متوسط - get_med_price
- محاسبه ATR - get_atr
- محاسبه باند های اصلی - get_basic_bands
- محاسبه باندهای نهایی - get_final_bands
- قرار دادن همه معماها - supertrend
بیایید عملکرد Supertrend را روی نماد BTCUSDT اجرا کنیم:
اگر سر سری Supert را با استفاده از Supert. head (10) چاپ کنید ، متوجه می شوید که 6 نقطه داده اول همه NAN هستند. این امر به این دلیل است که دوره نورد ATR 7 است ، بنابراین 6 ویندوز اول محاسبه شده حاوی داده های ناقص است.
یک نمودار 1000 کلمه ارزش دارد. بیایید ماه اول داده ها (ژانویه 2020) را ترسیم کنیم:
ما مقادیر Supertrend را تولید و تجسم کرده ایم ، اما عملکرد چیست؟آیا می توانیم دستگاه بیش از حد خود را با هزاران ترکیب پارامتر در حال چرخش بسازیم؟نه خیلی سریع. همانطور که احتمالاً حدس زده اید ، عملکرد Supertrend برای محاسبه مدتی طول می کشد:
آخ! انجام 1000 پشتی تقریباً 33 دقیقه طول می کشد.
بیایید بشنویم که پانداس TA در این باره چه می گوید:
این یک سرعت 3 برابر است ، بیشتر به این دلیل که Pandas TA از ATR از TA-Lib استفاده می کند.
آیا اکنون قابل قبول است؟البته که نه. آیا می توانیم از این بهتر شویم؟جهنم بله!
numpy + numba = ❤
پاندا هر زمان که می خواهد داده های جدولی ناهمگن را دستکاری کند ، می درخشد ، اما آیا این واقعاً برای شاخص ها کاربرد دارد؟شاید متوجه شده باشید که حتی اگر ما از پاندا استفاده کردیم ، هیچ یک از عملیات موجود در هیچ یک از توابع تازه تعریف شده ما از برچسب های فهرست یا ستون استفاده نمی کند. علاوه بر این ، اکثر شاخص ها آرایه های بازگرداندن و بازگشت از همان ابعاد و شکل را می گیرند ، که باعث می شود توسعه شاخص به یک چالش کاملاً جبری باشد که می تواند به خوبی در مراحل مختلف بردار تجزیه شود یا بر اساس هر عنصر (یا هر دو!) حل شود. با توجه به اینکه پاندا فقط Numpy را گسترش می دهد و دومی به عنوان یک بسته سریعتر (اگرچه سطح پایین تر) در نظر گرفته می شود ، اجازه می دهیم منطق خود را به جای آن با آرایه های numpy سازگار کنیم.
هر دو کارکرد get_med_price و get_basic_bands بر اساس محاسبات اساسی حسابی مانند افزودن و ضرب هستند که برای هر دو آرایه پاندا و Numpy قابل استفاده هستند و نیازی به تغییر دیگری ندارند. اما در مورد get_atr و get_final_bands چیست؟اولی را می توان با استفاده از زرادخانه Numpy و VectorBT از توابع Numba ترکیب کرد:
از طرف دیگر ، دومی یک الگوریتم تکراری است-این یک مناسب برای Numpy و یک مناسب برای Numba است ، که می تواند به راحتی با سرعت کد دستگاه برای حلقه ها اجرا شود:
اگر به عملکرد بالا نگاه کنید ، متوجه خواهید شد که 1) این یک کد معمولی پایتون است که حتی بدون تزئین با NJit می تواند اجرا شود ، و 2) تقریباً با اجرای با پاندا یکسان است - تفاوت اصلی در هر ILOC است[)] جایگزین [.]. ما می توانیم یک تابع ساده پایتون بنویسیم که بر روی ثابت و آرایه های Numpy کار می کند ، و Numba سعی خواهد کرد که آن را بسیار سریعتر ، کاملاً خودکار انجام دهد. آیا این چشمگیر نیست؟
بیایید به نتیجه این اصلاح مجدد نگاه کنیم:
همانطور که انتظار می رفت ، این آرایه هایی شبیه به آنهایی هستند که توسط عملکرد Supertrend بازگردانده شده اند ، فقط بدون هیچ برچسب. برای ضمیمه برچسب ها ، ما به سادگی می توانیم انجام دهیم:
نمی دانید کد ما در عملکرد چقدر به دست آورده است؟تعجب بیشتر:
این یک سرعت 780 برابر با یک پانداس متوسط است
numpy + numba + ta-lib = ⚡
اگر فکر می کنید این نتیجه را نمی توان در صدر قرار داد ، پس ظاهراً شما با TA-Lib کار نکرده اید. حتی اگر هیچ شاخص فوق العاده ای در TA-Lib موجود نباشد ، ما هنوز هم می توانیم از توابع نشانگر بسیار بهینه شده آن برای محاسبات میانی استفاده کنیم. به طور خاص ، به جای اختراع مجدد چرخ و اجرای قیمت متوسط و عملکرد ATR از ابتدا ، می توانیم به ترتیب از توابع MedPrice و ATR TA-Lib استفاده کنیم. آنها دو مزیت عمده نسبت به اجرای سفارشی ما دارند:
- واحد عبور از طریق داده ها
- بدون تلفیقی از Numba
پیشرفت 4 برابر دیگر - تا زمانی که یک معامله گر دیگر یک ستون داده را پردازش کرد ، ما حدود 3 هزار ستون پردازش می کردیم. موافقت کرد ، سرعت نشانگر ما به آرامی مسخره می شود
کارخانه شاخص
بیایید اینجا متوقف شویم و از خود بپرسیم: چرا ما حتی به چنین عملکرد دیوانه وار احتیاج داریم؟
این زمانی است که بهینه سازی پارامتر بازی می شود. دو پارامتر که ما داریم - دوره و ضرب - مقادیر پیش فرض معمولاً در تجزیه و تحلیل فنی استفاده می شوند. اما چه چیزی این ارزش ها را جهانی می کند و چگونه می دانیم ارزش بهتری برای بازارهایی که در آنها شرکت می کنیم وجود ندارد؟تصور کنید خط لوله ای دارید که می تواند صدها یا حتی هزاران پارامتر را پشت سر بگذارد و تنظیمات و رژیم های بازار را نشان دهد که به طور متوسط ارتباط بهتری دارند؟
IndicatorFective یک نیروگاه شخصی VectorBT است که می تواند هر عملکرد شاخص را پارامتر کند. برای به دست آوردن بهتر از این به معنای این ، اجازه دهید عملکرد Faster_Supertrend_Talib را شارژ کنیم:
نکته: takes_1d توسط نسخه جامعه پشتیبانی نمی شود-شما باید سریعتر_سواپرترند_تالی را بپذیرید آرایه های دو بعدی را قبول کنید.
کارخانه شاخص کلاس است که می تواند کلاسهای به اصطلاح شاخص را تولید کند. شما می توانید تصور کنید که این یک کمربند نقاله است که می تواند مشخصات عملکرد نشانگر شما را به خود اختصاص دهد و یک کلاس پایتون مستقل را برای اجرای آن عملکرد به روشی بسیار انعطاف پذیر تولید کند. در مثال ما ، هنگامی که ما VBT. if (.) نامیدیم ، آن را به صورت داخلی یک کلاس نشانگر ایجاد کرده است ، و هنگامی که ما سریعتر_ supertrend_talib را به inditorfactory. with_apply_func تهیه کردیم ، یک روش supertrend. run را برای اجرای شاخص وصل کرد. بیایید آن را امتحان کنیم!
توجه کنید که چگونه شاخص Supertrend ما به طرز جادویی آرایه های دو بعدی پانداس را پذیرفت ، حتی اگر این عملکرد فقط بتواند روی آرایه های Numpy یک بعدی کار کند. نه تنها Supertrend را در هر ستون محاسبه کرد ، بلکه آرایه های حاصل را نیز برای راحتی خالص به فرمت پاندا تبدیل کرد. بنابراین ، چگونه همه اینها بر عملکرد تأثیر می گذارد؟
نه چندان! با وجود تمام پردازش های قبل و بعد از آن ، شاخص برای پردازش یک ستون تقریباً به یک میلی ثانیه نیاز دارد (یعنی نقاط داده 17K).
اصطلاحات
اگر فکر می کنید فراخوانی vbt. if (.) و ارائه input_names ، param_names و سایر اطلاعات به صورت دستی کار بسیار زیادی است ، خوب ، VectorBT چیزی برای شما دارد. ما Faster_Supertrend_Talib به طور موثری یک جعبه سیاه برای کارخانه شاخص است - به همین دلیل کارخانه نمی تواند آن را درون نگرانه کند و اطلاعات مورد نیاز را به صورت برنامه ای استخراج کند. اما اگر ما سریعتر_سوپرترند_تالیب را به یک عبارت تبدیل کنیم ، به راحتی می توانست!
عبارات رشته های منظم هستند که می توانند در کد پایتون ارزیابی شوند. با ارائه چنین رشته ای به inditorfactory. from_expr ، این کارخانه قادر خواهد بود تا آنچه را که در داخل است ، مشخص کنید ، مشخصات را تجزیه کنید و یک کلاس نشانگر تمام عیار تولید کنید.
در اینجا عبارتی برای FASTR_SUPERTREND_TALIB وجود دارد:
با استفاده از حاشیه نویسی با @ ما به کارخانه می گوییم که چگونه متغیرهای خاص را درمان کنیم. به عنوان مثال ، هر متغیر با پیشوند talib با عملکرد TA-Lib مربوطه که با پخش و چند بعدی به روز شده است جایگزین می شود. همچنین می توانید ببینید که پارامترها با p حاشیه نویسی شده اند ، در حالی که ورودی ها و خروجی ها به هیچ وجه حاشیه نویسی نشده اند - کارخانه دقیقاً می داند که قیمت بالایی است ، در حالی که آخرین خط ظاهراً 4 شیء خروجی را برمی گرداند.
به هر حال ، این دقیقاً نحوه اجرای ALPHA های WorldQuant در VectorBT است. هرگز دوست داشتن پایتون را برای جادویی که امکان پذیر است
توجه: عبارات توسط نسخه جامعه پشتیبانی نمی شوند.
توطئه
به یاد دارید که چگونه ما قبلاً Supertrend ترسیم کردیم؟ما مجبور شدیم دامنه تاریخ را از هر آرایه خروجی به صورت دستی انتخاب کنیم و با عبور از شکل در اطراف آن را به طرح اضافه کنیم. بیایید SUPERTREND SUPERTREND را زیر کلاس تعریف کنیم و یک طرح متد را تعریف کنیم که همه اینها را برای ما انجام می دهد:
اما چگونه قرار است محدوده تاریخ را برای طرح انتخاب کنیم؟بسیار آسان: کارخانه نشانگر درست مانند هر شیء معمولی پانداس ، Supertrend را قابل توصیف کرد! بیایید همان محدوده و نماد تاریخ را ترسیم کنیم اما پالت رنگ را کمی تغییر دهیم:
پشتی
Backtesting معمولاً ساده ترین مرحله در VectorBT است: مقادیر شاخص را به دو آرایه سیگنال تبدیل کنید - ورودی و خروج - و آنها را به نمونه کارها عرضه کنید. برای بهتر کردن تست واقعیت ، بیایید چندین تنظیم انجام دهیم. از آنجا که ما مقادیر Supertrend را بر اساس قیمت نزدیک فعلی محاسبه می کنیم و VectorBT بلافاصله سفارشات را اجرا می کند ، ما اجرای سیگنال ها را با یک تیک به جلو تغییر خواهیم داد:
ما همچنین کمیسیون 0. 1 ٪ را اعمال خواهیم کرد:
ما یک نمونه کارها با دو ستون داریم که می توان با ابزارهای داخلی متعدد مورد تجزیه و تحلیل قرار گرفت. به عنوان مثال ، بیایید آمار نماد EthusDT را محاسبه و نمایش دهیم:
بهینه سازی
بهینه سازی در VectorBT می تواند به دو روش انجام شود: تکراری و با ستون.
رویکرد اول شامل یک حلقه ساده است که از هر ترکیبی از پارامترهای استراتژی عبور می کند و کل منطق را اجرا می کند. این امر به شما نیاز دارد تا به صورت دستی یک شبکه پارامتر مناسب تولید کنید و نتایج را برای تجزیه و تحلیل جمع کنید. در صعود ، شما می توانید از HyperOpt و سایر ابزارهایی که بر اساس هرچه کار می کنند استفاده کنید.
رویکرد دوم به طور بومی توسط VectorBT پشتیبانی می شود و شامل ستون های انباشته می شود. اگر 2 نماد و 5 پارامتر دارید ، VectorBT در کل 10 ستون ایجاد می کند-یکی برای هر نماد و پارامتر ، و پشت هر ستون به طور جداگانه بدون ترک Numba (به همین دلیل بیشتر توابع در VectorBT در پردازش داده های دو بعدی تخصص دارند ، توسطمسیر). نه تنها این یک مزیت عملکرد عظیم برای داده های کوچک و متوسط دارد ، بلکه این امر به موازات آن نیز امکان پذیر است با NUMBA و ارائه نتایج در قالب دوستانه پاندا.
بیایید مقادیر دوره 4 ، 5 را آزمایش کنیم. 20 ، و مقادیر چند برابر 2 ، 2. 1 ، 2. 2 ،. 4 ، که در کل 336 ترکیب پارامتر به دست می آورد. از آنجا که شاخص ما اکنون پارامتر شده است ، می توانیم آن دو آرایه پارامتر را مستقیماً به روش Supertrend. run منتقل کنیم و همچنین با آموزش آن برای انجام محصول دکارتی با استفاده از param_product = پرچم واقعی:
این شاخص 672 تکرار - 336 در هر نماد. بیایید ستون هایی را که انباشته شده اند ببینیم:
هر یک از DataFrames اکنون 672 ستون دارد. بیایید با مشخص کردن ستون به عنوان یک Tuple معمولی ، آخرین ترکیب را ترسیم کنیم:
هنگام جمع آوری تعداد زیادی ستون ، اطمینان حاصل کنید که از رم خارج نشده اید. شما می توانید با استفاده از روش pickleable. getSize اندازه هر شیء قابل انتخاب را در VectorBT چاپ کنید:
قسمت پشتی بدون توجه به تعداد ستون ها ، یکسان است:
به جای محاسبه تمام آمار برای هر ترکیب واحد ، اجازه دهید یک نقشه گرمای از مقادیر شارپ آنها را با دوره هایی که به صورت افقی گذاشته شده اند و ضرباننده ها به صورت عمودی قرار داده ایم ، ترسیم کنیم. از آنجا که ما یک سطح ستون اضافی داریم که حاوی نمادها است ، ما آن را به یک کشویی تبدیل خواهیم کرد:
اکنون ما یک نمای کلی از هر منطقه پارامتر که در طول دوره پس زمینه عملکرد خوبی داشته اند ، داریم!
نتیجه
این مثال ثابت کرد که تجزیه و تحلیل فنی با پایتون لازم نیست آهسته باشد: طیف وسیعی از بسته های شتاب دهنده مانند Cython ، Pypy و Numba در دسترس است تا عملکرد کد ما را با سایر زبانهای کامپایل شده باشد ، در حالی که ماهنوز هم می تواند از قدرت اکوسیستم بسته غنی و انعطاف پذیری عالی این زبان برنامه نویسی لذت ببرد. بسته VectorBT با این امکان که از شتاب معرفی شده استفاده کنیم ، به عنوان مثال ، برای انجام بهینه سازی پارامتر در استراتژی های معاملاتی دلخواه و تجزیه و تحلیل پویایی کل بازارها در چشمان چشم ، یک مکان محکم در آن اکوسیستم می گیرد.
آموزش اصلی را از اینجا مشاهده کنید.
حمایت کردن
لطفاً از من در مورد حامیان GitHub حمایت کنید و در اکوسیستم در حال رشد جدید برای تجزیه و تحلیل معاملات آفلاین کمک کنید. در عوض ، شما می توانید دسترسی زودهنگام به VectorBT Pro - جانشین تجاری توسعه یافته و VectorBT با هدف ارائه ابزارهای تجزیه و تحلیل حرفه ای برای Quants - و محتوای یادگیری منحصر به فرد جدید را بدست آورید. به طور خاص ، شما یاد خواهید گرفت که چگونه
بهترین استراتژی معاملات...
ما را در سایت بهترین استراتژی معاملات دنبال می کنید
برچسب :
نویسنده : صدرا ذوالریاستین
بازدید : 61
تاريخ : سه
شنبه
22 فروردين
1402 ساعت: 19:21