1. پارامترهای ورودی
//Import External class #include <Trade\PositionInfo.mqh> #include <Trade\Trade.mqh> #include <Trade\SymbolInfo.mqh> #include <Trade\AccountInfo.mqh> #include <Trade\OrderInfo.mqh> //--- introduce predefined variables for code readability #define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK) #define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID) //--- input parameters input string EASettings = "---------------------------------------------"; //-------- <EA Settings> -------- input int InpMagicNumber = 123456; //Magic Number input string InpBotName = "LazyBot_V1"; //Bot Name input string TradingSettings = "---------------------------------------------"; //-------- <Trading Settings> -------- input double Inpuser_lot = 0.01; //Lots input double Inpuser_SL = 5.0; //Stoploss (in Pips) input double InpAddPrice_pip = 0; //Dist from [H], [L] to OP_Price (in Pips) input int Inpuser_SLippage = 3; // Maximum slippage allow_Pips. input double InpMax_spread = 0; //Maximum allowed spread (in Pips) (0 = floating) input string TimeSettings = "---------------------------------------------"; //-------- <Trading Time Settings> -------- input bool isTradingTime = true; //Allow trading time input int InpStartHour = 7; //Start Hour input int InpEndHour = 22; //End Hour input string MoneyManagementSettings = "---------------------------------------------"; //-------- <Money Settings> -------- input bool isVolume_Percent = false; //Allow Volume Percent input double InpRisk = 1; //Risk Percentage of Balance (%)
2. مقداردهی اولیه متغیرهای محلی
//Local parameters datetime last; int totalBars; int Pips2Points; // slippage 3 pips 3=points 30=points double Pips2Double; // Stoploss 15 pips 0.015 0.0150 double slippage; double acSpread; string strComment = ""; CPositionInfo m_position; // trade position object CTrade m_trade; // trading object CSymbolInfo m_symbol; // symbol info object CAccountInfo m_account; // account info wrapper COrderInfo m_order; // pending orders object
3. کد اصلی
توضیح استراتژی: هر روز، ربات تمام سفارشهای قدیمی را حذف میکند و بیشترین و کمترین مقدار کندل روزانه قبلی را پیدا کرده و دو سفارش شرطی “BUY_STOP” و “SELL_STOP” ارسال میکند. (بدون TakeProfit)
a/ تابع مقداردهی اولیه اکسپرت
int OnInit()
{
//---
//3 or 5 digits detection
//Pip and point
if(_Digits % 2 == 1)
{
Pips2Double = _Point*10;
Pips2Points = 10;
slippage = 10* Inpuser_SLippage;
}
else
{
Pips2Double = _Point;
Pips2Points = 1;
slippage = Inpuser_SLippage;
}
if(!m_symbol.Name(Symbol())) // sets symbol name
return(INIT_FAILED);
RefreshRates();
//---
m_trade.SetExpertMagicNumber(InpMagicNumber);
m_trade.SetMarginMode();
m_trade.SetTypeFillingBySymbol(m_symbol.Name());
m_trade.SetDeviationInPoints(slippage);
//---
return(INIT_SUCCEEDED);
}
b/ تابع تیک اکسپرت
int OnInit()
{
//---
//3 or 5 digits detection
//Pip and point
if(_Digits % 2 == 1)
{
Pips2Double = _Point*10;
Pips2Points = 10;
slippage = 10* Inpuser_SLippage;
}
else
{
Pips2Double = _Point;
Pips2Points = 1;
slippage = Inpuser_SLippage;
}
if(!m_symbol.Name(Symbol())) // sets symbol name
return(INIT_FAILED);
RefreshRates();
//---
m_trade.SetExpertMagicNumber(InpMagicNumber);
m_trade.SetMarginMode();
m_trade.SetTypeFillingBySymbol(m_symbol.Name());
m_trade.SetDeviationInPoints(slippage);
//---
return(INIT_SUCCEEDED);
}
3.1 محاسبه سیگنال و ارسال سفارشها
//+------------------------------------------------------------------+
//| CALCULATE SIGNAL AND SEND ORDER |
//+------------------------------------------------------------------+
void OpenOrder()
{
double TP_Buy = 0, TP_Sell = 0;
double SL_Buy = 0, SL_Sell = 0;
//Check Maximum Spread
if(InpMax_spread != 0){
if(acSpread > InpMax_spread){
Print(__FUNCTION__," > current Spread is greater than user Spread!...");
return;
}
}
double Bar1High = m_symbol.NormalizePrice(iHigh(m_symbol.Name(), PERIOD_D1, 1));
double Bar1Low = m_symbol.NormalizePrice(iLow(m_symbol.Name(), PERIOD_D1, 1));
//Calculate Lots
double lot1 = CalculateVolume();
double OpenPrice = m_symbol.NormalizePrice(Bar1High + InpAddPrice_pip * Pips2Double);// + NormalizeDouble((acSpread/Pips2Points) * Pips2Double, Digits);
//For BUY_STOP --------------------------------
TP_Buy = 0;//Bar1High + NormalizeDouble(min_sl* Pips2Double, Digits);
SL_Buy = m_symbol.NormalizePrice(OpenPrice - Inpuser_SL * Pips2Double);
totalBars = iBars(m_symbol.Name(), PERIOD_D1);
string comment = InpBotName + ";" + m_symbol.Name() + ";" + totalBars;
if(CheckVolumeValue(lot1)
&& CheckOrderForFREEZE_LEVEL(ORDER_TYPE_BUY_STOP, OpenPrice)
&& CheckMoneyForTrade(m_symbol.Name(),lot1, ORDER_TYPE_BUY)
&& CheckStopLoss(OpenPrice, SL_Buy))
{
if(!m_trade.BuyStop(lot1, OpenPrice, m_symbol.Name(), SL_Buy, TP_Buy, ORDER_TIME_GTC, 0, comment))// use "ORDER_TIME_GTC" when expiration date = 0
Print(__FUNCTION__, "--> Buy Error");
}
//For SELL_STOP --------------------------------
OpenPrice = m_symbol.NormalizePrice(Bar1Low - InpAddPrice_pip * Pips2Double);// - NormalizeDouble((acSpread/Pips2Points) * Pips2Double, Digits);
TP_Sell = 0;//Bar1Low - NormalizeDouble(min_sl* Pips2Double, Digits);
SL_Sell = m_symbol.NormalizePrice(OpenPrice + Inpuser_SL * Pips2Double);
if(CheckVolumeValue(lot1)
&& CheckOrderForFREEZE_LEVEL(ORDER_TYPE_SELL_STOP, OpenPrice)
&& CheckMoneyForTrade(m_symbol.Name(),lot1, ORDER_TYPE_SELL)
&& CheckStopLoss(OpenPrice, SL_Sell))
{
if(!m_trade.SellStop(lot1, OpenPrice, m_symbol.Name(), SL_Sell, TP_Sell, ORDER_TIME_GTC, 0, comment))
Print(__FUNCTION__, "--> Sell Error");
}
}
3.2 روز جدید، حذف تمام سفارشهای قدیمی
//+------------------------------------------------------------------+
//| Delele Old Orders |
//+------------------------------------------------------------------+
void DeleteOldOrds()
{
string sep=";"; // A separator as a character
ushort u_sep; // The code of the separator character
string result[]; // An array to get strings
for(int i = OrdersTotal() - 1; i >= 0; i--) // returns the number of current orders
{
if(m_order.SelectByIndex(i)) // selects the pending order by index for further access to its properties
{
//--- Get the separator code
u_sep = StringGetCharacter(sep, 0);
string Ordcomment = m_order.Comment();
//Split OrderComment (EAName;Symbol;totalBar) to get Ordersymbol
int k = StringSplit(Ordcomment, u_sep, result);
if(k > 2)
{
string sym = m_symbol.Name();
if((m_order.Magic() == InpMagicNumber) && (sym == result[1]))
{
m_trade.OrderDelete(m_order.Ticket());
}
}
}
}
}
3.3 اکسپرت دارای تابع “Trailing StopLoss” است، SL هر بار که قیمت تغییر میکند، تغییر میکند و باعث افزایش سود میشود.
//+------------------------------------------------------------------+
//| TRAILING STOPLOSS |
//+------------------------------------------------------------------+
void TrailingSL()
{
double SL_in_Pip = 0;
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
if(m_position.SelectByIndex(i)) // selects the orders by index for further access to its properties
{
if((m_position.Magic() == InpMagicNumber) && (m_position.Symbol() == m_symbol.Name())) //m_symbol.Name()
{
double order_stoploss1 = m_position.StopLoss();
// For Buy oder
if(m_position.PositionType() == POSITION_TYPE_BUY)
{
//--Calculate SL when price changed
SL_in_Pip = NormalizeDouble((Bid - order_stoploss1), _Digits) / Pips2Double;
//Print(__FUNCTION__, "Modify Order Buy " + (string)SL_in_Pip);
if(SL_in_Pip > Inpuser_SL)
{
order_stoploss1 = NormalizeDouble(Bid - (Inpuser_SL * Pips2Double), _Digits);
m_trade.PositionModify(m_position.Ticket(), order_stoploss1, m_position.TakeProfit());
}
}
//For Sell Order
if(m_position.PositionType() == POSITION_TYPE_SELL)
{
//--Calculate SL when price changed
SL_in_Pip = NormalizeDouble((m_position.StopLoss() - Ask), _Digits) / Pips2Double;
if(SL_in_Pip > Inpuser_SL)
{
order_stoploss1 = NormalizeDouble(Ask + (Inpuser_SL * Pips2Double), _Digits);
m_trade.PositionModify(m_position.Ticket(), order_stoploss1, m_position.TakeProfit());
}
}
}
}
}
}
3.4 بررسی مقدار حجم (Volume)
//+------------------------------------------------------------------+
//| Check the correctness of the order volume |
//+------------------------------------------------------------------+
bool CheckVolumeValue(double volume)
{
//--- minimal allowed volume for trade operations
double min_volume = m_symbol.LotsMin();
//--- maximal allowed volume of trade operations
double max_volume = m_symbol.LotsMax();
//--- get minimal step of volume changing
double volume_step = m_symbol.LotsStep();
if(volume < min_volume || volume>max_volume)
{
return(false);
}
int ratio = (int)MathRound(volume/volume_step);
if(MathAbs(ratio*volume_step-volume)>0.0000001)
{
return(false);
}
return(true);
}
3.5 بررسی سطح آزاد (FreeLevel)
//+------------------------------------------------------------------+
//| CHECK FREEZE LEVEL |
//+------------------------------------------------------------------+
bool CheckOrderForFREEZE_LEVEL(ENUM_ORDER_TYPE type, double price)//change name of this function
{
int freeze_level = (int)SymbolInfoInteger(_Symbol, SYMBOL_TRADE_FREEZE_LEVEL);
bool check = false;
//--- check only two order types
switch(type)
{
//--- Buy operation
case ORDER_TYPE_BUY_STOP:
{
//--- check the distance from the opening price to the activation price
check = ((price-Ask) > freeze_level*_Point);
//--- return the result of checking
return(check);
}
//--- Sell operation
case ORDER_TYPE_SELL_STOP:
{
//--- check the distance from the opening price to the activation price
check = ((Bid-price)>freeze_level*_Point);
//--- return the result of checking
return(check);
}
break;
}
//--- a slightly different function is required for pending orders
return false;
}
3.6 بررسی موجودی حساب برای معامله (Money)
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CheckMoneyForTrade(string symb,double lots,ENUM_ORDER_TYPE type)
{
//--- Getting the opening price
MqlTick mqltick;
SymbolInfoTick(symb,mqltick);
double price=mqltick.ask;
if(type==ORDER_TYPE_SELL)
price=mqltick.bid;
//--- values of the required and free margin
double margin,free_margin=AccountInfoDouble(ACCOUNT_MARGIN_FREE);
//--- call of the checking function
if(!OrderCalcMargin(type,symb,lots,price,margin))
{
//--- something went wrong, report and return false
Print("Error in ",__FUNCTION__," code=",GetLastError());
return(false);
}
//--- if there are insufficient funds to perform the operation
if(margin>free_margin)
{
//--- report the error and return false
Print("Not enough money for ",EnumToString(type)," ",lots," ",symb," Error code=",GetLastError());
return(false);
}
//--- checking successful
return(true);
}
3.7 بررسی حد ضرر (Stoploss)
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CheckMoneyForTrade(string symb,double lots,ENUM_ORDER_TYPE type)
{
//--- Getting the opening price
MqlTick mqltick;
SymbolInfoTick(symb,mqltick);
double price=mqltick.ask;
if(type==ORDER_TYPE_SELL)
price=mqltick.bid;
//--- values of the required and free margin
double margin,free_margin=AccountInfoDouble(ACCOUNT_MARGIN_FREE);
//--- call of the checking function
if(!OrderCalcMargin(type,symb,lots,price,margin))
{
//--- something went wrong, report and return false
Print("Error in ",__FUNCTION__," code=",GetLastError());
return(false);
}
//--- if there are insufficient funds to perform the operation
if(margin>free_margin)
{
//--- report the error and return false
Print("Not enough money for ",EnumToString(type)," ",lots," ",symb," Error code=",GetLastError());
return(false);
}
//--- checking successful
return(true);
}

جهت عضویت در کانال اندیکاتور و اکسپرت کلیک کنید ایتا | بله | تلگرام
جهت سفارش طراحی و برنامهنویسی اختصاصی اندیکاتور، اکسپرت و ربات معاملهگر برای MetaTrader 4 و MetaTrader 5 میتوانید استراتژی، ایده یا نیاز معاملاتی خود را با تیم هوش فعال در میان بگذارید. برای دریافت مشاوره، بررسی امکان پیادهسازی و ثبت سفارش، از طریق شماره 09364549266 با پشتیبانی هوش فعال در ارتباط باشید.
⚠️ هشدار و سلب مسئولیت
اکسپرتهای رایگان ارائهشده در سایت هوش فعال صرفاً با هدف آموزش، آزمایش و آشنایی با ابزارهای معاملاتی ارائه میشوند و هیچگونه تضمینی بابت سوددهی یا عملکرد آنها در شرایط مختلف بازار وجود ندارد.
معاملات فارکس و سایر بازارهای مالی دارای ریسک بالایی هستند. هوش فعال هیچگونه مسئولیتی در قبال سود، زیان، تصمیمات معاملاتی یا خسارات احتمالی ناشی از استفاده از این اکسپرتها ندارد.
لطفاً پیش از استفاده در حساب واقعی، اکسپرت را در حساب Demo و یا سرمایهای که توان از دست دادن آن را دارید، آزمایش کنید.











