در مقاله پیشین یعنی سومین مقاله آموزش زبان mql از سری مقالات مرتبط با برنامهنویسی در بازارهای مالی به شرح و بررسی به شرح «Basic data types or simple data types» پرداختیم. در چهارمین مقاله این سری به بررسی «ساختار در زبان MQL5» میپردازیم. و موارد باقیمانده را در مقاله آتی جمعبندی میکنیم.
در تعاریف OOP : انواع دادههای پیچیده(Complex data types) را انواع دادههای انتزاعی(abstract data types) مینامند.
در تعاریف OOP : انواع دادههای پیچیده(Complex data types) را انواع دادههای انتزاعی(abstract data types) مینامند.
نوع color و datetime فقط برای تسهیل تجسم و ورود پارامترهای خارجی – از جدول ربات معاملاتی یا تنظیمات اندیکاتور سفارشی (Inputs tab) منطقی است. دادههای color و datetime به صورت اعداد صحیح نمایش داده میشوند. انواع عدد صحیح و انواع اعداد اعشاری، انواع حسابی(arithmetic) یا عددی(numeric) نامیده میشوند.
تعییر نوع داده فایل (type casting) ضمنی از طریق عبارات(expressions) انجام میشود، مگر اینکه تغییر نوع داده فایل (type casting) صریح مشخص شده باشد.
ساختار در زبان MQL5 – بخش 1
ساختار در زبان 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 سایت جهان بورس استفاده نمایید.
دیدگاهتان را بنویسید
برای نوشتن دیدگاه باید وارد بشوید.