
رویـــکــــرد شــــیءگرا در MQL [۱]
مقدمه
این مقاله، در ابتدا، برای برنامهنویسهای حرفهای و حتی تازهکارها، که در محیط MQL کار میکنند، بسیار جذاب خواهد بود. همچنین توصیه میشود توسعهدهندگان محیط MQL و ایدئولوژیستها نیز این مقاله را بخوانند، چراکه قطعاً پروژههای خوبی از دل این مقاله بیرون خواهند آمد. همچنین، تا حد زیادی میتوانید ایدههای مشابه را در مقالههای Universal Expert Advisor Template و Sending Trading Signals in a Universal Expert Advisor پیدا کنید.
بسیار خب،
یکی از معایب MQL، بهنظر شخص والای خودم، و از نظر برنامهنویسی، این است که رویکرد شیءگرایانه در ساخت مدل سیستم معاملاتی، ندارد. توسعهدهندگان MQL دو راه پیش روی ما میگذارند: استفاده از فراخوانی توابع اکسترنال یا استفاده از پارامتر معامله MAGIC برای شناسایی متعلقات معامله [معامله متعلق به کجاست].
فیالواقع اگر فقط یک سیستم [ترید] را روی یک حساب داشته باشیم، نیازی به شناسایی نیست. اما وقتی این امکان در اختیار ما گذاشته شده که بتوانیم روی یک حساب چندین سیستم معاملاتی خودکار را داشته باشیم، بدون MAGIC هیچ نوع خاکی نمیشود بر سر ریخت! حتی وقتی توابع اکسترنال را صدا میزنیم، باید [وضعیت] آنها را تعیین کنیم. البته شاید حضرتعالی بگویید میشود یک آرایه بهنام OrderTicket ایجاد کرد و مشخص کنیم که این آرایه متعلق به فقط یک سیستم ترید است، اما این را بدانید که در برخی از بروکرهای نسبتاً محترم، تیکت معامله در سوآپ، تغییر میکند (در حقیقت، یکی بسته و دیگری باز میشود). به همین دلیل است که بدون MAGIC هرگز!
حال که توسعهدهندهها سرشان شلوغ است و مشغول توسعه و انعطافپذیری بیشتر زبان MQL هستند، بیایید سعی کنیم همین الان رویکرد شیءگرایانه را در ساخت یک مدل معاملاتی پیادهسازی کنیم.
این یک سیستم ترید مطابق با مدل شیءگرا من است. البته، جهانی نیست، اما اکنون رویکرد دیگری سراغ ندارم.
پس بیایید این مدل را آنالیز کنیم.
- A) سیستم سیگنال (SS)
هدف این ماژول، پردازش و تفسیر خوانشهای دریافتی است. معمولاً، “Object” این سیستم سیگنال، مجموعهای از اندیکاتورها است، برای مثال، مووینگ اَورجها. نتیجهی پردازش خوانشها و مقادیر اندیکاتور این است که، “این Object” (یا سمافور) سیگنالهایی تولید میکند تا ورود/خروج، یا اصلاح معامله و غیره را داشته باشیم.
سمافور سیگنالاَش را شکل میدهد و آن را به یک Object دیگر از ماژول ورود/خروج (Enter/Exit (EE)) میفرستد.
تنظیم سمافور در MQL نسبتاً ساده است.
- تعریف یک مشخصکننده جهانی[۲] با استفاده از #define
بهتر است شمارههای متوالی مانند ۱، ۲، ۳، ۴، …. تعیین نشوند، بلکه ۵تا ۵تا یا ۱۰تا ۱۰تا باشد، تا در یک اکسپرت بتوانیم یک سیگنال را برای چندین فرآیند استفاده کنیم (ماژول دوم را ببینید).
//+------------------------------------------------------------------+ //| Signals.mqh | //| Copyright © ۲۰۰۷ Сергеев Алексей | //| los@we.kherson.ua | //+------------------------------------------------------------------+ #property copyright "Copyright © ۲۰۰۷, Сергеев Алексей " #property link "mailto: los@we.kherson.ua" #property library #define BLACKSYS 10 #define BORCHAN 20 #define ELDER 80 #define ENVELOP 90
- سپس در تابع جهانی این ماژول، باید پردازشگر (processor) آن را فعال کنیم.
int CheckSignal(bool bEntry, int SignalID) { switch (SignalID) { case BLACKSYS: return (BlackSys(bEntry)); break; case BORCHAN: return (BorChan(bEntry)); break; case ELDER: return (Elder(bEntry)); break; case ENVELOP: return (Envelop(bEntry)); break; default: return (-1); } }
- و قدم آخر توضیح توابع است.
در اینجا مثالی برای پردازش سیگنالهای یک Object داریم که ویژگیهای اندیکاتور Envelope را به ارث برده است.
int Envelope(bool bEntry) { int MA=21; double Deviation=0.6; int Mode=MODE_SMA;//0-sma, 1-ema, 2-smma, 3-lwma int Price=PRICE_CLOSE;//0-close, 1-open, 2-high, 3-low, 4-median, 5-typic, 6-wieight double envH0, envL0, m0; double envH1, envL1, m1; envH0=iEnvelopes(NULL, 0, MA, Mode, 0, Price, Deviation, MODE_UPPER, 0); envL0=iEnvelopes(NULL, 0, MA, Mode, 0, Price, Deviation, MODE_LOWER, 0); envH1=iEnvelopes(NULL, 0, MA, Mode, 0, Price, Deviation, MODE_UPPER, 1); envL1=iEnvelopes(NULL, 0, MA, Mode, 0, Price, Deviation, MODE_LOWER, 1); m0 = (Low[0]+High[0])/2; m1 = (Low[1]+High[1])/2; //----- condition for operation execution if (bEntry) //for opening { if (envH0<m0 && envH1<m1) return (OP_SELL); if (envL0>m0 && envL1>m1) return (OP_BUY); } else //for closing { if (envH0<m0 && envH1<m1) return (OP_BUY); if (envL0>m0 && envL1>m1) return (OP_SELL); } return (-1); //no signal }
بنابراین، ماژولی بدست میآوریم که شامل objects-signalsهای مختلف است.
- B) Objectهای بلوک EE حداقل وظایف را دارند:
اول، objectهای آن با objects-signals فعلوانفعال دارند – آنها را مشاهده کنید. چرخهی زندگی و تعاملات اینگونه است:
بررسی سمافور »» اگر هرگونه سیگنال مثبتی وجود داشته باشد »» باز کردن/بستن/اصلاح پوزیشنها »» واگذاری کنترل به objectها در ماژول PS.
تمام objectها در ماژول EE، پیشوند Process… دارند،که رفتار آنها را بهطور خاص تعیین میکند.
برای مثال:
ProcessAvgLim // - the object processes signals with opening pending limit-orders and positions averaging ProcessTurn // - the object processes signals with position turning
هر نمونه از کلاس سیستم ترید باید خصوصیات فردی خودش را داشته باشد (همه این را متوجه میشویم و در ماژولهایمان استفاده میکنیم)، مانند سود، حد ضرر، سیستم مدیریت پول مخصوص به خود، [درست] همانند دیگر پارامترهای اضافی که در حالتهای مختلف تریلینگ استفاده شدهاند، و غیره.
هنگام بهکار بردن این ویژگیها، چندین حالت از رویکرد را امتحان کردم و بهنظر من مناسبترین آنها در MQL، ایجاد یک آرایهی دوبُعدی است. در اینجا توضیحات مربوطه را داریم:
double SysPar[nSignal][11]; #define _TP 0 // Profit #define _NullTP 1 // profit level, after which we set into losslessness #define _NullTP2 2 // profit level, after which we set into losslessness #define _TS 3 // distance of the trailing stop #define _NullSL 4 // level, after achieving which the expected profit is transfered into opening point #define _SL 5 // level, after achieving which the expected profit is transfered into opening point #define _dSL 6 // the initial step upon the opening level of the next order in the position support #define _dStep 7 // The step is increased in .. times upon the level of the next opening #define _dLot 8 // In how many times (as compared to the last one) we increase the lot on the next one #define _nLot 9 // In how many times (as compared to the initial one) we increase the lot on the next one string SysParName[nSignal];
که در اینجا nSignal، مشخصکنندهی[۳] object-signals است.
برای مثال:
SysPar[ENVELOP][_TS] = 40.0; // distance of the trailing stop SysPar[ENVELOP][_NullSL] = 20.0;// level, after achieving which the expected profit is transfered into opening point SysPar[ENVELOP][_SL] = 70; // changing stop-loss
مطابق میل خود، ممکن است بخواهید تعداد پارامترهای تعیینشدهی این ساختار-آرایه را افزایش دهید.
بنابراین، بعد از تنظیم پارامترها، تابع پردازش سمافور را فرا میخوانیم. بهعبارت دیگر، با سیستم سیگنال تعامل میکنیم. این کار در تابع مورد علاقهی من یعنی start() انجام میشود.
void start() { ProcessAvgLim(ENVELOP, ENVELOP, Green, Red); … …
همانطور که در این طرح میبینید، در این سیستم ترید، ما ۴ سمافور ثبتشده و ۳ ناظر (observer) داریم. هر سمافور بر اساس مدل خودش از تفسیر خوانش، بنا شدهاست.
برای مثال، سمافور ۱ سیگنالهای آنالیز اندیکاتور MACD را میفرستد. Observer 1 در جای خودش بعد از دریافت این سیگنالها معاملات را در یک طرح سادۀ ProcessSimple باز میکند.
Observer 2 و ۳، سختتر هستند. هرکدام از آنها سیگنالهای دو سمافور را کنترل میکند. و، نتیجتاً، رویکرد بازشدن معاملات متفاوت است.
پس، بعد از اینکه پارامترهای observer را تعیین کردیم و یک سمافور را به آن متصل ساختیم، نیاز داریم که بازشدن پوزیشنها را کنترل و دنبال کنیم.
“مسئول” وضعیت معاملات بازشده، objectهای ماژول Position Support (PS) هستند.
- C) Block PS، بهنظر من، جزء جالبترینها است، و اهمیت آن کمتر از سمافورها نیست.
در اینجا، حالتهای مختلف تریلینگ، بهکار گرفته شدهاند، معاملات انتظاری باز شدهاند، position support و locking، کنترل سود و ضرر، و موارد دیگر را داریم. چنین PSایی باید روی سیگنالهای EE، دربارهی خروج از بازار در شرایط [وجود] پوزیشنهای ضرر، با کمترین ضرر [ممکن]، بهاندازهی کافی واکنش نشان دهد.
یک کتابخانهی جالب از تریلینگها روی این سایت وجود داردLibrary of Functions and Expert Advisors for trailing / Yury Dzyuban . تمام انواع تریلینگها بهسادگی به این سیستم متصل میشوند.
برای اینکه درک راحتتری داشته باشیم، تمام support objectها از پیشوند Trailing… شروع میشوند.
طرح آن بدین گونه است:
فراخوانی، و کنترل تبادل از یک observer به تریلینگ، در همان تابع start() انجام شدهاست
void start() { ProcessSimple(MACD, MACD, Black, Plum); TrailingSimple(MACD, Black, Plum); ProcessAvgLim(ENVELOPE, ENVELOPE, Green, Red); TrailingAvgLim(ENVELOPE, Green, Red); }
یک نوع مثال از رویکرد شیءگرا در ساخت یک سیستم را دیدیم. میتوانید از این رویکرد استفاده کنید.
بار دیگر در اینجا میخواهم از توسعهدهندگان MQL خواهش کنم، امکانات این زبان را گسترش دهند. بهعنوان مثال در اینجا حالتی از بهکارگیری کلاسهای شیء[۴]، نوشتهشده با زبان C++ را، داریم.
struct SystemParam { double TP; // profit double NullTP; // profit level, after which we set into losslessness double NullTP2; // profit level, after which we set into losslessness a set of one-direction orders double TS; // distance of the trailing stop double NullSL; // loss level, at which we transfer the expected profit into losslessness double SL; // stop-loss double dSL; // a step upon the opening level of the next order for the position support double dStep; // In how many times we increase the step upon the opening level of the next order double dLot; // In how many times we increase the lot on the next order } class MTS { public: string m_NameTS; // system name (for making comments for the order) int m_SignalID; // identifier of trading signals (for semaphore inquiry) long int Tickets[1000]; // array of order tickets, selected upon m_SignalID (MAGIC) SystemParam SysPar; // Trading system parameters color ClrBuy; // color for indicating BUY order color ClrSell; // color for indicating SELL order // Initialization void MyMTS (); // standard function that sets initial values of the system void MyMTS (int aSignalID, int nProcessMode, int nTrailingMode); // standard function // that sets initial values of the system // Implementation int CheckSignal(); //function of checking state of market signals // Processing int m_nProcessMode; // identifier of observation mode int m_nTrailingMode; // identifier of trailing mode void Process(); // EE function - processing CheckSignal() void Trailing(); // PS function - order trailing // Special functions bool CreatTicketArray(int dir); // creating an array of tickets, selected upon m_SignalID (MAGIC) // and desired type dir: buy, sell, buylim, buystop, sellim, sellstop bool ArrangeOrderBy(int iSort); // arranging array Tickets upon the parameter (date, profit, price...) }; … MTS MyTS; // our trading system … int init() { … MyTS.m_SignalID = SIGNAL_MACD; // our system is based on MACD signals MyTS.m_NameTS = "MACD"; MyTS.SysPar.TP = 500; MyTS.SysPar.NullTP = 20; MyTS.SysPar.TS = 50; MyTS.SysPar.SL = 1000; MyTS.SetProcess (MODE_AVGLIM); MyTS.SetTrailing (MODE_AVGLIM); … } void start() { … MyTS.Process (); MyTS.Trailing (); … } … void MTS::Process() { … int Signal = CheckSignal(true, m_SignalID); //calling the global function of signal processing if (Signal == -1) return; // if no signal, do nothing //----- for buying if(Signal == OP_BUY) { } if(Signal == OP_SELL) { } … } … // global processor of semaphores int CheckSignal(bool bEntry, int SignalID) { switch (SignalID) { case ELDER: return (Elder(bEntry)); break; case ENVELOP: return (Envelop(bEntry)); break; case LAGUER: return (Laguer(bEntry)); break; case MACD: return (Macd(bEntry)); break; … } } // calling a certain semaphore int Macd(bool bEntry) { double MACDOpen=3; double MACDClose=2; double MA=26; int MODE_MA = MODE_EMA; // method of the calculation of averages int PRICE_MA = PRICE_CLOSE; // method of the calculation of averages int PERIOD = PERIOD_H1; // the period to work with //parameters of averages double MacdCur, MacdPre, SignalCur; double SignalPre, MaCur, MaPre; //---- get the value MacdCur=iMACD(NULL,0,8,17,9,PRICE_MA,MODE_MAIN,0); MacdPre=iMACD(NULL,0,8,17,9,PRICE_MA,MODE_MAIN,1); SignalCur=iMACD(NULL,0,8,17,9,PRICE_MA,MODE_SIGNAL,0); SignalPre=iMACD(NULL,0,8,17,9,PRICE_MA,MODE_SIGNAL,1); MaCur=iMA(NULL,0,MA,0,MODE_MA,PRICE_MA,0); MaPre=iMA(NULL,0,MA,0,MODE_MA,PRICE_MA,1); //----- condition for the operation execution if (bEntry) //for buying bEntry==true { if(MacdCur<0 && MacdCur>SignalCur && MacdPre<SignalPre && MathAbs(MacdCur)>(MACDOpen*Point) && MaCur>MaPre) return (OP_BUY); if(MacdCur>0 && MacdCur<SignalCur && MacdPre>SignalPre && MacdCur>(MACDOpen*Point) && MaCur<MaPre) return (OP_SELL); } else //for closing bEntry==false { if(MacdCur>0 && MacdCur<SignalCur && MacdPre>SignalPre && MacdCur>(MACDClose*Point)) return (OP_BUY); if(MacdCur>0 && MacdCur<SignalCur && MacdPre>SignalPre && MacdCur>(MACDOpen*Point) && MaCur<MaPre) return (OP_BUY); if(MacdCur<0 && MacdCur>SignalCur && MacdPre<SignalPre && MathAbs(MacdCur)>(MACDClose*Point)) return (OP_SELL); if(MacdCur<0 && MacdCur>SignalCur && MacdPre<SignalPre && MathAbs(MacdCur)>(MACDOpen*Point) && MaCur>MaPre) return (OP_SELL); } return (-1); //no signal }
منطق این سیستم در زبان MQL، خیلی متفاوت نخواهد بود. تمام توابع جهانی میشوند. و برای متفاوت شدن معاملات یک سیستم ترید، با معاملات یک سیستم دیگر، نیاز است پارامتر SignalID (بهعبارت دیگر، MAGIC) را در تمام توابعی که با معاملات سروکار دارند، اضافه کنید.
این مقاله دارای فایل پیوست است.
۳۷ مورد نظر
natural treatment for ed
cheap ed pills best ed pills at gnc online ed medications
ivermectin covid 19 treatment buy ivermectin online stromectol ivermectin
treatment with drugs buy prescription drugs from canada ed cures that work
buying generic cialis cialis 20 mg best price cialis black in australia
topical ivermectin rosacea ivermectin dosage chart for dogs how do i get ivermectin
prednisone price australia buy prednisone online prednisone 50 mg tablet canada
ed devices medications for ed pet meds without vet prescription
ivermectin for tapeworms ivermectin for horses tractor supply ivermectin tablets price
best otc ed pills men’s ed pills cheap erectile dysfunction pills
ivermectin dose dogs pour on ivermectin for chickens traitement gale stromectol
ivermectin studies stromectol coronavirus what parasites does ivermectin kill
finasteride 5 mg prices buy propecia cheap online where to get propecia
cheapest propecia for sale where can i buy propecia propecia without a prescription
stromectol price ivermectin solubility ivermectin nobel prize
stromectol stromectol 12 mg tablets prescribing stromectol
best online international pharmacies india buy prescriptions from india pharmacy best online international pharmacies india
india pharmacy without dr prescriptions overseas pharmacies online overseas pharmacies online
modafinil pill provigil 200mg without prescription
modafinil order buy provigil 200mg pill
best ed medications best ed pills new ed drugs
order modafinil online oral modafinil 100mg order generic provigil
buy modafinil 100mg online cheap modafinil 200mg sale modafinil 100mg oral
stromectol 3 mg tablets price stromectol for humans for sale stromectol without a doctor prescription
purchase modafinil online cheap modafinil 100mg generic
order modafinil 200mg pill purchase provigil online generic provigil 200mg
provigil 100mg without prescription
clomid for sale canada clomid tablets clomid tablets
provigil 200mg canada
clomid tablets where to buy cheap clomid online where to buy cheap clomid online
erythromycin ophthalmic ointment for newborns
tadalafil 10mg price cialis 20 mg price cialis 20mg
provigil 100mg usa provigil 100mg tablet
best price for daily cialis cialis pharmacy lowest price tadalafil
modafinil 100mg without prescription order modafinil 100mg online
modafinil uk purchase provigil without prescription
generic tadalafil 20mg india online purchase of tadalafil in india tadalafil best price 20 mg