مبانی زبان MQL5 _ بخش 3

مبانی زبان MQL5 _ بخش 3
مبانی زبان MQL5 _ بخش 3

 

در سومین مقاله‌ی آموزش زبان mql از سری مقالات مرتبط با برنامه نویسی در بازار‌ها‌ی مالی به شرح و بررسی «انواع داده‌ها در زبان MQL5» می‌پردازیم. در مقاله‌ی پیشین به شرح «برخی از انواع داده‌ها در زبان MQL5» پرداختیم. و در این بخش موارد را پی می‌گیریم.

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

– – –

Basic or Simple data types
Basic or Simple data types

مبانی زبان MQL5 و اعداد اعشاری (floating-point numbers)

عدد حقیقی (Real Types)

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

 

انواع عدد صحیح (Integer Types)
انواع عدد صحیح (Integer Types)

نام double به این معنی است که دقت این اعداد دو برابر دقت اعداد float است.؛ در بیشتر موارد، نوع double مناسب‌ترین نوع داده است. در بسیاری از موارد دقت محدود اعداد float کافی نیست. دلیل اینکه هنوز از نوع float استفاده می شود ذخیره حافظه است (این نکته برای آرایه‌های بزرگ اعداد حقیقی نکته‌ی حائز اهمیتی است).

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

double a=12.111;
double b=-956.1007;
float  c =0.0001;
float  d =16;

 

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

double c1=1.12123515e-25;
double c2=0.000000000000000000000000112123515; // 24 zero after the decimal point

Print("1. c1 =",DoubleToString(c1,16));
// Result: 1. c1 = 0.0000000000000000

Print("2. c1 =",DoubleToString(c1,-16));
// Result: 2. c1 = 1.1212351499999999e-025
 
Print("3. c2 =",DoubleToString(c2,-16));
// Result: 3. c2 = 1.1212351499999999e-025

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

به عنوان مثال، اعداد 0.3 و 0.7 در رایانه به صورت کسرهای بی نهایت نشان داده می شوند، در حالی که عدد 0.25 دقیقاً ذخیره می شود، زیرا نشان دهنده توان دو است.

در این رابطه اکیداً توصیه می شود که دو عدد حقیقی را برای برابری با هم مقایسه نکنید، زیرا چنین مقایسه ای صحیح نیست.

void OnStart()
  {
//---
   double three=3.0;
   double x,y,z;
   x=1/three;
   y=4/three;
   z=5/three;
   if(x+y==z) 
      Print("1/3 + 4/3 == 5/3");
   else 
      Print("1/3 + 4/3 != 5/3");
// Result: 1/3 + 4/3 != 5/3
  }

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

 

bool EqualDoubles(double d1,double d2,double epsilon)
  {
   if(epsilon<0) 
      epsilon=-epsilon;
//---
   if(d1-d2>epsilon) 
      return false;
   if(d1-d2<-epsilon) 
      return false;
//---
   return true;
  }
void OnStart()
  {
   double d_val=0.7;
   float  f_val=0.7;
   if(EqualDoubles(d_val,f_val,0.000000000000001)) 
      Print(d_val," equals ",f_val);
   else 
      Print("Different: d_val = ",DoubleToString(d_val,16),"  f_val = ",DoubleToString(f_val,16));
// Result: Different: d_val= 0.7000000000000000   f_val= 0.6999999880790710
  }

توجه داشته باشید که مقدار epsilon در مثال بالا نمی‌تواند کمتر از ثابت از پیش تعریف شده DBL_EPSILON باشد. مقدار این ثابت 2.2204460492503131e-016 است.

ثابت مربوط به نوع عدد اعشاری FLT_EPSILON = 1.192092896e-07 است. معنای این مقادیر به شرح زیر است: کمترین مقداری است که شرط 1.0 + DBL_EPSILON را برآورده می‌کند! = 1.0 (برای اعداد از نوع شناور 1.0 + FLT_EPSILON! = 1.0).

راه دوم مقایسه تفاوت نرمال شده دو عدد واقعی با صفر را ارائه می‌دهد. مقایسه تفاوت اعداد نرمال شده با صفر بی معنی است، زیرا هر عملیات ریاضی با اعداد نرمال شده یک نتیجه غیر عادی می‌دهد.

 

bool CompareDoubles(double number1,double number2)
  {
   if(NormalizeDouble(number1-number2,8)==0) 
      return(true);
   else 
      return(false);
  }
void OnStart()
  {
   double d_val=0.3;
   float  f_val=0.3;
   if(CompareDoubles(d_val,f_val)) 
      Print(d_val," equals ",f_val);
   else 
      Print("Different: d_val = ",DoubleToString(d_val,16),"  f_val = ",DoubleToString(f_val,16));
// Result: Different: d_val= 0.3000000000000000   f_val= 0.3000000119209290
  }

برخی از عملیات پردازنده کمکی ریاضی می تواند منجر به عدد واقعی نامعتبر شود که نمی‌توان از آن در عملیات ریاضی و عملیات مقایسه استفاده کرد، زیرا نتیجه عملیات با اعداد واقعی نامعتبر تعریف نشده است. به عنوان مثال، هنگام تلاش برای محاسبه آرکسین 2(arcsine of 2)، نتیجه بی‌نهایت منفی است.

   double abnormal = MathArcsin(2.0);
   Print("MathArcsin(2.0) =",abnormal);
// Result:  MathArcsin(2.0) = -1.#IND

علاوه بر بی‌نهایت منفی، بی‌نهایت مثبت و NaN (not a number) نیز وجود دارد. برای تعیین این که این عدد نامعتبر است، می‌توانید از ()MathIsValidNumber استفاده کنید. طبق استاندارد IEEE، آن‌ها یک نمایندگی ماشین ویژه دارند. به عنوان مثال، مثبت بی‌نهایت برای double دارای نمایش بیت 0x7FF0 0000 0000 0000 است.

struct str1
  {
   double d;
  };
struct str2
  {
   long l;
  };
 
//--- Start 
   str1 s1;
   str2 s2;
//---
   s1.d=MathArcsin(2.0);        // Get the invalid number -1.#IND
   s2=s1;
   printf("1.  %f %I64X",s1.d,s2.l);
//---
   s2.l=0xFFFF000000000000;     // invalid number -1.#QNAN
   s1=s2;
   printf("2.  %f %I64X",s1.d,s2.l);
//---
   s2.l=0x7FF7000000000000;     // greatest non-number SNaN
   s1=s2;
   printf("3.   %f %I64X",s1.d,s2.l);
//---
   s2.l=0x7FF8000000000000;     // smallest non-number QNaN
   s1=s2;
   printf("4.   %f %I64X",s1.d,s2.l);
//---
   s2.l=0x7FFF000000000000;     // greatest non-number QNaN
   s1=s2;
   printf("5.   %f %I64X",s1.d,s2.l);
//---
   s2.l=0x7FF0000000000000;     // Positive infinity 1.#INF and smallest non-number SNaN
   s1=s2;
   printf("6.   %f %I64X",s1.d,s2.l);
//---
   s2.l=0xFFF0000000000000;     // Negative infinity -1.#INF
   s1=s2;
   printf("7.  %f %I64X",s1.d,s2.l);
//---
   s2.l=0x8000000000000000;     // Negative zero -0.0
   s1=s2;
   printf("8.  %f %I64X",s1.d,s2.l);
//---
   s2.l=0x3FE0000000000000;     // 0.5
   s1=s2;
   printf("9.   %f %I64X",s1.d,s2.l);
//---
   s2.l=0x3FF0000000000000;     // 1.0
   s1=s2;
   printf("10.  %f %I64X",s1.d,s2.l);
//---
   s2.l=0x7FEFFFFFFFFFFFFF;     // Greatest normalized number (MAX_DBL)
   s1=s2;
   printf("11.  %.16e %I64X",s1.d,s2.l);
//---
   s2.l=0x0010000000000000;     // Smallest positive normalized (MIN_DBL)
   s1=s2;
   printf("12.  %.16e %.16I64X",s1.d,s2.l);
//---
   s1.d=0.7;                    // Show that the number of 0.7 - endless fraction
   s2=s1;
   printf("13.  %.16e %.16I64X",s1.d,s2.l);
/*
1.  -1.#IND00 FFF8000000000000
2.  -1.#QNAN0 FFFF000000000000
3.   1.#SNAN0 7FF7000000000000
4.   1.#QNAN0 7FF8000000000000
5.   1.#QNAN0 7FFF000000000000
6.   1.#INF00 7FF0000000000000
7.  -1.#INF00 FFF0000000000000
8.  -0.000000 8000000000000000
9.   0.500000 3FE0000000000000
10.  1.000000 3FF0000000000000
11.  1.7976931348623157e+308 7FEFFFFFFFFFFFFF
12.  2.2250738585072014e-308 0010000000000000
13.  6.9999999999999996e-001 3FE6666666666666 
*/

 

نوع رنگ (Color Type)

Color Type برای ذخیره اطلاعات مربوط به رنگ در نظر گرفته شده است.

4 بایت در حافظه اشغال می‌کند. بایت اول نادیده گرفته می‌شود، 3 بایت باقی مانده شامل اجزای RGB است.

ثابت‌های رنگی را می‌توان به سه روش نشان داد:

  1. به صورت literal
  2. به صورت integer
  3. با نام (فقط Web-colors)

نمایش literal شامل سه بخش است که مقادیر نرخ عددی سه جزء اصلی رنگ را نشان می‌دهد: قرمز، سبز، آبی. ثابت با C شروع می شود و در یک ‘ قرار می‌گیرد. مقادیر نرخ عددی هر جزء رنگی در محدوده‌ی 0 تا 255 قرار دارد.

نمایش با مقدار صحیح به شکل عدد هگزادسیمال یا اعشاری نوشته می شود. یک عدد هگزادسیمال شبیه 0x00BBGGRR است، که در آن RR نرخ جزء رنگ قرمز، GG مربوط به میزان رنگ سبز و BB نمایان‌گر میزان رنگ آبی است. ثابت های اعشاری مستقیماً در RGB منعکس نمی‌شوند. آن‌ها یک مقدار اعشاری از نمایش عدد صحیح هگزادسیمال را نشان می‌دهند.

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

//--- Literals
C'128,128,128'    // Gray
C'0x00,0x00,0xFF' // Blue
//color names
clrRed               // Red
clrYellow            // Yellow
clrBlack             // Black
//--- Integral representations
0xFFFFFF          // White
16777215          // White
0x008000          // Green
32768             // Green

 

نوع زمان (Datetime Type)

نوع datetime برای ذخیره تاریخ و زمان به عنوان تعداد ثانیه‌های سپری شده از 01 ژانویه 1970 در نظر گرفته شده است. این نوع 8 بایت حافظه را اشغال می‌کند.

ثابت‌های تاریخ و زمان را می‌توان به عنوان یک literal string نشان داد که از 6 قسمت تشکیل شده است که مقدار عددی سال، ماه، روز (یا روز، ماه، سال)، ساعت، دقیقه و ثانیه را نشان می‌دهد. ثابت در یک علامت نقل قول قرار می‌گیرد و با کاراکتر D شروع می شود.

مقادیر از 1 ژانویه 1970 تا 31 دسامبر 3000 متغیر است. تاریخ (سال، ماه، روز) یا زمان (ساعت، دقیقه، ثانیه)، یا همه با هم می‌توانند حذف شوند.

با مشخصات literal date، مطلوب است که سال، ماه و روز را مشخص کنید. در غیر این صورت کامپایلر یک هشدار در مورد یک ورودی ناقص(an incomplete entry) برمی‌گرداند.

datetime NY=D'2015.01.01 00:00';     // Time of beginning of year 2015
datetime d1=D'1980.07.19 12:30:27';  // Year Month Day Hours Minutes Seconds
datetime d2=D'19.07.1980 12:30:27';  // Equal to D'1980.07.19 12:30:27';
datetime d3=D'19.07.1980 12';        // Equal to D'1980.07.19 12:00:00'
datetime d4=D'01.01.2004';           // Equal to D'01.01.2004 00:00:00'
datetime compilation_date=__DATE__;             // Compilation date
datetime compilation_date_time=__DATETIME__;    // Compilation date and time
datetime compilation_time=__DATETIME__-__DATE__;// Compilation time
//--- Examples of declarations after which compiler warnings will be returned
datetime warning1=D'12:30:27';       // Equal to D'[date of compilation] 12:30:27'
datetime warning2=D'';               // Equal to __DATETIME__

 

 

نوع Enumerations

داده های نوع enum متعلق به مجموعه ای محدود از داده ها هستند.

تعریف نوع شمارش:

enum name of enumerable type
  {
   list of values
  };

لیست مقادیر لیستی از شناسه‌های ثابت‌های نامگذاری شده است که با کاما از هم جدا شده‌اند.

enum months  // enumeration of named constants
   {
    January,
    February,
    March,
    April,
    May,
    June,
    July,
    August,
    September,
    October,
    November,
    December
   };

پس از تعریف enum، یک نوع داده 4 بایتی جدید با عدد صحیح ظاهر می‌شود. تعریف نوع داده جدید به کامپایلر اجازه می‌دهد تا انواع پارامترهای ارسال شده(passed parameters) را به دقت کنترل کند، زیرا enum ثابت‌های نامگذاری شده جدیدی را معرفی می کند. در مثال بالا، ثابت ژانویه دارای مقدار 0، فوریه – 1، دسامبر – 11 است.

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

  • اگر اولین عضو شمارش باشد، مقدار 0 به آن اختصاص داده می شود.
  • برای همه اعضای بعدی، مقادیر بر اساس ارزش اعضای قبلی با اضافه کردن یک محاسبه می شود.

 

enum intervals  // Enumeration of named constants
   {
    month=1,     // Interval of one month
    two_months,  // Two months
    quarter,     // Three months - quarter
    halfyear=6,  // Half a year
    year=12,     // Year - 12 months
   };

برخلاف C++، اندازه نمایش داخلی enum در MQL5 همیشه برابر با 4 بایت است. یعنی sizeof (months) مقدار 4 را برمی‌گرداند.
بر خلاف C++، یک enum ناشناس را نمی‌توان در MQL5 تعریف کرد. یعنی همیشه باید بعد از کلمه کلیدی enum یک نام منحصر به فرد مشخص شود.

 

هگزادسیمال(Hexadecimal)

اعداد 0-9، حروف a-f یا A-F برای مقادیر 10-15. با 0x یا 0X شروع می‌شوند.

//
0x0A, 0x12, 0X12, 0x2f, 0xA3, 0Xa3, 0X7C7
//

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

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- set 1 for working hours and 0 for nonworking ones
   int AsianSession   =B'111111111'; // Asian session from 0:00 to 9:00
   int EuropeanSession=B'111111111000000000'; // European session 9:00 - 18:00
   int AmericanSession =B'111111110000000000000011'; // American session 16:00 - 02:00
//--- derive numerical values of the sessions
   PrintFormat("Asian session hours as value =%d",AsianSession);
   PrintFormat("European session hours as value is %d",EuropeanSession);
   PrintFormat("American session hours as value is %d",AmericanSession);
//--- and now let's display string representations of the sessions' working hours
   Print("Asian session ",GetHoursForSession(AsianSession));
   Print("European session ",GetHoursForSession(EuropeanSession));
   Print("American session ",GetHoursForSession(AmericanSession));   
//---
  }
//+------------------------------------------------------------------+
//| return the session's working hours as a string                   |
//+------------------------------------------------------------------+
string GetHoursForSession(int session)
  {
//--- in order to check, use AND bit operations and left shift by 1 bit <<=1
//--- start checking from the lowest bit
   int bit=1;
   string out="working hours: ";
//--- check all 24 bits starting from the zero and up to 23 inclusively  
   for(int i=0;i<24;i++)
     {
      //--- receive bit state in number
      bool workinghour=(session&bit)==bit;
      //--- add the hour's number to the message
      if(workinghour )out=out+StringFormat("%d ",i); 
      //--- shift by one bit to the left to check the value of the next one
      bit<<=1;
     }
//--- result string
   return out;
  }

 

عدد مختلط (Complex number)

ساختار از پیش تعریف‌شده‌‌ای است که از دو بخش double تشکیل شده است.

struct complex
  {
   double             real;   // Real part
   double             imag;   // Imaginary part
  };

عدد مختلط را می توان به صورت passed by value به عنوان پارامتری برای توابع MQL5 ارسال کرد (بر خلاف ساختارهای معمولی که فقط به صورت passed by reference ارسال می شوند). برای توابع import شده از DLL، عدد مختلط باید فقط با passed by reference ارسال شود.

پسوند “i” برای توصیف ثابت‌های عدد مختلط استفاده می شود.:

complex square(complex c)
  {
   return(c*c);
  }  
void OnStart()
  {
   Print(square(1+2i));  // A constant is passed as a parameter
  }
// "(-3,4)" will be output, which is a string representation of the complex number

در حال حاضر فقط عملیات ساده برای اعداد مختلط امکان پذیر است:

+ * / = !=
+= -= *= /=  ==

 

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

 

 

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

همچنین می‌توانید از سسله مقالات آموزش Python سایت جهان بورس استفاده نمایید.

0 0 رای ها
امتیازدهی به مقاله
0 نظرات
بازخورد (Feedback) های اینلاین
مشاهده همه دیدگاه ها
سبد خرید
هیچ محصولی در سبد خرید وجود ندارد!
خرید را ادامه دهید