TrendlineColorOpenClose

Author: Copyright © 2021, Aleksandr Klapatyuk
9 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