ساختار در زبان MQL5 – بخش 1
محتوا:
در مقالهی پیشین یعنی سومین مقاله آموزش زبان mql از سری مقالات مرتبط با برنامه نویسی در بازارهای مالی به شرح و بررسی به شرح «Basic data types or simple data types» پرداختیم. در چهارمین مقالهی این سری به بررسی «ساختار در زبان MQL5» میپردازیم. و موارد باقیمانده را در مقالهی آتی جمعبندی میکنیم.
در صورت برقراری شرایط معاملات الگوریتمی در بازار هدف برای اعمال هر یک از این مفاهیم در استراتژیهای معاملاتی میتوانید از سفارش کد پایتون، سفارش کد mql و … برای کد کردن و بهینهیابی استراتژیهای معاملاتی خود استفاده کنید. و در عین حال سوای امکان سفارش اکسپرت میتوانید از سفارش اندیکاتور برای دریافت یک نمایش گرافیکی از محاسبات استراتژی خود بهره ببرید.
– – –
انواع داده های پیچیده (Complex data types)
- در تعاریف OOP : انواع دادههای پیچیده(Complex data types) را انواع دادههای انتزاعی(abstract data types) مینامند.
نوع color و datetime فقط برای تسهیل تجسم و ورود پارامترهای خارجی – از جدول ربات معاملاتی یا تنظیمات اندیکاتور سفارشی (Inputs tab) منطقی است. دادههای color و datetime به صورت اعداد صحیح نمایش داده میشوند. انواع عدد صحیح و انواع اعداد اعشاری، انواع حسابی(arithmetic) یا عددی(numeric) نامیده میشوند.
- تعییر نوع داده فایل (type casting) ضمنی از طریق عبارات(expressions) انجام میشود، مگر اینکه تغییر نوع داده فایل (type casting) صریح مشخص شده باشد.
ساختار در زبان MQL5
در این بخش از آموزش زبان mql به بررسی ساختار در زبان MQL5 میپردازیم. مجموعهای از عناصر از هر نوع (به جز نوع void) است.؛ بنابراین ساختار دادههای از نظر منطقی مرتبط و غیر همنوع را با یکدیگر ترکیب میکند.
تعریف کردن یک ساختار در زبان MQL5
نوع داده ساختار با شرح زیر تعریف میگردد. :
struct structure_name { elements_description };
نام ساختار را نمیتوان به عنوان یک identifier (نام متغیر یا تابع) استفاده کرد.
تغییر alignment در structureها در زبان MQL5
لازم به ذکر است که در MQL5 structure عناصر به طور مستقیم و بدون alignment(تراز) از یکدیگر پیروی میکنند. در ++C با استفاده از دستورالعمل زیر چنین سفارشی به کامپایلر داده میشود:
#pragma pack(1) //
اگر می خواهید alignment دیگری در ساختار انجام دهید، از اعضای کمکی، “filler“ها به اندازهی مناسب استفاده کنید.
struct trade_settings { uchar slippage; // value of the permissible slippage-size 1 byte char reserved1; // skip 1 byte short reserved2; // skip 2 bytes int reserved4; // another 4 bytes are skipped. ensure alignment of the boundary 8 bytes double take; // values of the price of profit fixing double stop; // price value of the protective stop };
- چنین توصیفی از aligned structures فقط برای انتقال به imported dll-functions ضروری است.
توجه: این مثال دادههای طراحی شده نادرست را نشان می دهد. بهتر است ابتدا دادههای بزرگ از نوع double را دریافت و توقف کنید و سپس عضو slippage نوع uchar را تعریف کنید. در این حالت، نمایش داخلی دادهها بدون توجه به مقدار مشخص شده در pragma pack# همیشه یکسان خواهد بود.
اگر ساختاری دارای متغیرهایی از نوع رشته(string) و/یا شیء یک آرایه پویا(object of a dynamic array) باشد، کامپایلر یک سازنده ضمنی(implicit constructor) به چنین ساختاری اختصاص میدهد. این سازنده تمام اعضای ساختار از نوع رشته را بازنشانی میکند و اشیاء آرایه پویا را به درستی مقداردهی اولیه میکند.
ساختارهای ساده(Simple Structures)
ساختارهایی که شامل رشتهها(strings)، اشیاء کلاس(class objects)، اشارهگر(pointers) و اشیاء آرایههای پویا(objects of dynamic arrays) نیستند، ساختارهای ساده(simple structures) نامیده میشوند.
متغیرهای ساختارهای ساده و همچنین آرایههای آنها را میتوان به عنوان پارامتر به imported dll-functions ارسال کرد.
کپی کردن ساختارهای ساده
کپی برداری از ساختارهای ساده فقط در دو مورد مجاز است:
- اگر اشیاء متعلق به یک نوع ساختار باشند.؛ و یا در واقع دو ساختار مبدا و مقصد عمل کپی از یک اسکلت کلی برخوردار باشند.
- اگر اشیاء با نسب به هم متصل شوند به این معنی که یک ساختار از نسل ساختار دیگر باشد.
- اشیاء متعلق به یک نوع ساختار
برای ارائهی یک مثال، اجازه دهید ساختار سفارشی CustomMqlTick را با محتوای آن مشابه با MqlTick داخلی توسعه دهیم. کامپایلر اجازه کپی مقدار شی MqlTick را به شی نوع CustomMqlTick نمیدهد. typecasting مستقیم به نوع لازم نیز باعث خطای کامپایل میشود. :
//--- copying simple structures of different types is forbidden my_tick1=last_tick; // compiler returns an error here //--- typecasting structures of different types to each other is forbidden as well my_tick1=(CustomMqlTick)last_tick;// compiler returns an error here
بنابراین، تنها یک گزینه باقی مانده است – کپی کردن یک به یک مقادیر عناصر ساختار. کپی کردن مقادیر همان نوع CustomMqlTick همچنان مجاز است.
CustomMqlTick my_tick1,my_tick2; //--- it is allowed to copy the objects of the same type of CustomMqlTick the following way my_tick2=my_tick1; //--- create an array out of the objects of the simple CustomMqlTick structure and write values to it CustomMqlTick arr[2]; arr[0]=my_tick1; arr[1]=my_tick2;
تابع ()ArrayPrint برای بررسی نمایش مقدار آرایه []arr در journal فراخوانی میشود.
//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- develop the structure similar to the built-in MqlTick struct CustomMqlTick { datetime time; // Last price update time double bid; // Current Bid price double ask; // Current Ask price double last; // Current price of the last trade (Last) ulong volume; // Volume for the current Last price long time_msc; // Last price update time in milliseconds uint flags; // Tick flags }; //--- get the last tick value MqlTick last_tick; CustomMqlTick my_tick1,my_tick2; //--- attempt to copy data from MqlTick to CustomMqlTick if(SymbolInfoTick(Symbol(),last_tick)) { //--- copying unrelated simple structures is forbidden //1. my_tick1=last_tick; // compiler returns an error here //--- typecasting unrelated structures to each other is forbidden as well //2. my_tick1=(CustomMqlTick)last_tick;// compiler returns an error here //--- therefore, copy the structure members one by one my_tick1.time=last_tick.time; my_tick1.bid=last_tick.bid; my_tick1.ask=last_tick.ask; my_tick1.volume=last_tick.volume; my_tick1.time_msc=last_tick.time_msc; my_tick1.flags=last_tick.flags; //--- it is allowed to copy the objects of the same type of CustomMqlTick the following way my_tick2=my_tick1; //--- create an array out of the objects of the simple CustomMqlTick structure and write values to it CustomMqlTick arr[2]; arr[0]=my_tick1; arr[1]=my_tick2; ArrayPrint(arr); //--- example of displaying values of the array containing the objects of CustomMqlTick type /* [time] [bid] [ask] [last] [volume] [time_msc] [flags] [0] 2017.05.29 15:04:37 1.11854 1.11863 +0.00000 1450000 1496070277157 2 [1] 2017.05.29 15:04:37 1.11854 1.11863 +0.00000 1450000 1496070277157 2 */ } else Print("SymbolInfoTick() failed, error = ",GetLastError()); }
- یک ساختار از نسل ساختار دیگری
مثال دوم ویژگیهای کپی ساختارهای ساده از نسل ساختار دیگری را نشان میدهد. فرض کنید ساختار اولیه Animal را داریم که ساختارهای Cat و Dog از آن گرفته شده است. ما می توانیم اشیاء Animal و Cat، و همچنین اشیاء Animal و Dog را به یکدیگر کپی کنیم، اما نمیتوانیم Cat و Dog را به یکدیگر کپی کنیم، اگرچه هر دو از فرزندان ساختار Animal هستند.
//--- structure for describing dogs struct Dog: Animal { bool hunting; // hunting breed }; //--- structure for describing cats struct Cat: Animal { bool home; // home breed }; //--- create objects of child structures Dog dog; Cat cat; //--- can be copied from ancestor to descendant (Animal ==> Dog) dog=some_animal; dog.swim=true; // dogs can swim //--- you cannot copy objects of child structures (Dog != Cat) cat=dog; // compiler returns an error
کد نمونه کامل:
//--- basic structure for describing animals struct Animal { int head; // number of heads int legs; // number of legs int wings; // number of wings bool tail; // tail bool fly; // flying bool swim; // swimming bool run; // running }; //--- structure for describing dogs struct Dog: Animal { bool hunting; // hunting breed }; //--- structure for describing cats struct Cat: Animal { bool home; // home breed }; //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- create and describe an object of the basic Animal type Animal some_animal; some_animal.head=1; some_animal.legs=4; some_animal.wings=0; some_animal.tail=true; some_animal.fly=false; some_animal.swim=false; some_animal.run=true; //--- create objects of child types Dog dog; Cat cat; //--- can be copied from ancestor to descendant (Animal ==> Dog) dog=some_animal; dog.swim=true; // dogs can swim //--- you cannot copy objects of child structures (Dog != Cat) //cat=dog; // compiler returns an error here //--- therefore, it is possible to copy elements one by one only cat.head=dog.head; cat.legs=dog.legs; cat.wings=dog.wings; cat.tail=dog.tail; cat.fly=dog.fly; cat.swim=false; // cats cannot swim //--- it is possible to copy the values from descendant to ancestor Animal elephant; elephant=cat; elephant.run=false;// elephants cannot run elephant.swim=true;// elephants can swim //--- create an array Animal animals[4]; animals[0]=some_animal; animals[1]=dog; animals[2]=cat; animals[3]=elephant; //--- print out ArrayPrint(animals); //--- execution result /* [head] [legs] [wings] [tail] [fly] [swim] [run] [0] 1 4 0 true false false true [1] 1 4 0 true false true true [2] 1 4 0 true false false false [3] 1 4 0 true false true false */ }
راه دیگر برای کپی کردن انواع ساده استفاده از مجموعهها است. اشیاء ساختارها باید اعضای یک مجموعه باشند – مثال را در مجموعه ببینید.
دسترسی به اعضای ساختار
نام یک ساختار به یک نوع داده جدید تبدیل میشود، بنابراین می توانید متغیرهایی از این نوع را تعریف کنید. ساختار را میتوان تنها یک بار در یک پروژه تعریف کرد. اعضای ساختار با استفاده از عملیات نقطه point operation (.) قابل دسترسی هستند.
مثال:
struct trade_settings { double take; // values of the profit fixing price double stop; // value of the protective stop price uchar slippage; // value of the acceptable slippage }; //--- create up and initialize a variable of the trade_settings type trade_settings my_set={0.0,0.0,5}; if (input_TP>0) my_set.take=input_TP;
در مقالات بعدی آموزش ام کیو ال، مطالب آموزش ساختار در زبان MQL پی گرفته و سایر نکات مربوط به این بخش را شرح خواهیم داد.
همچنین میتوانید از سسله مقالات آموزش Python سایت جهان بورس استفاده نمایید.