آموزش mql5 و ارائه نمونه کدهای مفید برای ساخت ربات فارکس

با سلام و عرض ادب و احترام خدمت تمام دوستان عزیز و اساتید برنامه نویس

هدف از ایجاد این تاپیک ، آموزش زبان برنامه نویسی متاترید 5 (MQL5) است

همچنین بنده سعی میکنم با ارائه مثال و نمونه کد های مفید ، از سورس های خودم در اینجا یک آرشیو جهت کمک به علاقمندان یادگیری فراهم کنم . امیدوارم دوستان دیگر و سایر اساتید برنامه نویس هم بنده را در این هدف کمک کنند .

9 لایک کرده

یک ابزار خیلی کاربردی برا متاتریدر مستطیل امتداد یافته هست که خط وسطش هم فعال باشه

2 لایک کرده

برای شروع ، ابتدا یک پروژه جدید ایجاد میکنیم تا بتونیم بعدا کد ها رو توی این پروژه اجرا و تست کنیم

در صورتیکه مراحل را مانند تصاویر انجام داده باشید باید چیزی شبیه به تصویر آخر را در پروژه خود مشاهده کنید

5 لایک کرده

در قسمت OnInit مقدار 60 در دستور EventSetTimer(60); را به 1 تغییر دهید .

این دستور یک تایمر را با زمانبندی 60 ثانیه یکبار در برنامه راه اندازی میکند . با تغییر عدد 60 به 1 این زمانبندی به یک ثانیه تغییر خواهد کرد . دستوراتی که قرار است در هر ثانیه اجرا شوند باید در قسمت OnTimer نوشته شوند

در این نمونه دستور Print با یک عبارت “Hello IranBroker!“ هر یک ثانیه یکبار در تب Expert نمایش داده خواهد شد

6 لایک کرده

خب بریم برای قسمت دوم آموزش

در این قسمت میخوام چند تا نکته کاربردی در ربات نویسی متا5 را آموزش بدم

هر بروکری با توجه به تنظیمات سرور های خودش و نوع اکانت هایی که در اختیار کاربراش قرار میده ممکنه نوع یا انواع خاصی از اصطلاحا (Filling Mode ) را در متاتریدر برای هر نماد ارائه بده. الان کاری به مفهوم و تفاوت این انواع با هم نداریم و فقط میخوام چگونگی کد نویسی ربات برای سازگاری با این ویژگی خاص هر نماد را انجام بدیم.

برای مشاهده این مورد ، ابتدا روی نماد طلا در Market Watch کلیک راست کرده و از منویی که نمایش داده میشود گزینه Specification را انتخاب کنید

در پنجره نمایش داده شده عبارت Filling را مشاهده می کنید

با این توضیحات از این پس می توانید این مقدار را برای هر نماد براحتی پیدا کرده و در ربات تنظیم کنید

البته شاید در آینده کد ربات را طوری تغییر دادیم که خودش بتواند این مقدار را بدون نیاز به تنظیم کاربر تشخیص دهد :grin:

3 لایک کرده

در مرحله بعد میریم سراغ سورس رباتی که قبلا با هم نوشتیم

ابتدا مقدار 0.01 به ورژن آن اضافه میکنیم!

و سپس کد زیر را در بالای فایل و در زیر دستورات اولیه وارد میکنیم. با این کد ها ربات قابلیت تشخیص Filling Mode را در پارامتر های ورودی بدست می آورد

//+------------------------------------------------------------------+
//|                                                     MyExpert.mq5 |
//|                                  Copyright 2026, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.01"

enum ENUM_ORDER_FILLING
  {
   Fire_or_kill = ORDER_FILLING_FOK,                 // Fill or Kill
   Immediate_or_cancel = ORDER_FILLING_IOC,          // Immediate or Cancel
   Order_Ffilling_boc = ORDER_FILLING_BOC,           // Passive (Book or Cancel)
   Order_filling_return = ORDER_FILLING_RETURN,      // Order filling return
  };
3 لایک کرده

برای دریافت Filling Mode از کابر در پارامتر های ورودی باید این کد را هم در ادامه وارد کنیم

input group           " ---------- Main Parameters ---------- "
input ENUM_ORDER_FILLING OrderFilling     = 1;                      // Choose order filling type

3 لایک کرده

معمولا ربات ها برای اینکه بتونن بین معاملات خودشون و سایر معاملات تفکیک قائل بشن نیاز به MagicNumber دارن

این اصطلاح در بین ربات ها بسیار رایج هست . ما هم باید برای ربات خودمون یک MagicNumber تعیین کنیم و اونو در پارامتر های ورودی از کاربر دریافت کنیم

این مقدار به ربات کمک میکنه تا فقط معاملات خودشو مدیریت کنه و با معاملات ربات های دیگه و یا معاملات دستی کاری نداشته باشه

input ulong  MagicNumber                  = 123456;                 // Magic Number

میتونید عدد 123456 را به دلخواه خودتون تغییر بدید

1 لایک کرده

در مرحله بعد قسمتی را به ربات اضافه میکنیم تا کابر بتونه در ورودی تعیین کنه لات سایز برای معاملات ثابت باشه یا بر اساس بالانس حساب بصورت خودکار محاسبه بشه

برای این منظور لازمه اول یک نوع برای اینکار تعریف کنیم

enum ENUM_LotMethod
  {
   LOT_FIXED = 0,                                                   // Fix Lot size
   LOT_DYNAMIC = 1                                                  // Calc Lot size by Balance
  };

و بعد در قسمت ورودی ها کد زیر را اضافه میکنیم

input group           " ---------- Lot Size Parameters ---------- "
input ENUM_LotMethod LotMethod            = LOT_DYNAMIC;            // Lot Method
input double FixLotSize                   = 0.01;                   // Fix Lot Size
input double InitialLotSize               = 0.01;                   // Initial Lot size
input double StepBalance                  = 1000.0;                 // Step Balance

بعدا درباره هر کدام از این پارامتر ها توضیح میدم

3 لایک کرده

برای تعیین لات سایز بر اساس ورودی کاربر نیاز به یک تابع داریم که کدشو اینجا میذارم

double GetLotSize()
  {
   double Result = 0.0;
   if(LotMethod == LOT_FIXED)
     {
      Result = FixLotSize;
     }
   else
      if(LotMethod == LOT_DYNAMIC)
        {
         double balance = AccountInfoDouble(ACCOUNT_BALANCE);
         int steps = int(balance / StepBalance);
         double l = 0;
         for(int i=0;i<steps;i++)
           {
            l = l + InitialLotSize;
           }

         Result = l;
        }

   Result = MathMax(Result, SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN));
   return Result;
  }

این تابع باید در زمان ارسال دستور بای و سل فراخوانی بشه

2 لایک کرده

قسمت بعدی ورودی های مربوط به Stop Loss و Take Profit هست که با اعداد صحیح که نشاندهنده فاصله از قیمت هستند مشخص میشن

input group           " ---------- SL/TP Parameters ---------- "
input int SL_Distance                     = 2000;                   // Stop loss distance
input int TP_Distance                     = 4000;                   // Take Profit distance

این قسمت هم باید به قسمت ورودی های ربات اضافه بشه

3 لایک کرده

تا اینجا قسمت بالای فایل اصلی ربات باید به این شکل شده باشه

//+------------------------------------------------------------------+
//|                                                     MyExpert.mq5 |
//|                                  Copyright 2026, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.01"

enum ENUM_ORDER_FILLING
  {
   Fire_or_kill = ORDER_FILLING_FOK,                 // Fill or Kill
   Immediate_or_cancel = ORDER_FILLING_IOC,          // Immediate or Cancel
   Order_Ffilling_boc = ORDER_FILLING_BOC,           // Passive (Book or Cancel)
   Order_filling_return = ORDER_FILLING_RETURN,      // Order filling return
  };

enum ENUM_LotMethod
  {
   LOT_FIXED = 0,                                                   // Fix Lot size
   LOT_DYNAMIC = 1                                                  // Calc Lot size by Balance
  };
input group           " ---------- Main Parameters ---------- "
input ENUM_ORDER_FILLING OrderFilling     = 1;                      // Choose order filling type
input ulong  MagicNumber                  = 123456;                 // Magic Number
input group           " ---------- Lot Size Parameters ---------- "
input ENUM_LotMethod LotMethod            = LOT_DYNAMIC;            // Lot Method
input double FixLotSize                   = 0.01;                   // Fix Lot Size
input double InitialLotSize               = 0.01;                   // Initial Lot size
input double StepBalance                  = 1000.0;                 // Step Balance
input group           " ---------- SL/TP Parameters ---------- "
input int SL_Distance                     = 2000;                   // Stop loss distance
input int TP_Distance                     = 4000;                   // Take Profit distance
4 لایک کرده

در ادامه فایل هایی را به این تاپیک اضافه میکنم تا به پروژه اضافه کنید

این فایل ها حاوی دستوراتی هستند که عملیات خرید و فروش و رسم دکمه روی چارت را انجام میدهند

BuySell.mq5 (5.8 کیلوبایت)

Objects.mq5 (60.4 کیلوبایت)

Functions.mq5 (553 بایت)

1 لایک کرده

بعد از قسمت پارامتر ها باید دو متغییر با عناوین زیر تعریف کنیم


MqlTick tick;
double vChartPrice;
1 لایک کرده

برای رسم دکمه های خرید و فروش روی چارت قسمت OnInit را به شکل زیر ویرایش میکنیم

int OnInit()
  {
  
   ButtonCreate(0, "Btn_Buy",  0, 100, 10, 100, 25, CORNER_LEFT_UPPER, "Buy");
   ButtonCreate(0, "Btn_Sell", 0, 400, 10, 100, 25, CORNER_LEFT_UPPER, "Sell");

   ButtonCreate(0, "Btn_Buy_Limit",  0, 100, 38, 200, 25, CORNER_LEFT_UPPER, "Buy Limit");
   ButtonCreate(0, "Btn_Sell_Limit", 0, 400, 38, 200, 25, CORNER_LEFT_UPPER, "Sell Limit");

   ButtonCreate(0, "Btn_Buy_Stop",  0, 100, 66, 200, 25, CORNER_LEFT_UPPER, "Buy Stop");
   ButtonCreate(0, "Btn_Sell_Stop", 0, 400, 66, 200, 25, CORNER_LEFT_UPPER, "Sell Stop");

//--- create timer
   EventSetTimer(1);

//---
   return(INIT_SUCCEEDED);
  }
1 لایک کرده

و برای رها سازی حافظه در زمان بسته شدن ربات کد های قسمت OnDeInit را بشکل زیر تغییر میدهیم

void OnDeinit(const int reason)
  {
   ButtonDelete(0, "Btn_Buy");
   ButtonDelete(0, "Btn_Sell");
   ButtonDelete(0, "Btn_Buy_Limit");
   ButtonDelete(0, "Btn_Sell_Limit");
   ButtonDelete(0, "Btn_Buy_Stop");
   ButtonDelete(0, "Btn_Sell_Stop");
//--- destroy timer
   EventKillTimer();

  }
1 لایک کرده

کد قبلی که برای نمایش و تست بود را کامنت میکنیم

void OnTimer()
  {
//---
//Print("Hello IranBroker!");
  }
1 لایک کرده

من این قسمتش رو نفهمیده ام. یعنی اگه ondeinit نذاری چی میشه؟ کمی توضیحی بیشتر بدید ممنون میشم :folded_hands:

1 لایک کرده

آبجکت ها (مثلا دکمه ها) پس از ایجاد مقداری حافظه اشغال میکنند

توصیه میشه وقتی ربات را از روی چارت حذف میکنیم ربات باید حاوی کد هایی باشه که هر آبجکتی که خودش ایجاد کرده باشه را حذف کنه تا حافظه مصرف شده آزاد بشه

این قسمت برای عملکرد ربات ضروری نیست ولی وجودش باعث میشه در بلند مدت و در صورتی که محدودیت منابع سیستم داشته باشید مقداری هر چند جزئی حافظه آزاد کنه تا منابع سیستم بی دلیل درگیر داده هایی نباشند که دیگه مرجعی برای اون وجود نداره . نمیدونم توضیحاتم مفید بود یا نه . فقط همینقدر بگم که این موضوع مربوط میشه به مدیریت حافظه نرم افزار ها در سیستم عامل و …

:wink:

3 لایک کرده

بسیار سپاسگزارم . بله توضیحات کافی بود. پس بجای نوشتن این قسمت از کد، میتوانیم چارت را کلوز و اپن کنیم یا که خودمان همه ابجکت ها را دیلیت کنیم.

1 لایک کرده