How to start with MQL5 - page 5

To add comments, please log in or register
Vladimir Karputov
Moderator
215418
Vladimir Karputov  

Open position every new candle.

First we define a new bar.

If this is a new bar - open a BUY position with a minimum volume.


//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- we work only at the time of the birth of new bar
   datetime time_0=iTime(m_symbol.Name(),Period(),0);
   if(time_0==m_prev_bars)
      return;
   m_prev_bars=time_0;
//---
   m_trade.Buy(m_symbol.LotsMin());
  }


Full code:

//+------------------------------------------------------------------+
//|                               Open position every new candle.mq5 |
//|                              Copyright © 2020, Vladimir Karputov |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2020, Vladimir Karputov"
#property version   "1.000"
/*
   barabashkakvn Trading engine 3.116
*/
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
//---
CTrade         m_trade;                      // object of CTrade class
CSymbolInfo    m_symbol;                     // object of CSymbolInfo class
//--- input parameters
input ulong    InpDeviation         = 10;          // Deviation, in points (1.00045-1.00055=10 points)
input ulong    InpMagic             = 201;         // Magic number
//---
datetime m_prev_bars                = 0;        // "0" -> D'1970.01.01 00:00';
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   if(!m_symbol.Name(Symbol())) // sets symbol name
     {
      Print(__FILE__," ",__FUNCTION__,", ERROR: CSymbolInfo.Name");
      return(INIT_FAILED);
     }
//---
   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()
  {
//--- we work only at the time of the birth of new bar
   datetime time_0=iTime(m_symbol.Name(),Period(),0);
   if(time_0==m_prev_bars)
      return;
   m_prev_bars=time_0;
//---
   m_trade.Buy(m_symbol.LotsMin());
  }
//+------------------------------------------------------------------+
Vladimir Karputov
Moderator
215418
Vladimir Karputov  

Bars after the last iMA crossing

Task: there are two iMA indicators. Need to find: how many bars have passed since the last crossing.

Algorithm: if this is the first run - use the first form of the CopyBuffer function

Call by the first position and the number of required elements

int  CopyBuffer(
   int       indicator_handle,     // indicator handle
   int       buffer_num,           // indicator buffer number
   int       start_pos,            // start position
   int       count,                // amount to copy
   double    buffer[]              // target array to copy
   );

copy 100 elements and search for the intersection. We print the number of the bar and the opening time of the bar with the intersection

      for(int i=1; i<count-1; i++)
        {
         if((fast[i+1]<slow[i+1] && fast[i]>slow[i]) || (fast[i+1]>slow[i+1] && fast[i]<slow[i]))
           {
            Comment("Bars after the last iMA crossing: ",IntegerToString(i+1)," (",TimeToString(rates[i].time,TIME_DATE|TIME_MINUTES),")");
            m_last_crossing=rates[i+2].time;
            return;
           }
        }


Next time we use the third form

Call by the start and end dates of a required time interval

int  CopyBuffer(
   int       indicator_handle,     // indicator handle
   int       buffer_num,           // indicator buffer number
   datetime  start_time,           // start date and time
   datetime  stop_time,            // end date and time
   double    buffer[]              // target array to copy
   );


Bars after the last iMA crossing

Documentation on MQL5: Timeseries and Indicators Access / CopyBuffer
Documentation on MQL5: Timeseries and Indicators Access / CopyBuffer
  • www.mql5.com
Counting of elements of copied data (indicator buffer with the index buffer_num) from the starting position is performed from the present to the past, i.e., starting position of 0 means the current bar (indicator value for the current bar). When copying the yet unknown amount of data, it is recommended to use a dynamic array as a buffer[]...
Vladimir Karputov
Moderator
215418
Vladimir Karputov  

iMACD value on chart

An example of how to create a handle to the MACD indicator. An example of how to get the MACD indicator values on the last three bars. Remember the main rule: you need to create an indicator handle once (the best option is to create a handle in OnInit).

Full code:

//+------------------------------------------------------------------+
//|                                         iMACD value on chart.mq5 |
//|                              Copyright © 2020, Vladimir Karputov |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2020, Vladimir Karputov"
#property version   "1.000"
//--- input parameters
input int                  Inp_MACD_fast_ema_period= 8;           // MACD: period for Fast average calculation
input int                  Inp_MACD_slow_ema_period= 17;          // MACD: period for Slow average calculation
input int                  Inp_MACD_signal_period  = 9;           // MACD: period for their difference averaging
input ENUM_APPLIED_PRICE   Inp_MACD_applied_price  = PRICE_CLOSE; // MACD: type of price
//---
int      handle_iMACD;                          // variable for storing the handle of the iMACD indicator
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create handle of the indicator iMACD
   handle_iMACD=iMACD(Symbol(),Period(),Inp_MACD_fast_ema_period,Inp_MACD_slow_ema_period,
                      Inp_MACD_signal_period,Inp_MACD_applied_price);
//--- if the handle is not created
   if(handle_iMACD==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code
      PrintFormat("Failed to create handle of the iMACD indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   double main[],signal[];
   ArraySetAsSeries(main,true);
   ArraySetAsSeries(signal,true);
   int start_pos=0,count=3;
   if(!iGetArray(handle_iMACD,MAIN_LINE,start_pos,count,main) ||
      !iGetArray(handle_iMACD,SIGNAL_LINE,start_pos,count,signal))
     {
      return;
     }
//---
   string text_main="Main |",text_signal="Signal |";
   for(int i=count-1; i>=0; i--)
     {
      text_main=text_main+" #"+IntegerToString(i)+" "+DoubleToString(main[i],Digits()+1)+" | ";
      text_signal=text_signal+" #"+IntegerToString(i)+" "+DoubleToString(signal[i],Digits()+1)+" | ";
     }
   Comment(text_main,"\n",text_signal);
  }
//+------------------------------------------------------------------+
//| Get value of buffers                                             |
//+------------------------------------------------------------------+
bool iGetArray(const int handle,const int buffer,const int start_pos,
               const int count,double &arr_buffer[])
  {
   bool result=true;
   if(!ArrayIsDynamic(arr_buffer))
     {
      PrintFormat("ERROR! EA: %s, FUNCTION: %s, this a no dynamic array!",__FILE__,__FUNCTION__);
      return(false);
     }
   ArrayFree(arr_buffer);
//--- reset error code
   ResetLastError();
//--- fill a part of the iBands array with values from the indicator buffer
   int copied=CopyBuffer(handle,buffer,start_pos,count,arr_buffer);
   if(copied!=count)
     {
      //--- if the copying fails, tell the error code
      PrintFormat("ERROR! EA: %s, FUNCTION: %s, amount to copy: %d, copied: %d, error code %d",
                  __FILE__,__FUNCTION__,count,copied,GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated
      return(false);
     }
   return(result);
  }
//+------------------------------------------------------------------+

Result:

iMACD value on chart

Vladimir Karputov
Moderator
215418
Vladimir Karputov  

An example of get values from the iStochastic indicator

Code: iStochastic get value.mq5

Do not forget the rules: create the indicator handle ONCE in OnInit, use CopyBuffer to get the data.

//+------------------------------------------------------------------+
//|                                        iStochastic get value.mq5 |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2019, Vladimir Karputov"
#property version   "1.001"
//--- input parameters
input group "Stochastic"
input ENUM_TIMEFRAMES   Inp_STO_period       = PERIOD_CURRENT; // Stochastic: timeframe
input int               Inp_STO_Kperiod      = 5;              // Stochastic: K-period (number of bars for calculations)
input int               Inp_STO_Dperiod      = 3;              // Stochastic: D-period (period of first smoothing)
input int               Inp_STO_slowing      = 3;              // Stochastic: final smoothing
input ENUM_MA_METHOD    Inp_STO_ma_method    = MODE_SMA;       // Stochastic: type of smoothing
input ENUM_STO_PRICE    Inp_STO_price_field  = STO_LOWHIGH;    // Stochastic: stochastic calculation method
input group "Service parameters"
input bool              InpPrintLog          = false;          // Print log
//---
int    handle_iStochastic;                   // variable for storing the handle of the iStochastic indicator
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create handle of the indicator iStochastic
   handle_iStochastic=iStochastic(Symbol(),Inp_STO_period,
                                  Inp_STO_Kperiod,Inp_STO_Dperiod,Inp_STO_slowing,
                                  Inp_STO_ma_method,Inp_STO_price_field);
//--- if the handle is not created
   if(handle_iStochastic==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code
      PrintFormat("Failed to create handle of the iStochastic indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Inp_STO_period),
                  GetLastError());
      //--- the indicator is stopped early
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   double main[],signal[];
   ArraySetAsSeries(main,true);
   ArraySetAsSeries(signal,true);
   int start_pos=0,count=2;
   if(!iGetArray(handle_iStochastic,MAIN_LINE,start_pos,count,main) ||
      !iGetArray(handle_iStochastic,SIGNAL_LINE,start_pos,count,signal))
     {
      return;
     }
//---
   string text="";
   int limit=(count>2)?2:count;
   for(int i=0; i<limit; i++)
     {
      text=text+
           " bar #"+IntegerToString(i)+": "+
           " main "+DoubleToString(main[i],2)+
           " signal "+DoubleToString(signal[i],2)+"\n";
     }
   Comment(text);
  }
//+------------------------------------------------------------------+
//| Get value of buffers                                             |
//+------------------------------------------------------------------+
bool iGetArray(const int handle,const int buffer,const int start_pos,
               const int count,double &arr_buffer[])
  {
   bool result=true;
   if(!ArrayIsDynamic(arr_buffer))
     {
      if(InpPrintLog)
         PrintFormat("ERROR! EA: %s, FUNCTION: %s, this a no dynamic array!",__FILE__,__FUNCTION__);
      return(false);
     }
   ArrayFree(arr_buffer);
//--- reset error code
   ResetLastError();
//--- fill a part of the iBands array with values from the indicator buffer
   int copied=CopyBuffer(handle,buffer,start_pos,count,arr_buffer);
   if(copied!=count)
     {
      //--- if the copying fails, tell the error code
      if(InpPrintLog)
         PrintFormat("ERROR! EA: %s, FUNCTION: %s, amount to copy: %d, copied: %d, error code %d",
                     __FILE__,__FUNCTION__,count,copied,GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated
      return(false);
     }
   return(result);
  }
//+------------------------------------------------------------------+


Result:

iStochastic get value

Vladimir Karputov
Moderator
215418
Vladimir Karputov  

Example Type of candle (we use MqlRates)

//+------------------------------------------------------------------+
//|                                       Example Type of candle.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//--- input parameters
input int      Input1=9;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   Comment("");
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   MqlRates rates[];
   ArraySetAsSeries(rates,true);
   int start_pos=0,count=3;
   if(CopyRates(Symbol(),Period(),start_pos,count,rates)!=count)
      return;

   if(rates[0].close>rates[0].open)
      Comment("Candle ",TimeToString(rates[0].time,TIME_DATE|TIME_MINUTES),": bullish");
   else
      Comment("Candle ",TimeToString(rates[0].time,TIME_DATE|TIME_MINUTES),": bearish ");
  }
//+------------------------------------------------------------------+
Ahmadahmad654
13
Ahmadahmad654  

Hi Vladimir, thank you for your great effort,  I have learned a lot from you MQL5 and I want to help you with the (PositionClosePartial) function and this code please look at it .. as it sometimes succeeds in closing a part and sometimes it fails and closes all deals in its use in hedging :

void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
    //--- get transaction type as enumeration value 
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
   ENUM_ACCOUNT_MARGIN_MODE AccountMargin = (ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE);
   if(AccountMargin==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING)accofif=true;
//--- if transaction is result of addition of the transaction in history
   if(type==TRADE_TRANSACTION_DEAL_ADD)
     {
      long     deal_type         =-1;
      long     deal_entry        =-1;
      double   deal_volume       =0.0;
      string   deal_symbol       ="";
      if(HistoryDealSelect(trans.deal))
        {
         deal_type         =HistoryDealGetInteger(trans.deal,DEAL_TYPE);
         deal_entry        =HistoryDealGetInteger(trans.deal,DEAL_ENTRY);
         deal_volume       =HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
         deal_symbol       =HistoryDealGetString(trans.deal,DEAL_SYMBOL);
        }
      else
         return;
      if(deal_entry==DEAL_ENTRY_OUT)
        {
         ulong PositionTicket=PositionGetInteger(POSITION_TICKET);
         ulong deviation=ULONG_MAX;
    
         switch((int)deal_type)
           {
            case  DEAL_TYPE_SELL:
            if(Total(POSITION_TYPE_SELL) >0&& accofif)
         
             m_trade.PositionClosePartial(PositionTicket,Lot,-1);
          
               break;
            case  DEAL_TYPE_BUY:
             if(Total(POSITION_TYPE_BUY) >0&& accofif)
       
     
             m_trade.PositionClosePartial(PositionTicket,Lot,-1);
            
               break;
            default:
               break;
           }
        }
     }
   
  }
Documentation on MQL5: Constants, Enumerations and Structures / Trade Constants / Trade Transaction Types
Documentation on MQL5: Constants, Enumerations and Structures / Trade Constants / Trade Transaction Types
  • www.mql5.com
Removing an order from the list of the open ones. An order can be deleted from the open ones as a result of setting an appropriate request or execution (filling) and moving to the history. Updating a deal in the history. There may be cases when a previously executed deal is changed on a server. For example, a deal has been changed in an...
Vladimir Karputov
Moderator
215418
Vladimir Karputov  
Ahmadahmad654 :

Hi Vladimir, thank you for your great effort,  I have learned a lot from you MQL5 and I want to help you with the (PositionClosePartial) function and this code please look at it .. as it sometimes succeeds in closing a part and sometimes it fails and closes all deals in its use in hedging :

Error:

      if(deal_entry==DEAL_ENTRY_OUT)
        {
         ulong PositionTicket=PositionGetInteger(POSITION_TICKET);

if you caught a transaction of a type 'DEAL_ENTRY_OUT', then there is ALREADY no position.


It is necessary to change the logic.

Ahmadahmad654
13
Ahmadahmad654  
thank you very much
Note: I searched a lot in the MQL5 library
 I have not found using PositionClosePartial and I hope you add this functionality to the library
... best wishes
Vladimir Karputov
Moderator
215418
Vladimir Karputov  
Ahmadahmad654 :
thank you very much
Note: I searched a lot in the MQL5 library
 I have not found using PositionClosePartial and I hope you add this functionality to the library
... best wishes

When I need to close part of a position (on a hedge account) I use CTrade.PositionClosePartial

Sergey Golubev
Moderator
118349
Sergey Golubev  
Comments that do not relate to this topic, have been moved to "I have been locked out from logging in or accessing the MQL5 web".
To add comments, please log in or register