Author: Copyright © 2016, Vladimir Karputov
Price Data Components
0 Views
0 Downloads
0 Favorites
Candle
ÿþ//+------------------------------------------------------------------+

//|                                                       Candle.mq5 |

//|                              Copyright © 2016, Vladimir Karputov |

//|                                           http://wmua.ru/slesar/ |

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

#property copyright "Copyright © 2016, Vladimir Karputov"

#property link      "http://wmua.ru/slesar/"

#property version   "1.002"

#property description "It is important to make sure that the expert works with a normal"

#property description "chart and the user did not make any mistakes setting input"

#property description "variables (Lots, TakeProfit, TrailingStop) in our case,"

#property description "we check TakeProfit on a chart of more than 2*trend_period bars"



#define MACD_MAGIC 7534502

//---

#include <Trade\Trade.mqh>

#include <Trade\SymbolInfo.mqh>

#include <Trade\PositionInfo.mqh>

#include <Trade\AccountInfo.mqh>

#include <Indicators\TimeSeries.mqh>

#include <Indicators\Indicators.mqh>

//---

input double InpLots          =0.1; // Lots

input int    InpTakeProfit    =50;  // Take Profit (in pips)

input int    InpTrailingStop  =30;  // Trailing Stop Level (in pips)

input int    InpMinBars=26;  // MA trend period

//---

int ExtTimeOut=10;                  // time out in seconds between trade operations

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

//| MACD Sample expert class                                         |

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

class CSampleExpert

  {

protected:

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

   CTrade            m_trade;                      // trading object

   CSymbolInfo       m_symbol;                     // symbol info object

   CPositionInfo     m_position;                   // trade position object

   CAccountInfo      m_account;                    // account info wrapper

   //---

   double            m_traling_stop;

   double            m_take_profit;



public:

                     CSampleExpert(void);

                    ~CSampleExpert(void);

   bool              Init(void);

   void              Deinit(void);

   bool              Processing(void);



protected:

   bool              InitCheckParameters(const int digits_adjust);

   bool              InitIndicators();

   bool              LongClosed(void);

   bool              ShortClosed(void);

   bool              LongModified(void);

   bool              ShortModified(void);

   bool              LongOpened(void);

   bool              ShortOpened(void);

  };

//--- global expert

CSampleExpert ExtExpert;

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

//| Constructor                                                      |

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

CSampleExpert::CSampleExpert(void) : m_adjusted_point(0),

                                     m_traling_stop(0),

                                     m_take_profit(0)

  {



  }

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

//| Destructor                                                       |

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

CSampleExpert::~CSampleExpert(void)

  {

  }

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

//| Initialization and checking for input parameters                 |

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

bool CSampleExpert::Init(void)

  {

//--- initialize common information

   m_symbol.Name(Symbol());                  // symbol

   m_trade.SetExpertMagicNumber(MACD_MAGIC); // magic

   m_trade.SetMarginMode();

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

//--- set default deviation for trading in adjusted points

   m_traling_stop    =InpTrailingStop*m_adjusted_point;

   m_take_profit     =InpTakeProfit*m_adjusted_point;

//--- set default deviation for trading in adjusted points

   m_trade.SetDeviationInPoints(3*digits_adjust);

//---

   if(!InitCheckParameters(digits_adjust))

      return(false);

//--- succeed

   return(true);

  }

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

//| Checking for input parameters                                    |

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

bool CSampleExpert::InitCheckParameters(const int digits_adjust)

  {

//--- initial data checks

   if(InpTakeProfit*digits_adjust<m_symbol.StopsLevel())

     {

      printf("Take Profit must be greater than %d",m_symbol.StopsLevel());

      return(false);

     }

   if(InpTrailingStop*digits_adjust<m_symbol.StopsLevel())

     {

      printf("Trailing Stop must be greater than %d",m_symbol.StopsLevel());

      return(false);

     }

//--- check for right lots amount

   if(InpLots<m_symbol.LotsMin() || InpLots>m_symbol.LotsMax())

     {

      printf("Lots amount must be in the range from %f to %f",m_symbol.LotsMin(),m_symbol.LotsMax());

      return(false);

     }

   if(MathAbs(InpLots/m_symbol.LotsStep()-MathRound(InpLots/m_symbol.LotsStep()))>1.0E-10)

     {

      printf("Lots amount is not corresponding with lot step %f",m_symbol.LotsStep());

      return(false);

     }

//--- warning

   if(InpTakeProfit<=InpTrailingStop)

      printf("Warning: Trailing Stop must be less than Take Profit");

//--- succeed

   return(true);

  }

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

//| Check for long position closing                                  |

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

bool CSampleExpert::LongClosed(void)

  {

   bool res=false;

   double open[2]; double high[2]; double low[2]; double close[2];

   if(CopyOpen(Symbol(),Period(),0,2,open)==-1)

      return(res);

   if(CopyHigh(Symbol(),Period(),0,2,high)==-1)

      return(res);

   if(CopyLow(Symbol(),Period(),0,2,low)==-1)

      return(res);

   if(CopyClose(Symbol(),Period(),0,2,close)==-1)

      return(res);

//--- should it be closed?

   if(close[0]<open[0])

     {

      //--- close position

      if(m_trade.PositionClose(Symbol()))

         printf("Long position by %s to be closed",Symbol());

      else

         printf("Error closing position by %s : '%s'",Symbol(),m_trade.ResultComment());

      //--- processed and cannot be modified

      res=true;

     }

//--- result

   return(res);

  }

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

//| Check for short position closing                                 |

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

bool CSampleExpert::ShortClosed(void)

  {

   bool res=false;

   double open[2]; double high[2]; double low[2]; double close[2];

   if(CopyOpen(Symbol(),Period(),0,2,open)==-1)

      return(res);

   if(CopyHigh(Symbol(),Period(),0,2,high)==-1)

      return(res);

   if(CopyLow(Symbol(),Period(),0,2,low)==-1)

      return(res);

   if(CopyClose(Symbol(),Period(),0,2,close)==-1)

      return(res);

   if(close[0]>open[0])

     {

      //--- close position

      if(m_trade.PositionClose(Symbol()))

         printf("Short position by %s to be closed",Symbol());

      else

         printf("Error closing position by %s : '%s'",Symbol(),m_trade.ResultComment());

      //--- processed and cannot be modified

      res=true;

     }

//--- result

   return(res);

  }

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

//| Check for long position modifying                                |

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

bool CSampleExpert::LongModified(void)

  {

   bool res=false;

//--- check for trailing stop

   if(InpTrailingStop>0)

     {

      if(m_symbol.Bid()-m_position.PriceOpen()>m_adjusted_point*InpTrailingStop)

        {

         double sl=NormalizeDouble(m_symbol.Bid()-m_traling_stop,m_symbol.Digits());

         double tp=m_position.TakeProfit();

         if(m_position.StopLoss()<sl || m_position.StopLoss()==0.0)

           {

            //--- modify position

            if(m_trade.PositionModify(Symbol(),sl,tp))

               printf("Long position by %s to be modified",Symbol());

            else

              {

               printf("Error modifying position by %s : '%s'",Symbol(),m_trade.ResultComment());

               printf("Modify parameters : SL=%f,TP=%f",sl,tp);

              }

            //--- modified and must exit from expert

            res=true;

           }

        }

     }

//--- result

   return(res);

  }

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

//| Check for short position modifying                               |

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

bool CSampleExpert::ShortModified(void)

  {

   bool   res=false;

//--- check for trailing stop

   if(InpTrailingStop>0)

     {

      if((m_position.PriceOpen()-m_symbol.Ask())>(m_adjusted_point*InpTrailingStop))

        {

         double sl=NormalizeDouble(m_symbol.Ask()+m_traling_stop,m_symbol.Digits());

         double tp=m_position.TakeProfit();

         if(m_position.StopLoss()>sl || m_position.StopLoss()==0.0)

           {

            //--- modify position

            if(m_trade.PositionModify(Symbol(),sl,tp))

               printf("Short position by %s to be modified",Symbol());

            else

              {

               printf("Error modifying position by %s : '%s'",Symbol(),m_trade.ResultComment());

               printf("Modify parameters : SL=%f,TP=%f",sl,tp);

              }

            //--- modified and must exit from expert

            res=true;

           }

        }

     }

//--- result

   return(res);

  }

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

//| Check for long position opening                                  |

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

bool CSampleExpert::ShortOpened(void)

  {

   bool res=false;

   double open[2]; double high[2]; double low[2]; double close[2];

   if(CopyOpen(Symbol(),Period(),0,2,open)==-1)

      return(res);

   if(CopyHigh(Symbol(),Period(),0,2,high)==-1)

      return(res);

   if(CopyLow(Symbol(),Period(),0,2,low)==-1)

      return(res);

   if(CopyClose(Symbol(),Period(),0,2,close)==-1)

      return(res);

//--- check for long position (BUY) possibility

   if(close[0]<open[0])

     {

      double price=m_symbol.Bid();

      double tp=m_symbol.NormalizePrice(m_symbol.Bid()-m_take_profit);

      double sl=m_symbol.NormalizePrice(m_symbol.Bid()+m_traling_stop);

      //--- check for free money

      if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_SELL,InpLots,price)<0.0)

         printf("We have no money. Free Margin = %f",m_account.FreeMargin());

      else

        {

         //--- open position

         if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_SELL,InpLots,price,sl,tp))

            printf("Position by %s to be opened",Symbol());

         else

           {

            printf("Error opening SELL position by %s : '%s'",Symbol(),m_trade.ResultComment());

            printf("Open parameters : price=%f,TP=%f",price,tp);

           }

        }

      //--- in any case we must exit from expert

      res=true;

     }

//--- result

   return(res);

  }

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

//| Check for short position opening                                 |

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

bool CSampleExpert::LongOpened(void)

  {

   bool res=false;

   double open[2]; double high[2]; double low[2]; double close[2];

   if(CopyOpen(Symbol(),Period(),0,2,open)==-1)

      return(res);

   if(CopyHigh(Symbol(),Period(),0,2,high)==-1)

      return(res);

   if(CopyLow(Symbol(),Period(),0,2,low)==-1)

      return(res);

   if(CopyClose(Symbol(),Period(),0,2,close)==-1)

      return(res);

//--- check for short position (SELL) possibility

   if(close[0]>open[0])

     {

      double price=m_symbol.Ask();

      double tp=m_symbol.NormalizePrice(m_symbol.Ask()+m_take_profit);

      double sl=m_symbol.NormalizePrice(m_symbol.Ask()-m_traling_stop);

      //--- check for free money

      if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_BUY,InpLots,price)<0.0)

         printf("We have no money. Free Margin = %f",m_account.FreeMargin());

      else

        {

         //--- open position

         if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_BUY,InpLots,price,sl,tp))

            printf("Position by %s to be opened",Symbol());

         else

           {

            printf("Error opening BUY position by %s : '%s'",Symbol(),m_trade.ResultComment());

            printf("Open parameters : price=%f,TP=%f",price,tp);

           }

        }

      //--- in any case we must exit from expert

      res=true;

     }

//--- result

   return(res);

  }

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

//| main function returns true if any position processed             |

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

bool CSampleExpert::Processing(void)

  {

//--- refresh rates

   if(!m_symbol.RefreshRates())

      return(false);

//--- to simplify the coding and speed up access

//--- it is important to enter the market correctly, 

//--- but it is more important to exit it correctly...   

//--- first check if position exists - try to select it

   if(m_position.Select(Symbol()))

     {

      if(m_position.PositionType()==POSITION_TYPE_BUY)

        {

         //--- try to close or modify long position

         if(LongClosed())

            //--- check for short position (SELL) possibility

            if(ShortOpened())

               return(true);

         //return(true);

         if(LongModified())

            return(true);

        }

      else

        {

         //--- try to close or modify short position

         if(ShortClosed())

            //--- check for long position (BUY) possibility

            if(LongOpened())

               return(true);

         if(ShortModified())

            return(true);

        }

     }

//--- no opened position identified

   else

     {

      //--- check for long position (BUY) possibility

      if(LongOpened())

         return(true);

      //--- check for short position (SELL) possibility

      if(ShortOpened())

         return(true);

     }

//--- exit without position processing

   return(false);

  }

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

//| Expert initialization function                                   |

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

int OnInit(void)

  {

//--- create all necessary objects

   if(!ExtExpert.Init())

      return(INIT_FAILED);

//--- secceed

   return(INIT_SUCCEEDED);

  }

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

//| Expert new tick handling function                                |

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

void OnTick(void)

  {

   static datetime limit_time=0; // last trade processing time + timeout

//--- don't process if timeout

   if(TimeCurrent()>=limit_time)

     {

      //--- check for data

      if(Bars(Symbol(),Period())>2*InpMinBars)

        {

         //--- change limit time by timeout in seconds if processed

         if(ExtExpert.Processing())

            limit_time=TimeCurrent()+ExtTimeOut;

        }

     }

  }

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

Comments