Showing posts with label Forex robot MT4. Show all posts
Showing posts with label Forex robot MT4. Show all posts

Monday, December 2, 2024

In this article, I'll explain how to create a standard and simple Expert Advisor (EA) or forex robot by applying Buy or Sell signals from the FiboPivotCandleBar indicator for MetaTrader 4.

First, let me explain that the FiboPivotCandleBar indicator for MetaTrader 4 is an indicator I created and have been sharing for free in the MQL5 Library since 2015. However, I have never applied the signals inan Expert Advisor or forex robot until now. This article won't delve into the Fibonacci and Pivot Point strategies, as they require a dedicated and lengthy discussion.

To create this Expert Advisor, I used the latest Event Handling Functions from MQL4 and several key properties and attributes that adhere to good MQL4 programming standards.

FiboPivotCandleBar Expert Advisor for MetaTrader 4

Now, I'll explain each function, the use of variables, and the algorithm's logic one by one.

Standard Include Files.

For creating this Expert Advisor, I used the standard include files (mqh files):

  • 1.- #include MovingAverages.mqh: Used for writing the MovingAverage indicator signal.
  • 2.- #include stderror.mqh: Contains standard errors returned from the trade server.
  • 3.- #include stdlib.mqh: Contains the Error Description from standard library.

You can find these three include files in the MQL4/Include folder.

Custom Enumerations.

YN Enum Function: I use this for Yes or No options. Most programmers prefer boolean variables (True or False), but I prefer using Yes or No for clarity.

MMT Enum Function: This function is used for determining the Lot Size (Money Management).

  • If FixedLot is selected, the expert advisor will use the value of the Lots variable entered by the user. By default, the Lots size variable is set to 0.01.
  • If AutoLot is selected, the expert advisor will calculate the Lot size according to the specified money management requirements.

//---
input string           grs0 = "=== Global Strategy EA Parameters ==="; // Global Strategy EA Parameter
input ENUM_TIMEFRAMES  ExTF = PERIOD_H1;      // Select Expert TimeFrame, default PERIOD_H1
input YN            SrictTF = Yes;            // Strict to Change TimeFrame (Yes) or (No)
//---
input string           grs1 = "=== Money Management Lot Size Parameters ==="; // Money Management Lot Size Parameter
input mmt             mmlot = AutoLot;        // Money Management Type
input double           Risk = 5.0;            // Percent Equity Risk to Trade (Min=1.0% / Max=50.0%)
input double           Lots = 0.01;           // If Money Management Type FixedLot, input Fixed Lot Size
//---
input string           grs2 = "=== Close Order Option ==="; // Close Order Option
input YN      Close_by_Opps = Yes;            // Close Trade By Opposite Signal (Yes) or (No)
input YN             CSexit = Yes;            // Use Close In Signal Exit (Yes) or (No)
//---
input string           grs3 = "=== Stop Loss & Take Profit Parameters ==="; // Stop Loss  && Take Profit Parameter
input YN             Use_SL = No;             // Use Order SL (Yes) or (No)
input YN             Use_TP = No;             // Use Order TP (Yes) or (No)
//---
input string           grs4 = "=== Trailing Stop Loss / Take Profit Parameters ==="; // Trailing SL / TP Parameter
input YN          use_trail = Yes;            // Use Trailing Stop / Trailing Profit (Yes) or (No)
input int            trstrt = 1;              // Input Start value for Trailing Stop in Pips
input int            trstop = 6;              // Input Trailing Stop value in Pips
//---
input string           grs5 = "=== Others Expert Advisor Parameters ==="; // Others EA Parameter
input YN             alerts = Yes;            // Display Alerts on Chart (Yes) or (No)
input YN      UseEmailAlert = No;             // Email Alert (Yes) or (No)
input YN      UseSendnotify = No;             // Send Notification (Yes) or (No)
input YN       Usechartcomm = Yes;            // Display Setting on Chart (Yes) or (No)
input int           magicEA = 20241202;        // Expert ID (Magic Number)
//---

Select Expert TimeFrame (default: PERIOD_H1): This parameter defines the Expert Timeframe for signal calculation. It prevents the EA from recalculating signals based on the chart's last changed timeframe by user, which could lead to premature order closures.

Strict to Change Timeframe (Yes or No): By default, this is set to Yes, preventing traders from changing timeframe charts directly in the MetaTrader 4 terminal. Timeframe changes can only be made through the Select Expert Timeframe input property. Set to No if the user wants to change the timeframe manually.

Money Management Lot Size Parameters.

Money Management Type: By default, this is set to AutoLot. The EA calculates the Lot Size based on the Percent Equity Risk to Trade, which is set at 5% by default (min 1.0%, max 50.0%). For trading on 20 pairs or more, consider increasing the risk to 20% or 30%. If FixedLot is selected, input the desired FixedLot Size.

Close Order Options.

Close Trade By Opposite Signal (Yes or No): By default, this is set to Yes. If there's an open BUY order and the signal reverses to SELL, the EA will close the BUY order and open a SELL order, and vice versa.

Use Close In Signal Exit (Yes or No): By default, this is set to Yes. If the BUY signal weakens but is still profitable, the EA will close the BUY order. If set to No, the EA won't close the order based on signal exit.

Stop Loss and Take Profit Parameters.

Use Order SL (Yes or No): By default, this is set to No. Despite this, the EA will automatically close orders if there's a reverse signal, thanks to the Close Trade By Opposite Signal parameter.

Use Order TP (Yes or No): By default, this is set to No, allowing for greater profits during long trends.

Trailing Stop Loss or Take Profit Parameters.

Use Trailing Stop or Trailing Profit (Yes or No): By default, this is set to Yes. If not preferred, set this parameter to No. The trailing start is set at 1 pip from the Order Open Price, with a trailing stop value of 6 pips. These values can be adjusted as desired.

Other Expert Advisor Parameters.

Display Alerts on Chart (Yes or No): By default, this is set to Yes, activating alerts, email, and push notification functions through the DoAlerts function.

Email Alert (Yes or No): By default, this is set to No. For email alerts, users must configure their email settings in MetaTrader 4:

  • 1. Click the Tools menu.
  • 2. Select Options.
  • 3. Click Email.

Configure the settings with your email identity:

  • SMTP server: e.g., smtp.gmail.com:587 for Gmail.
  • SMTP login: Your email address.
  • SMTP password: Your email password.
  • From: Your email address.
  • To: Recipient's email address (can be the same as the sender).

After configuring, click the Test button and check the Journal Tab for any errors.

Send Notification (Yes or No): By default, this is set to No. For push notifications, users must configure their MetaQuotes ID in MetaTrader 4:

  • 1. Click the Tools menu.
  • 2. Select Options.
  • 3. Click the Notifications tab.
  • 4. Check Enable Push Notification.
  • 5. Enter YOUR MetaQuotes ID.

Class Function.

In this Expert Advisor, I use a class function named "EXP", listing all main variables and functions used. This class serves as the blueprint of the Expert Advisor. However, this article won't delve into the class function's details, assuming readers are familiar with it.


//+------------------------------------------------------------------+
//| Class for working Expert Advisor                                 |
//+------------------------------------------------------------------+
class EXP 
  {
//---
    private:
    //---
    //--
    int           slip,bartotal;
    int           ldig,checkacc,cdb,cds;
    //--
    double        mSL,mTP,mPft;
    double        pip,xpip,trs;
    double        profitb,profits,floatprofit;
    //--
    double        OPEN[],HIGH[],LOW[],CLOSE[];
    double        trval,trstart,trstoptp,aapct;
    double        PvtS,POpen,PLow1,PHigh1,PClose1;
    //--
    bool          posBUY,posSELL;
    //--
    string        expname,
                  exsymbol,
                  trade_mode;
    //-- 
    long          chart_id;
    ENUM_TIMEFRAMES BnC;
    //------------
     
    //------------
    int           LotsDigit(void);
    int           DirectionMove(ENUM_TIMEFRAMES xtf,int shift);
    int           FiboPivotCB(void);
    int           AllowOpen(void);
    int           SignalCondition(void);
    //--
    string        TF2Str(int period);
    string        GetCommentForOrder(void)                  { return(expname); }    
    string        ReturnsOrderType(ENUM_ORDER_TYPE ordtype);
    string        AccountMode(void);
    //--
    double        NonZeroDiv(double val1,double val2);
    double        MLots(void);
    //--   
    void          CopyPrices(void);
    void          RefreshPrice(string symbx,ENUM_TIMEFRAMES xtf,int bars);
    //--
    bool          ModifyStopTP(double mStop,double mProfit) { return(OrderModify(OrderTicket(),OrderOpenPrice(),mStop,mProfit,0,CLR_NONE)); }
    bool          SameAs(double v1,double v2)               { if((double)v1==(double)v2) return(true); return(false); }
    bool          CloseAllOrder(void);
    //------------

    public:
    //---
    //--
    int           utr,ALO,cB,cS,checktml;
    int           oBm,oSm,hBm,hSm,tto;
    //--
    bool          IfTradeAllowed;
    //--
    datetime      PbarB,TbarB,PbarS,TbarS;
    //------------
     
    //------------
    void          FPCB_Config(void);
    void          GetOpenPosition(void);
    void          CheckOpen(void);
    void          CheckClose(void);
    void          TrailingPositionsBuy(void);
    void          TrailingPositionsSell(void);
    void          CloseBuyPositions(void);
    void          CloseSellPositions(void);
    void          Do_Alerts(string msgText);
    void          ChartComm(void);
    void          SignalExit(void);
    //--
    bool          takeBuyPositions(void);
    bool          takeSellPositions(void);
    bool          OpenBuy(void);
    bool          OpenSell(void);
    bool          CloseAllOrdersProfit(void);
    bool          IFNewBarsB(string symb);
    bool          IFNewBarsS(string symb);
    //--
    string        getUninitReasonText(int reasonCode);
    //--
    //------------
//---
  }; //-end class fxt
//---------//
 
EXP fx;

OnInit: Here, I create an algorithm where if SrictTF enumeration is set to Yes, it utilizes the Strict to Change TimeFrame parameter. This function calls "FPCBConfig" function for setting the default configuration used in the Expert Advisor.


//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit(void)
  {
//----
   Comment("");
   //--
   if(SrictTF==Yes)
     {
       if(!ChartSetSymbolPeriod(ChartID(),Symbol(),ExTF))
         {ChartSetSymbolPeriod(ChartID(),Symbol(),ExTF);}
     }
   //--
   fx.FPCB_Config();
   //--
//--- initialization done
   return(INIT_SUCCEEDED);
  }
//---------//

FPCB_Config() function.


void EXP::FPCB_Config(void)
  {
//---
   expname="@ExpFPCB-MT4";
   exsymbol=Symbol();
   //--
   slip=20;
   checktml=0;
   AccountMode();
   utr=use_trail;
   BnC=ExTF; 
   bartotal=108;
   chart_id=ChartID();
   ALO=(int)AccountInfoInteger(ACCOUNT_LIMIT_ORDERS);
   //--
   //-- Checking the Digits Point
   slip=20;
   PbarB=iTime(Symbol(),BnC,1);
   PbarS=iTime(Symbol(),BnC,1);
   double point=SymbolInfoDouble(Symbol(),SYMBOL_POINT);
   mPft=0.5;
   //--
   if(exsymbol=="XAGUSD")
     {
       xpip=4; 
       pip=point*xpip;
       if(Use_SL==Yes) mSL=100*point;
       else mSL=0.0;
       if(Use_TP==Yes) mTP=50*point;
       else mTP=0.0;
       //--
       trstart=NormalizeDouble(trstrt*pip,Digits());
       trstoptp=NormalizeDouble(trstop*pip,Digits());
       trval=NormalizeDouble(trstart+trstoptp,Digits());
     }
   if(exsymbol=="XAUUSD")
     {
       xpip=10; 
       pip=point*xpip;
       if(Use_SL==Yes) mSL=250*point;
       else mSL=0.0;
       if(Use_TP==Yes) mTP=50*point;
       else mTP=0.0;
       //--
       trstart=NormalizeDouble(trstrt*pip,Digits());
       trstoptp=NormalizeDouble(trstop*pip,Digits());
       trval=NormalizeDouble(trstart+trstoptp,Digits());
     }
   if(exsymbol=="XBRUSD")
     {
       xpip=10; 
       pip=point*xpip;
       if(Use_SL==Yes) mSL=250*point;
       else mSL=0.0;
       if(Use_TP==Yes) mTP=50*point;
       else mTP=0.0;
       //--
       trstart=NormalizeDouble(trstrt*pip,Digits());
       trstoptp=NormalizeDouble(trstop*pip,Digits());
       trval=NormalizeDouble(trstart+trstoptp,Digits());
     }
   if(exsymbol=="XTIUSD")
     {
       xpip=10; 
       pip=point*xpip;
       if(Use_SL==Yes) mSL=250*point;
       else mSL=0.0;
       if(Use_TP==Yes) mTP=50*point;
       else mTP=0.0;
       //--
       trstart=NormalizeDouble(trstrt*pip,Digits());
       trstoptp=NormalizeDouble(trstop*pip,Digits());
       trval=NormalizeDouble(trstart+trstoptp,Digits());
     }
   else
     {
       xpip=10; 
       pip=point*xpip;
       if(Use_SL==Yes) mSL=25*pip;
       else mSL=0.0;
       if(Use_TP==Yes) mTP=5*pip;
       else mTP=0.0;
       //--
       trstart=NormalizeDouble(trstrt*pip,Digits());
       trstoptp=NormalizeDouble(trstop*pip,Digits());
       trval=NormalizeDouble(trstart+trstoptp,Digits());
     }
   //--
   IfTradeAllowed=IsTradeAllowed();
   CopyPrices();
   //--
   return;
//---
  } //-end FPCB_Config()
//---------//

OnDeinit: in this function, I call the getUninitReasonText function, which provides the description of the reason Code when the Expert Advisor calls the OnDeinit function.


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   Comment("");
   //--
   PrintFormat("%s: Deinitialization reason code=%d",__FUNCTION__,reason);
   Print(fx.getUninitReasonText(reason));
   //--
   return;
  } //-end OnDeinit()
//---------//

OnTick: This is where the Expert Advisor carries out trading activities based on the settings specified in the input properties parameter.


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick(void)
  {  
//---
   //Check Trading Terminal
   if(!fx.IfTradeAllowed && fx.checktml==0)
     {
       fx.Do_Alerts("Trading at "+Symbol()+" are NOT Allowed by Setting.");
       fx.checktml=1;
       return;
     }
   //--
   RefreshRates();
   fx.CheckOpen();
   if(fx.tto==0 && fx.hBm+fx.hSm>0) fx.CheckClose();
   //--
   if(Usechartcomm==Yes) fx.ChartComm();
   //--
   fx.GetOpenPosition();
   //Buy Condition
   if(fx.takeBuyPositions())
     {
       //--
       fx.CheckOpen();
       //--
       if(fx.oBm==0 && fx.IFNewBarsB(Symbol())) {fx.cB=1; fx.OpenBuy(); fx.PbarB=fx.TbarB;}
       else if(fx.oBm==0 && fx.oSm>0) {fx.cB=2; fx.OpenBuy(); fx.PbarB=fx.TbarB;}
       fx.CheckOpen();
       if(fx.oBm>0 && Close_by_Opps==Yes && fx.oSm>0) {fx.CloseSellPositions(); fx.PbarB=fx.TbarB;}
     }
   //--
   //Sell Condition
   if(fx.takeSellPositions())
     {
       //--
       fx.CheckOpen();
       //--
       if(fx.oSm==0 && fx.IFNewBarsS(Symbol())) {fx.cS=1; fx.OpenSell(); fx.PbarS=fx.TbarS;}
       else if(fx.oSm==0 && fx.oBm>0) {fx.cS=2; fx.OpenSell(); fx.PbarS=fx.TbarS;}
       fx.CheckOpen();
       if(fx.oSm>0 && Close_by_Opps==Yes && fx.oBm>0) {fx.CloseBuyPositions(); fx.PbarS=fx.TbarS;}
     }
   //--
   if(CSexit==Yes) fx.SignalExit();
   //--
   if(OrdersTotal()>=fx.ALO) fx.CloseAllOrdersProfit();
   //---
   //Trailing Stop / Take Profit Position
   if(fx.utr==Yes)
     {
       fx.CheckOpen();
       if(fx.oBm>0) fx.TrailingPositionsBuy();
       if(fx.oSm>0) fx.TrailingPositionsSell();
     }
   //--
   return;
//---
  } //-end OnTick()
//---------//

First, the Expert Advisor checks whether automatic trading on symbols and MetaTrader 4 is allowed. If is not, it alerts that "Trading on the symbol is NOT Allowed by Setting."

Especially for novice traders:

  • 1. Check if the "AutoTrading" button is red or green. If red, click it once to turn it green.
  • 2. Check if the Expert Advisor icon in the upper right corner of the chart shows a crying or laughing face. If crying:
    • 1. Click the Tools menu.
    • 2. Select Options.
    • 3. Click the Expert Advisors tab.
    • 4. Check "Allow automated trading." The icon will show a laughing face, and the "AutoTrading" button will turn green.

After that, the Expert Advisor starts trading activities by:

  • 1. Calling the CheckOpen function to check for open orders. If none, it calls the CheckClose function to reset the open buy or sell order count to zero.
  • 2. If Display Setting on Chart is Yes, it calls the ChartComm function to display settings on the chart.

CheckOpen function.

This is a function named CheckOpen in the EXP class, which seems to be used for checking the status of open trades. Here's a step-by-step explanation:

1. Initialization:

  • oBm and oSm are set to 0. These might represent the count of Buy and Sell orders, respectively.
  • profitb and profits are set to 0.0. These variables likely store the profit from Buy and Sell orders.
  • totalorder is set to OrdersTotal(), which retrieves the total number of orders.

2. Order Checking Loop:

  • A loop iterates through all orders (totalorder). The loop runs as long as opn is less than totalorder and the IsStopped() function returns false.
  • Inside the loop, OrderSelect(opn, SELECT_BY_POS, MODE_TRADES) selects the order at position opn.

3. Order Validation:

  • It checks if the selected order's symbol matches the current symbol (OrderSymbol() == Symbol()) and its magic number matches magicEA.
  • If these conditions are met, it proceeds to check the order type.

4. Order Type Checking:

  • If the order is a Buy order (OrderType() == OP_BUY):
    • oBm and hBm are incremented.
    • profitb is calculated as the sum of OrderProfit(), OrderCommission(), and OrderSwap().
  • If the order is a Sell order (OrderType() == OP_SELL):
    • oSm and hSm are incremented.
    • profits is calculated similarly.

5.Profit Calculation:

  • floatprofit is set to the sum of profitb and profits.

6.Total Orders:

  • tto is set to the sum of oBm and oSm, which likely represents the total number of Buy and Sell orders.

7.End of Function::

  • The function ends and returns..

The CheckOpen function essentially counts the number of Buy and Sell orders, calculates their respective profits, and totals them up. It handles trades by ensuring they match specific criteria (symbol and magic number) before processing.


void EXP::CheckOpen(void) //-- function: CheckOpenTrade.
  {
//---
    oBm=0;
    oSm=0;
    profitb=0.0;
    profits=0.0;
    int totalorder=OrdersTotal();
    //--
    for(int opn=0; opn<totalorder && !IsStopped(); opn++)
      {
        if(OrderSelect(opn,SELECT_BY_POS,MODE_TRADES))
          {
            if(OrderSymbol()==Symbol() && OrderMagicNumber()==magicEA)
              {
                //--
                if(OrderType()==OP_BUY)  
                  {
                    oBm++; 
                    hBm++;
                    profitb=OrderProfit()+OrderCommission()+OrderSwap();                
                  }
                if(OrderType()==OP_SELL) 
                  {
                    oSm++; 
                    hSm++;
                    profits=OrderProfit()+OrderCommission()+OrderSwap();
                  }
                //--
                floatprofit=profitb+profits;
              }
            //--
          }
      }
    //--
    tto=oBm+oSm;
    //---
    return;
//---
  } //-end CheckOpen()
//---------//

CheckClose function.


void EXP::CheckClose(void) //-- function: CheckOrderClose.
  {
//----
    //--
    CheckOpen();
    datetime octm;
    int hyst=OrdersHistoryTotal();
    //--
    for(int b=hyst-1; b>=0; b--)
      {
        //--
        if(OrderSelect(b,SELECT_BY_POS,MODE_HISTORY))
          {
            if(OrderSymbol()==Symbol() && OrderMagicNumber()==magicEA)
              {
                //--
                if(OrderType()==OP_BUY)
                  {
                    octm=OrderCloseTime();
                    if(hBm>0 && oBm==0 && octm>0) hBm=0;                            
                  }
                //--
                if(OrderType()==OP_SELL)
                  {
                    octm=OrderCloseTime();
                    if(hSm>0 && oSm==0 && octm>0)  hSm=0;                              
                  }
              }
          }
        //--
      }
   //--
   //---
   return;
//----
  } //-end CheckClose()
//---------//

ChartComm function.


void EXP::ChartComm() // function: write comments on the chart
  {
//---
   string opnsignal=posBUY ? "BUY" : posSELL ? "SELL" : "Not Trade";
   //--
   Comment("n     :: Server Date Time : ",(string)Year(),".",(string)Month(),".",(string)Day(), "   ",TimeToString(TimeCurrent(),TIME_SECONDS), 
      "n     ------------------------------------------------------------", 
      "n      :: Broker             :  ",TerminalCompany(), 
      "n      :: Acc. Name       :  ",AccountName(), 
      "n      :: Acc, Number    :  ",(string)AccountNumber(),
      "n      :: Acc,TradeMode :  ",AccountMode(),
      "n      :: Acc. Leverage   :  1 : ",(string)AccountLeverage(), 
      "n      :: Acc. Balance     :  ",DoubleToString(AccountBalance(),2),
      "n      :: Acc. Equity       :  ",DoubleToString(AccountEquity(),2),
      "n      :: Timeframe        :  ",TF2Str(BnC),
      "n      :: Magic Number   :  ",string(magicEA),
      "n     --------------------------------------------",
      "n      :: Currency Pair    :  ",Symbol(),
      "n      :: Current Spread  :  ",IntegerToString(SymbolInfoInteger(Symbol(),SYMBOL_SPREAD),0),
      "n      :: Signal          : ",opnsignal,
      "n      :: Position BUY  : ",string(oBm),
      "n      :: Position SELL : ",string(oSm),
      "n      :: Current Profit : ",DoubleToString(floatprofit,2));
   //---
   ChartRedraw();
   return;
//----
  } //-end ChartComm()  
//---------//

Then, the Expert Advisor calls the GetOpenPosition function, which in turn calls the SignalCondition function. This function processes signals through:

  • 1. DirectionMove function: Checks if the Close Price is above (Buy Signal) or below (Sell Signal) the Open Price.
  • 2. AllowOpen function: Checks the Open Price position against the Moving Averages period 2 (LWMA Mode, Price Weighted).
  • 3. FiboPivotCB function: Calculates signal using four Moving Average indicators, standard ZigZag indicators for M30 and H1 Timeframes, and the MACD indicator.

SignalCondition function.


int EXP::SignalCondition(void) 
  {
//---
    int rise=1,
        down=-1;
    int InTRise=3;
    int InTDown=-3;
    int cond=0;
    //--   
    CheckOpen();
    int dmove=DirectionMove(BnC,0);
    int alopn=AllowOpen();
    int fbcb3=FiboPivotCB();
    //--
    int TrendIndi=fbcb3+dmove+alopn;
    //--
    if(TrendIndi==InTRise) {cond=rise; cdb=11;}
    if(TrendIndi==InTDown) {cond=down; cds=11;}
    if(oSm>0 && TrendIndi==InTRise) {cond=rise; cdb=12;}
    if(oBm>0 && TrendIndi==InTDown) {cond=down; cds=12;}
    //--
    return(cond);
//---
  } //-end SignalCondition()
//---------//

The SignalCondition function will call 4 functions:

  • CheckOpen();
  • DirectionMove();
  • AllowOpen();
  • FiboPivotCB();

DirectionMove function.


int EXP::DirectionMove(ENUM_TIMEFRAMES xtf,int shift) // Bar Direction 
  {
//---
    int ret=0;
    int rise=1,
        down=-1;
    int br=shift+1;
    RefreshPrice(Symbol(),xtf,br);
    //--
    double diff=iClose(Symbol(),xtf,shift)-iOpen(Symbol(),xtf,shift);
    if( diff>0.0) ret=rise;
    if (diff<0.0) ret=down;
    //--
    return(ret);
//---
  } //-end DirectionMove()
//---------//

AllowOpen function.


int EXP::AllowOpen(void)
  {
//---
    int res=0;
    int rise=1,
        down=-1;
    //--
    int MAWper02=2;
    double MAFast[];
    //--
    ArrayResize(MAFast,bartotal,bartotal);
    ArraySetAsSeries(MAFast,true);
    //--
    CopyPrices();
    //--
    for(int x=bartotal-1; x>=0; x--)
      MAFast[x]=iMA(Symbol(),BnC,MAWper02,0,MODE_LWMA,PRICE_WEIGHTED,x);
    //--
    bool OpenUp=(OPEN[0]<MAFast[0]);
    bool OpenDn=(OPEN[0]>MAFast[0]);
    //--
    if(OpenUp) res=rise;
    if(OpenDn) res=down;
    //--
    //Print(Symbol()+" : AllowOpen res = "+string(res));
    //--
    return(res);
//---
  } //-end AllowOpen()
//---------//

FiboPivotCB function.


int EXP::FiboPivotCB(void) // Signal BUY / SELL Indicator FiboPivotCandleBar
  {
//---
    int res=0;
    int rise=1,
        down=-1;
    //--
    int zzh1=0;
    int zzl1=0;
    int zhm1=0;
    int zlm1=0;
    bool ArrUp=false;
    bool ArrDn=false;
    bool opsup=false;
    bool opsdn=false;
    bool opsnt=false;
    //--   
    ENUM_TIMEFRAMES
       cprz=PERIOD_M15,
       prhh=PERIOD_M30,
       prh1=PERIOD_H1;
    ENUM_MA_METHOD mmeth1=MODE_EMA;
    ENUM_MA_METHOD mmeth2=MODE_SMA;
    ENUM_APPLIED_PRICE aprice=PRICE_MEDIAN;
    //--
    double ema02m[];
    double sma20m[];
    double maon10[];
    double maon62[];
    //--
    ArrayResize(ema02m,bartotal);
    ArrayResize(sma20m,bartotal);
    ArrayResize(maon10,bartotal);
    ArrayResize(maon62,bartotal);
    ArraySetAsSeries(ema02m,true);
    ArraySetAsSeries(sma20m,true);
    ArraySetAsSeries(maon10,true);
    ArraySetAsSeries(maon62,true);
    //--
    RefreshPrice(Symbol(),cprz,bartotal);
    //--
    for(int j=bartotal-1; j>=0; j--)
      {ema02m[j]=iMA(Symbol(),cprz,2,0,mmeth1,aprice,j);}
    for(int k=bartotal-1; k>=0; k--)
      {sma20m[k]=iMA(Symbol(),cprz,20,0,mmeth2,aprice,k);}
    //--
    SimpleMAOnBuffer(bartotal,0,0,10,sma20m,maon10);
    SimpleMAOnBuffer(bartotal,0,0,62,sma20m,maon62);
    //--
    double ma10620=maon10[0]-maon62[0];
    double ma10621=maon10[1]-maon62[1];
    double ma20100=sma20m[0]-maon10[0];
    double ma20101=sma20m[1]-maon10[1];
    //--
    bool ma5xupn=(ema02m[0]>ema02m[1])&&(sma20m[0]>sma20m[1])&&(ma10620>=ma10621)&&((maon10[2]<maon62[2])&&(maon10[0]>maon62[0]));
    bool ma5xupc=(ema02m[0]>ema02m[1])&&(sma20m[0]>sma20m[1])&&(ma10620>=ma10621)&&(maon10[0]>maon62[0])&&(maon10[0]>maon10[1]);
    bool ma5xupb=(ema02m[0]>ema02m[1])&&(sma20m[0]>sma20m[1])&&(ma20100>ma20101)&&(maon62[0]>maon62[1])&&(sma20m[0]>maon10[0]);
    bool ma5xdnn=(ema02m[0]<ema02m[1])&&(sma20m[0]<sma20m[1])&&(ma10620<=ma10621)&&((maon10[2]>maon62[2])&&(maon10[0]<maon62[0]));
    bool ma5xdnc=(ema02m[0]<ema02m[1])&&(sma20m[0]<sma20m[1])&&(ma10620<=ma10621)&&(maon10[0]<maon62[0])&&(maon10[0]<maon10[1]);
    bool ma5xdna=(ema02m[0]<ema02m[1])&&(sma20m[0]<sma20m[1])&&(ma20100<ma20101)&&(maon62[0]<maon62[1])&&(sma20m[0]<maon10[0]);
    //--
    RefreshPrice(Symbol(),prhh,bartotal);
    for(int zz=bartotal-1; zz>=0; zz--) //- for(zz)
      {
        if(iHigh(Symbol(),prhh,zz)==iCustom(Symbol(),prhh,"ZigZag",12,5,3,1,1,zz))
          {zhm1=zz;}
        if(iLow(Symbol(),prhh,zz)==iCustom(Symbol(),prhh,"ZigZag",12,5,3,1,2,zz))
          {zlm1=zz;}
      } //-end for(zz m30)
    //--
    RefreshPrice(Symbol(),prh1,bartotal);
    for(int zz=bartotal-1; zz>=0; zz--) //- for(zz)
      {
        if(iHigh(Symbol(),prh1,zz)==iCustom(Symbol(),prh1,"ZigZag",12,5,3,1,zz))
          {zzh1=zz;}
        if(iLow(Symbol(),prh1,zz)==iCustom(Symbol(),prh1,"ZigZag",12,5,3,1,2,zz))
          {zzl1=zz;}
      } //-end for(zz h1)
    //--
    double macd0=iMACD(Symbol(),prh1,12,26,9,0,MODE_MAIN,0)-iMACD(Symbol(),prh1,12,26,9,0,MODE_SIGNAL,0);
    double macd1=iMACD(Symbol(),prh1,12,26,9,0,MODE_MAIN,1)-iMACD(Symbol(),prh1,12,26,9,0,MODE_SIGNAL,1);
    double mcdm0=iMACD(Symbol(),prh1,12,26,9,0,MODE_MAIN,0);
    double mcdm1=iMACD(Symbol(),prh1,12,26,9,0,MODE_MAIN,1);
    double mcds0=iMACD(Symbol(),prh1,12,26,9,0,MODE_SIGNAL,0);
    double mcds1=iMACD(Symbol(),prh1,12,26,9,0,MODE_SIGNAL,1);
    //--
    if((((zzl1<zzh1)&&(zzl1>0)&&(zzl1<4)&&(zlm1<zhm1)))||((macd0>macd1)&&(mcdm0>mcdm1))) {ArrUp=true;}
    //--
    if((((zzl1>zzh1)&&(zzh1>0)&&(zzh1<4)&&(zlm1>zhm1)))||((macd0<macd1)&&(mcdm0<mcdm1))) {ArrDn=true;}
    //--
    if(((ArrUp==true)&&(zzl1>4))||((mcdm0<mcdm1)&&(macd0<macd1))) {ArrDn=true; ArrUp=false;}
    if(((ArrDn==true)&&(zzh1>4))||((mcdm0>mcdm1)&&(macd0>macd1))) {ArrUp=true; ArrDn=false;}
    if((mcdm0>=mcdm1)&&(mcdm0>mcds0)&&(mcds0>mcds1)) {ArrUp=true; ArrDn=false;}
    if((mcdm0<=mcdm1)&&(mcdm0<mcds0)&&(mcds0<mcds1)) {ArrDn=true; ArrUp=false;}
    if(ma5xupn||ma5xupc||ma5xupb) {ArrUp=true; ArrDn=false;}
    if(ma5xdnn||ma5xdnc||ma5xdna) {ArrDn=true; ArrUp=false;}
    //--
    double fpCls0=(iHigh(Symbol(),prh1,0)+iLow(Symbol(),prh1,0)+iClose(Symbol(),prh1,0)+iClose(Symbol(),prh1,0))/4;
    double fpCls1=(iHigh(Symbol(),prh1,1)+iLow(Symbol(),prh1,1)+iClose(Symbol(),prh1,1)+iClose(Symbol(),prh1,1))/4;
    double hlcc0=fpCls0-iMA(Symbol(),prh1,20,0,mmeth2,aprice,0);
    double hlcc1=fpCls1-iMA(Symbol(),prh1,20,0,mmeth2,aprice,1);
    //--
    if((ArrUp==true)&&(hlcc0>hlcc1)) {opsup=true; opsdn=false; opsnt=false;}
    //--
    if((ArrDn==true)&&(hlcc0<hlcc1)) {opsdn=true; opsup=false; opsnt=false;}
    //--
    if((!opsup)&&(!opsdn)) {opsnt=true; opsup=false; opsdn=false;}
    //--
    //---
    if(ArrUp && opsup) res=rise;
    //--
    if(ArrDn && opsdn) res=down;
    //--
    //---
    return(res);
//---
  } //-end FiboPivotCB()
//---------//

The FiboPivotCB() that utilizes a combination of technical analysis indicators and Fibonacci Pivot Points to generate buy and sell signals.

1. Variable Declaration:

  • Various integer and boolean variables are declared to store intermediate calculations and signal flags.
  • Timeframe variables cprz, prhh, and prh1 are defined to specify different timeframes for calculations.
  • Arrays ema02m, sma20m, maon10, and maon62 are declared to store calculated moving averages.

2. Calculating Moving Averages:

  • The code calculates several moving averages using the iMA() function.
  • It also calculates differences between moving averages to identify potential trend changes.

3. Fibonacci Pivot Points:

  • The code calculates Fibonacci Pivot Points using the iHigh(), iLow(), and iClose() functions.
  • It identifies potential support and resistance levels based on these pivot points.

4. Trend Identification:

  • The code uses a combination of moving average crossovers and Fibonacci Pivot Points to identify potential uptrends and downtrends.
  • Boolean variables ArrUp and ArrDn are used to indicate upward and downward trends, respectively.

5. Signal Generation:

  • The final if conditions check the values of the trend indicators and Fibonacci Pivot Points to generate buy or sell signals.
  • res variable is set to rise for a buy signal and down for a sell signal.

Key Points to Note:

  • Timeframe Importance: The choice of timeframes (e.g., cprz, prhh, prh1) significantly impacts the sensitivity and accuracy of the signals.
  • Indicator Combination: The code combines multiple indicators to generate more robust signals, reducing the risk of false signals.

Buy Orders condition:

  • takeBuyPositions function is true.
  • No existing Buy order (one order per direction signal).
  • On a new bar (no previous Buy order or Close Buy order on that bar).
  • If a Sell order exists and Close Trade By Opposite Signal is Yes, it opens a Buy order and closes the Sell order.
  • If Close Trade By Opposite Signal is No, it opens a Buy order and leaves the Sell order open.

Sell Orders condition:

  • takeSellPositions function is true.
  • No existing Sell order (one order per direction signal).
  • On a new bar (no previous Sell order or Close Sell order on that bar).
  • If a Buy order exists and Close Trade By Opposite Signal is Yes, it opens a Sell order and closes the Buy order.
  • If Close Trade By Opposite Signal is No, it opens a Sell order and leaves the Buy order open.

If Use Close In Signal Exit is Yes, the Expert Advisor calls the SignalExit function to close orders if the signal is not significant.

If the Orders Total is greater than or equal to the ACCOUNT LIMIT ORDERS set by the broker, the Expert Advisor calls the CloseAllOrdersProfit function to close profitable orders, keeping the total open orders below the broker's limit.

If Use Trailing Stop and Trailing Profit is Yes, the Expert Advisor performs trailing stop and trailing profit using TrailingPositionsBuy for Buy orders and TrailingPositionsSell for Sell orders.

For additional functions, you can explore and learn from the Expert Advisor program it self. If you have any questions, feel free to write in the comments or email me.

I recommend testing this expert advisor directly on the trading terminal using a demo account. While you can use the StrategyTester, keep in mind that its results depend heavily on the complete history of price data in your MetaTrader 4. This expert advisor integrates multiple indicators, including a 6-period Moving Average, ZigZag indicator (two timeframes), and MACD indicator.

I've tested this expert advisor on the MT4 trading terminal using a demo account to evaluate its performance. As you can see, the expert advisor has opened orders according to the FiboPivotCandleBar for the MT4 indicator signal, which indicates that it is functioning well.

Final Words

We hope that this article and the MQL5 Multi-Currency Expert Advisor program will be useful for traders in learning and generating new ideas, which can ultimately make money from forex trading.

Please download the Expert Advisor: ExpFPCB-MT4 and Indicator: FiboPivotCandleBar

See you in the next article on Expert Advisor programs or indicators for MetaTrader 4 and MetaTrader 5.

If you have any ideas for developing this EA program, please leave your comments below this article.

Thanks for reading this article.

Read more..


//+------------------------------------------------------------------+
//|                                                  ExpFPCB-MT4.mq4 |
//|        Copyright 2022, Roberto Jacobs (3rjfx) ~ Date: 2022-09-22 |
//|                              https://www.mql5.com/en/users/3rjfx |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, Roberto Jacobs (3rjfx) ~ Date: 2022-09-24"
#property link      "https://www.mql5.com/en/users/3rjfx"
#property version   "1.00"
#property strict
#property description "The Expert @ExpFPCB-MT4 is the Automated Trading Forex Expert Advisor for MetaTrader 4."
#property description "version: 1.00 ~ Last update: 2022/09/24 @ 21:25 (PM) WIT (West Indonesia Time)"
#property description "WARNING:"
#property description "In any case the author is not liable for any damage or loss whatsever."
#property description "Sometimes high profits can be disrupted by a row of losses."
#property description "In the Forex online trading, it is impossible to always profit."
//#property icon "\\Images\\@ExpFPCB-MT4.ico";
//---------------------//
#include <MovingAverages.mqh>
#include <stderror.mqh> 
#include <stdlib.mqh>
//--
enum YN
 {
   No,
   Yes
 };
//--
enum mmt
 {
   FixedLot,   // Manual Lot
   AutoLot     // Automatic Lot
   
 };
//--
//---
input string           grs0 = "=== Global Strategy EA Parameters ==="; // Global Strategy EA Parameter
input ENUM_TIMEFRAMES  ExTF = PERIOD_H1;      // Select Expert TimeFrame, default PERIOD_H1
input YN            SrictTF = Yes;            // Strict to Change TimeFrame (Yes) or (No)
//---
input string           grs1 = "=== Money Management Lot Size Parameters ==="; // Money Management Lot Size Parameter
input mmt             mmlot = AutoLot;        // Money Management Type
input double           Risk = 5.0;            // Percent Equity Risk to Trade (Min=1.0% / Max=50.0%)
input double           Lots = 0.01;           // If Money Management Type FixedLot, input Fixed Lot Size
//---
input string           grs2 = "=== Close Order Option ==="; // Close Order Option
input YN      Close_by_Opps = Yes;            // Close Trade By Opposite Signal (Yes) or (No)
input YN             CSexit = Yes;            // Use Close In Signal Exit (Yes) or (No)
//---
input string           grs3 = "=== Stop Loss & Take Profit Parameters ==="; // Stop Loss  && Take Profit Parameter
input YN             Use_SL = No;             // Use Order SL (Yes) or (No)
input YN             Use_TP = No;             // Use Order TP (Yes) or (No)
//---
input string           grs4 = "=== Trailing Stop Loss / Take Profit Parameters ==="; // Trailing SL / TP Parameter
input YN          use_trail = Yes;            // Use Trailing Stop / Trailing Profit (Yes) or (No)
input int            trstrt = 1;              // Input Start value for Trailing Stop in Pips
input int            trstop = 6;              // Input Trailing Stop value in Pips
//---
input string           grs5 = "=== Others Expert Advisor Parameters ==="; // Others EA Parameter
input YN             alerts = Yes;            // Display Alerts on Chart (Yes) or (No)
input YN      UseEmailAlert = No;             // Email Alert (Yes) or (No)
input YN      UseSendnotify = No;             // Send Notification (Yes) or (No)
input YN       Usechartcomm = Yes;            // Display Setting on Chart (Yes) or (No)
input int           magicEA = 20241202;        // Expert ID (Magic Number)
//---
//---------//
//+------------------------------------------------------------------+
//| Class for working Expert Advisor                                 |
//+------------------------------------------------------------------+
class EXP 
  {
//---
    private:
    //---
    //--
    int           slip,bartotal;
    int           ldig,checkacc,cdb,cds;
    //--
    double        mSL,mTP,mPft;
    double        pip,xpip,trs;
    double        profitb,profits,floatprofit;
    //--
    double        OPEN[],HIGH[],LOW[],CLOSE[];
    double        trval,trstart,trstoptp,aapct;
    double        PvtS,POpen,PLow1,PHigh1,PClose1;
    //--
    bool          posBUY,posSELL;
    //--
    string        expname,
                  exsymbol,
                  trade_mode;
    //-- 
    long          chart_id;
    ENUM_TIMEFRAMES BnC;
    //------------
     
    //------------
    int           LotsDigit(void);
    int           DirectionMove(ENUM_TIMEFRAMES xtf,int shift);
    int           FiboPivotCB(void);
    int           AllowOpen(void);
    int           SignalCondition(void);
    //--
    string        TF2Str(int period);
    string        GetCommentForOrder(void)                  { return(expname); }    
    string        ReturnsOrderType(ENUM_ORDER_TYPE ordtype);
    string        AccountMode(void);
    //--
    double        NonZeroDiv(double val1,double val2);
    double        MLots(void);
    //--   
    void          CopyPrices(void);
    void          RefreshPrice(string symbx,ENUM_TIMEFRAMES xtf,int bars);
    //--
    bool          ModifyStopTP(double mStop,double mProfit) { return(OrderModify(OrderTicket(),OrderOpenPrice(),mStop,mProfit,0,CLR_NONE)); }
    bool          SameAs(double v1,double v2)               { if((double)v1==(double)v2) return(true); return(false); }
    bool          CloseAllOrder(void);
    //------------

    public:
    //---
    //--
    int           utr,ALO,cB,cS,checktml;
    int           oBm,oSm,hBm,hSm,tto;
    //--
    bool          IfTradeAllowed;
    //--
    datetime      PbarB,TbarB,PbarS,TbarS;
    //------------
     
    //------------
    void          FPCB_Config(void);
    void          GetOpenPosition(void);
    void          CheckOpen(void);
    void          CheckClose(void);
    void          TrailingPositionsBuy(void);
    void          TrailingPositionsSell(void);
    void          CloseBuyPositions(void);
    void          CloseSellPositions(void);
    void          Do_Alerts(string msgText);
    void          ChartComm(void);
    void          SignalExit(void);
    //--
    bool          takeBuyPositions(void);
    bool          takeSellPositions(void);
    bool          OpenBuy(void);
    bool          OpenSell(void);
    bool          CloseAllOrdersProfit(void);
    bool          IFNewBarsB(string symb);
    bool          IFNewBarsS(string symb);
    //--
    string        getUninitReasonText(int reasonCode);
    //--
    //------------
//---
  }; //-end class fxt
//---------//
 
EXP fx;

//-------//

void EXP::FPCB_Config(void)
  {
//---
   expname="@ExpFPCB-MT4";
   exsymbol=Symbol();
   //--
   slip=20;
   checktml=0;
   AccountMode();
   utr=use_trail;
   BnC=ExTF; 
   bartotal=108;
   chart_id=ChartID();
   ALO=(int)AccountInfoInteger(ACCOUNT_LIMIT_ORDERS);
   //--
   //-- Checking the Digits Point
   slip=20;
   PbarB=iTime(Symbol(),BnC,1);
   PbarS=iTime(Symbol(),BnC,1);
   double point=SymbolInfoDouble(Symbol(),SYMBOL_POINT);
   mPft=0.5;
   //--
   if(exsymbol=="XAGUSD")
     {
       xpip=4; 
       pip=point*xpip;
       if(Use_SL==Yes) mSL=100*point;
       else mSL=0.0;
       if(Use_TP==Yes) mTP=50*point;
       else mTP=0.0;
       //--
       trstart=NormalizeDouble(trstrt*pip,Digits());
       trstoptp=NormalizeDouble(trstop*pip,Digits());
       trval=NormalizeDouble(trstart+trstoptp,Digits());
     }
   if(exsymbol=="XAUUSD")
     {
       xpip=10; 
       pip=point*xpip;
       if(Use_SL==Yes) mSL=250*point;
       else mSL=0.0;
       if(Use_TP==Yes) mTP=50*point;
       else mTP=0.0;
       //--
       trstart=NormalizeDouble(trstrt*pip,Digits());
       trstoptp=NormalizeDouble(trstop*pip,Digits());
       trval=NormalizeDouble(trstart+trstoptp,Digits());
     }
   if(exsymbol=="XBRUSD")
     {
       xpip=10; 
       pip=point*xpip;
       if(Use_SL==Yes) mSL=250*point;
       else mSL=0.0;
       if(Use_TP==Yes) mTP=50*point;
       else mTP=0.0;
       //--
       trstart=NormalizeDouble(trstrt*pip,Digits());
       trstoptp=NormalizeDouble(trstop*pip,Digits());
       trval=NormalizeDouble(trstart+trstoptp,Digits());
     }
   if(exsymbol=="XTIUSD")
     {
       xpip=10; 
       pip=point*xpip;
       if(Use_SL==Yes) mSL=250*point;
       else mSL=0.0;
       if(Use_TP==Yes) mTP=50*point;
       else mTP=0.0;
       //--
       trstart=NormalizeDouble(trstrt*pip,Digits());
       trstoptp=NormalizeDouble(trstop*pip,Digits());
       trval=NormalizeDouble(trstart+trstoptp,Digits());
     }
   else
     {
       xpip=10; 
       pip=point*xpip;
       if(Use_SL==Yes) mSL=25*pip;
       else mSL=0.0;
       if(Use_TP==Yes) mTP=5*pip;
       else mTP=0.0;
       //--
       trstart=NormalizeDouble(trstrt*pip,Digits());
       trstoptp=NormalizeDouble(trstop*pip,Digits());
       trval=NormalizeDouble(trstart+trstoptp,Digits());
     }
   //--
   IfTradeAllowed=IsTradeAllowed();
   CopyPrices();
   //--
   return;
//---
  } //-end FPCB_Config()
//---------//

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit(void)
  {
//----
   Comment("");
   //--
   if(SrictTF==Yes)
     {
       if(!ChartSetSymbolPeriod(ChartID(),Symbol(),ExTF))
         {ChartSetSymbolPeriod(ChartID(),Symbol(),ExTF);}
     }
   //--
   fx.FPCB_Config();
   //--
//--- initialization done
   return(INIT_SUCCEEDED);
  }
//---------//
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   Comment("");
   //--
   PrintFormat("%s: Deinitialization reason code=%d",__FUNCTION__,reason);
   Print(fx.getUninitReasonText(reason));
   //--
   return;
  } //-end OnDeinit()
//---------//
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick(void)
  {  
//---
   //Check Trading Terminal
   if(!fx.IfTradeAllowed && fx.checktml==0)
     {
       fx.Do_Alerts("Trading at "+Symbol()+" are NOT Allowed by Setting.");
       fx.checktml=1;
       return;
     }
   //--
   RefreshRates();
   fx.CheckOpen();
   if(fx.tto==0 && fx.hBm+fx.hSm>0) fx.CheckClose();
   //--
   if(Usechartcomm==Yes) fx.ChartComm();
   //--
   fx.GetOpenPosition();
   //Buy Condition
   if(fx.takeBuyPositions())
     {
       //--
       fx.CheckOpen();
       //--
       if(fx.oBm==0 && fx.IFNewBarsB(Symbol())) {fx.cB=1; fx.OpenBuy(); fx.PbarB=fx.TbarB;}
       else if(fx.oBm==0 && fx.oSm>0) {fx.cB=2; fx.OpenBuy(); fx.PbarB=fx.TbarB;}
       fx.CheckOpen();
       if(fx.oBm>0 && Close_by_Opps==Yes && fx.oSm>0) {fx.CloseSellPositions(); fx.PbarB=fx.TbarB;}
     }
   //--
   //Sell Condition
   if(fx.takeSellPositions())
     {
       //--
       fx.CheckOpen();
       //--
       if(fx.oSm==0 && fx.IFNewBarsS(Symbol())) {fx.cS=1; fx.OpenSell(); fx.PbarS=fx.TbarS;}
       else if(fx.oSm==0 && fx.oBm>0) {fx.cS=2; fx.OpenSell(); fx.PbarS=fx.TbarS;}
       fx.CheckOpen();
       if(fx.oSm>0 && Close_by_Opps==Yes && fx.oBm>0) {fx.CloseBuyPositions(); fx.PbarS=fx.TbarS;}
     }
   //--
   if(CSexit==Yes) fx.SignalExit();
   //--
   if(OrdersTotal()>=fx.ALO) fx.CloseAllOrdersProfit();
   //---
   //Trailing Stop / Take Profit Position
   if(fx.utr==Yes)
     {
       fx.CheckOpen();
       if(fx.oBm>0) fx.TrailingPositionsBuy();
       if(fx.oSm>0) fx.TrailingPositionsSell();
     }
   //--
   return;
//---
  } //-end OnTick()
//---------//

bool EXP::IFNewBarsB(string symb) // New bar check
  {
//---
    bool Nb=false;
    //--
    TbarB=iTime(symb,BnC,0);
    if(TbarB!=PbarB) Nb=true;
    //--
    return(Nb);
//---
  } //-end IFNewBarsB()
//---------//

bool EXP::IFNewBarsS(string symb) // New bar check
  {
//---
    bool Nb=false;
    //--
    TbarS=iTime(symb,BnC,0);
    if(TbarS!=PbarS) Nb=true;
    //--
    return(Nb);
//---
  } //-end IFNewBarsS()
//---------//

void EXP::RefreshPrice(string symbx,ENUM_TIMEFRAMES xtf,int bar)
  {
//---
    MqlRates parray[]; 
    ArraySetAsSeries(parray,true); 
    int copied=CopyRates(symbx,xtf,0,bar,parray);
    //--
    return;
//---
  } //-end RefreshPrice()
//---------//

void EXP::CopyPrices(void) // Copy Price Buffres
  {
//---
    ArrayResize(OPEN,bartotal,bartotal);
    ArrayResize(HIGH,bartotal,bartotal);
    ArrayResize(LOW,bartotal,bartotal);
    ArrayResize(CLOSE,bartotal,bartotal);
    //--
    ArraySetAsSeries(OPEN,true);
    ArraySetAsSeries(HIGH,true);
    ArraySetAsSeries(LOW,true);
    ArraySetAsSeries(CLOSE,true);
    //--
    RefreshRates();
    //--
    RefreshPrice(Symbol(),BnC,bartotal);
    int co=CopyOpen(Symbol(),BnC,0,bartotal,OPEN);
    int ch=CopyHigh(Symbol(),BnC,0,bartotal,HIGH);
    int cl=CopyLow(Symbol(),BnC,0,bartotal,LOW);
    int cc=CopyClose(Symbol(),BnC,0,bartotal,CLOSE);
    //--
    return;
//---
  } //-end CopyPrices()
//---------//

string EXP::ReturnsOrderType(ENUM_ORDER_TYPE ordtype)
  { 
   string str_type;
   switch(ordtype) 
     { 
      case 0: str_type="BUY";        break;
      case 1: str_type="SELL";       break; 
      case 2: str_type="BUY Limit";  break; 
      case 3: str_type="SELL Limit"; break; 
      case 4: str_type="BUY STOP";   break; 
      case 5: str_type="SELL STOP";  break;
     }
   return(str_type);
//----
  } //-end ReturnsOrderType()
//---------//

void EXP::CheckOpen(void) //-- function: CheckOpenTrade.
  {
//---
    oBm=0;
    oSm=0;
    profitb=0.0;
    profits=0.0;
    int totalorder=OrdersTotal();
    //--
    for(int opn=0; opn<totalorder && !IsStopped(); opn++)
      {
        if(OrderSelect(opn,SELECT_BY_POS,MODE_TRADES))
          {
            if(OrderSymbol()==Symbol() && OrderMagicNumber()==magicEA)
              {
                //--
                if(OrderType()==OP_BUY)  
                  {
                    oBm++; 
                    hBm++;
                    profitb=OrderProfit()+OrderCommission()+OrderSwap();                
                  }
                if(OrderType()==OP_SELL) 
                  {
                    oSm++; 
                    hSm++;
                    profits=OrderProfit()+OrderCommission()+OrderSwap();
                  }
                //--
                floatprofit=profitb+profits;
              }
            //--
          }
      }
    //--
    tto=oBm+oSm;
    //---
    return;
//---
  } //-end CheckOpen()
//---------//
  
int EXP::DirectionMove(ENUM_TIMEFRAMES xtf,int shift) // Bar Direction 
  {
//---
    int ret=0;
    int rise=1,
        down=-1;
    int br=shift+1;
    RefreshPrice(Symbol(),xtf,br);
    //--
    double diff=iClose(Symbol(),xtf,shift)-iOpen(Symbol(),xtf,shift);
    if( diff>0.0) ret=rise;
    if (diff<0.0) ret=down;
    //--
    return(ret);
//---
  } //-end DirectionMove()
//---------//

int EXP::AllowOpen(void)
  {
//---
    int res=0;
    int rise=1,
        down=-1;
    //--
    int MAWper02=2;
    double MAFast[];
    //--
    ArrayResize(MAFast,bartotal,bartotal);
    ArraySetAsSeries(MAFast,true);
    //--
    CopyPrices();
    //--
    for(int x=bartotal-1; x>=0; x--)
      MAFast[x]=iMA(Symbol(),BnC,MAWper02,0,MODE_LWMA,PRICE_WEIGHTED,x);
    //--
    bool OpenUp=(OPEN[0]<MAFast[0]);
    bool OpenDn=(OPEN[0]>MAFast[0]);
    //--
    if(OpenUp) res=rise;
    if(OpenDn) res=down;
    //--
    //Print(Symbol()+" : AllowOpen res = "+string(res));
    //--
    return(res);
//---
  } //-end AllowOpen()
//---------//

int EXP::FiboPivotCB(void) // Signal BUY / SELL Indicator FiboPivotCandleBar
  {
//---
    int res=0;
    int rise=1,
        down=-1;
    //--
    int zzh1=0;
    int zzl1=0;
    int zhm1=0;
    int zlm1=0;
    bool ArrUp=false;
    bool ArrDn=false;
    bool opsup=false;
    bool opsdn=false;
    bool opsnt=false;
    //--   
    ENUM_TIMEFRAMES
       cprz=PERIOD_M15,
       prhh=PERIOD_M30,
       prh1=PERIOD_H1;
    ENUM_MA_METHOD mmeth1=MODE_EMA;
    ENUM_MA_METHOD mmeth2=MODE_SMA;
    ENUM_APPLIED_PRICE aprice=PRICE_MEDIAN;
    //--
    double ema02m[];
    double sma20m[];
    double maon10[];
    double maon62[];
    //--
    ArrayResize(ema02m,bartotal);
    ArrayResize(sma20m,bartotal);
    ArrayResize(maon10,bartotal);
    ArrayResize(maon62,bartotal);
    ArraySetAsSeries(ema02m,true);
    ArraySetAsSeries(sma20m,true);
    ArraySetAsSeries(maon10,true);
    ArraySetAsSeries(maon62,true);
    //--
    RefreshPrice(Symbol(),cprz,bartotal);
    //--
    for(int j=bartotal-1; j>=0; j--)
      {ema02m[j]=iMA(Symbol(),cprz,2,0,mmeth1,aprice,j);}
    for(int k=bartotal-1; k>=0; k--)
      {sma20m[k]=iMA(Symbol(),cprz,20,0,mmeth2,aprice,k);}
    //--
    SimpleMAOnBuffer(bartotal,0,0,10,sma20m,maon10);
    SimpleMAOnBuffer(bartotal,0,0,62,sma20m,maon62);
    //--
    double ma10620=maon10[0]-maon62[0];
    double ma10621=maon10[1]-maon62[1];
    double ma20100=sma20m[0]-maon10[0];
    double ma20101=sma20m[1]-maon10[1];
    //--
    bool ma5xupn=(ema02m[0]>ema02m[1])&&(sma20m[0]>sma20m[1])&&(ma10620>=ma10621)&&((maon10[2]<maon62[2])&&(maon10[0]>maon62[0]));
    bool ma5xupc=(ema02m[0]>ema02m[1])&&(sma20m[0]>sma20m[1])&&(ma10620>=ma10621)&&(maon10[0]>maon62[0])&&(maon10[0]>maon10[1]);
    bool ma5xupb=(ema02m[0]>ema02m[1])&&(sma20m[0]>sma20m[1])&&(ma20100>ma20101)&&(maon62[0]>maon62[1])&&(sma20m[0]>maon10[0]);
    bool ma5xdnn=(ema02m[0]<ema02m[1])&&(sma20m[0]<sma20m[1])&&(ma10620<=ma10621)&&((maon10[2]>maon62[2])&&(maon10[0]<maon62[0]));
    bool ma5xdnc=(ema02m[0]<ema02m[1])&&(sma20m[0]<sma20m[1])&&(ma10620<=ma10621)&&(maon10[0]<maon62[0])&&(maon10[0]<maon10[1]);
    bool ma5xdna=(ema02m[0]<ema02m[1])&&(sma20m[0]<sma20m[1])&&(ma20100<ma20101)&&(maon62[0]<maon62[1])&&(sma20m[0]<maon10[0]);
    //--
    RefreshPrice(Symbol(),prhh,bartotal);
    for(int zz=bartotal-1; zz>=0; zz--) //- for(zz)
      {
        if(iHigh(Symbol(),prhh,zz)==iCustom(Symbol(),prhh,"ZigZag",12,5,3,1,1,zz))
          {zhm1=zz;}
        if(iLow(Symbol(),prhh,zz)==iCustom(Symbol(),prhh,"ZigZag",12,5,3,1,2,zz))
          {zlm1=zz;}
      } //-end for(zz m30)
    //--
    RefreshPrice(Symbol(),prh1,bartotal);
    for(int zz=bartotal-1; zz>=0; zz--) //- for(zz)
      {
        if(iHigh(Symbol(),prh1,zz)==iCustom(Symbol(),prh1,"ZigZag",12,5,3,1,zz))
          {zzh1=zz;}
        if(iLow(Symbol(),prh1,zz)==iCustom(Symbol(),prh1,"ZigZag",12,5,3,1,2,zz))
          {zzl1=zz;}
      } //-end for(zz h1)
    //--
    double macd0=iMACD(Symbol(),prh1,12,26,9,0,MODE_MAIN,0)-iMACD(Symbol(),prh1,12,26,9,0,MODE_SIGNAL,0);
    double macd1=iMACD(Symbol(),prh1,12,26,9,0,MODE_MAIN,1)-iMACD(Symbol(),prh1,12,26,9,0,MODE_SIGNAL,1);
    double mcdm0=iMACD(Symbol(),prh1,12,26,9,0,MODE_MAIN,0);
    double mcdm1=iMACD(Symbol(),prh1,12,26,9,0,MODE_MAIN,1);
    double mcds0=iMACD(Symbol(),prh1,12,26,9,0,MODE_SIGNAL,0);
    double mcds1=iMACD(Symbol(),prh1,12,26,9,0,MODE_SIGNAL,1);
    //--
    if((((zzl1<zzh1)&&(zzl1>0)&&(zzl1<4)&&(zlm1<zhm1)))||((macd0>macd1)&&(mcdm0>mcdm1))) {ArrUp=true;}
    //--
    if((((zzl1>zzh1)&&(zzh1>0)&&(zzh1<4)&&(zlm1>zhm1)))||((macd0<macd1)&&(mcdm0<mcdm1))) {ArrDn=true;}
    //--
    if(((ArrUp==true)&&(zzl1>4))||((mcdm0<mcdm1)&&(macd0<macd1))) {ArrDn=true; ArrUp=false;}
    if(((ArrDn==true)&&(zzh1>4))||((mcdm0>mcdm1)&&(macd0>macd1))) {ArrUp=true; ArrDn=false;}
    if((mcdm0>=mcdm1)&&(mcdm0>mcds0)&&(mcds0>mcds1)) {ArrUp=true; ArrDn=false;}
    if((mcdm0<=mcdm1)&&(mcdm0<mcds0)&&(mcds0<mcds1)) {ArrDn=true; ArrUp=false;}
    if(ma5xupn||ma5xupc||ma5xupb) {ArrUp=true; ArrDn=false;}
    if(ma5xdnn||ma5xdnc||ma5xdna) {ArrDn=true; ArrUp=false;}
    //--
    double fpCls0=(iHigh(Symbol(),prh1,0)+iLow(Symbol(),prh1,0)+iClose(Symbol(),prh1,0)+iClose(Symbol(),prh1,0))/4;
    double fpCls1=(iHigh(Symbol(),prh1,1)+iLow(Symbol(),prh1,1)+iClose(Symbol(),prh1,1)+iClose(Symbol(),prh1,1))/4;
    double hlcc0=fpCls0-iMA(Symbol(),prh1,20,0,mmeth2,aprice,0);
    double hlcc1=fpCls1-iMA(Symbol(),prh1,20,0,mmeth2,aprice,1);
    //--
    if((ArrUp==true)&&(hlcc0>hlcc1)) {opsup=true; opsdn=false; opsnt=false;}
    //--
    if((ArrDn==true)&&(hlcc0<hlcc1)) {opsdn=true; opsup=false; opsnt=false;}
    //--
    if((!opsup)&&(!opsdn)) {opsnt=true; opsup=false; opsdn=false;}
    //--
    //---
    if(ArrUp && opsup) res=rise;
    //--
    if(ArrDn && opsdn) res=down;
    //--
    //---
    return(res);
//---
  } //-end FiboPivotCB()
//---------//

int EXP::SignalCondition(void) 
  {
//---
    int rise=1,
        down=-1;
    int InTRise=3;
    int InTDown=-3;
    int cond=0;
    //--   
    CheckOpen();
    int dmove=DirectionMove(BnC,0);
    int alopn=AllowOpen();
    int fbcb3=FiboPivotCB();
    //--
    int TrendIndi=fbcb3+dmove+alopn;
    //--
    if(TrendIndi==InTRise) {cond=rise; cdb=11;}
    if(TrendIndi==InTDown) {cond=down; cds=11;}
    if(oSm>0 && TrendIndi==InTRise) {cond=rise; cdb=12;}
    if(oBm>0 && TrendIndi==InTDown) {cond=down; cds=12;}
    //--
    return(cond);
//---
  } //-end SignalCondition()
//---------//

void EXP::GetOpenPosition(void) // Signal Open Position 
  {
//---
    ResetLastError();
    RefreshRates();
    //--
    posBUY=false;
    posSELL=false;
    //--
    int beli=1,
        jual=-1;
    int position=SignalCondition();
    //Print("position = "+string(position));
    //--
    if(SameAs(position,beli)) posBUY=true; 
    if(SameAs(position,jual)) posSELL=true;
    //--
    return;
//---
  } //-end GetOpenPosition()
//---------//

void EXP::SignalExit(void) 
  {
//---
    int rise=1,
        down=-1;
    int nosg=0;
    //--
    CheckOpen();
    if(tto==0) return;
    //--
    int dmove=DirectionMove(BnC,0);
    int fbcb3=FiboPivotCB();
    int TrendIndi=fbcb3;
    //--
    if((dmove==down && TrendIndi==nosg) && (oBm>0 && profitb>0.03))
      {CloseBuyPositions();  Print(Symbol()+": Signal exit BUY");}
    if((dmove==rise && TrendIndi==nosg) && (oSm>0 && profits>0.03))
      {CloseSellPositions(); Print(Symbol()+": Signal exit SELL");}
    //--
    return;
//---
  } //-end SignalExit()
//---------//

//+------------------------------------------------------------------+
//| Condition for Open BUY Positions                                 |
//+------------------------------------------------------------------+
bool EXP::takeBuyPositions(void) 
  {
//---
   if(posBUY) return(true);
   //--
   return(false);
//---
  } //-end takeBuyPositions()
//---------//
//+------------------------------------------------------------------+
//| Condition for Open SELL Positions                                |
//+------------------------------------------------------------------+
bool EXP::takeSellPositions(void) 
  {
//---
   if(posSELL) return(true);
   //--
   return(false);
//---
  } //-end takeSellPositions()
//---------//

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool EXP::OpenBuy(void) 
  {
//---
    ResetLastError();
    //--
    int error=0;
    int tiket=0;
    color buyclr=clrBlue;
    double ldStop=0;
    double ldTake=0;
    RefreshRates();
    double ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK); 
    double bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);
    //--
    ldStop=mSL==0.0 ? 0.0 : NormalizeDouble(bid-mSL,_Digits);
    ldTake=mTP==0.0 ? 0.0 : NormalizeDouble(ask+mTP,_Digits);
    //--
    CheckOpen();
    double ldLot=MLots();
    string ldComm=GetCommentForOrder()+"#"+TF2Str(BnC)+"#"+string(cdb)+"@Buy"+"#"+string(cB);
    bool buyopen=tiket=OrderSend(Symbol(),OP_BUY,ldLot,ask,slip,ldStop,ldTake,ldComm,magicEA,0,buyclr); 
    if(!buyopen)
      {
        error=GetLastError();
        if(error!=ERR_NO_ERROR || error==148)
          {
            Do_Alerts("Open "+ReturnsOrderType(OP_BUY)+" order for "+Symbol()+" failed. Error: "+ErrorDescription(error));
            return(buyopen);
          }
      }
    else
    if(tiket>0)
      {
        string bsopen="OrderSend "+ReturnsOrderType(OP_BUY)+" Order for "+Symbol()+" ticket: "+string(tiket)+" successfully..!";
        Do_Alerts(bsopen);
        PbarB=iTime(Symbol(),BnC,0);
      }
    //--
    return(buyopen);
    //--
//---
  } //-end OpenBuy
//---------//

bool EXP::OpenSell(void) 
  {
//---
    ResetLastError();
    //--
    int error=0;
    int tiket=0;
    color selclr=clrRed;
    double sdStop=0;
    double sdTake=0;
    RefreshRates();
    double ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK); 
    double bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);
    //--
    sdStop=mSL==0.0 ? 0.0 : NormalizeDouble(ask+mSL,_Digits);
    sdTake=mTP==0.0 ? 0.0 : NormalizeDouble(bid-mTP,_Digits);
    //--
    CheckOpen();
    double sdLot=MLots();
    string sdComm=GetCommentForOrder()+"#"+TF2Str(BnC)+"#"+string(cds)+"@Sell"+"#"+string(cS);
    bool selopen=tiket=OrderSend(Symbol(),OP_SELL,sdLot,bid,slip,sdStop,sdTake,sdComm,magicEA,0,selclr);
    if(!selopen)
      {
        error=GetLastError();
        if(error!=ERR_NO_ERROR || error==148)
          {
            Do_Alerts("Open "+ReturnsOrderType(OP_SELL)+" order for "+Symbol()+" failed. Error: "+ErrorDescription(error));
            return(selopen);
          }
      }
    else
    if(tiket>0)
      {
        string bsopen="OrderSend "+ReturnsOrderType(OP_SELL)+" Order for "+Symbol()+" ticket: "+string(tiket)+"#"+" successfully..!";
        Do_Alerts(bsopen);
        PbarS=iTime(Symbol(),BnC,0);
      }
    //--
    return(selopen);
    //--
//---
  } //-end OpenSell
//---------//

void EXP::TrailingPositionsBuy(void) 
  {
//---
   RefreshRates();
   for(int i=0; i<OrdersTotal(); i++) 
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) 
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==magicEA) 
           {
            if(OrderType()==OP_BUY) 
              {
                bool modtp=((OrderTakeProfit()-OrderClosePrice()<trval)||(OrderTakeProfit()==0.0));
                double mtp=(modtp) ? NormalizeDouble(OrderClosePrice()+trval,Digits()) : OrderTakeProfit(); 
                double pospr=NormalizeDouble(OrderOpenPrice()+trval,Digits());
                double postr=NormalizeDouble(OrderClosePrice()-trstoptp,Digits());
                bool modsl=(OrderClosePrice()>pospr) && (OrderStopLoss()==0.0||OrderStopLoss()<postr);
                if(modsl)
                  {
                    bool modslB=ModifyStopTP(postr,mtp);
                  }
              }
           }
        }
     }
    //--
    return;
//---
  } //-end TrailingPositionsBuy
//---------//

void EXP::TrailingPositionsSell(void) 
  {
//---
   RefreshRates();
   for(int i=0; i<OrdersTotal(); i++) 
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) 
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==magicEA) 
           {
            if(OrderType()==OP_SELL) 
              {
                bool modtp=((OrderClosePrice()-OrderTakeProfit()<trval)||(OrderTakeProfit()==0.0));
                double mtp=(modtp) ? NormalizeDouble(OrderClosePrice()-trval,Digits()) : OrderTakeProfit(); 
                double pospr=NormalizeDouble(OrderOpenPrice()-trval,Digits());
                double postr=NormalizeDouble(OrderClosePrice()+trstoptp,Digits());
                bool modsl=(OrderClosePrice()<pospr) && (OrderStopLoss()==0.0||OrderStopLoss()>postr);
                if(modsl)
                  {
                    bool modslS=ModifyStopTP(postr,mtp);
                  }
              }
           }
        }
     }
    //--
    return;
//---
  } //-end TrailingPositionsSell
//---------//

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void EXP::CloseBuyPositions(void)
  {
//---
   int error=0;
   color clbuy=clrAqua;
   bool clsbuy=false;
   RefreshRates();
   for(int i=0; i<OrdersTotal(); i++) 
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) 
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==magicEA) 
           {
             if(OrderType()==OP_BUY) clsbuy=OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),slip,clbuy);
             if(clsbuy) PbarB=iTime(OrderSymbol(),BnC,0);
             if(!clsbuy)
               {
                 error=GetLastError();
                 if(error!=ERR_NO_ERROR)
                   {
                     Do_Alerts("Close BUY order for "+Symbol()+" failed. Error: "+ErrorDescription(error));
                     break;
                   }
               }
           }
        }
     }
    //--
    return;
//---
  } //-end CloseBuyPositions
//---------//
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void EXP::CloseSellPositions(void)
  {
//---
   int error=0;
   color clsel=clrMagenta;
   bool clssel=false;
   RefreshRates();
   for(int i=0; i<OrdersTotal(); i++) 
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) 
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==magicEA) 
           {
             if(OrderType()==OP_SELL) clssel=OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),slip,clsel);
             if(clssel) PbarS=iTime(OrderSymbol(),BnC,0);
             if(!clssel)
               {
                 error=GetLastError();
                 if(error!=ERR_NO_ERROR)
                   {
                     Do_Alerts("Close SELL order for "+Symbol()+" failed. Error: "+ErrorDescription(error));
                     break;
                   }
               }
           }
        }
     }
    //--
    return;
//---
  } //-end CloseSellPositions
//---------//

bool EXP::CloseAllOrdersProfit(void) //-- function: close all order in profit
   {
//----
      int error=0;
      bool orclose=false;
      int ttlorder=OrdersTotal()-1;
      RefreshRates();
      //--
      for(int ip=ttlorder; ip>=0; ip--)
         {
           if(OrderSelect(ip,SELECT_BY_POS,MODE_TRADES)==true)
             {
               if(OrderType()<2)
                 {
                   double inprofit=OrderProfit()+OrderSwap()+OrderCommission();
                   if(inprofit>0.02)
                      orclose=OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),slip,clrSnow);
                   if(orclose)
                     {
                       if(OrderType()==OP_BUY)  PbarB=iTime(OrderSymbol(),BnC,0);
                       if(OrderType()==OP_SELL) PbarS=iTime(OrderSymbol(),BnC,0);
                     }
                 }
             }
         }
     //--
     return(orclose);
//----
   } //-end CloseAllOrdersProfit()
//---------//

bool EXP::CloseAllOrder(void) //-- function: close all order
   {
//----
      int error=0;
      bool orclose=false;
      int ttlorder=OrdersTotal()-1;
      RefreshRates();
      //--
      for(int ip=ttlorder; ip>=0; ip--)
         {
           if(OrderSelect(ip,SELECT_BY_POS,MODE_TRADES)==true)
             {
               if(OrderType()<2)
                 {
                   orclose=OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),slip,clrSnow);
                   if(orclose)
                     {
                       if(OrderType()==OP_BUY)  PbarB=iTime(OrderSymbol(),BnC,0);
                       if(OrderType()==OP_SELL) PbarS=iTime(OrderSymbol(),BnC,0);
                     }
                 }
             }
         }
     //--
     return(orclose);
//----
   } //-end CloseAllOrder()
//---------//

void EXP::CheckClose(void) //-- function: CheckOrderClose.
  {
//----
    //--
    CheckOpen();
    datetime octm;
    int hyst=OrdersHistoryTotal();
    //--
    for(int b=hyst-1; b>=0; b--)
      {
        //--
        if(OrderSelect(b,SELECT_BY_POS,MODE_HISTORY))
          {
            if(OrderSymbol()==Symbol() && OrderMagicNumber()==magicEA)
              {
                //--
                if(OrderType()==OP_BUY)
                  {
                    octm=OrderCloseTime();
                    if(hBm>0 && oBm==0 && octm>0) hBm=0;                            
                  }
                //--
                if(OrderType()==OP_SELL)
                  {
                    octm=OrderCloseTime();
                    if(hSm>0 && oSm==0 && octm>0)  hSm=0;                              
                  }
              }
          }
        //--
      }
   //--
   //---
   return;
//----
  } //-end CheckClose()
//---------//

void EXP::Do_Alerts(string msgText)
  {
//---
    //--
    Print("--- "+Symbol()+": "+msgText+
          "\n--- at: ",TimeToString(TimeCurrent(),TIME_DATE|TIME_MINUTES));
    //--
    if(alerts==Yes)
      {
        Alert("--- "+Symbol()+": "+msgText+
              "--- at: ",TimeToString(TimeCurrent(),TIME_DATE|TIME_MINUTES));
      }
    //--
    if(UseEmailAlert==Yes) 
      SendMail(expname,"--- "+Symbol()+" "+TF2Str(BnC)+": "+msgText+
                       "\n--- at: "+TimeToString(TimeCurrent(),TIME_DATE|TIME_MINUTES));
    //--
    if(UseSendnotify==Yes) 
      SendNotification(expname+"--- "+Symbol()+" "+TF2Str(BnC)+": "+msgText+
                      "\n--- at: "+TimeToString(TimeCurrent(),TIME_DATE|TIME_MINUTES));
    //--
    return;
    //--
//---
  } //-end Do_Alerts()
//---------//

string EXP::TF2Str(int period)
  {
//---
   switch(period)
     {
       //--
       case PERIOD_M1: return("M1");
       case PERIOD_M5: return("M5");
       case PERIOD_M15: return("M15");
       case PERIOD_M30: return("M30");
       case PERIOD_H1: return("H1");
       case PERIOD_H4: return("H4");
       case PERIOD_D1: return("D1");
       case PERIOD_W1: return("W1");
       case PERIOD_MN1: return("MN");
       //--
     }
   return(string(period));
//---
  } //-end TF2Str()
//---------//

string EXP::AccountMode(void)
  {
//--- Demo, contest or real account 
   ENUM_ACCOUNT_TRADE_MODE account_type=(ENUM_ACCOUNT_TRADE_MODE)AccountInfoInteger(ACCOUNT_TRADE_MODE);
   //--- Now transform the value of  the enumeration into an understandable form 
   switch(account_type) 
     { 
      case  ACCOUNT_TRADE_MODE_DEMO: 
         trade_mode="demo"; 
         break; 
      case  ACCOUNT_TRADE_MODE_CONTEST: 
         trade_mode="contest"; 
         break; 
      default: 
         trade_mode="real"; 
         break; 
     } 
   //--
   return(trade_mode);
//---
  } //-end AccountMode
//---------//

double EXP::MLots(void) // function: calculation lots size
  {
//----
   double Lsize=0.0;
   double sym_Lm=0.0;
   string sym_use ="";
   string xcur[]={"EUR","GBP","AUD","NZD","XAU","XAG","XTI","XBR"}; // 7 major pairs vs USD
   int xcar=ArraySize(xcur);
   int pairx=-1;
   //--
   int Cpair = StringFind(Symbol(),"USD",0);
   if(Cpair<0)
     {
       string dpn=StringSubstr(Symbol(),0,3);
       for(int x=0; x<xcar; x++)
         {
           if(dpn==xcur[x]) 
             {
               pairx=x; 
               break;
             }
         }
       if(pairx>=0)
         sym_use=xcur[pairx]+"USD";
       else
         sym_use="USD"+StringSubstr(Symbol(),0,3);
     }
   else
     sym_use=Symbol();
   //--
   int Lpair = StringFind(sym_use,"USD",0);
   double Lmax  = MarketInfo(sym_use,MODE_MAXLOT);
   double Lmin  = MarketInfo(sym_use,MODE_MINLOT);
   double csize = MarketInfo(sym_use,MODE_LOTSIZE);
   RefreshRates();
   double symbid=MarketInfo(sym_use,MODE_BID);
   double sym_coe=0.075;
   double NZ0=NonZeroDiv(AccountFreeMargin()*AccountLeverage(),csize);
   double NZ3=NonZeroDiv(AccountFreeMargin()*AccountLeverage(),symbid);
   //--
   if(Lpair == 0) 
     sym_Lm = fmin(Lmax,NZ0);
   if(Lpair == 3)
     sym_Lm = fmin(Lmax,NonZeroDiv(NZ3,csize));
   //--
   double sym_Lc = NormalizeDouble(sym_coe*sym_Lm,LotsDigit());
   //--
   if(mmlot==AutoLot) 
     { 
       Lsize = NormalizeDouble(AccountEquity()*Risk/102.0/100.0/10/ALO,LotsDigit());
       if(Lsize > sym_Lc) Lsize = sym_Lc;     
     } 
   else {Lsize = Lots;}
   //--
   if(Lsize < Lmin) Lsize = Lmin;
   if(Lsize > Lmax) Lsize = Lmax;
   double lotsize=NormalizeDouble(Lsize,LotsDigit());
   //--
   return(lotsize);
//----
  } //-end MLots()
//---------//

double EXP::NonZeroDiv(double val1,double val2)
  {
//---
   double resval=0;
   if(val1==0 || val2==0) resval=0.00;
   else
   resval=val1/val2;
   //--
   return(resval);
//---
  } //-end NonZeroDiv()
//---------//

int EXP::LotsDigit(void)
  {
//---
   //--
   double lots_step=MarketInfo(Symbol(),MODE_LOTSTEP);
   //--
   if(lots_step==0.01)
      ldig=2;
   //--
   if(lots_step==0.1)
      ldig=1;
   //--
   if(lots_step==1.0)
      ldig=0;
     //---
     return(ldig);
//----
  } //-end LotsDigit()
//---------//

void EXP::ChartComm() // function: write comments on the chart
  {
//---
   string opnsignal=posBUY ? "BUY" : posSELL ? "SELL" : "Not Trade";
   //--
   Comment("\n     :: Server Date Time : ",(string)Year(),".",(string)Month(),".",(string)Day(), "   ",TimeToString(TimeCurrent(),TIME_SECONDS), 
      "\n     ------------------------------------------------------------", 
      "\n      :: Broker             :  ",TerminalCompany(), 
      "\n      :: Acc. Name       :  ",AccountName(), 
      "\n      :: Acc, Number    :  ",(string)AccountNumber(),
      "\n      :: Acc,TradeMode :  ",AccountMode(),
      "\n      :: Acc. Leverage   :  1 : ",(string)AccountLeverage(), 
      "\n      :: Acc. Balance     :  ",DoubleToString(AccountBalance(),2),
      "\n      :: Acc. Equity       :  ",DoubleToString(AccountEquity(),2),
      "\n      :: Timeframe        :  ",TF2Str(BnC),
      "\n      :: Magic Number   :  ",string(magicEA),
      "\n     --------------------------------------------",
      "\n      :: Currency Pair    :  ",Symbol(),
      "\n      :: Current Spread  :  ",IntegerToString(SymbolInfoInteger(Symbol(),SYMBOL_SPREAD),0),
      "\n      :: Signal          : ",opnsignal,
      "\n      :: Position BUY  : ",string(oBm),
      "\n      :: Position SELL : ",string(oSm),
      "\n      :: Current Profit : ",DoubleToString(floatprofit,2));
   //---
   ChartRedraw();
   return;
//----
  } //-end ChartComm()  
//---------//

double NormalizePrice(const double dprice)
  {
//---
    int SymDigits=(int)SymbolInfoInteger(Symbol(),SYMBOL_DIGITS);
    double result=NormalizeDouble(dprice,SymDigits);
    //--
    return(result);
//---
  } //-end NormalizePrice()
//---------//

string EXP::getUninitReasonText(int reasonCode) 
  { 
//---
   string text=""; 
   //--- 
   switch(reasonCode) 
     { 
       case REASON_PROGRAM:
            text="The EA has stopped working calling by remove function."; break;
       case REASON_REMOVE: 
            text="Program "+__FILE__+" was removed from chart"; break;
       case REASON_RECOMPILE:
            text="Program recompiled."; break;    
       case REASON_CHARTCHANGE: 
            text="Symbol or timeframe was changed"; break;
       case REASON_CHARTCLOSE: 
            text="Chart was closed"; break; 
       case REASON_PARAMETERS: 
            text="Input-parameter was changed"; break;            
       case REASON_ACCOUNT: 
            text="Account was changed"; break; 
       case REASON_TEMPLATE: 
            text="New template was applied to chart"; break; 
       case REASON_INITFAILED:
            text="The OnInit() handler returned a non-zero value."; break;
       case REASON_CLOSE: 
            text="Terminal closed."; break;
       default: text="Another reason"; break;
     } 
   //--
   return text;
//---
  } //-end getUninitReasonText()
//---------//
//--------------------------------------------------------------------//

Featured Post

How to create a simple Multi-Currency Expert Advisor using MQL5 with Zigzag and RSI Indicators Signal

Introduction The Expert Advisor discussed in this article is a multi-currency trading robot that uses the Zigzag and RSI indicators. It fol...