Author: Copyright 2018, Baskakov Vladimir
Price Data Components
Series array that contains open prices of each barSeries array that contains close prices for each barSeries array that contains the lowest prices of each barSeries array that contains the highest prices of each bar
Miscellaneous
It issuies visual alerts to the screen
0 Views
0 Downloads
0 Favorites
Explosion
ÿþ//+------------------------------------------------------------------+

//|                                                    Explosion.mq5 |

//|                                Copyright 2018, Baskakov Vladimir |

//|                        https://www.mql5.com/ru/users/kalipso1979 |

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

#property copyright "Copyright 2018, Baskakov Vladimir"

#property link      "https://www.mql5.com/ru/users/kalipso1979"

#property version   "1.00"



//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

#include <Trade\PositionInfo.mqh>

#include <Trade\Trade.mqh>

#include <Trade\SymbolInfo.mqh>  

#include <Trade\AccountInfo.mqh>

#include <Expert\Money\MoneyFixedMargin.mqh>

CPositionInfo  m_position;                   // trade position object

CTrade         m_trade;                      // trading object

CSymbolInfo    m_symbol;                     // symbol info object

CAccountInfo   m_account;                    // account info wrapper

CMoneyFixedMargin *m_money;

//--- input parameters

input ushort               InpStopLoss             = 20;          // Stop Loss

input ushort               InpTakeProfit           = 10;         // Take Profit 

input ushort               InpTrailingStop         = 0;          // Trailing Stop 

input ushort               InpTrailingStep         = 1;           // Trailing Step

input double               Ratio                    = 1.6;         // Ratio

input double               InpLots                 = 0.0;           // Lots 

input double               Risk                    = 3.0;           // Risk %

uchar                InpMaxPositions         = 1;          // Maximum number of positions

uchar                InpPeriod               = 3;          // Number of candles for analysis

ushort               InpPause                = 36000;         // Pause between transactions 

uchar                InpStartHour            = 1;           // Start hour

uchar                InpEndHour              = 23;           // End hour

bool                 InpOneDayOneDeal = true;     // One day: one deal



input ulong                m_magic=555;                     // Magic 

//---

input ulong          m_slippage=3;                // Slippage

           // variable for storing the handle of the iIchimoku indicator 





double         ExtStopLoss=0.0;

double         ExtTakeProfit=0.0;

double         ExtTrailingStop=0.0;

double         ExtTrailingStep=0.0;



double         m_adjusted_point;             // point value adjusted for 3 or 5 points

bool     is_hedging=false;

bool     Work=true;



long           m_last_deal_IN=0;



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

//| Expert initialization function                                   |

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

int OnInit()

  {

    if(AccountInfoInteger(ACCOUNT_MARGIN_MODE)!=ACCOUNT_MARGIN_MODE_RETAIL_NETTING) is_hedging=true;

   Work = true;

   if(!is_hedging) {

      Work=false;

      Print("">@3>2;O @07@5H5=0 B>;L:> =0 E546 AG5B0E");

      }

      

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  

   if(InpTrailingStop!=0 && InpTrailingStep==0)

     {

      Alert(__FUNCTION__," ERROR: Trailing is not possible: the parameter \"Trailing Step\" is zero!");

      return(INIT_PARAMETERS_INCORRECT);

     }

   if(InpStartHour>=InpEndHour)

     {

      Alert(__FUNCTION__," ERROR: Traiding is not possible: the parameter \"Start hour\" (",InpStartHour,") >= \"End hour\" (",InpEndHour,")!");

      return(INIT_PARAMETERS_INCORRECT);

     }

   if(InpStartHour>24)

     {

      Alert(__FUNCTION__," ERROR: Traiding is not possible: the parameter \"Start hour\" (",InpStartHour,") > 24!");

      return(INIT_PARAMETERS_INCORRECT);

     }

   if(InpEndHour>24)

     {

      Alert(__FUNCTION__," ERROR: Traiding is not possible: the parameter \"End hour\" (",InpEndHour,") > 24!");

      return(INIT_PARAMETERS_INCORRECT);

     }

//---

   if(!m_symbol.Name(Symbol())) // sets symbol name

      return(INIT_FAILED);

   RefreshRates();

//---

   m_trade.SetExpertMagicNumber(m_magic);

   m_trade.SetMarginMode();

   m_trade.SetTypeFillingBySymbol(m_symbol.Name());

   m_trade.SetDeviationInPoints(m_slippage);

//--- tuning for 3 or 5 digits

   int digits_adjust=1;

   if(m_symbol.Digits()==3 || m_symbol.Digits()==5)

      digits_adjust=10;

   m_adjusted_point=m_symbol.Point()*digits_adjust;



   ExtStopLoss    =  InpStopLoss    * m_adjusted_point;

   ExtTakeProfit  =  InpTakeProfit  * m_adjusted_point;

   ExtTrailingStop=  InpTrailingStop* m_adjusted_point;

   ExtTrailingStep=  InpTrailingStep* m_adjusted_point;

//---

   if(!LotsOrRisk(InpLots,Risk,digits_adjust))

      return(INIT_PARAMETERS_INCORRECT);

//---

   return(INIT_SUCCEEDED);

  }

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

//| Expert deinitialization function                                 |

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

void OnDeinit(const int reason)

  {

//---



  }

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

//| Expert tick function                                             |

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

void OnTick()

  {

 

   Trailing();

//---

   if(CalculateAllPositions()>=InpMaxPositions)

      return;



   MqlDateTime STimeCurrent;

   TimeToStruct(TimeCurrent(),STimeCurrent);

   MqlDateTime SLastDealIN;

   TimeToStruct(m_last_deal_IN,SLastDealIN);



   if(STimeCurrent.hour<InpStartHour || STimeCurrent.hour>InpEndHour)

      return;



      if(InpOneDayOneDeal && STimeCurrent.day_of_year==SLastDealIN.day_of_year)

      return;



   MqlRates rates[];

   ArraySetAsSeries(rates,true);

   

double open,close,high,low,high1,low1;

         open = iOpen(m_symbol.Name(),0,0); 

         close = iClose(m_symbol.Name(),0,0); 

         low = iLow(m_symbol.Name(),0,0); 

         low1 = iLow(m_symbol.Name(),0,1);          

         high = iHigh(m_symbol.Name(),0,0); 

         high1 = iHigh(m_symbol.Name(),0,1); 

        

   if(CopyRates(m_symbol.Name(),Period(),0,InpPeriod,rates)!=InpPeriod)

  

      return;



  



//--- buy

if((high-low)>(high1-low1)* Ratio && (close>open))

     {

      if(!RefreshRates())

         return;

      double sl=(InpStopLoss==0)?0.0:m_symbol.Ask()-ExtStopLoss;

      double tp=(InpTakeProfit==0)?0.0:m_symbol.Ask()+ExtTakeProfit;

      OpenBuy(sl,tp);

     }

//--- sell

if((high-low)>(high1-low1)* Ratio && (close<open))

     {

      if(!RefreshRates())

         return;

      double sl=(InpStopLoss==0)?0.0:m_symbol.Bid()+ExtStopLoss;

      double tp=(InpTakeProfit==0)?0.0:m_symbol.Bid()-ExtTakeProfit;

      OpenSell(sl,tp);

     }

  }

  

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

//| TradeTransaction function                                        |

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

void OnTradeTransaction(const MqlTradeTransaction &trans,

                        const MqlTradeRequest &request,

                        const MqlTradeResult &result)

  {

//--- get transaction type as enumeration value 

   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;

//--- if transaction is result of addition of the transaction in history

   if(type==TRADE_TRANSACTION_DEAL_ADD)

     {

      long     deal_ticket       =0;

      long     deal_order        =0;

      long     deal_time         =0;

      long     deal_time_msc     =0;

      long     deal_type         =-1;

      long     deal_entry        =-1;

      long     deal_magic        =0;

      long     deal_reason       =-1;

      long     deal_position_id  =0;

      double   deal_volume       =0.0;

      double   deal_price        =0.0;

      double   deal_commission   =0.0;

      double   deal_swap         =0.0;

      double   deal_profit       =0.0;

      string   deal_symbol       ="";

      string   deal_comment      ="";

      string   deal_external_id  ="";

      if(HistoryDealSelect(trans.deal))

        {

         deal_ticket       =HistoryDealGetInteger(trans.deal,DEAL_TICKET);

         deal_order        =HistoryDealGetInteger(trans.deal,DEAL_ORDER);

         deal_time         =HistoryDealGetInteger(trans.deal,DEAL_TIME);

         deal_time_msc     =HistoryDealGetInteger(trans.deal,DEAL_TIME_MSC);

         deal_type         =HistoryDealGetInteger(trans.deal,DEAL_TYPE);

         deal_entry        =HistoryDealGetInteger(trans.deal,DEAL_ENTRY);

         deal_magic        =HistoryDealGetInteger(trans.deal,DEAL_MAGIC);

         deal_reason       =HistoryDealGetInteger(trans.deal,DEAL_REASON);

         deal_position_id  =HistoryDealGetInteger(trans.deal,DEAL_POSITION_ID);



         deal_volume       =HistoryDealGetDouble(trans.deal,DEAL_VOLUME);

         deal_price        =HistoryDealGetDouble(trans.deal,DEAL_PRICE);

         deal_commission   =HistoryDealGetDouble(trans.deal,DEAL_COMMISSION);

         deal_swap         =HistoryDealGetDouble(trans.deal,DEAL_SWAP);

         deal_profit       =HistoryDealGetDouble(trans.deal,DEAL_PROFIT);



         deal_symbol       =HistoryDealGetString(trans.deal,DEAL_SYMBOL);

         deal_comment      =HistoryDealGetString(trans.deal,DEAL_COMMENT);

         deal_external_id  =HistoryDealGetString(trans.deal,DEAL_EXTERNAL_ID);

        }

      else

         return;

      if(deal_symbol==m_symbol.Name() && deal_magic==m_magic)

         if(deal_entry==DEAL_ENTRY_IN && (deal_type==DEAL_TYPE_BUY || deal_type==DEAL_TYPE_SELL))

            m_last_deal_IN=(datetime)deal_time;

     }

  }

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

//| Refreshes the symbol quotes data                                 |

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

bool RefreshRates(void)

  {

//--- refresh rates

   if(!m_symbol.RefreshRates())

     {

      Print("RefreshRates error");

      return(false);

     }

//--- protection against the return value of "zero"

   if(m_symbol.Ask()==0 || m_symbol.Bid()==0)

      return(false);

//---

   return(true);

  }

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

//| Check the correctness of the position volume                     |

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

bool CheckVolumeValue(double volume,string &error_description)

  {

//--- minimal allowed volume for trade operations

   double min_volume=m_symbol.LotsMin();

   if(volume<min_volume)

     {

      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)

     {

      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)

     {

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

  }

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

//| Lots or risk in percent for a deal from a free margin            |

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

bool LotsOrRisk(const double lots,const double risk,const int digits_adjust)

  {

   if(lots<0.0 && risk<0.0)

     {

      Print(__FUNCTION__,", ERROR: Parameter (\"lots\" or \"risk\") can't be less than zero");

      return(false);

     }

   if(lots==0.0 && risk==0.0)

     {

      Print(__FUNCTION__,", ERROR: Trade is impossible: You have set \"lots\" == 0.0 and \"risk\" == 0.0");

      return(false);

     }

   if(lots>0.0 && risk>0.0)

     {

      Print(__FUNCTION__,", ERROR: Trade is impossible: You have set \"lots\" > 0.0 and \"risk\" > 0.0");

      return(false);

     }

   if(lots>0.0)

     {

      string err_text="";

      if(!CheckVolumeValue(lots,err_text))

        {

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

         return(false);

        }

     }

   else if(risk>0.0)

     {

      if(m_money!=NULL)

         delete m_money;

      m_money=new CMoneyFixedMargin;

      if(m_money!=NULL)

        {

         if(!m_money.Init(GetPointer(m_symbol),Period(),m_symbol.Point()*digits_adjust))

            return(true);

         m_money.Percent(risk);

        }

      else

        {

         Print(__FUNCTION__,", ERROR: Object CMoneyFixedMargin is NULL");

         return(true);

        }

     }

//---

   return(true);

  }

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

//| Calculate all positions                                          |

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

int CalculateAllPositions()

  {

   int total=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()==m_magic)

            total++;

//---

   return(total);

  }

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

//| Trailing                                                         |

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

void Trailing()

  {

   if(InpTrailingStop==0)

      return;

   for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of open positions

      if(m_position.SelectByIndex(i))

         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==m_magic)

           {

            if(m_position.PositionType()==POSITION_TYPE_BUY)

              {

               if(m_position.PriceCurrent()-m_position.PriceOpen()>ExtTrailingStop+ExtTrailingStep)

                  if(m_position.StopLoss()<m_position.PriceCurrent()-(ExtTrailingStop+ExtTrailingStep))

                    {

                     if(!m_trade.PositionModify(m_position.Ticket(),

                        m_symbol.NormalizePrice(m_position.PriceCurrent()-ExtTrailingStop),

                        m_position.TakeProfit()))

                        Print("Modify BUY ",m_position.Ticket(),

                              " Position -> false. Result Retcode: ",m_trade.ResultRetcode(),

                              ", description of result: ",m_trade.ResultRetcodeDescription());

                    }

              }

            else

              {

               if(m_position.PriceOpen()-m_position.PriceCurrent()>ExtTrailingStop+ExtTrailingStep)

                  if((m_position.StopLoss()>(m_position.PriceCurrent()+(ExtTrailingStop+ExtTrailingStep))) || 

                     (m_position.StopLoss()==0))

                    {

                     if(!m_trade.PositionModify(m_position.Ticket(),

                        m_symbol.NormalizePrice(m_position.PriceCurrent()+ExtTrailingStop),

                        m_position.TakeProfit()))

                        Print("Modify SELL ",m_position.Ticket(),

                              " Position -> false. Result Retcode: ",m_trade.ResultRetcode(),

                              ", description of result: ",m_trade.ResultRetcodeDescription());

                    }

              }



           }

  }

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

//| Open Buy position                                                |

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

void OpenBuy(double sl,double tp)

  {

   sl=m_symbol.NormalizePrice(sl);

   tp=m_symbol.NormalizePrice(tp);



   double check_open_long_lot=0.0;

   if(Risk>0.0)

     {

      check_open_long_lot=m_money.CheckOpenLong(m_symbol.Ask(),sl);

      Print("sl=",DoubleToString(sl,m_symbol.Digits()),

            ", CheckOpenLong: ",DoubleToString(check_open_long_lot,2),

            ", Balance: ",    DoubleToString(m_account.Balance(),2),

            ", Equity: ",     DoubleToString(m_account.Equity(),2),

            ", FreeMargin: ", DoubleToString(m_account.FreeMargin(),2));

      if(check_open_long_lot==0.0)

        {

         Print(__FUNCTION__,", ERROR: method CheckOpenLong returned the value of \"0.0\"");

         return;

        }

     }

   else

      check_open_long_lot=InpLots;

//--- check volume before OrderSend to avoid "not enough money" error (CTrade)

   double check_volume_lot=m_trade.CheckVolume(m_symbol.Name(),check_open_long_lot,m_symbol.Ask(),ORDER_TYPE_BUY);



   if(check_volume_lot!=0.0)

     {

      if(check_volume_lot>=check_open_long_lot)

        {

         if(m_trade.Buy(check_open_long_lot,NULL,m_symbol.Ask(),sl,tp))

           {

            if(m_trade.ResultDeal()==0)

              {

               Print("#1 Buy -> false. Result Retcode: ",m_trade.ResultRetcode(),

                     ", description of result: ",m_trade.ResultRetcodeDescription());

               PrintResult(m_trade,m_symbol);

              }

            else

              {

               Print("#2 Buy -> true. Result Retcode: ",m_trade.ResultRetcode(),

                     ", description of result: ",m_trade.ResultRetcodeDescription());

               PrintResult(m_trade,m_symbol);

              }

           }

         else

           {

            Print("#3 Buy -> false. Result Retcode: ",m_trade.ResultRetcode(),

                  ", description of result: ",m_trade.ResultRetcodeDescription());

            PrintResult(m_trade,m_symbol);

           }

        }

      else

        {

         string text="";

         if(Risk>0.0)

            text="< method CheckOpenLong ("+DoubleToString(check_open_long_lot,2)+")";

         else

            text="< Lots ("+DoubleToString(InpLots,2)+")";

         Print(__FUNCTION__,", ERROR: method CheckVolume (",DoubleToString(check_volume_lot,2),") ",

               text);

         return;

        }

     }

   else

     {

      Print(__FUNCTION__,", ERROR: method CheckVolume returned the value of \"0.0\"");

      return;

     }

//---

  }

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

//| Open Sell position                                               |

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

void OpenSell(double sl,double tp)

  {

   sl=m_symbol.NormalizePrice(sl);

   tp=m_symbol.NormalizePrice(tp);



   double check_open_short_lot=0.0;

   if(Risk>0.0)

     {

      check_open_short_lot=m_money.CheckOpenShort(m_symbol.Bid(),sl);

      Print("sl=",DoubleToString(sl,m_symbol.Digits()),

            ", CheckOpenLong: ",DoubleToString(check_open_short_lot,2),

            ", Balance: ",    DoubleToString(m_account.Balance(),2),

            ", Equity: ",     DoubleToString(m_account.Equity(),2),

            ", FreeMargin: ", DoubleToString(m_account.FreeMargin(),2));

      if(check_open_short_lot==0.0)

        {

         Print(__FUNCTION__,", ERROR: method CheckOpenShort returned the value of \"0.0\"");

         return;

        }

     }

   else

      check_open_short_lot=InpLots;

//--- check volume before OrderSend to avoid "not enough money" error (CTrade)

   double check_volume_lot=m_trade.CheckVolume(m_symbol.Name(),check_open_short_lot,m_symbol.Bid(),ORDER_TYPE_SELL);



   if(check_volume_lot!=0.0)

     {

      if(check_volume_lot>=check_open_short_lot)

        {

         if(m_trade.Sell(check_open_short_lot,NULL,m_symbol.Bid(),sl,tp))

           {

            if(m_trade.ResultDeal()==0)

              {

               Print("#1 Sell -> false. Result Retcode: ",m_trade.ResultRetcode(),

                     ", description of result: ",m_trade.ResultRetcodeDescription());

               PrintResult(m_trade,m_symbol);

              }

            else

              {

               Print("#2 Sell -> true. Result Retcode: ",m_trade.ResultRetcode(),

                     ", description of result: ",m_trade.ResultRetcodeDescription());

               PrintResult(m_trade,m_symbol);

              }

           }

         else

           {

            Print("#3 Sell -> false. Result Retcode: ",m_trade.ResultRetcode(),

                  ", description of result: ",m_trade.ResultRetcodeDescription());

            PrintResult(m_trade,m_symbol);

           }

        }

      else

        {

         string text="";

         if(Risk>0.0)

            text="< method CheckOpenShort ("+DoubleToString(check_open_short_lot,2)+")";

         else

            text="< Lots ("+DoubleToString(InpLots,2)+")";

         Print(__FUNCTION__,", ERROR: method CheckVolume (",DoubleToString(InpLots,2),") ",

               text);

         return;

        }

     }

   else

     {

      Print(__FUNCTION__,", ERROR: method CheckVolume returned the value of \"0.0\"");

      return;

     }

//---

  }

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

//| Print CTrade result                                              |

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

void PrintResult(CTrade &trade,CSymbolInfo &symbol)

  {

   Print("Code of request result: "+IntegerToString(trade.ResultRetcode()));

   Print("code of request result: "+trade.ResultRetcodeDescription());

   Print("deal ticket: "+IntegerToString(trade.ResultDeal()));

   Print("order ticket: "+IntegerToString(trade.ResultOrder()));

   Print("volume of deal or order: "+DoubleToString(trade.ResultVolume(),2));

   Print("price, confirmed by broker: "+DoubleToString(trade.ResultPrice(),symbol.Digits()));

   Print("current bid price: "+DoubleToString(trade.ResultBid(),symbol.Digits()));

   Print("current ask price: "+DoubleToString(trade.ResultAsk(),symbol.Digits()));

   Print("broker comment: "+trade.ResultComment());

//int d=0;

  }

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

bool CheckMoneyForTrade(string symb,double lots,ENUM_ORDER_TYPE type)

  {

//--- ?>;CG8< F5=C >B:@KB8O

   MqlTick mqltick;

   SymbolInfoTick(symb,mqltick);

   double price=mqltick.ask;

   if(type==ORDER_TYPE_SELL)

      price=mqltick.bid;

//--- 7=0G5=8O =5>1E>48<>9 8 A2>1>4=>9 <0@68

   double margin,free_margin=AccountInfoDouble(ACCOUNT_MARGIN_FREE);

   //--- 2K7>25< DC=:F8N ?@>25@:8

   if(!OrderCalcMargin(type,symb,lots,price,margin))

     {

      //--- GB>-B> ?>H;> =5 B0:, A>>1I8< 8 25@=5< false

      Print("Error in ",__FUNCTION__," code=",GetLastError());

      return(false);

     }

   //--- 5A;8 =5 E20B05B A@54AB2 =0 ?@>2545=85 >?5@0F88

   if(margin>free_margin)

     {

      //--- A>>1I8< >1 >H81:5 8 25@=5< false

      Print("Not enough money for ",EnumToString(type)," ",lots," ",symb," Error code=",GetLastError());

      return(false);

     }

//--- ?@>25@:0 ?@>H;0 CA?5H=>

   return(true);

  }

Comments