How to start with MQL5 - page 28

 
Vladimir Karputov:

Problem # 1: Determine to what depth you need to scan the market.

By depth im hoping you mean lookback period, i usually have 150-200 bars on my screen, so i would like for it to be 200

 
Ahmad861 :

By depth im hoping you mean lookback period, i usually have 150-200 bars on my screen, so i would like for it to be 200

Yes, you got it right. Next, you need to enter the settings for "similar candles" - this is a percentage spread or a spread in points. The parameter "group of candles" is also needed - a group of neighboring candles among which there is a search ...

 
Vladimir Karputov:

Yes, you got it right. Next, you need to enter the settings for "similar candles" - this is a percentage spread or a spread in points. The parameter "group of candles" is also needed - a group of neighboring candles among which there is a search ...

I did not get this part

 
I searched for similar candles in the Similar Candle indicator - you can take it as a basis.
Similar Candle
Similar Candle
  • www.mql5.com
Индикатор ищет подобные свечи
 
Vladimir Karputov:
I searched for similar candles in the Similar Candle indicator - you can take it as a basis.

Im sorry, but i still don't understand what i should be doing

 

Close a position if Swap was accrued

Function: 'CloseAllPositionsFirstSwap'

//+------------------------------------------------------------------+
//| Close all positions First Swap                                   |
//+------------------------------------------------------------------+
void CloseAllPositionsFirstSwap(void)
  {
   for(int i=PositionsTotal()-1; i>=0; i--) // returns the number of current positions
      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
           {
            double swap=m_position.Swap();
            if(swap<=0.0)
               continue;
            if(m_position.PositionType()==POSITION_TYPE_BUY)
              {
               if(!m_trade.PositionClose(m_position.Ticket())) // close a position by the specified m_symbol
                  if(InpPrintLog)
                     Print(__FILE__," ",__FUNCTION__,", ERROR: ","BUY PositionClose ",m_position.Ticket(),", ",m_trade.ResultRetcodeDescription());
              }
            if(m_position.PositionType()==POSITION_TYPE_SELL)
              {
               if(!m_trade.PositionClose(m_position.Ticket())) // close a position by the specified m_symbol
                  if(InpPrintLog)
                     Print(__FILE__," ",__FUNCTION__,", ERROR: ","SELL PositionClose ",m_position.Ticket(),", ",m_trade.ResultRetcodeDescription());
              }
           }
  }

It is recommended to call this function at the beginning of the day.

 

The EA can open only one position of the same type

Code: Example One position of one type.mq5

How the Expert Advisor works: the 'CalculateAllPositions' function is called in 'OnTick'. The 'CalculateAllPositions' function calculates 'BUY' and 'SELL' positions.

//+------------------------------------------------------------------+
//|                             Example One position of one type.mq5 |
//|                              Copyright © 2021, Vladimir Karputov |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2021, Vladimir Karputov"
#property version   "1.000"
//---
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
//---
CPositionInfo  m_position;                   // object of CPositionInfo class
CTrade         m_trade;                      // object of CTrade class
CSymbolInfo    m_symbol;                     // object of CSymbolInfo class
//--- input parameters
input group             "Additional features"
input ulong    InpDeviation         = 10;          // Deviation, in Points (1.00045-1.00055=10 points)
input ulong    InpMagic             = 200;         // Magic number
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
//---
   ResetLastError();
   if(!m_symbol.Name(Symbol())) // sets symbol name
     {
      Print(__FILE__," ",__FUNCTION__,", ERROR: CSymbolInfo.Name");
      return(INIT_FAILED);
     }
   RefreshRates();
//---
   m_trade.SetExpertMagicNumber(InpMagic);
   m_trade.SetMarginMode();
   m_trade.SetTypeFillingBySymbol(m_symbol.Name());
   m_trade.SetDeviationInPoints(InpDeviation);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   int count_buys=0,count_sells=0;
   CalculateAllPositions(count_buys,count_sells);
   if(count_buys==0)
     {
      // Search for a BUY signal
     }
   if(count_sells==0)
     {
      // Search for a SELL signal
     }
  }
//+------------------------------------------------------------------+
//| Refreshes the symbol quotes data                                 |
//+------------------------------------------------------------------+
bool RefreshRates()
  {
//--- refresh rates
   if(!m_symbol.RefreshRates())
     {
      Print(__FILE__," ",__FUNCTION__,", ERROR: ","RefreshRates error");
      return(false);
     }
//--- protection against the return value of "zero"
   if(m_symbol.Ask()==0 || m_symbol.Bid()==0)
     {
      Print(__FILE__," ",__FUNCTION__,", ERROR: ","Ask == 0.0 OR Bid == 0.0");
      return(false);
     }
//---
   return(true);
  }
//+------------------------------------------------------------------+
//| Calculate all positions Buy and Sell                             |
//+------------------------------------------------------------------+
void CalculateAllPositions(int &count_buys,int &count_sells)
  {
   count_buys=0;
   count_sells=0;
   for(int i=PositionsTotal()-1; i>=0; i--)
      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
           {
            if(m_position.PositionType()==POSITION_TYPE_BUY)
               count_buys++;
            if(m_position.PositionType()==POSITION_TYPE_SELL)
               count_sells++;
           }
//---
   return;
  }
//+------------------------------------------------------------------+
 

The number of pending orders (only system functions, no OOP)

'CalculateAllPendingOrdersSystem' function

//+------------------------------------------------------------------+
//| Calculate all pending orders for symbol                          |
//+------------------------------------------------------------------+
int CalculateAllPendingOrdersSystem(const string symbol,const ulong magic)
  {
   int total=0;
   for(int i=OrdersTotal()-1; i>=0; i--) // returns the number of current orders
     {
      ulong order_ticket=OrderGetTicket(i); // selects the pending order by index for further access to its properties
      if(order_ticket==0)
         continue;
      string order_symbol=OrderGetString(ORDER_SYMBOL); // get symbol
      long order_magic=OrderGetInteger(ORDER_MAGIC); // get magic
      //---
      if(order_symbol==symbol && order_magic==magic)
         total++;
     }
//---
   return(total);
  }

There are two pending orders with Magic '200' and one with Magic '100' in the market - only three pending orders (all three pending orders for the 'EURAUD' symbol).

Run the script:

//+------------------------------------------------------------------+
//|                                                     Script 1.mq5 |
//|                              Copyright © 2021, Vladimir Karputov |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2021, Vladimir Karputov"
#property version   "1.000"
#property script_show_inputs
//--- input parameters
input string   InpSymbol   = "EURUSD"; // Symbol
input ulong    InpMagic    = 200;      // Magic number
//---
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   int total=CalculateAllPendingOrdersSystem(InpSymbol,InpMagic);
   PrintFormat("Symbol %s, Magic %d, Pending Orders %d:",InpSymbol,InpMagic,total);
  }
//+------------------------------------------------------------------+
//| Calculate all pending orders for symbol                          |
//+------------------------------------------------------------------+
int CalculateAllPendingOrdersSystem(const string symbol,const ulong magic)
  {
   int total=0;
   for(int i=OrdersTotal()-1; i>=0; i--) // returns the number of current orders
     {
      ulong order_ticket=OrderGetTicket(i); // selects the pending order by index for further access to its properties
      if(order_ticket==0)
         continue;
      string order_symbol=OrderGetString(ORDER_SYMBOL); // get symbol
      long order_magic=OrderGetInteger(ORDER_MAGIC); // get magic
      //---
      if(order_symbol==symbol && order_magic==magic)
         total++;
     }
//---
   return(total);
  }
//+------------------------------------------------------------------+

We get the result:

2021.08.24 08:34:20.871 Script 1 (EURAUD,H1)    Symbol EURUSD, Magic 200, Pending Orders 0:
2021.08.24 08:34:29.510 Script 1 (EURAUD,H1)    Symbol EURAUD, Magic 200, Pending Orders 2:
2021.08.24 08:34:38.224 Script 1 (EURAUD,H1)    Symbol EURAUD, Magic 100, Pending Orders 1:
Files:
Script_1.mq5  4 kb
 

How to create an indicator - the difference between two iMAs (Moving Average)

Forum on trading, automated trading systems and testing trading strategies

Cannot initialize buffers

Vladimir Karputov, 2021.08.27 05:32

How to create an indicator - the difference between two iMAs (Moving Average).

Step 1

Step 1. Right click on the folder and select 'New File'

Step 2

Step 2. Indicator name (string 'Namde'), one input parameter ('Parameters')

Step 3

Step 3. Selecting the full version of OnCalculate

Step 4

Step 4. 'Indicator in separate windows'c, add one line' Diff_Two_iMA '

We get the workpiece:

//+------------------------------------------------------------------+
//|                                           Difference Two iMA.mq5 |
//|                              Copyright © 2021, Vladimir Karputov |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2021, Vladimir Karputov"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot Diff_Two_iMA
#property indicator_label1  "Diff_Two_iMA"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrYellowGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters
input int      Input1=9;
//--- indicator buffers
double         Diff_Two_iMABuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,Diff_Two_iMABuffer,INDICATOR_DATA);
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+


Now we start thinking: we need to add two arrays - for two iMAs. So we change the counter and add these two arrays, and we will declare two variables - they will store two handles

#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots   1
//--- plot Diff_Two_iMA
#property indicator_label1  "Diff_Two_iMA"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrYellowGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters
input int      Input1=9;
//--- indicator buffers
double   Diff_Two_iMABuffer[];
double   FastBuffer[];
double   SlowBuffer[];
//---
int      handle_iMA_Fast;              // variable for storing the handle of the iMA indicator
int      handle_iMA_Slow;              // variable for storing the handle of the iMA indicator
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |


Add variable 'm_init_error' - this is a flag. If there is an error while creating the indicator, this flag will be set to 'true'.

double   SlowBuffer[];
//---
bool     m_init_error      = false;    // error on InInit
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |


Adding input parameters for the 'Fast' and 'Slow' indicator

//--- input parameters
input group             "Fast MA"
input int                  Inp_MA_Fast_ma_period      = 9;              // MA Fast: averaging period
input int                  Inp_MA_Fast_ma_shift       = 0;              // MA Fast: horizontal shift
input ENUM_MA_METHOD       Inp_MA_Fast_ma_method      = MODE_SMA;       // MA Fast: smoothing type
input ENUM_APPLIED_PRICE   Inp_MA_Fast_applied_price  = PRICE_CLOSE;    // MA Fast: type of price
input group             "Slow MA"
input int                  Inp_MA_Slow_ma_period      = 26;             // MA Slow: averaging period
input int                  Inp_MA_Slow_ma_shift       = 0;              // MA Slow: horizontal shift
input ENUM_MA_METHOD       Inp_MA_Slow_ma_method      = MODE_SMA;       // MA Slow: smoothing type
input ENUM_APPLIED_PRICE   Inp_MA_Slow_applied_price  = PRICE_CLOSE;    // MA Slow: type of price
//--- indicator buffers


Go to 'OnInit': link two arrays and create two handles

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,Diff_Two_iMABuffer,INDICATOR_DATA);
   SetIndexBuffer(1,FastBuffer,INDICATOR_DATA);
   SetIndexBuffer(2,SlowBuffer,INDICATOR_DATA);
//--- create handle of the indicator iMA
   handle_iMA_Fast=iMA(Symbol(),Period(),Inp_MA_Fast_ma_period,Inp_MA_Fast_ma_shift,
                       Inp_MA_Fast_ma_method,Inp_MA_Fast_applied_price);
//--- if the handle is not created
   if(handle_iMA_Fast==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code
      PrintFormat("Failed to create handle of the iMA ('Fast') indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early
      m_init_error=true;
      return(INIT_SUCCEEDED);
     }
//--- create handle of the indicator iMA
   handle_iMA_Slow=iMA(Symbol(),Period(),Inp_MA_Slow_ma_period,Inp_MA_Slow_ma_shift,
                       Inp_MA_Slow_ma_method,Inp_MA_Slow_applied_price);
//--- if the handle is not created
   if(handle_iMA_Slow==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code
      PrintFormat("Failed to create handle of the iMA ('Slow') indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early
      m_init_error=true;
      return(INIT_SUCCEEDED);
     }
//---
   return(INIT_SUCCEEDED);
  }


Go to OnCalculate - Here are mainly copy-paste operations (using the iMA help)

Continued later ...


 

Forum on trading, automated trading systems and testing trading strategies

Cannot initialize buffers

Vladimir Karputov, 2021.08.27 12:24

Continuation ...

Apply copy-paste and do some manual work. From the help ( iMA ) we copy almost the entire function and change it a little for ourselves (change the name of the indicator buffers, change the name of the handle and throw out 'Comment') Here just carefully compare the help ( iMA  ) and my code. First of all, add the variable 'bars_calculated' to the program header:

int      handle_iMA_Slow;              // variable for storing the handle of the iMA indicator
//---
int      bars_calculated   = 0;        // we will keep the number of values in the Moving Average indicator 
bool     m_init_error      = false;    // error on InInit
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |


I have highlighted the main thing - this is the calculation of the difference

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   if(m_init_error)
      return(0);
//--- number of values copied from the iMA indicator
   int values_to_copy;
//--- determine the number of values calculated in the indicator
   int calculated_fast=BarsCalculated(handle_iMA_Fast);
   if(calculated_fast<=0)
     {
      PrintFormat("BarsCalculated(handle_iMA_Fast) returned %d, error code %d",calculated_fast,GetLastError());
      return(0);
     }
   int calculated_slow=BarsCalculated(handle_iMA_Slow);
   if(calculated_slow<=0)
     {
      PrintFormat("BarsCalculated(handle_iMA_Slow) returned %d, error code %d",calculated_slow,GetLastError());
      return(0);
     }
   if(calculated_fast!=calculated_slow)
     {
      PrintFormat("BarsCalculated(handle_iMA_Fast) returned %d, BarsCalculated(handle_iMA_Slow) returned %d",calculated_fast,calculated_slow);
      return(0);
     }
   int calculated=calculated_fast;
//--- if it is the first start of calculation of the indicator or if the number of values in the iMA indicator changed
//---or if it is necessary to calculated the indicator for two or more bars (it means something has changed in the price history)
   if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
     {
      //--- if the iMABuffer array is greater than the number of values in the iMA indicator for symbol/period, then we don't copy everything
      //--- otherwise, we copy less than the size of indicator buffers
      if(calculated>rates_total)
         values_to_copy=rates_total;
      else
         values_to_copy=calculated;
     }
   else
     {
      //--- it means that it's not the first time of the indicator calculation, and since the last call of OnCalculate()
      //--- for calculation not more than one bar is added
      values_to_copy=(rates_total-prev_calculated)+1;
     }
//--- fill the iMABuffer array with values of the Moving Average indicator
//--- if FillArrayFromBuffer returns false, it means the information is nor ready yet, quit operation
   if(!FillArrayFromBuffer(FastBuffer,Inp_MA_Fast_ma_shift,handle_iMA_Fast,values_to_copy))
      return(0);
   if(!FillArrayFromBuffer(SlowBuffer,Inp_MA_Slow_ma_shift,handle_iMA_Slow,values_to_copy))
      return(0);
//--- memorize the number of values in the Moving Average indicator
   bars_calculated=calculated;
//--- main loop
   int limit=prev_calculated-1;
   if(prev_calculated==0)
      limit=0;
   for(int i=limit; i<rates_total; i++)
     {
      Diff_Two_iMABuffer[i]=FastBuffer[i]-SlowBuffer[i];
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Filling indicator buffers from the MA indicator                  |
//+------------------------------------------------------------------+
bool FillArrayFromBuffer(double &values[],   // indicator buffer of Moving Average values
                         int shift,          // shift
                         int ind_handle,     // handle of the iMA indicator
                         int amount          // number of copied values
                        )
  {
//--- reset error code
   ResetLastError();
//--- fill a part of the iMABuffer array with values from the indicator buffer that has 0 index
   if(CopyBuffer(ind_handle,0,-shift,amount,values)<0)
     {
      //--- if the copying fails, tell the error code
      PrintFormat("Failed to copy data from the iMA indicator, error code %d",GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated
      return(false);
     }
//--- everything is fine
   return(true);
  }
//+------------------------------------------------------------------+
//| Indicator deinitialization function                              |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   if(handle_iMA_Fast!=INVALID_HANDLE)
      IndicatorRelease(handle_iMA_Fast);
   if(handle_iMA_Slow!=INVALID_HANDLE)
      IndicatorRelease(handle_iMA_Slow);
  }
//+------------------------------------------------------------------+


Result:

Difference Two iMA


Reason: