TrendlineColorOpenClose

Author: Copyright © 2021, Aleksandr Klapatyuk
Price Data Components
Series array that contains tick volumes of each bar Series array that contains open prices of each barSeries array that contains close prices for each bar
Miscellaneous
It issuies visual alerts to the screenIt sends emailsIt plays sound alerts
0 Views
0 Downloads
0 Favorites
TrendlineColorOpenClose
ÿþ//+------------------------------------------------------------------+

//|                                      TrendlineColorOpenClose.mq5 |

//|                        Copyright 2021, MetaQuotes Software Corp. |

//|                                             https://www.mql5.com |

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

#define   EAName      "TrendlineColor"

#define   EAVersion   "1.004"

#property description "Copyright 2021, Strx"

#property description "https://www.mql5.com/en/users/strx"

#property version     EAVersion

#property copyright   "Copyright © 2021, Aleksandr Klapatyuk"

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

#property description "Copyright © 2021, Vladimir Karputov"

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

#property description "Klymenko Roman (needtome@icloud.com)"

#property description "https://www.mql5.com/ru/users/needtome"

#property description "Copyright © 2021, SEM "

#property description "https://www.mql5.com/ru/users/seliveru"

#property description "Horizontal and Trendlines cross detection on any pair/timeframe"

#property description "good for scalping on small timeframes (M1 to M15) and trend following on bigger ones."

#property description "It send notifications when price crosses trendlines and horizontal lines"

//---

#define MACD_MAGIC 1234502

//---

#include <Trade\Trade.mqh>

#include <Trade\SymbolInfo.mqh>

#include <Trade\PositionInfo.mqh>

#include <Trade\AccountInfo.mqh>

#include <Arrays\ArrayString.mqh>

#include <ChartObjects\ChartObject.mqh>

#include <ChartObjects\ChartObjectsLines.mqh>

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

//| ENUM_PROFIT_COMMAND                                              |

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

enum ENUM_P

  {

   tpl_b=0, // Close

   tpl_s=1, // Close + Open + '.tpl'

  };

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

input group  "---- Trailing Line:Open ------"

input bool   InpStartOpen               = false;       // Start Trailing Line

input string InpObjUpNameOpen           = "openup";    // Obj: Up (Trailing Horizontal Line)

sinput color InpObjUpclrOpen            = clrYellow;   // Obj: command: UP MonitoringColor, EA only monitors this lines color

input string InpObjDownNameOpen         = "opendown";  // Obj: Down (Trailing Horizontal Line)

sinput color InpObjDownclrOpen          = clrGold;     // Obj: command: DOWN MonitoringColor, EA only monitors this lines color

input double InpObjTrailingStopOpen     = 0;           // Obj: Trailing Stop (distance from price to object, in pips)

input double InpObjTrailingStepOpen     = 0;           // Obj: Trailing Step, in pips (1.00045-1.00055=1 pips)

input group  "---- Trailing Line:Close -----"

input bool   InpStartClos               = false;       // Start Trailing Line

input string InpObjUpNameClos           = "closup";    // Obj: Up (Trailing Horizontal Line)

sinput color InpObjUpclrClos            = clrMagenta;  // Obj: command: UP MonitoringColor, EA only monitors this lines color

input string InpObjDownNameClos         = "closdown";  // Obj: Down (Trailing Horizontal Line)

sinput color InpObjDownclrClos          = clrOrangeRed;// Obj: command: DOWN MonitoringColor, EA only monitors this lines color

input double InpObjTrailingStopClos     = 0;           // Obj: Trailing Stop (distance from price to object, in pips)

input double InpObjTrailingStepClos     = 0;           // Obj: Trailing Step, in pips (1.00045-1.00055=1 pips)

input group  "---- Balans Parameters --------"

input double TargetProfit               = 1000000;     // 0;0=A + @81K;L(?@81028BL : 10;0=AC)

input double TargetLoss                 = 0;           // 0;0=A - #1KB>:(>B=OBL >B 10;0=A0)

input string Template                   = "ADX";       // <O H01;>=0(without '.tpl')

input group  "---- Lots Parameters ----------"

input double InpLots1                   = 0.01;        // : Lots 1

input int    InpLots_01                 = 2500;        // Exchange Lots >< Point Lots

input double InpLots2                   = 0.02;        // : Lots 2

input int    InpLots_02                 = 5000;        // Exchange Lots >< Point Lots

input double InpLots3                   = 0.04;        // : Lots 3

input int    InpLots_03                 = 10000;       // Exchange Lots >< Point Lots

input double InpLots4                   = 0.08;        // : Lots 4

input group  "---- Exchange><Point ----------"

input double InpPoints                  = 10000;       // :Gold=0.133/:JPY=100/:USD=10000

input bool   InpExcPoi                  = false;       // Exchange= false; Point= true;

input group  "---- TP SL Total profit -------"

input double InpTProfit                 = 40000;       // Exchange TP >< Point TP

input double InpStopLoss                = 1000000;     // Exchange SL >< Point SL

input ENUM_P InpProfitCommand           = tpl_b;       // TP SL: command Close

input string Template_1                 = "Momentum";  // <O H01;>=0(without '.tpl')

input group  "---- Buy: ---------------------"

sinput color MonitoringColorBuy         = clrGold;     // Buy MonitoringColor, EA only monitors this lines color

sinput color CrossedColorBuy            = clrGreen;    // CrossedColor, EA changes crossed lines color to this value

sinput bool  EnableAlertsBuy            = true;        // Buy

sinput bool  EnableNotificationsBuy     = false;       //

sinput bool  EnableEmailsBuy            = false;       //

input group  "---- Sell: --------------------"

sinput color MonitoringColorSell        = clrYellow;   // Sell MonitoringColor, EA only monitors this lines color

sinput color CrossedColorSell           = clrGreen;    // CrossedColor, EA changes crossed lines color to this value

sinput bool  EnableAlertsSell           = true;        // Sell

sinput bool  EnableNotificationsSell    = false;       //

sinput bool  EnableEmailsSell           = false;       //

input group  "---- Close Buy: ---------------"

sinput color MonitoringColorClosBuy     = clrOrangeRed;// Close Buy MonitoringColor, EA only monitors this lines color

sinput color CrossedColorClosBuy        = clrGreen;    // CrossedColor, EA changes crossed lines color to this value

sinput bool  EnableAlertsClosBuy        = true;        // Close Buy

sinput bool  EnableNotificationsClosBuy = false;       //

sinput bool  EnableEmailsClosBuy        = false;       //

input group  "---- Close Sell: --------------"

sinput color MonitoringColorClosSell    = clrMagenta;  // Close Sell MonitoringColor, EA only monitors this lines color

sinput color CrossedColorClosSell       = clrGreen;    // CrossedColor, EA changes crossed lines color to this value

sinput bool  EnableAlertsClosSell       = true;        // Close Sell

sinput bool  EnableNotificationsClosSell= false;       //

sinput bool  EnableEmailsClosSell       = false;       //

//---

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

string _name[]= {"BUY","SELL","BUY_Close","SELL_Close","CLOSE_ALL"};

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

//| Trendlines and Horizontal lines crossing notification expert

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

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

   //--- Logic vars

   CArrayString      m_objectNamesBuy;

   CArrayString      m_objectNamesSell;

   CArrayString      m_objectNamesClosBuy;

   CArrayString      m_objectNamesClosSell;



public:

                     CSampleExpert(void);

                    ~CSampleExpert(void);

   bool              Init(void);

   void              Deinit(void);

   bool              Processing(void);

   bool              ProcessingBuy(void);

   bool              ProcessingSell(void);

   bool              ProcessingClosBuy(void);

   bool              ProcessingClosSell(void);



protected:

   //--- Inline functions

   string            txt;

   string            FormatPrice(double price) { return StringFormat("%."+(string)m_symbol.Digits()+"f",price); };

   bool              IsNewBar() { return iVolume(NULL,0,0)==1; };

   ENUM_TIMEFRAMES   TimeFrame; // Change TimeFrame - Current = dont changed

   double            m_Point;

   double            m_obj_trailing_stopOpen;      // Obj: Trailing Stop   -> double

   double            m_obj_trailing_stepOpen;      // Obj: Trailing Step   -> double

   datetime          m_obj_last_trailingOpen;      // "0" -> D'1970.01.01 00:00';

   datetime          m_prev_barsOpen;              // "0" -> D'1970.01.01 00:00';

   double            m_obj_up_priceOpen;           //

   double            m_obj_down_priceOpen;         //

   double            m_obj_trailing_stopClos;      // Obj: Trailing Stop   -> double

   double            m_obj_trailing_stepClos;      // Obj: Trailing Step   -> double

   datetime          m_obj_last_trailingClos;      // "0" -> D'1970.01.01 00:00';

   datetime          m_prev_barsClos;              // "0" -> D'1970.01.01 00:00';

   double            m_obj_up_priceClos;           //

   double            m_obj_down_priceClos;         //

   //--- Logic functions

   int               FindActiveObjectsBuy(void);

   bool              ActiveObjectBuy(string objName);

   bool              PriceCrossedBuy(string objName);

   void              NotifyCrossingBuy(string objName);

   int               FindActiveObjectsSell();

   bool              ActiveObjectSell(string objName);

   bool              PriceCrossedSell(string objName);

   void              NotifyCrossingSell(string objName);

   int               FindActiveObjectsClosBuy(void);

   bool              ActiveObjectClosBuy(string objName);

   bool              PriceCrossedClosBuy(string objName);

   void              NotifyCrossingClosBuy(string objName);

   int               FindActiveObjectsClosSell();

   bool              ActiveObjectClosSell(string objName);

   bool              PriceCrossedClosSell(string objName);

   void              NotifyCrossingClosSell(string objName);

   bool              LongObjOpen(void);

   bool              ShortObjOpen(void);

   bool              LongObjClosed(void);

   bool              ShortObjClosed(void);

   bool              RefreshRates(void);

   bool              FreezeStopsLevels(double &level);

   void              ClosePositions(const ENUM_POSITION_TYPE pos_type,const double level);

   void              CloseAll(void);

   void              ClosePosition(const string symbol);

   bool              InitTrade(const string symbol);

   bool              IsFillingTypeAllowed(string symbol,int fill_type);

   bool              ProfitTarget(void);

   void              DeleteChart(void);

   void              DeleteChart_1(void);

   bool              ProfitOnTick(void);

   double            OptimizedBuy(void);

   double            OptimizedSell(void);

   void              Optimized(void);

   void              DrawLABEL(int c,string name,string text,int X,int Y,color clr,int ANCHOR=ANCHOR_LEFT,int FONTSIZE=8);

   void              OnTickObjTrailingOpen(void);

   void              ObjTrailingOpen(void);

   bool              HLineMove(const long chart_ID=0,const string name="HLine",double price=0);

   void              OnTickObjTrailingClos(void);

   void              ObjTrailingClos(void);

   void              ButtonCreate(string name,int Xdist,int Ydist,int Xsize,int Ysize,int FONTSIZE=12);

   bool              ButtonOnTick(void);

   bool              Obj_SELLOpen(void);

   bool              Obj_BUYOpen(void);

   bool              Obj_SELLClos(void);

   bool              Obj_BUYClos(void);

   int               CreateHline(long ch_id,int sub_window,

                                 string name,double price,

                                 color clr,ENUM_LINE_STYLE style,

                                 int width,bool back,

                                 bool selectable,bool selected,

                                 bool hidden,long z_order);

  };

//--- global expert

CSampleExpert ExtExpert;

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

//| Constructor                                                      |

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

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

   m_obj_trailing_stopOpen(0),

   m_obj_trailing_stepOpen(0),

   m_obj_last_trailingOpen(0),

   m_prev_barsOpen(0),

   m_obj_up_priceOpen(0),

   m_obj_down_priceOpen(0),

   m_obj_trailing_stopClos(0),

   m_obj_trailing_stepClos(0),

   m_obj_last_trailingClos(0),

   m_prev_barsClos(0),

   m_obj_up_priceClos(0),

   m_obj_down_priceClos(0),

   m_Point(0)

  {

  }

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

//| Destructor                                                       |

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

CSampleExpert::~CSampleExpert(void)

  {

  }

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

//| Initialization and checking for input parameters                 |

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

bool CSampleExpert::Init(void)

  {

//--- initialize common information

   RefreshRates();

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

   m_trade.SetExpertMagicNumber(MACD_MAGIC); // magic

   m_trade.SetMarginMode();

   m_trade.SetTypeFillingBySymbol(Symbol());

//--- 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_obj_trailing_stopOpen   = InpObjTrailingStopOpen*m_adjusted_point;

   m_obj_trailing_stepOpen   = InpObjTrailingStepOpen*m_adjusted_point;

   m_obj_trailing_stopClos   = InpObjTrailingStopClos*m_adjusted_point;

   m_obj_trailing_stepClos   = InpObjTrailingStepClos*m_adjusted_point;

   m_Point                   = InpPoints*m_adjusted_point;

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

   m_trade.SetDeviationInPoints(3*digits_adjust);

//---

   int _y=100;

   for(int i=0; i<ArraySize(_name); i++)

     {

      ButtonCreate(_name[i],5,_y,130,20,10);

      _y=_y+25;

     }

//--- succeed

   return(true);

  }

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

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

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

bool CSampleExpert::Processing(void)

  {

//--- refresh rates

   if(!m_symbol.RefreshRates())

      return(false);

   Optimized();

   ButtonOnTick();

   ProfitOnTick();

   ProfitTarget();

   ProcessingBuy();

   ProcessingSell();

   ProcessingClosBuy();

   ProcessingClosSell();

   if(InpStartOpen)

     {

      OnTickObjTrailingOpen();

     }

   if(InpStartClos)

     {

      OnTickObjTrailingClos();

     }

//--- exit without position processing

   return(false);

  }

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

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

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

bool CSampleExpert::ProcessingBuy(void)

  {

   bool rv=false;

   int i;

   string objName;

   if(m_symbol.RefreshRates())

     {

      if(FindActiveObjectsBuy())

        {

         for(i=0; i<m_objectNamesBuy.Total(); i++)

           {

            objName=m_objectNamesBuy[i];

            if(PriceCrossedBuy(objName))

              {

               ObjectSetInteger(0,objName,OBJPROP_COLOR,CrossedColorBuy);

               NotifyCrossingBuy(objName);

              }

           }

        }

     }

   Comment("MonitoringBuy ",m_objectNamesBuy.Total()," lines""\n",

           "MonitoringClose ",m_objectNamesClosBuy.Total()," lines""\n",

           "\n",

           "MonitoringSell ",m_objectNamesSell.Total()," lines""\n",

           "MonitoringClose ",m_objectNamesClosSell.Total()," lines");

   return(rv);

  }

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

//| Send Notifications function

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

void CSampleExpert::NotifyCrossingBuy(string objName)

  {

   string msg="Price crossed lineBuy ''"+objName+"' on "+m_symbol.Name();

   if(EnableAlertsBuy)

      Alert(msg);

   LongObjOpen();

   Obj_BUYOpen();

   if(EnableNotificationsBuy)

      SendNotification(msg);

   if(EnableEmailsBuy)

      SendMail(EAName+" EventBuy",msg);

   Print(msg);

  }

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

//| Returns true if objName has been crossed up or down by current price

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

bool CSampleExpert::PriceCrossedBuy(string objName)

  {

   ENUM_OBJECT objType;

   double objPrice=0.0,openPrice,curPrice;

   objType=(ENUM_OBJECT)ObjectGetInteger(0,objName,OBJPROP_TYPE);

   if(objType==OBJ_HLINE)

     {

      objPrice= ObjectGetDouble(0, objName, OBJPROP_PRICE);

     }

   else

      if(objType==OBJ_TREND)

        {

         objPrice=ObjectGetValueByTime(0,objName,TimeCurrent(),0);

        }

   if(objPrice)

     {

      openPrice= iOpen(NULL,0,0);

      curPrice = iClose(NULL,0,0);

      return (openPrice<=objPrice && curPrice>objPrice) || (openPrice>=objPrice && curPrice<objPrice);

     }

   return false;

  }

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

//| Returns true if object has to be monitored based on color and

//| previous crosses

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

bool CSampleExpert::ActiveObjectBuy(string objName)

  {

   int objColor=(int)ObjectGetInteger(0,objName,OBJPROP_COLOR,0);

   return objColor == MonitoringColorBuy;

  }

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

//| Returns the list of object to be monitored

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

int CSampleExpert::FindActiveObjectsBuy(void)

  {

   m_objectNamesBuy.Clear();

   int nHLines=ObjectsTotal(0,-1,OBJ_HLINE),

       nTrendLines=ObjectsTotal(0,-1,OBJ_TREND),

       i;

   string objName;

   for(i=0; i<nHLines; i++)

     {

      objName=ObjectName(0,i,0,OBJ_HLINE);

      if(ActiveObjectBuy(objName))

        {

         m_objectNamesBuy.Add(objName);

        }

     }

   for(i=0; i<nTrendLines; i++)

     {

      objName=ObjectName(0,i,0,OBJ_TREND);

      if(ActiveObjectBuy(objName))

        {

         m_objectNamesBuy.Add(objName);

        }

     }

   return m_objectNamesBuy.Total();

  }

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

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

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

bool CSampleExpert::ProcessingSell(void)

  {

   bool rv=false;

   int i;

   string objName;

   if(m_symbol.RefreshRates())

     {

      if(FindActiveObjectsSell())

        {

         for(i=0; i<m_objectNamesSell.Total(); i++)

           {

            objName=m_objectNamesSell[i];

            if(PriceCrossedSell(objName))

              {

               ObjectSetInteger(0,objName,OBJPROP_COLOR,CrossedColorSell);

               NotifyCrossingSell(objName);

              }

           }

        }

     }

   return(rv);

  }

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

//| Send Notifications function

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

void CSampleExpert::NotifyCrossingSell(string objName)

  {

   string msg="Price crossed lineSell ''"+objName+"' on "+m_symbol.Name();

   if(EnableAlertsSell)

      Alert(msg);

   ShortObjOpen();

   Obj_SELLOpen();

   if(EnableNotificationsSell)

      SendNotification(msg);

   if(EnableEmailsSell)

      SendMail(EAName+" EventSell",msg);

   Print(msg);

  }

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

//| Returns true if objName has been crossed up or down by current price

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

bool CSampleExpert::PriceCrossedSell(string objName)

  {

   ENUM_OBJECT objType;

   double objPrice=0.0,openPrice,curPrice;

   objType=(ENUM_OBJECT)ObjectGetInteger(0,objName,OBJPROP_TYPE);

   if(objType==OBJ_HLINE)

     {

      objPrice= ObjectGetDouble(0, objName, OBJPROP_PRICE);

     }

   else

      if(objType==OBJ_TREND)

        {

         objPrice=ObjectGetValueByTime(0,objName,TimeCurrent(),0);

        }

   if(objPrice)

     {

      openPrice= iOpen(NULL,0,0);

      curPrice = iClose(NULL,0,0);

      return (openPrice<=objPrice && curPrice>objPrice) || (openPrice>=objPrice && curPrice<objPrice);

     }

   return false;

  }

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

//| Returns true if object has to be monitored based on color and

//| previous crosses

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

bool CSampleExpert::ActiveObjectSell(string objName)

  {

   int objColor=(int)ObjectGetInteger(0,objName,OBJPROP_COLOR,0);

   return objColor == MonitoringColorSell;

  }

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

//| Returns the list of object to be monitored

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

int CSampleExpert::FindActiveObjectsSell(void)

  {

   m_objectNamesSell.Clear();

   int nHLines=ObjectsTotal(0,-1,OBJ_HLINE),

       nTrendLines=ObjectsTotal(0,-1,OBJ_TREND),

       i;

   string objName;

   for(i=0; i<nHLines; i++)

     {

      objName=ObjectName(0,i,0,OBJ_HLINE);

      if(ActiveObjectSell(objName))

        {

         m_objectNamesSell.Add(objName);

        }

     }

   for(i=0; i<nTrendLines; i++)

     {

      objName=ObjectName(0,i,0,OBJ_TREND);

      if(ActiveObjectSell(objName))

        {

         m_objectNamesSell.Add(objName);

        }

     }

   return m_objectNamesSell.Total();

  }

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

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

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

bool CSampleExpert::ProcessingClosBuy(void)

  {

   bool rv=false;

   int i;

   string objName;

   if(m_symbol.RefreshRates())

     {

      if(FindActiveObjectsClosBuy())

        {

         for(i=0; i<m_objectNamesClosBuy.Total(); i++)

           {

            objName=m_objectNamesClosBuy[i];

            if(PriceCrossedClosBuy(objName))

              {

               ObjectSetInteger(0,objName,OBJPROP_COLOR,CrossedColorClosBuy);

               NotifyCrossingClosBuy(objName);

              }

           }

        }

     }

   return(rv);

  }

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

//| Send Notifications function

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

void CSampleExpert::NotifyCrossingClosBuy(string objName)

  {

   string msg="Price crossed lineClosBuy ''"+objName+"' on "+m_symbol.Name();

   if(EnableAlertsClosBuy)

      Alert(msg);

   LongObjClosed();

   Obj_BUYClos();

   if(EnableNotificationsClosBuy)

      SendNotification(msg);

   if(EnableEmailsClosBuy)

      SendMail(EAName+" EventClosBuy",msg);

   Print(msg);

  }

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

//| Returns true if objName has been crossed up or down by current price

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

bool CSampleExpert::PriceCrossedClosBuy(string objName)

  {

   ENUM_OBJECT objType;

   double objPrice=0.0,openPrice,curPrice;

   objType=(ENUM_OBJECT)ObjectGetInteger(0,objName,OBJPROP_TYPE);

   if(objType==OBJ_HLINE)

     {

      objPrice= ObjectGetDouble(0, objName, OBJPROP_PRICE);

     }

   else

      if(objType==OBJ_TREND)

        {

         objPrice=ObjectGetValueByTime(0,objName,TimeCurrent(),0);

        }

   if(objPrice)

     {

      openPrice= iOpen(NULL,0,0);

      curPrice = iClose(NULL,0,0);

      return (openPrice<=objPrice && curPrice>objPrice) || (openPrice>=objPrice && curPrice<objPrice);

     }

   return false;

  }

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

//| Returns true if object has to be monitored based on color and

//| previous crosses

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

bool CSampleExpert::ActiveObjectClosBuy(string objName)

  {

   int objColor=(int)ObjectGetInteger(0,objName,OBJPROP_COLOR,0);

   return objColor == MonitoringColorClosBuy;

  }

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

//| Returns the list of object to be monitored

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

int CSampleExpert::FindActiveObjectsClosBuy(void)

  {

   m_objectNamesClosBuy.Clear();

   int nHLines=ObjectsTotal(0,-1,OBJ_HLINE),

       nTrendLines=ObjectsTotal(0,-1,OBJ_TREND),

       i;

   string objName;

   for(i=0; i<nHLines; i++)

     {

      objName=ObjectName(0,i,0,OBJ_HLINE);

      if(ActiveObjectClosBuy(objName))

        {

         m_objectNamesClosBuy.Add(objName);

        }

     }

   for(i=0; i<nTrendLines; i++)

     {

      objName=ObjectName(0,i,0,OBJ_TREND);

      if(ActiveObjectClosBuy(objName))

        {

         m_objectNamesClosBuy.Add(objName);

        }

     }

   return m_objectNamesClosBuy.Total();

  }

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

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

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

bool CSampleExpert::ProcessingClosSell(void)

  {

   bool rv=false;

   int i;

   string objName;

   if(m_symbol.RefreshRates())

     {

      if(FindActiveObjectsClosSell())

        {

         for(i=0; i<m_objectNamesClosSell.Total(); i++)

           {

            objName=m_objectNamesClosSell[i];

            if(PriceCrossedClosSell(objName))

              {

               ObjectSetInteger(0,objName,OBJPROP_COLOR,CrossedColorClosSell);

               NotifyCrossingClosSell(objName);

              }

           }

        }

     }

   return(rv);

  }

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

//| Send Notifications function

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

void CSampleExpert::NotifyCrossingClosSell(string objName)

  {

   string msg="Price crossed lineClosSell ''"+objName+"' on "+m_symbol.Name();

   if(EnableAlertsClosSell)

      Alert(msg);

   ShortObjClosed();

   Obj_SELLClos();

   if(EnableNotificationsClosSell)

      SendNotification(msg);

   if(EnableEmailsClosSell)

      SendMail(EAName+" EventClosSell",msg);

   Print(msg);

  }

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

//| Returns true if objName has been crossed up or down by current price

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

bool CSampleExpert::PriceCrossedClosSell(string objName)

  {

   ENUM_OBJECT objType;

   double objPrice=0.0,openPrice,curPrice;

   objType=(ENUM_OBJECT)ObjectGetInteger(0,objName,OBJPROP_TYPE);

   if(objType==OBJ_HLINE)

     {

      objPrice= ObjectGetDouble(0, objName, OBJPROP_PRICE);

     }

   else

      if(objType==OBJ_TREND)

        {

         objPrice=ObjectGetValueByTime(0,objName,TimeCurrent(),0);

        }

   if(objPrice)

     {

      openPrice= iOpen(NULL,0,0);

      curPrice = iClose(NULL,0,0);

      return (openPrice<=objPrice && curPrice>objPrice) || (openPrice>=objPrice && curPrice<objPrice);

     }

   return false;

  }

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

//| Returns true if object has to be monitored based on color and

//| previous crosses

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

bool CSampleExpert::ActiveObjectClosSell(string objName)

  {

   int objColor=(int)ObjectGetInteger(0,objName,OBJPROP_COLOR,0);

   return objColor == MonitoringColorClosSell;

  }

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

//| Returns the list of object to be monitored

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

int CSampleExpert::FindActiveObjectsClosSell(void)

  {

   m_objectNamesClosSell.Clear();

   int nHLines=ObjectsTotal(0,-1,OBJ_HLINE),

       nTrendLines=ObjectsTotal(0,-1,OBJ_TREND),

       i;

   string objName;

   for(i=0; i<nHLines; i++)

     {

      objName=ObjectName(0,i,0,OBJ_HLINE);

      if(ActiveObjectClosSell(objName))

        {

         m_objectNamesClosSell.Add(objName);

        }

     }

   for(i=0; i<nTrendLines; i++)

     {

      objName=ObjectName(0,i,0,OBJ_TREND);

      if(ActiveObjectClosSell(objName))

        {

         m_objectNamesClosSell.Add(objName);

        }

     }

   return m_objectNamesClosSell.Total();

  }

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

//| Check for long position closing                                  |

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

bool CSampleExpert::ProfitOnTick(void)

  {

   bool res=false;

   double PROFIT_BUY=0.00;

   double PROFIT_SELL=0.00;

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

     {

      string   position_GetSymbol=PositionGetSymbol(i); // GetSymbol ?>78F88

      if(position_GetSymbol==m_symbol.Name())

        {

         if(!InpExcPoi)

           {

            if(m_position.PositionType()==POSITION_TYPE_BUY)

              {

               PROFIT_BUY=PROFIT_BUY+PositionGetDouble(POSITION_PROFIT);

              }

            else

              {

               PROFIT_SELL=PROFIT_SELL+PositionGetDouble(POSITION_PROFIT);

              }

           }

         if(InpExcPoi)

           {

            if(m_position.PositionType()==POSITION_TYPE_BUY)

              {

               PROFIT_BUY=PROFIT_BUY+(PositionGetDouble(POSITION_PROFIT)/PositionGetDouble(POSITION_VOLUME)/

                                      SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE)*m_Point);

              }

            else

              {

               PROFIT_SELL=PROFIT_SELL+(PositionGetDouble(POSITION_PROFIT)/PositionGetDouble(POSITION_VOLUME)/

                                        SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE)*m_Point);

              }

           }

        }

     }

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

      if(m_position.SelectByIndex(w)) // selects the position by index for further access to its properties

         if(m_position.Symbol()==m_symbol.Name())

           {

            if(m_position.PositionType()==POSITION_TYPE_BUY)

              {

               if(PROFIT_BUY<-InpStopLoss || PROFIT_BUY>=InpTProfit) // if the profit

                  switch(InpProfitCommand)

                    {

                     case  tpl_b:

                        LongObjClosed();

                        break;

                     case  tpl_s:

                        LongObjClosed();

                        ShortObjOpen();

                        ExpertRemove();

                        DeleteChart_1();

                        break;

                    }

               res=true;

              }

           }

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

      if(m_position.SelectByIndex(u)) // selects the position by index for further access to its properties

         if(m_position.Symbol()==m_symbol.Name())

           {

            if(m_position.PositionType()==POSITION_TYPE_SELL)

              {

               if(PROFIT_SELL<-InpStopLoss || PROFIT_SELL>=InpTProfit) // if the profit

                  switch(InpProfitCommand)

                    {

                     case  tpl_b:

                        ShortObjClosed();

                        break;

                     case  tpl_s:

                        ShortObjClosed();

                        LongObjOpen();

                        ExpertRemove();

                        DeleteChart_1();

                        break;

                    }

               res=true;

              }

           }

//--- result

   return(res);

  }

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

//| Calculate optimal lot size                                       |

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

double CSampleExpert::OptimizedBuy(void)

  {

   double PROFIT_BUY=0.00;

   double PROFIT_SELL=0.00;

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

     {

      string   position_GetSymbol=PositionGetSymbol(i); // GetSymbol ?>78F88

      if(position_GetSymbol==m_symbol.Name())

        {

         if(!InpExcPoi)

           {

            if(m_position.PositionType()==POSITION_TYPE_BUY)

              {

               PROFIT_BUY=PROFIT_BUY+PositionGetDouble(POSITION_PROFIT);

              }

            else

              {

               PROFIT_SELL=PROFIT_SELL+PositionGetDouble(POSITION_PROFIT);

              }

           }

         if(InpExcPoi)

           {

            if(m_position.PositionType()==POSITION_TYPE_BUY)

              {

               PROFIT_BUY=PROFIT_BUY+(PositionGetDouble(POSITION_PROFIT)/PositionGetDouble(POSITION_VOLUME)/

                                      SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE)*m_Point);

              }

            else

              {

               PROFIT_SELL=PROFIT_SELL+(PositionGetDouble(POSITION_PROFIT)/PositionGetDouble(POSITION_VOLUME)/

                                        SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE)*m_Point);

              }

           }

        }

     }

   double Lots=InpLots1;

   double ab=PROFIT_BUY;

   if(ab<-1 && ab>=-InpLots_01)

      Lots=InpLots1;

   if(ab<-InpLots_01 && ab>=-InpLots_02)

      Lots=InpLots2;

   if(ab<-InpLots_02 && ab>=-InpLots_03)

      Lots=InpLots3;

   if(ab<-InpLots_03)

      Lots=InpLots4;

//--- return trading volume

   return(Lots);

  }

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

//| Calculate optimal lot size                                       |

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

double CSampleExpert::OptimizedSell(void)

  {

   double PROFIT_BUY=0.00;

   double PROFIT_SELL=0.00;

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

     {

      string   position_GetSymbol=PositionGetSymbol(i); // GetSymbol ?>78F88

      if(position_GetSymbol==m_symbol.Name())

        {

         if(!InpExcPoi)

           {

            if(m_position.PositionType()==POSITION_TYPE_BUY)

              {

               PROFIT_BUY=PROFIT_BUY+PositionGetDouble(POSITION_PROFIT);

              }

            else

              {

               PROFIT_SELL=PROFIT_SELL+PositionGetDouble(POSITION_PROFIT);

              }

           }

         if(InpExcPoi)

           {

            if(m_position.PositionType()==POSITION_TYPE_BUY)

              {

               PROFIT_BUY=PROFIT_BUY+(PositionGetDouble(POSITION_PROFIT)/PositionGetDouble(POSITION_VOLUME)/

                                      SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE)*m_Point);

              }

            else

              {

               PROFIT_SELL=PROFIT_SELL+(PositionGetDouble(POSITION_PROFIT)/PositionGetDouble(POSITION_VOLUME)/

                                        SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE)*m_Point);

              }

           }

        }

     }

   double Lots=InpLots1;

   double ab=PROFIT_SELL;

   if(ab<-1 && ab>=-InpLots_01)

      Lots=InpLots1;

   if(ab<-InpLots_01 && ab>=-InpLots_02)

      Lots=InpLots2;

   if(ab<-InpLots_02 && ab>=-InpLots_03)

      Lots=InpLots3;

   if(ab<-InpLots_03)

      Lots=InpLots4;

//--- return trading volume

   return(Lots);

  }

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

//| Calculate optimal lot size                                       |

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

void CSampleExpert::Optimized(void)

  {

   double PROFIT_BUY=0.00;

   double PROFIT_SELL=0.00;

   double PROFIT_BUY_1=0.00;

   double PROFIT_SELL_1=0.00;

   double PROFIT_CLOSE_Lot=0.00;

   int _all =0;

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

     {

      string   position_GetSymbol=PositionGetSymbol(i); // GetSymbol ?>78F88

      if(position_GetSymbol==m_symbol.Name())

        {

         PROFIT_CLOSE_Lot=AccountInfoDouble(ACCOUNT_EQUITY);

         _all=_all+1;

         if(m_position.PositionType()==POSITION_TYPE_BUY)

           {

            PROFIT_BUY=PROFIT_BUY+PositionGetDouble(POSITION_PROFIT);

           }

         else

           {

            PROFIT_SELL=PROFIT_SELL+PositionGetDouble(POSITION_PROFIT);

           }

         if(m_position.PositionType()==POSITION_TYPE_BUY)

           {

            PROFIT_BUY_1=PROFIT_BUY_1+(PositionGetDouble(POSITION_PROFIT)/PositionGetDouble(POSITION_VOLUME)/

                                       SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE)*m_Point);

           }

         else

           {

            PROFIT_SELL_1=PROFIT_SELL_1+(PositionGetDouble(POSITION_PROFIT)/PositionGetDouble(POSITION_VOLUME)/

                                         SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE)*m_Point);

           }

        }

     }

   StringConcatenate(txt,"SELL 2 ?C=:B0E = ",DoubleToString(PROFIT_SELL_1,2));

   DrawLABEL(2,"cm 2",txt,5,30,clrWhite,ANCHOR_RIGHT);

   StringConcatenate(txt,"SELL 2 20;NB5 = ",DoubleToString(PROFIT_SELL,2));

   DrawLABEL(2,"cm 3",txt,5,45,clrWhite,ANCHOR_RIGHT);

   StringConcatenate(txt,"BUY 2 ?C=:B0E = ",DoubleToString(PROFIT_BUY_1,2));

   DrawLABEL(2,"cm 4",txt,5,75,clrWhite,ANCHOR_RIGHT);

   StringConcatenate(txt,"BUY 2 20;NB5 = ",DoubleToString(PROFIT_BUY,2));

   DrawLABEL(2,"cm 5",txt,5,90,clrWhite,ANCHOR_RIGHT);

   StringConcatenate(txt,"!@54AB20 = ",DoubleToString(AccountInfoDouble(ACCOUNT_EQUITY),2));

   DrawLABEL(3,"cm 6",txt,5,25,clrWhite,ANCHOR_RIGHT);

   StringConcatenate(txt,">78F89 = ",DoubleToString(_all,0)," all = "+DoubleToString(PositionsTotal(),0));

   DrawLABEL(3,"cm 7",txt,5,40,clrWhite,ANCHOR_RIGHT);

  }

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

//|   DrawLABEL                                                      |

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

void CSampleExpert::DrawLABEL(int c,string name,string text,int X,int Y,color clr,int ANCHOR=ANCHOR_LEFT,int FONTSIZE=8)

  {

   if(ObjectFind(0,name)==-1)

     {

      ObjectCreate(0,name,OBJ_LABEL,0,0,0);

      ObjectSetInteger(0,name,OBJPROP_CORNER,c);

      ObjectSetInteger(0,name,OBJPROP_XDISTANCE,X);

      ObjectSetInteger(0,name,OBJPROP_YDISTANCE,Y);

      ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);

      ObjectSetInteger(0,name,OBJPROP_SELECTED,false);

      ObjectSetInteger(0,name,OBJPROP_FONTSIZE,FONTSIZE);

      ObjectSetString(0,name,OBJPROP_FONT,"Arial");

      ObjectSetInteger(0,name,OBJPROP_ANCHOR,ANCHOR);

     }

   ObjectSetString(0,name,OBJPROP_TEXT,text);

   ObjectSetInteger(0,name,OBJPROP_COLOR,clr);

  }

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

//| Check for long short position closing                            |

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

bool CSampleExpert::ProfitTarget(void)

  {

   bool res=false;

   if(AccountInfoDouble(ACCOUNT_EQUITY)<=TargetLoss ||

      AccountInfoDouble(ACCOUNT_EQUITY)>=TargetProfit)

     {

      CloseAll();

      PlaySound("expert.wav");

      ExpertRemove();

      DeleteChart();

      res=true;

     }

//--- result

   return(res);

  }

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

//| Check for long position open                                     |

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

bool CSampleExpert::LongObjOpen(void)

  {

   bool res=false;

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

   double price=m_symbol.Ask();

   if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_BUY,OptimizedBuy(),price,0.0,0.0))

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

     }

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

   res=true;

//--- result

   return(res);

  }

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

//| Check for short position open                                    |

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

bool CSampleExpert::ShortObjOpen(void)

  {

   bool res=false;

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

   double price=m_symbol.Bid();

   if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_SELL,OptimizedSell(),price,0.0,0.0))

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

     }

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

   res=true;

//--- result

   return(res);

  }

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

//| Check for long position closing                                  |

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

bool CSampleExpert::LongObjClosed(void)

  {

   bool res=false;

//--- close position

   double level;

   if(FreezeStopsLevels(level))

      ClosePositions(POSITION_TYPE_BUY,level);

//--- processed and cannot be modified

   res=true;

//--- result

   return(res);

  }

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

//| Check for short position closing                                 |

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

bool CSampleExpert::ShortObjClosed(void)

  {

   bool res=false;

//--- close position

   double level;

   if(FreezeStopsLevels(level))

      ClosePositions(POSITION_TYPE_SELL,level);

//--- processed and cannot be modified

   res=true;

//--- result

   return(res);

  }

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

//| Refreshes the symbol quotes data                                 |

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

bool CSampleExpert::RefreshRates(void)

  {

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

  }

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

//| Check Freeze and Stops levels                                    |

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

bool CSampleExpert::FreezeStopsLevels(double &level)

  {

//--- check Freeze and Stops levels

   if(!RefreshRates() || !m_symbol.Refresh())

      return(false);

//--- FreezeLevel -> for pending order and modification

   double freeze_level=m_symbol.FreezeLevel()*m_symbol.Point();

   if(freeze_level==0.0)

      freeze_level=(m_symbol.Ask()-m_symbol.Bid())*3.0;

//--- StopsLevel -> for TakeProfit and StopLoss

   double stop_level=m_symbol.StopsLevel()*m_symbol.Point();

   if(stop_level==0.0)

      stop_level=(m_symbol.Ask()-m_symbol.Bid())*3.0;

   if(freeze_level<=0.0 || stop_level<=0.0)

      return(false);

   level=(freeze_level>stop_level)?freeze_level:stop_level;

   double spread=m_symbol.Spread()*m_adjusted_point;

   level=(level>spread)?level:spread;

//---

   return(true);

  }

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

//| Close positions                                                  |

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

void CSampleExpert::ClosePositions(const ENUM_POSITION_TYPE pos_type,const double level)

  {

   for(int i=PositionsTotal()-1; i>=0; i--)

      if(m_position.SelectByIndex(i))

         if(m_position.Symbol()==m_symbol.Name())

            if(m_position.PositionType()==pos_type)

              {

               if(m_position.PositionType()==POSITION_TYPE_BUY)

                 {

                  bool take_profit_level=(m_position.TakeProfit()!=0.0 && m_position.TakeProfit()-m_position.PriceCurrent()>=level) || m_position.TakeProfit()==0.0;

                  bool stop_loss_level=(m_position.StopLoss()!=0.0 && m_position.PriceCurrent()-m_position.StopLoss()>=level) || m_position.StopLoss()==0.0;

                  if(take_profit_level && stop_loss_level)

                     m_trade.PositionClose(m_position.Ticket());

                  PlaySound("ok.wav");

                 }

               if(m_position.PositionType()==POSITION_TYPE_SELL)

                 {

                  bool take_profit_level=(m_position.TakeProfit()!=0.0 && m_position.PriceCurrent()-m_position.TakeProfit()>=level) || m_position.TakeProfit()==0.0;

                  bool stop_loss_level=(m_position.StopLoss()!=0.0 && m_position.StopLoss()-m_position.PriceCurrent()>=level) || m_position.StopLoss()==0.0;

                  if(take_profit_level && stop_loss_level)

                     m_trade.PositionClose(m_position.Ticket());

                  PlaySound("ok.wav");

                 }

              }

  }

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

//| start function                                                   |

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

void CSampleExpert::CloseAll(void)

  {

   for(int i=PositionsTotal()-1; i>=0; i--)

      if(m_position.SelectByIndex(i))

        {

         ClosePosition(m_position.Symbol());

        }

  }

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

//| Close selected position                                          |

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

void CSampleExpert::ClosePosition(const string symbol)

  {

   if(InitTrade(symbol))

      m_trade.PositionClose(m_position.Ticket());

   PlaySound("ok.wav");

  }

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

//| Init trade object                                                |

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

bool CSampleExpert::InitTrade(const string symbol)

  {

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

      return(false);

//---

   if(IsFillingTypeAllowed(symbol,SYMBOL_FILLING_FOK))

      m_trade.SetTypeFilling(ORDER_FILLING_FOK);

   else

      if(IsFillingTypeAllowed(symbol,SYMBOL_FILLING_IOC))

         m_trade.SetTypeFilling(ORDER_FILLING_IOC);

      else

         m_trade.SetTypeFilling(ORDER_FILLING_RETURN);

//---

   return(true);

//---

  }

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

//| Checks if the specified filling mode is allowed                  |

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

bool CSampleExpert::IsFillingTypeAllowed(string symbol,int fill_type)

  {

//--- Obtain the value of the property that describes allowed filling modes

   int filling=(int)SymbolInfoInteger(symbol,SYMBOL_FILLING_MODE);

//--- Return true, if mode fill_type is allowed

   return((filling & fill_type)==fill_type);

  }

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

//| start function                                                   |

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

void CSampleExpert::DeleteChart(void)

  {

   long currChart,prevChart=ChartFirst();

   int i=0,limit=100;

   bool errTemplate;

   while(i<limit)

     {

      currChart=ChartNext(prevChart);

      if(TimeFrame!=PERIOD_CURRENT)

        {

         ChartSetSymbolPeriod(prevChart,ChartSymbol(prevChart),TimeFrame);

        }

      errTemplate=ChartApplyTemplate(prevChart,Template+".tpl");

      if(!errTemplate)

        {

         Print("Error ",ChartSymbol(prevChart),"-> ",GetLastError());

        }

      if(currChart<0)

         break;

      Print(i,ChartSymbol(currChart)," ID =",currChart);

      prevChart=currChart;

      i++;

     }

  }

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

//| start function                                                   |

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

void CSampleExpert::DeleteChart_1(void)

  {

   long prevChart=0;

   bool errTemplate;

   if(TimeFrame!=PERIOD_CURRENT)

     {

      ChartSetSymbolPeriod(prevChart,ChartSymbol(prevChart),TimeFrame);

     }

   errTemplate=ChartApplyTemplate(prevChart,Template_1+".tpl");

   if(!errTemplate)

     {

      Print("Error ",ChartSymbol(prevChart),"-> ",GetLastError());

     }

  }

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

//| Expert tick function                                             |

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

void CSampleExpert::OnTickObjTrailingOpen(void)

  {

//---

   if(ExtTimeOut>=10) // trailing no more than once every 10 seconds

     {

      datetime time_current=TimeCurrent();

      if(time_current-m_obj_last_trailingOpen>10)

        {

         if(RefreshRates())

            ObjTrailingOpen();

         else

            return;

         m_obj_last_trailingOpen=time_current;

        }

     }

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

      return;

   m_prev_barsOpen=time_0;

   if(ExtTimeOut<10) // trailing only at the time of the birth of new bar

     {

      if(RefreshRates())

         ObjTrailingOpen();

     }

  }

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

//| Object Trailing                                                  |

//|   InpObjTrailingStop: min distance from price to object          |

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

void CSampleExpert::ObjTrailingOpen(void)

  {

   if(InpObjTrailingStopOpen==0)

      return;

   double new_up_price        = 0.0;   //

   double new_down_price      = 0.0;   //

   double current_up_price    = ObjectGetDouble(0,InpObjUpNameOpen,OBJPROP_PRICE);

   double current_down_price  = ObjectGetDouble(0,InpObjDownNameOpen,OBJPROP_PRICE);

   if(current_up_price>0.0)

     {

      if(current_up_price>(m_symbol.Ask()+(m_obj_trailing_stopOpen+m_obj_trailing_stepOpen)))

        {

         m_obj_up_priceOpen=m_symbol.NormalizePrice(m_symbol.Ask()+m_obj_trailing_stopOpen);

         HLineMove(0,InpObjUpNameOpen,m_obj_up_priceOpen);

        }

     }

   if(current_down_price>0.0)

     {

      if(current_down_price<m_symbol.Bid()-(m_obj_trailing_stopOpen+m_obj_trailing_stepOpen))

        {

         m_obj_down_priceOpen=m_symbol.NormalizePrice(m_symbol.Bid()-m_obj_trailing_stopOpen);

         HLineMove(0,InpObjDownNameOpen,m_obj_down_priceOpen);

        }

     }

  }

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

//| Move horizontal line                                             |

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

bool CSampleExpert::HLineMove(const long chart_ID=0,const string name="HLine",double price=0)

  {

//--- if the line price is not set, move it to the current Bid price level

   if(!price)

      price=SymbolInfoDouble(Symbol(),SYMBOL_BID);

//--- reset the error value

   ResetLastError();

//--- move a horizontal line

   if(!ObjectMove(chart_ID,name,0,0,price))

     {

      Print(__FUNCTION__,

            ": failed to move the horizontal line! Error code = ",GetLastError());

      return(false);

     }

//--- successful execution

   return(true);

  }

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

//| Expert tick function                                             |

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

void CSampleExpert::OnTickObjTrailingClos(void)

  {

//---

   if(ExtTimeOut>=10) // trailing no more than once every 10 seconds

     {

      datetime time_current=TimeCurrent();

      if(time_current-m_obj_last_trailingClos>10)

        {

         if(RefreshRates())

            ObjTrailingClos();

         else

            return;

         m_obj_last_trailingClos=time_current;

        }

     }

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

      return;

   m_prev_barsClos=time_0;

   if(ExtTimeOut<10) // trailing only at the time of the birth of new bar

     {

      if(RefreshRates())

         ObjTrailingClos();

     }

  }

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

//| Object Trailing                                                  |

//|   InpObjTrailingStop: min distance from price to object          |

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

void CSampleExpert::ObjTrailingClos(void)

  {

   if(InpObjTrailingStopClos==0)

      return;

   double new_up_price        = 0.0;   //

   double new_down_price      = 0.0;   //

   double current_up_price    = ObjectGetDouble(0,InpObjUpNameClos,OBJPROP_PRICE);

   double current_down_price  = ObjectGetDouble(0,InpObjDownNameClos,OBJPROP_PRICE);

   if(current_up_price>0.0)

     {

      if(current_up_price>(m_symbol.Ask()+(m_obj_trailing_stopClos+m_obj_trailing_stepClos)))

        {

         m_obj_up_priceClos=m_symbol.NormalizePrice(m_symbol.Ask()+m_obj_trailing_stopClos);

         HLineMove(0,InpObjUpNameClos,m_obj_up_priceClos);

        }

     }

   if(current_down_price>0.0)

     {

      if(current_down_price<m_symbol.Bid()-(m_obj_trailing_stopClos+m_obj_trailing_stepClos))

        {

         m_obj_down_priceClos=m_symbol.NormalizePrice(m_symbol.Bid()-m_obj_trailing_stopClos);

         HLineMove(0,InpObjDownNameClos,m_obj_down_priceClos);

        }

     }

  }

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

//| start function                                                   |

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

bool CSampleExpert::Obj_SELLOpen(void)

  {

   bool res=false;

// F5=0 4;O 2KAB02;5=8O >@45@>2 A5B:8

   double curPrice;

// B5:CI0O F5=0 ?> 8=AB@C<5=BC

   MqlTick lastme;

   SymbolInfoTick(m_symbol.Name(),lastme);

// 5A;8 B5:CI59 F5=K ?>;CG8BL =5 C40;>AL, >B<5=O5< 2KAB02;5=85 A5B:8

   if(lastme.bid==0)

     {

      return(true);

     }

// <8=8<0;L=>5 @0AAB>O=85 >B F5=K, =0 :>B>@>< <>6=> AB028BL AB>? ;>AAK

   double minStop=SymbolInfoDouble(m_symbol.Name(),SYMBOL_POINT)*SymbolInfoInteger(m_symbol.Name(),SYMBOL_TRADE_STOPS_LEVEL);

// 2KAB02;O5< >@45@0 2 Long

   curPrice=lastme.bid;

   for(uint i=0; i<1; i++)

     {

      curPrice+=m_obj_trailing_stopOpen;

      if(curPrice-lastme.ask<minStop)

         continue;

      CreateHline(0,0,InpObjUpNameOpen,curPrice,InpObjUpclrOpen,0,0,1,1,1,1,2);

      PlaySound("tick.wav");

     }

   res=true;

//---

   return(true);

  }

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

//| start function                                                   |

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

bool CSampleExpert::Obj_BUYOpen(void)

  {

   bool res=false;

// F5=0 4;O 2KAB02;5=8O >@45@>2 A5B:8

   double curPrice;

// B5:CI0O F5=0 ?> 8=AB@C<5=BC

   MqlTick lastme;

   SymbolInfoTick(m_symbol.Name(),lastme);

// 5A;8 B5:CI59 F5=K ?>;CG8BL =5 C40;>AL, >B<5=O5< 2KAB02;5=85 A5B:8

   if(lastme.bid==0)

     {

      return(true);

     }

// <8=8<0;L=>5 @0AAB>O=85 >B F5=K, =0 :>B>@>< <>6=> AB028BL AB>? ;>AAK

   double minStop=SymbolInfoDouble(m_symbol.Name(),SYMBOL_POINT)*SymbolInfoInteger(m_symbol.Name(),SYMBOL_TRADE_STOPS_LEVEL);

// 2KAB02;O5< >@45@0 2 Short

   curPrice=lastme.ask;

   for(uint i=0; i<1; i++)

     {

      curPrice-=m_obj_trailing_stopOpen;

      if(lastme.bid-curPrice<minStop)

         continue;

      CreateHline(0,0,InpObjDownNameOpen,curPrice,InpObjDownclrOpen,0,0,1,1,1,1,2);

      PlaySound("tick.wav");

     }

   res=true;

//---

   return(true);

  }

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

//| start function                                                   |

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

bool CSampleExpert::Obj_SELLClos(void)

  {

   bool res=false;

// F5=0 4;O 2KAB02;5=8O >@45@>2 A5B:8

   double curPrice;

// B5:CI0O F5=0 ?> 8=AB@C<5=BC

   MqlTick lastme;

   SymbolInfoTick(m_symbol.Name(),lastme);

// 5A;8 B5:CI59 F5=K ?>;CG8BL =5 C40;>AL, >B<5=O5< 2KAB02;5=85 A5B:8

   if(lastme.bid==0)

     {

      return(true);

     }

// <8=8<0;L=>5 @0AAB>O=85 >B F5=K, =0 :>B>@>< <>6=> AB028BL AB>? ;>AAK

   double minStop=SymbolInfoDouble(m_symbol.Name(),SYMBOL_POINT)*SymbolInfoInteger(m_symbol.Name(),SYMBOL_TRADE_STOPS_LEVEL);

// 2KAB02;O5< >@45@0 2 Long

   curPrice=lastme.bid;

   for(uint i=0; i<1; i++)

     {

      curPrice+=m_obj_trailing_stopClos;

      if(curPrice-lastme.ask<minStop)

         continue;

      CreateHline(0,0,InpObjUpNameClos,curPrice,InpObjUpclrClos,0,0,1,1,1,1,2);

      PlaySound("tick.wav");

     }

   res=true;

//---

   return(true);

  }

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

//| start function                                                   |

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

bool CSampleExpert::Obj_BUYClos(void)

  {

   bool res=false;

// F5=0 4;O 2KAB02;5=8O >@45@>2 A5B:8

   double curPrice;

// B5:CI0O F5=0 ?> 8=AB@C<5=BC

   MqlTick lastme;

   SymbolInfoTick(m_symbol.Name(),lastme);

// 5A;8 B5:CI59 F5=K ?>;CG8BL =5 C40;>AL, >B<5=O5< 2KAB02;5=85 A5B:8

   if(lastme.bid==0)

     {

      return(true);

     }

// <8=8<0;L=>5 @0AAB>O=85 >B F5=K, =0 :>B>@>< <>6=> AB028BL AB>? ;>AAK

   double minStop=SymbolInfoDouble(m_symbol.Name(),SYMBOL_POINT)*SymbolInfoInteger(m_symbol.Name(),SYMBOL_TRADE_STOPS_LEVEL);

// 2KAB02;O5< >@45@0 2 Short

   curPrice=lastme.ask;

   for(uint i=0; i<1; i++)

     {

      curPrice-=m_obj_trailing_stopClos;

      if(lastme.bid-curPrice<minStop)

         continue;

      CreateHline(0,0,InpObjDownNameClos,curPrice,InpObjDownclrClos,0,0,1,1,1,1,2);

      PlaySound("tick.wav");

     }

   res=true;

//---

   return(true);

  }

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

//|  !>740=85 3>@87>=B0;L=>3>, F5=>2>3> C@>2=O                       |

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

int CSampleExpert::CreateHline(long ch_id,int sub_window,

                               string name,double price,

                               color clr,ENUM_LINE_STYLE style,

                               int width,bool back,

                               bool selectable,bool selected,

                               bool hidden,long z_order)

  {

   int    err = GetLastError();

   string lnName = name;

   err = 0;

   if(ObjectFind(0,lnName)!=-1)

      ObjectDelete(0,lnName);

   if(!ObjectCreate(ch_id,lnName,OBJ_HLINE,sub_window,0,price))

     {

      err = GetLastError();

      Print("Can't create object #", lnName, "# Error(",err,"):", err);

      return(err);

     }

   ObjectSetInteger(ch_id,lnName,OBJPROP_COLOR,clr);

   ObjectSetInteger(ch_id,lnName,OBJPROP_STYLE,style);

   ObjectSetInteger(ch_id,lnName,OBJPROP_WIDTH,width);

   ObjectSetInteger(ch_id,lnName,OBJPROP_BACK,back);

   ObjectSetInteger(ch_id,lnName,OBJPROP_SELECTABLE,selectable);

   ObjectSetInteger(ch_id,lnName,OBJPROP_SELECTED,selected);

   ObjectSetInteger(ch_id,lnName,OBJPROP_HIDDEN,hidden);

   ObjectSetInteger(ch_id,lnName,OBJPROP_ZORDER,z_order);

   return(0);

  }

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

//|                                                                  |

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

void CSampleExpert::ButtonCreate(string name,int Xdist,int Ydist,int Xsize,int Ysize,int FONTSIZE=12)

  {

   if(ObjectFind(0,m_symbol.Name()+name)<0)

      ObjectCreate(0,m_symbol.Name()+name,OBJ_BUTTON,0,100,100);

   ObjectSetInteger(0,m_symbol.Name()+name,OBJPROP_COLOR,clrWhite);

   ObjectSetInteger(0,m_symbol.Name()+name,OBJPROP_BGCOLOR,clrBlack);

   ObjectSetInteger(0,m_symbol.Name()+name,OBJPROP_XDISTANCE,Xdist);

   ObjectSetInteger(0,m_symbol.Name()+name,OBJPROP_YDISTANCE,Ydist);

   ObjectSetInteger(0,m_symbol.Name()+name,OBJPROP_XSIZE,Xsize);

   ObjectSetInteger(0,m_symbol.Name()+name,OBJPROP_YSIZE,Ysize);

   ObjectSetString(0,m_symbol.Name()+name,OBJPROP_FONT,"Sans Serif");

   ObjectSetString(0,m_symbol.Name()+name,OBJPROP_TEXT,name);

   ObjectSetInteger(0,m_symbol.Name()+name,OBJPROP_FONTSIZE,FONTSIZE);

   ObjectSetInteger(0,m_symbol.Name()+name,OBJPROP_SELECTABLE,false);

  }

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

//| Check for long position closing                                  |

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

bool CSampleExpert::ButtonOnTick(void)

  {

   bool res=false;

   double level;

   if(ObjectGetInteger(0,m_symbol.Name()+"SELL_Close",OBJPROP_STATE,0)==true)

     {

      if(FreezeStopsLevels(level))

         ClosePositions(POSITION_TYPE_SELL,level);

      PlaySound("ok.wav");

      Obj_BUYClos();

      ObjectSetInteger(0,m_symbol.Name()+"SELL_Close",OBJPROP_STATE,false);

      ObjectSetInteger(0,m_symbol.Name()+"SELL",OBJPROP_STATE,false);

     }

   if(ObjectGetInteger(0,m_symbol.Name()+"BUY_Close",OBJPROP_STATE,0)==true)

     {

      if(FreezeStopsLevels(level))

         ClosePositions(POSITION_TYPE_BUY,level);

      PlaySound("ok.wav");

      Obj_SELLClos();

      ObjectSetInteger(0,m_symbol.Name()+"BUY_Close",OBJPROP_STATE,false);

      ObjectSetInteger(0,m_symbol.Name()+"BUY",OBJPROP_STATE,false);

     }

   if(ObjectGetInteger(0,m_symbol.Name()+"CLOSE_ALL",OBJPROP_STATE,0)==true)

     {

      CloseAll();

      PlaySound("expert.wav");

      ExpertRemove();

      DeleteChart();

      ObjectSetInteger(0,m_symbol.Name()+"CLOSE_ALL",OBJPROP_STATE,false);

      ObjectSetInteger(0,m_symbol.Name()+"CLOSE",OBJPROP_STATE,false);

     }

   double PROFIT_BUY=0.00;

   double PROFIT_SELL=0.00;

   double PROFIT_CLOSE=0.00;

   double PROFIT_BUY_Lot=0.00;

   double PROFIT_SELL_Lot=0.00;

   double PROFIT_CLOSE_Lot=0.00;

   int _all =0;

   for(int i=PositionsTotal()-1; i>=0; i--)

     {

      string   position_GetSymbol=PositionGetSymbol(i); // GetSymbol ?>78F88

      if(position_GetSymbol==m_symbol.Name())

        {

         PROFIT_CLOSE_Lot=AccountInfoDouble(ACCOUNT_EQUITY);

         _all=_all+1;

         if(m_position.PositionType()==POSITION_TYPE_BUY)

           {

            PROFIT_BUY=PROFIT_BUY+PositionGetDouble(POSITION_PROFIT);

            PROFIT_BUY_Lot=PROFIT_BUY_Lot+PositionGetDouble(POSITION_VOLUME);

           }

         else

           {

            PROFIT_SELL=PROFIT_SELL+PositionGetDouble(POSITION_PROFIT);

            PROFIT_SELL_Lot=PROFIT_SELL_Lot+PositionGetDouble(POSITION_VOLUME);

           }

           {

            PROFIT_CLOSE=AccountInfoDouble(ACCOUNT_PROFIT);

            PROFIT_CLOSE_Lot=AccountInfoDouble(ACCOUNT_PROFIT);

           }

        }

     }

   ObjectSetString(0,m_symbol.Name()+"BUY_Close",OBJPROP_TEXT,"BUY Close ("+DoubleToString(PROFIT_BUY,2)+")");

   if(PROFIT_BUY>0)

     {

      ObjectSetInteger(0,Symbol()+"BUY_Close",OBJPROP_BGCOLOR,clrLimeGreen);

     }

   else

      if(PROFIT_BUY==0)

        {

         ObjectSetInteger(0,m_symbol.Name()+"BUY_Close",OBJPROP_BGCOLOR,clrBlack);

        }

      else

        {

         ObjectSetInteger(0,m_symbol.Name()+"BUY_Close",OBJPROP_BGCOLOR,clrCrimson);

        };

   ObjectSetString(0,m_symbol.Name()+"SELL_Close",OBJPROP_TEXT,"SELL Close ("+DoubleToString(PROFIT_SELL,2)+")");

   if(PROFIT_SELL>0)

     {

      ObjectSetInteger(0,m_symbol.Name()+"SELL_Close",OBJPROP_BGCOLOR,clrLimeGreen);

     }

   else

      if(PROFIT_SELL==0)

        {

         ObjectSetInteger(0,m_symbol.Name()+"SELL_Close",OBJPROP_BGCOLOR,clrBlack);

        }

      else

        {

         ObjectSetInteger(0,m_symbol.Name()+"SELL_Close",OBJPROP_BGCOLOR,clrCrimson);

        }

   ObjectSetString(0,m_symbol.Name()+"CLOSE_ALL",OBJPROP_TEXT,"CLOSE ALL ("+DoubleToString(PROFIT_CLOSE,2)+")");

   if(PROFIT_CLOSE>0)

     {

      ObjectSetInteger(0,m_symbol.Name()+"CLOSE_ALL",OBJPROP_BGCOLOR,clrLimeGreen);

     }

   else

      if(PROFIT_CLOSE==0)

        {

         ObjectSetInteger(0,m_symbol.Name()+"CLOSE_ALL",OBJPROP_BGCOLOR,clrBlack);

        }

      else

        {

         ObjectSetInteger(0,m_symbol.Name()+"CLOSE_ALL",OBJPROP_BGCOLOR,clrCrimson);

        }

   ObjectSetString(0,m_symbol.Name()+"BUY",OBJPROP_TEXT,"BUY Lot ("+DoubleToString(PROFIT_BUY_Lot,2)+")");

   ObjectSetString(0,m_symbol.Name()+"SELL",OBJPROP_TEXT,"SELL Lot ("+DoubleToString(PROFIT_SELL_Lot,2)+")");

   ObjectSetString(0,m_symbol.Name()+"CLOSE",OBJPROP_TEXT,"CLOSE Lot ("+DoubleToString(PROFIT_CLOSE_Lot,2)+")");

   if(ObjectGetInteger(0,m_symbol.Name()+"BUY",OBJPROP_STATE,0)==true)

     {

      ObjectSetInteger(0,m_symbol.Name()+"BUY",OBJPROP_BGCOLOR,clrDeepSkyBlue);

     }

   else

     {

      ObjectSetInteger(0,m_symbol.Name()+"BUY",OBJPROP_BGCOLOR,clrBlack);

     }

   if(ObjectGetInteger(0,m_symbol.Name()+"SELL",OBJPROP_STATE,0)==true)

     {

      ObjectSetInteger(0,m_symbol.Name()+"SELL",OBJPROP_BGCOLOR,clrRed);

     }

   else

     {

      ObjectSetInteger(0,m_symbol.Name()+"SELL",OBJPROP_BGCOLOR,clrBlack);

     }

   if(ObjectGetInteger(0,m_symbol.Name()+"CLOSE",OBJPROP_STATE,0)==true)

     {

      ObjectSetInteger(0,m_symbol.Name()+"CLOSE",OBJPROP_BGCOLOR,clrRed);

     }

   else

     {

      ObjectSetInteger(0,m_symbol.Name()+"CLOSE",OBJPROP_BGCOLOR,clrBlack);

     }

   if(ObjectGetInteger(0,m_symbol.Name()+"SELL",OBJPROP_STATE)!=0)

     {

      ObjectSetInteger(0,m_symbol.Name()+"SELL",OBJPROP_STATE,0);

      ShortObjOpen();

      PlaySound("ok.wav");

      Obj_BUYOpen();

      res=true;

     }

   if(ObjectGetInteger(0,m_symbol.Name()+"BUY",OBJPROP_STATE)!=0)

     {

      ObjectSetInteger(0,m_symbol.Name()+"BUY",OBJPROP_STATE,0);

      LongObjOpen();

      PlaySound("ok.wav");

      Obj_SELLOpen();

      res=true;

     }

//--- result

   return(res);

  }

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

//| Expert initialization function                                   |

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

int OnInit(void)

  {

   if(!ExtExpert.Init())

      return(INIT_FAILED);

   return(INIT_SUCCEEDED);

  }

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

//| Expert deinitialization function                                 |

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

void OnDeinit(const int reason)

  {

   for(int i=0; i<ArraySize(_name); i++)

     {

      ObjectDelete(0,Symbol()+_name[i]);

     };

   EventKillTimer();

//---

   Print(TimeCurrent(),": ",__FUNCTION__," reason code = ",reason);

   Comment("");

   ObjectsDeleteAll(0,"cm");

//---

  }

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

//| 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*0)

        {

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

         if(ExtExpert.Processing())

            limit_time=TimeCurrent()+ExtTimeOut;

        }

     }

  }

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

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---