Two pending orders Multisymbol

Author: Copyright © 2021, Vladimir Karputov
Price Data Components
Miscellaneous
It issuies visual alerts to the screen
0 Views
0 Downloads
0 Favorites
Two pending orders Multisymbol
ÿþ//+------------------------------------------------------------------+

//|                               Two pending orders Multisymbol.mq5 |

//|                              Copyright © 2021, Vladimir Karputov |

//|                      https://www.mql5.com/en/users/barabashkakvn |

//+------------------------------------------------------------------+

#property copyright "Copyright © 2021, Vladimir Karputov"

#property link      "https://www.mql5.com/en/users/barabashkakvn"

#property version   "1.001"

#property script_show_inputs

//---

#include <Trade\Trade.mqh>

#include <Trade\SymbolInfo.mqh>

CTrade         m_trade;                      // trading object

CSymbolInfo    m_symbol_0;                   // symbol info object

CSymbolInfo    m_symbol_1;                   // symbol info object

//+------------------------------------------------------------------+

//| Enum pending orders                                              |

//+------------------------------------------------------------------+

enum ENUM_PENDING_ORDERS

  {

   buy_limit   = 0,  // Buy Limit

   sell_limit  = 1,  // Sell Limit

   buy_stop    = 2,  // Buy Stop

   sell_stop   = 3,  // Sell Stop

  };

//--- input parameters

input group                "Symbol #0"

input string                  InpNameSymbol_0   = "EURUSD";    // Symbol Name

input ENUM_PENDING_ORDERS     InpOrdersType_0   = buy_limit;   // Pending order type

input ushort                  InpGap_0          = 150;         // Gap from the current price

input double                  InpLots_0         = 0.1;         // Lots

input group                "Symbol #1"

input string                  InpNameSymbol_1   = "USDJPY";    // Symbol Name

input ENUM_PENDING_ORDERS     InpOrdersType_1   = sell_limit;  // Pending order type

input ushort                  InpGap_1          = 150;         // Gap from the current price

input double                  InpLots_1         = 0.1;         // Lots

input group                "Additional features"

input ulong                   InpDeviation      = 100;         // Deviation, in Points (1.00045-1.00055=10 points)

input ulong                   InpMagic          = 205;         // Magic number

//+------------------------------------------------------------------+

//| Script program start function                                    |

//+------------------------------------------------------------------+

void OnStart()

  {

//---

   ResetLastError();

   if(!m_symbol_0.Name(InpNameSymbol_0)) // sets symbol name

     {

      Print(__FILE__," ",__FUNCTION__,", ERROR: CSymbolInfo.Name");

      return;

     }

   if(!m_symbol_1.Name(InpNameSymbol_1)) // sets symbol name

     {

      Print(__FILE__," ",__FUNCTION__,", ERROR: CSymbolInfo.Name");

      return;

     }

//--- check the input parameter "Lots"

   string err_text="";

   if(!CheckVolumeValue(m_symbol_0,InpLots_0,err_text))

     {

      if(MQLInfoInteger(MQL_TESTER)) // when testing, we will only output to the log about incorrect input parameters

         Print(__FILE__," ",__FUNCTION__,", ERROR: ",err_text);

      else // if the Expert Advisor is run on the chart, tell the user about the error

         Alert(__FILE__," ",__FUNCTION__,", ERROR: ",err_text);

      //---

      return;

     }

   err_text="";

   if(!CheckVolumeValue(m_symbol_1,InpLots_1,err_text))

     {

      if(MQLInfoInteger(MQL_TESTER)) // when testing, we will only output to the log about incorrect input parameters

         Print(__FILE__," ",__FUNCTION__,", ERROR: ",err_text);

      else // if the Expert Advisor is run on the chart, tell the user about the error

         Alert(__FILE__," ",__FUNCTION__,", ERROR: ",err_text);

      //---

      return;

     }

//---

   m_trade.SetExpertMagicNumber(InpMagic);

   m_trade.SetMarginMode();

   m_trade.SetTypeFillingBySymbol(m_symbol_0.Name());

   m_trade.SetDeviationInPoints(InpDeviation);

   m_trade.SetAsyncMode(true);

//---

   if(!RefreshRates(m_symbol_0))

      return;

   if(!RefreshRates(m_symbol_1))

      return;

//---

   PlacePending(InpOrdersType_0,InpLots_0,m_symbol_0,InpGap_0);

   PlacePending(InpOrdersType_1,InpLots_1,m_symbol_1,InpGap_1);

  }

//+------------------------------------------------------------------+

//| Check the correctness of the position volume                     |

//+------------------------------------------------------------------+

bool CheckVolumeValue(CSymbolInfo &m_symbol, const double volume,string &error_description)

  {

//--- minimal allowed volume for trade operations

   double min_volume=m_symbol.LotsMin();

   if(volume<min_volume)

     {

      if(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian")

         error_description=StringFormat("1J5< <5=LH5 <8=8<0;L=> 4>?CAB8<>3> SYMBOL_VOLUME_MIN=%.2f",min_volume);

      else

         error_description=StringFormat("Volume is less than the minimal allowed SYMBOL_VOLUME_MIN=%.2f",min_volume);

      return(false);

     }

//--- maximal allowed volume of trade operations

   double max_volume=m_symbol.LotsMax();

   if(volume>max_volume)

     {

      if(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian")

         error_description=StringFormat("1J5< 1>;LH5 <0:A8<0;L=> 4>?CAB8<>3> SYMBOL_VOLUME_MAX=%.2f",max_volume);

      else

         error_description=StringFormat("Volume is greater than the maximal allowed SYMBOL_VOLUME_MAX=%.2f",max_volume);

      return(false);

     }

//--- get minimal step of volume changing

   double volume_step=m_symbol.LotsStep();

   int ratio=(int)MathRound(volume/volume_step);

   if(MathAbs(ratio*volume_step-volume)>0.0000001)

     {

      if(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian")

         error_description=StringFormat("1J5< =5 :@0B5= <8=8<0;L=><C H03C SYMBOL_VOLUME_STEP=%.2f, 1;8609H89 ?@028;L=K9 >1J5< %.2f",

                                        volume_step,ratio*volume_step);

      else

         error_description=StringFormat("Volume is not a multiple of the minimal step SYMBOL_VOLUME_STEP=%.2f, the closest correct volume is %.2f",

                                        volume_step,ratio*volume_step);

      return(false);

     }

   error_description="Correct volume value";

//---

   return(true);

  }

//+------------------------------------------------------------------+

//| Refreshes the symbol quotes data                                 |

//+------------------------------------------------------------------+

bool RefreshRates(CSymbolInfo &m_symbol)

  {

//--- 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);

  }

//+------------------------------------------------------------------+

//| Place Pending                                                    |

//+------------------------------------------------------------------+

void PlacePending(const ENUM_PENDING_ORDERS order_type,double volume,CSymbolInfo &m_symbol,const ushort gap)

  {

//--- buy limit

   if(order_type==buy_limit)

     {

      if(!m_trade.BuyLimit(volume,m_symbol.NormalizePrice(m_symbol.Ask()-m_symbol.Point()*gap),m_symbol.Name()))

        {

         Print(" ERROR: Buy Limit ",m_symbol.Name());

         return;

        }

     }

//--- sell limit

   if(order_type==sell_limit)

     {

      if(!m_trade.SellLimit(volume,m_symbol.NormalizePrice(m_symbol.Bid()+m_symbol.Point()*gap),m_symbol.Name()))

        {

         Print(" ERROR: Sell Limit ",m_symbol.Name());

         return;

        }

     }

//--- buy stop

   if(order_type==buy_stop)

     {

      if(!m_trade.BuyStop(volume,m_symbol.NormalizePrice(m_symbol.Ask()+m_symbol.Point()*gap),m_symbol.Name()))

        {

         Print(" ERROR: Buy Stop ",m_symbol.Name());

         return;

        }

     }

//--- sell stop

   if(order_type==sell_stop)

     {

      if(!m_trade.SellStop(volume,m_symbol.NormalizePrice(m_symbol.Bid()-m_symbol.Point()*gap),m_symbol.Name()))

        {

         Print(" ERROR: Sell Stop ",m_symbol.Name());

         return;

        }

     }

  }

//+------------------------------------------------------------------+

Comments