Tuesday, May 5, 2026

Author: Roberto Jacobs (3rjfx) | Featured on Forex Home Expert

Introduction

In the dynamic and often volatile world of Forex trading, the ability to identify, follow, and capitalize on market trends is arguably the most critical skill a trader can possess. While manual trading requires constant vigilance, emotional discipline, and hours of chart analysis, automated trading systems have emerged as powerful tools that can execute these strategies with precision and speed.

Among the myriad of solutions available for the MetaTrader 5 (MT5) platform, few are as robust and versatile as the ADX_Trend_MCEA. Developed by Roberto Jacobs, an active MQL5 programmer since 2012, this Expert Advisor (EA) represents a sophisticated approach to multi-currency trading, leveraging the power of the Average Directional Index (ADX) to detect trend strength and direction across multiple asset classes simultaneously.

ADX_Trend_MCEA an illustration of 3 currency pairs
Figure 1: ADX_Trend_MCEA an Illustration of Three Currency Pairs

The ADX_Trend_MCEA is not just another generic trading bot; it is a carefully engineered multi-currency EA designed to trade up to 30 different Forex pairs and metals from a single chart. This capability significantly reduces the computational load on the trader’s terminal while maximizing diversification opportunities. By integrating advanced money management techniques, including a configurable Martingale System, and precise trend detection algorithms, this EA aims to provide a balanced approach to risk and reward. In this comprehensive article, we will delve deep into the architecture, functionality, and strategic advantages of the ADX_Trend_MCEA, exploring how it can serve as a cornerstone in your automated trading portfolio.

1. The Philosophy of Automated Trend Following in Multi-Currency Markets

Trend following is a timeless trading strategy based on the premise that markets which are moving in a certain direction are likely to continue moving in that direction for a period. However, identifying a "true" trend amidst market noise is challenging. This is where the Average Directional Index (ADX) becomes invaluable. The ADX does not indicate the direction of the trend (up or down) but rather its strength. A rising ADX indicates a strengthening trend, while a falling ADX suggests a weakening trend or a ranging market. The ADX_Trend_MCEA utilizes this indicator not in isolation, but in conjunction with price action dynamics to filter out false signals and enter trades only when the momentum is statistically significant.

The core philosophy behind this MT5 trading robot is diversification through automation. Trading a single currency pair exposes the trader to idiosyncratic risks associated with that specific economy or central bank policy. By spreading trades across 30 different pairs—including major pairs like EURUSD and GBPUSD, crosses like EURGBP and AUDJPY, and even precious metals like XAUUSD (Gold) and XAGUSD (Silver)—the EA smooths out the equity curve. When one market is ranging, another might be trending strongly. This 30 Pairs EA capability ensures that the trading system is always exposed to potential opportunities, regardless of the specific geopolitical or economic conditions affecting a single currency.

Furthermore, the EA is designed with flexibility in mind. It recognizes that no two traders have the same risk appetite or trading schedule. Therefore, it includes extensive customization options for trading sessions, allowing users to align their trading activity with specific market overlaps, such as the London-New York session, which typically offers the highest volatility and liquidity. This alignment is crucial for a trend-following system, as trends are more likely to establish and persist during periods of high market participation. By combining the mathematical rigor of the ADX indicator with the logistical efficiency of multi-currency execution, the ADX_Trend_MCEA offers a holistic solution for modern Forex traders seeking to automate their trend-following strategies.

Another critical aspect of this philosophy is the integration of strategic risk management.
Forex Automated Trading systems often fail not because their entry logic is flawed, but because their exit logic or money management is rigid. The ADX_Trend_MCEA addresses this by incorporating dynamic lot sizing, partial close capabilities, and trailing stop mechanisms that adapt to market conditions. This ensures that profits are protected while allowing winning trades to run, a fundamental principle of successful trend following. The system’s ability to manage risk on a per-trade basis, while maintaining a global view of the account’s exposure, makes it a sophisticated tool for both novice and experienced algorithmic traders.

2. Comprehensive Input Properties: Customizing Your Trading Experience

The power of any Expert Advisor lies in its configurability. The ADX_Trend_MCEA offers a rich set of input parameters that allow traders to tailor the system to their specific needs. These inputs are categorized into logical groups, making them easy to navigate and understand. Let’s explore the key sections and their significance.

Input Parameters

 
//---
input group               "=== Global Strategy EA Parameter ==="; // Global Strategy EA Parameter
input TFUSE               tfinuse = TFH4;             // Select Expert TimeFrame, default PERIOD_H4
//---
input group               "=== ADX Indicator Input Properties ===";  // ADX Indicator Input Properties
input int              period_ADX = 14;               // Input Period ADX 
//---
input group               "=== Select Pairs to Trade ===";  // Selected Pairs to trading
input MS                trademode = MP;              // Select Trading Pairs Mode (Multi or Single)
input PairsTrade         usepairs = All30;           // Select Pairs to Use
input string         traderwishes = "eg. eurusd,usdchf"; // If Use Trader Wishes Pairs, input pair name here, separate by comma
//--
input group               "=== Money Management Lot Size Parameter ==="; // Money Management Lot Size Parameter
input mmt                  mmlot = DynamLot;         // Money Management Type
input double                Risk = 5.0;              // Percent Equity Risk per Trade (Min=1.0% / Max=10.0%)
input double                Lots = 0.01;             // Input Manual Lot Size FixedLot
input double             maxmrgn = 80.0;             // Input Maximum Free Margin from Equity to Trade (in Percent)
input YN               UseMartin = Yes;              // Select to use Martingale method (Yes) or (No)
input double              lotmp1 = 2.00;             // If use Martingale Input 2nd Lot (2nd x Lots) Multiplier
input double              lotmp2 = 2.00;             // If use Martingale Input 3rd Lot (3rd x 2nd) Multiplier
//--Trade on Specific Time
input group               "=== Trade on Specific Time ==="; // Trade on Specific Time
input YN           trd_time_zone = Yes;              // Select If You Like to Trade on Specific Time Zone
input tm_zone            session = Cus_Session;      // Select Trading Time Zone
input swhour            stsescuh = hr_00;            // Time Hour to Start Trading Custom Session (0-23)
input inmnt             stsescum = mn_15;            // Time Minute to Start Trading Custom Session (0-55)
input swhour            clsescuh = hr_23;            // Time Hour to Stop Trading Custom Session (0-23)
input inmnt             clsescum = mn_55;            // Time Minute to Stop Trading Custom Session (0-55)
//--Day Trading On/Off
input group               "=== Day Trading On/Off ==="; // Day Trading On/Off
input YN                    ttd0 = No;               // Select Trading on Sunday (Yes) or (No)
input YN                    ttd1 = Yes;              // Select Trading on Monday (Yes) or (No)
input YN                    ttd2 = Yes;              // Select Trading on Tuesday (Yes) or (No)
input YN                    ttd3 = Yes;              // Select Trading on Wednesday (Yes) or (No)
input YN                    ttd4 = Yes;              // Select Trading on Thursday (Yes) or (No)
input YN                    ttd5 = Yes;              // Select Trading on Friday (Yes) or (No)
input YN                    ttd6 = No;               // Select Trading on Saturday (Yes) or (No)
//--Trade & Order management Parameter
input group               "=== Trade & Order management Parameter ==="; // Trade & Order management Parameter
input YN                  use_sl = No;               // Use Order Stop Loss (Yes) or (No)
input YN                  autosl = Yes;              // Use Automatic Calculation Stop Loss (Yes) or (No)
input double               SLval = 30.0;             // If Not Use Automatic SL - Input SL value in Pips
input YN                  use_tp = Yes;              // Use Order Take Profit (Yes) or (No)
input YN                  autotp = Yes;              // Use Automatic Calculation Take Profit (Yes) or (No)
input double               TPval = 60.0;             // If Not Use Automatic TP - Input TP value in Pips
input YN            PartialClose = Yes;              // Use Partial Close Profit (Yes) or (No)
input double        profitinpips = 10.0;             // Input Profit in Pips for Partial Close, default 10 Pips
input double         percentlots = 50.0;             // Percentage Lot Size to Partial Close
input YN              TrailingSL = Yes;              // Use Trailing Stop Loss (Yes) or (No)
input TrType               trlby = byindi;          // Select Trailing Stop Type
input double               TSval = 10.0;             // If Use Trailing Stop by Price Input value in Pips
input double               TSmin = 5.0;              // Minimum Pips to start Trailing Stop
input YN              TrailingTP = Yes;              // Use Trailing Take Profit (Yes) or (No)
input double               TPmin = 25.0;             // Input Trailing Profit Value in Pips
input YN           Close_by_Opps = Yes;              // Close Trade By Opposite Signal (Yes) or (No)
input YN               SaveOnRev = Yes;              // Close Trade and Save profit due to weak signal (Yes) or (No)
input YN              CheckVSLTP = No;              // Check Virtual SL/TP & Close Loss Trade (Yes) or (No)
//--Others Expert Advisor Parameter
input group               "=== Others Expert Advisor Parameter ==="; // Others EA Parameter
input YN                  alerts = Yes;              // Display Alerts / Messages (Yes) or (No)
input YN           UseEmailAlert = No;               // Email Alert (Yes) or (No)
input YN           UseSendnotify = No;               // Send Notification (Yes) or (No)
input YN      trade_info_display = Yes;              // Select Display Trading Info on Chart (Yes) or (No)
input ulong              magicEA = 20260504;         // Expert ID (Magic Number)
//---
//---------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***

Global Strategy and Indicator Settings

The foundation of the EA’s logic is defined in the "Global Strategy EA Parameter" and "ADX Indicator Input Properties" sections. The tfinuse parameter allows the user to select the timeframe on which the EA operates. Options range from M15 (15 minutes) to D1 (Daily). The default is H4 (4-hour), which is often considered a sweet spot for trend following as it filters out intraday noise while still providing frequent enough signals for active trading. The period_ADX input sets the lookback period for the ADX indicator, with 14 being the standard default. Traders can adjust this to make the indicator more sensitive (lower value) or smoother (higher value) depending on their preference for signal frequency versus reliability.

Pair Selection and Trading Modes

One of the standout features of this EA is its flexible pair selection mechanism, controlled by the trademode and usepairs inputs. Users can choose between "Single Pair" (SP) and "Multi Pairs" (MP) modes. In MP mode, the usepairs enum allows for granular control over which assets are traded. Options include:

  • All30: Trades all 30 predefined Forex and Metal pairs.
  • TrdWi (Trader Wishes): Allows the user to specify a custom list of pairs via the traderwishes string input (e.g., "eurusd,usdchf").
  • Currency-Specific Groups: Trade only USD pairs, EUR pairs, GBP pairs, etc.
  • Metal: Trade only XAUUSD and XAGUSD.

This flexibility is crucial for multi-currency EA strategies, as it allows traders to focus on specific sectors of the market or exclude pairs that do not suit their risk profile. The EA automatically handles symbol prefixes and suffixes, ensuring compatibility with various brokers.

Money Management and Martingale Configuration

The "Money Management Lot Size Parameter" section is where the risk profile of the EA is defined. The mmlot enum allows users to choose between "FixedLot" and "DynamLot" (Dynamic Lot). In Dynamic mode, the lot size is calculated based on a percentage of the account equity, defined by the Risk input (1.0% to 10.0%). This ensures that the position size scales with the account growth, a key component of compounding.

For those who employ aggressive recovery strategies, the UseMartin boolean enables the Martingale feature. If enabled, the lotmp1 and lotmp2 inputs define the multipliers for the second and third lots, respectively. For example, if lotmp1 is 2.0, the second trade will be double the size of the first. This feature must be used with caution, as it increases exposure significantly, but it can be effective in recovering from short-term drawdowns in ranging markets.

Time and Session Management

Trading during optimal times is critical for trend strategies. The "Trade on Specific Time" and "Day Trading On/Off" sections allow for precise scheduling. The trd_time_zone input enables time-based filtering, with presets for major sessions like New Zealand, Australia, Tokyo, London, and New York. Alternatively, users can define a Cus_Session (Custom Session) by specifying start and stop hours and minutes. Additionally, individual days of the week can be toggled on or off using the ttd0 through ttd6 inputs, allowing traders to avoid low-liquidity periods like weekends or specific holidays.

Trade and Order Management

The final major section controls the lifecycle of the trade. Inputs like use_sl and use_tp enable Stop Loss and Take Profit orders. The EA offers both automatic calculation (autosl, autotp) and manual fixed values (SLval, TPval). The PartialClose feature, when enabled, allows the EA to close a portion of the position (defined by percentlots) once a certain profit target (profitinpips) is reached. This locks in profits while leaving the remainder of the position open to capture further trend movement. The TrailingSL and TrailingTP features further enhance profit protection by dynamically adjusting stop levels as the market moves in favor of the trade. The Close_by_Opps input allows the EA to close existing positions if an opposite signal is generated, ensuring that the system does not hold conflicting biases in the same pair.

3. Initialization and Configuration: The Role of MCEA::ADX_Trend_MCEA_Config

The initialization phase of any Expert Advisor is critical, as it sets up the environment for all subsequent trading operations. In the ADX_Trend_MCEA, this is handled by the MCEA::ADX_Trend_MCEA_Config(void) function. This method is called during the OnInit() event and performs several essential tasks that ensure the EA runs smoothly and efficiently.

ADX_Trend_MCEA_Config()

 
//+------------------------------------------------------------------+
//| Expert Configuration                                             |
//+------------------------------------------------------------------+
void MCEA::ADX_Trend_MCEA_Config(void) 
  {
//---
    //--
    HandlingSymbolArrays(); // With this function we will handle all pairs that will be traded
    //--
    ENUM_TIMEFRAMES TFs[]={PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H2,PERIOD_H3,PERIOD_H4,PERIOD_H6,PERIOD_H8,PERIOD_H12,PERIOD_D1};
    int arTFs=ArraySize(TFs);
    for(int x=0; x<arTFs; x++) if(tfinuse==x) { TFt=TFs[x]; break; } // TF for calculation signal
    //-- Indicators handle for all symbol
    for(int x=0; x<arrsymbx; x++) 
      {
        hADX[x]   = iADX(DIRI[x],TFt,period_ADX);                 //-- Handle for ADX indicator
        hSMA20[x] = iMA(DIRI[x],TFt,20,0,MODE_SMA,PRICE_MEDIAN);  //-- Handle for the SMA 20 indicator for Trailing Stop
        //--
      }
    //--
    TesterHideIndicators(true);
    minprofit=NormalizeDouble(TSmin/100.0,2);
    //--
    ALO=(int)mc_account.LimitOrders()>sall ? sall : (int)mc_account.LimitOrders();
    if(Close_by_Opps==No) 
      {
        if((int)mc_account.LimitOrders()>=(sall*2)) ALO=sall*2;
        else 
        ALO=(int)(mc_account.LimitOrders()/2);
      }
    //--
    LotPS=(double)ALO;
    Lotmpx[0]=lotmp1;
    Lotmpx[1]=lotmp2;
    //--
    mc_trade.SetExpertMagicNumber(magicEA);
    mc_trade.SetDeviationInPoints(slip);
    mc_trade.SetMarginMode();
    Set_Time_Zone();
    //--
    return;
//---
  } //-end ADX_Trend_MCEA_Config()
//---------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***

First, the function calls HandlingSymbolArrays(). This is a pivotal step for a 30 Pairs EA. It populates the internal arrays with the list of symbols to be traded based on the user’s input selections. It also detects any prefix or suffix added by the broker to the standard symbol names (e.g., "EURUSD.pro" instead of "EURUSD") and adjusts the symbol strings accordingly. This ensures that the EA can interact with the broker’s server without symbol mismatch errors. The function then selects these symbols in the Market Watch window, ensuring that price data is available for calculation.

Next, the configuration function initializes the indicator handles. For each symbol in the trading array, it creates handles for the ADX indicator (iADX) and a Simple Moving Average (iMA with period 20). The SMA is primarily used for the trailing stop logic when the byindi trailing type is selected. By creating these handles upfront, the EA avoids the performance penalty of creating and destroying indicators on every tick, which is crucial for a multi-currency system that may be monitoring dozens of charts simultaneously.

The function also calculates the maximum number of allowed open orders (ALO). This is derived from the account’s limit orders setting and the trading mode. If Close_by_Opps is disabled, the EA allows for more open positions to accommodate hedging strategies. This limit is crucial for strategic risk management, preventing the EA from over-leveraging the account by opening too many positions simultaneously. The LotPS variable is also set here, which is used in the dynamic lot size calculation to distribute risk evenly across all open positions.

Finally, the configuration sets the magic number for the EA using mc_trade.SetExpertMagicNumber(magicEA). This ensures that the EA only manages trades it has opened, ignoring manual trades or trades opened by other EAs on the same account. It also sets the deviation (slippage tolerance) and margin mode. The Set_Time_Zone() function is called to pre-calculate the start and end times for the selected trading session, converting them from local time to server time. This pre-calculation ensures that the time-checking logic during the trading loop is fast and efficient, avoiding complex time conversions on every tick.

In summary, MCEA::ADX_Trend_MCEA_Config is the backbone of the EA’s setup process. It transforms the user’s static input parameters into dynamic, ready-to-use data structures and handles. By performing these heavy-lifting tasks at initialization, the EA ensures that the main trading loop (OnTick) remains lightweight and responsive, capable of executing trades with minimal latency. This architectural decision is a hallmark of professional-grade MQL5 programming, reflecting the developer’s experience and attention to performance optimization.

4. Risk Control and Margin Verification: MCEA::GoodMarginTrade

One of the most common reasons for automated trading failures is insufficient margin. Opening a position without verifying that the account has enough free margin can lead to immediate rejections by the broker or, worse, a margin call if the trade goes against the user. The ADX_Trend_MCEA addresses this critical issue with the MCEA::GoodMarginTrade(const string symbol, ENUM_ORDER_TYPE _cmd, double lotsz, double atprice) function. This function acts as a gatekeeper, ensuring that every trade attempt is financially viable before it is sent to the server.

MCEA::GoodMarginTrade()

   
bool MCEA::GoodMarginTrade(const string symbol,ENUM_ORDER_TYPE _cmd,double lotsz,double atprice)
  {
//---
   bool goodmrgn=true;
   //--
   if((mc_account.FreeMarginCheck(symbol,_cmd,lotsz,atprice)<=0.0)||(mc_account.FreeMargin()<(mc_account.Equity()*maxmrgn/100))) goodmrgn=false;
   //--
   if(!goodmrgn)
     {
       string nomargn="Account Free Margin minimum has reached the specified limit, Order will not opened";
       Do_Alerts(symbol,nomargn);
     }
   //--
   return(goodmrgn);
//---
  } //-end GoodMarginTrade()
//---------//  
***Copyright © 2026 3rjfx ~ For educational purposes only.***

The function performs two primary checks. First, it uses the mc_account.FreeMarginCheck method to simulate the impact of the proposed trade on the account’s free margin. It takes into account the symbol, the order type (Buy or Sell), the lot size, and the current price. If the resulting free margin is zero or negative, the function returns false, indicating that the trade cannot be opened. This prevents the EA from attempting trades that would immediately violate margin requirements.

Second, the function checks the free margin against a user-defined threshold. The input parameter maxmrgn allows the user to specify the maximum percentage of equity that can be used as margin. For example, if maxmrgn is set to 80%, the EA will only open trades if the free margin is at least 20% of the equity. This buffer is crucial for strategic risk management, as it ensures that the account has enough breathing room to withstand adverse market movements without triggering a margin call. If the free margin falls below this threshold, the function returns false and triggers an alert via the Do_Alerts function, informing the user that the margin limit has been reached.

This dual-layer verification process is particularly important for a multi-currency EA that may open multiple positions across different pairs. Since each pair has different margin requirements based on its contract size and leverage, a simple lot size check is insufficient. The GoodMarginTrade function dynamically calculates the specific margin requirement for each trade, ensuring that the cumulative risk across all open positions remains within safe limits. This proactive approach to margin management helps preserve capital and extends the longevity of the trading system, even during periods of high volatility or drawdown.

Furthermore, by centralizing this logic in a single function, the code remains clean and maintainable. Every order execution function (OpenBuy and OpenSell) calls GoodMarginTrade before proceeding. This consistency ensures that no trade can bypass the margin checks, providing a robust safety net for the user’s account. It reflects a professional approach to algorithmic trading, where risk control is not an afterthought but an integral part of the execution pipeline.

5. The Core Signal Logic: MCEA::ADXSignal and MCEA::GetOpenPosition

The heart of the ADX_Trend_MCEA is its signal generation logic, which determines when to enter the market. This process is split into two main functions: MCEA::ADXSignal and MCEA::GetOpenPosition. Together, they combine indicator analysis with price action confirmation to produce high-probability trade signals.

MCEA::ADXSignal: Detecting Trend Strength and Direction

 
int MCEA::ADXSignal(const string symbol) // Stochastic Degree Signal for Open Position
  {
//---
    int ret=0;
    int rise=1,
        down=-1;
    int risex=-2;
    int downx=2;
    int barcalc=arper;
    //--
    double ADIp[];
    double ADIm[];
    //--
    ArrayResize(ADIp,barcalc,barcalc);
    ArrayResize(ADIm,barcalc,barcalc);
    ArraySetAsSeries(ADIp,true);
    ArraySetAsSeries(ADIm,true);
    //--
    int xs=PairsIdxArray(symbol);
    mc_indicator.Refresh(TFt);
    //--
    CopyBuffer(hADX[xs],1,0,barcalc,ADIp);
    CopyBuffer(hADX[xs],2,0,barcalc,ADIm);
    //--
    if(ADIp[2]<=ADIm[2] && ADIp[1]>ADIm[1] && ADIp[0]>=ADIp[1]) ret=rise;
    if(ADIp[2]>=ADIm[2] && ADIp[1]<ADIm[1] && ADIp[0]<=ADIp[1]) ret=down;
    //--
    if(ADIp[0]>ADIm[0] && ADIp[0]<ADIp[1]) ret=risex;
    if(ADIp[0]<ADIm[0] && ADIp[0]>ADIp[1]) ret=downx;
    //--
    return(ret);
//---
  } //-end ADXSignal()
//---------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***

The MCEA::ADXSignal(const string symbol) function analyzes the ADX indicator to determine the strength and potential direction of the trend. It retrieves the values of the ADX line, the Plus Directional Indicator (+DI), and the Minus Directional Indicator (-DI) for the current and previous bars. The logic looks for specific crossovers and relationships between these lines:

  • Bullish Signal: If the +DI crosses above the -DI, and the ADX line is rising or above a certain threshold, it indicates a strengthening uptrend. The function returns a value of 1 (rise).
  • Bearish Signal: If the -DI crosses above the +DI, and the ADX line is rising or above a certain threshold, it indicates a strengthening downtrend. The function returns a value of -1 (down).
  • Weak Signal: If the ADX lines are converging or the ADX line is falling, the function returns values of -2 or 2, indicating a weak or reversing trend. These signals are used for closing positions rather than opening new ones.

This nuanced approach allows the EA to distinguish between strong, tradable trends and weak, choppy markets. By requiring the ADX to confirm the directional crossover, the EA filters out many false signals that plague simpler crossover strategies. This is a key aspect of its trend detection capability.

MCEA::GetOpenPosition: Confirming with Price Action

 
int MCEA::GetOpenPosition(const string symbol) // Signal Open Position 
  {
//---
    int ret=0;
    int rise=1,
        down=-1;
    //--
    int WPRMove=WPRPlus(symbol,TFt);
    int dirmove=DirectionMove(symbol,TFt);
    int ADSignal=ADXSignal(symbol);
    //--
    if(ADSignal==rise && dirmove==rise && WPRMove==rise) ret=rise;
    if(ADSignal==down && dirmove==down && WPRMove==down) ret=down;
    //--
    return(ret);
//---
  } //-end GetOpenPosition()
//---------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***

The MCEA::GetOpenPosition(const string symbol) function acts as a final filter before a trade is executed. It calls ADXSignal to get the indicator-based signal, but it also calls DirectionMove and WPRPlus to analyze the actual price movement of the current bar. The DirectionMove function checks if the current candle’s close is significantly higher or lower than its open, based on a pip threshold. This ensures that the price action aligns with the indicator signal.

 
int MCEA::DirectionMove(const string symbol,const ENUM_TIMEFRAMES stf) // Bar Price Direction 
  {
//---
    int ret=0;
    int rise=1,
        down=-1;
    //--
    Pips(symbol);
    double difud=mc_symbol.NormalizePrice(2.6*pip);
    UpdatePrice(symbol,stf,2);
    //--
    if(CLOSE[0]>OPEN[0]+difud) ret=rise;
    if(CLOSE[0]<OPEN[0]-difud) ret=down;
    //--
    return(ret);
//---
  } //-end DirectionMove()
//---------//

int MCEA::WPRPlus(const string symbol,const ENUM_TIMEFRAMES stf)
  {
//---
    int ret=0;
    int rise=1,
        down=-1;
    //--
    double wprpos=0.0;
    int wperiod=14;
    //--
    UpdatePrice(symbol,stf);
    //--
    double WPRP[];
    double RANGEP[];
    ArrayResize(WPRP,arper,arper);
    ArrayResize(RANGEP,arper,arper);
    ArraySetAsSeries(WPRP,true);
    ArraySetAsSeries(RANGEP,true);
    //--
    for(int i=arper-2; i>=0; i--)
      {
        double RHigh = HIGH[ArrayMaximum(HIGH,i,wperiod)];
        double RLow  = LOW[ArrayMinimum(LOW,i,wperiod)];
        RANGEP[i]=NonZeroDiv((RHigh-CLOSE[i]),(RHigh-RLow))*100;
        WPRP[i]=100-fabs(RANGEP[i]);
        if(i==0) 
          {
            wprpos=NormalizeDouble(WPRP[i],2);
            if(WPRP[0]>WPRP[1] && wprpos<80.00) ret=rise;
            if(WPRP[0]<WPRP[1] && wprpos>20.00) ret=down;
          }
      }
    //--
    return(ret);
//---
  } //-end WPRPlus()
//---------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***

For a Buy signal to be valid, these three functions ADXSignal, DirectionMove and WPRPlus must return a bullish result. Similarly, for a Sell signal, these three functions must return a bearish result. If there is a discrepancy (e.g., the ADX suggests a buy, but the price candle is bearish), the function returns 0, and no trade is opened. This confluence of indicator and price action significantly increases the reliability of the entries, reducing the likelihood of entering a trade just as the market is reversing.

WPRPlus is a modified Williams Percent Range to filter out momentum shifts.
This function prevents the EA from opening orders when the price is nearly Overbought or Oversold with WPRPlus blocking value parameters Overbought < 80.00 and Oversold value > 20.00

This three-step verification process is a hallmark of robust MT5 trading robot design. It acknowledges that indicators are lagging and can sometimes give false signals in rapidly changing markets. By requiring confirmation from real-time price action, the EA ensures that it is trading with the momentum, not against it. This logic is applied to every symbol in the trading array on every tick, allowing the EA to react quickly to new trend opportunities across the entire portfolio of 30 pairs.

6. Advanced Money Management: MCEA::LotMartingale and the Martingale System

Money management is the bridge between a profitable strategy and a profitable account. The ADX_Trend_MCEA offers a sophisticated approach to lot sizing, including a configurable Martingale system. The MCEA::LotMartingale(const string symbol, double lotinit, double lastlot) function is responsible for calculating the lot size for subsequent trades if the Martingale feature is enabled.

MCEA::LotMartingale: Multiplier Lot Size Martingale System

   
double MCEA::LotMartingale(const string symbol,double lotinit,double lastlot)
  {
//---
    double lotmart=0.0;
    //--
    double lotx1=NormalizeDouble(lotinit*Lotmpx[0],LotDig(symbol));
    double lotx2=NormalizeDouble(lotx1*Lotmpx[1],LotDig(symbol));
    //--
    if(lastlot>=lotx2) lotmart=lotinit;
    else
    if(lastlot>=lotx1 && lastlot<lotx2) lotmart=lotx2;
    else lotmart=lotx1;
    //--
    return(lotmart);
//---
  } //-end LotMartingale()
//---------//  
***Copyright © 2026 3rjfx ~ For educational purposes only.***

Understanding the Martingale System

The Martingale system is a betting strategy that originated in 18th-century France. In trading, it involves doubling the position size after every losing trade. The theory is that a winning trade will eventually occur, and when it does, it will recover all previous losses plus generate a profit equal to the original stake. While controversial due to its high risk, it can be effective in ranging markets or for recovering from short-term drawdowns if managed correctly.

Implementation in ADX_Trend_MCEA

The EA implements a modified, controlled version of the Martingale system. When UseMartin is set to "Yes", the EA checks the history of the last closed trade for the specific symbol using the CheckLastOrderIFLoss function. If the last trade was a loss, the LotMartingale function is called to calculate the new lot size.

The function uses the lotmp1 and lotmp2 multipliers to determine the size of the next trade. For example:

  • If the initial lot was 0.01 and lotmp1 is 2.0, the second trade will be 0.02 lots.
  • If the second trade loses, the third trade will be calculated using lotmp2. If lotmp2 is also 2.0, the third trade will be 0.04 lots.

The function includes logic to reset the lot size back to the initial value if the maximum multiplier level is reached. This prevents the lot size from growing exponentially and becoming unmanageable. This "capped" Martingale approach mitigates some of the extreme risks associated with traditional Martingale strategies.

Additionally, the EA employs a Volume Cut Logic through its Partial Close feature. This allows the EA to reduce exposure by closing a portion of the position when a certain profit target is reached. This complements the Martingale system by securing profits early, which can help offset potential losses from subsequent Martingale trades. The combination of these features allows traders to customize their risk-reward profile, balancing the aggressive recovery potential of Martingale with the conservative profit-taking of partial closes.

It is important to note that while the Martingale system can enhance profitability in certain conditions, it requires careful monitoring and sufficient account balance. The GoodMarginTrade function plays a crucial role here, preventing the EA from opening oversized Martingale positions if the account margin is insufficient. This integrated approach to money management demonstrates the EA’s focus on strategic risk management, providing tools for both aggressive and conservative trading styles.

Key Takeaway: Strategic Risk Management

The ADX_Trend_MCEA does not rely on a single risk management technique. Instead, it combines dynamic lot sizing, margin verification, partial closes, and trailing stops to create a multi-layered defense against market volatility. This holistic approach is what distinguishes it as a professional-grade multi-currency EA.

Strategy Tester Report - 01

MetaQuotes-Demo (Build 5836)

Settings:

Expert: ADX_Trend_MCEA
Symbol: AUDUSD
Period: H4 (2026.03.01 - 2026.05.05)

Inputs Properties:

 
//---
input group               "=== Global Strategy EA Parameter ==="; // Global Strategy EA Parameter
input TFUSE               tfinuse = TFH4;             // Select Expert TimeFrame, default PERIOD_H4
//---
input group               "=== ADX Indicator Input Properties ===";  // ADX Indicator Input Properties
input int              period_ADX = 14;               // Input Period ADX 
//---
input group               "=== Select Pairs to Trade ===";  // Selected Pairs to trading
input MS                trademode = MP;              // Select Trading Pairs Mode (Multi or Single)
input PairsTrade         usepairs = All30;           // Select Pairs to Use
input string         traderwishes = "eg. eurusd,usdchf"; // If Use Trader Wishes Pairs, input pair name here, separate by comma
//--
input group               "=== Money Management Lot Size Parameter ==="; // Money Management Lot Size Parameter
input mmt                  mmlot = DynamLot;         // Money Management Type
input double                Risk = 5.0;              // Percent Equity Risk per Trade (Min=1.0% / Max=10.0%)
input double                Lots = 0.01;             // Input Manual Lot Size FixedLot
input double             maxmrgn = 80.0;             // Input Maximum Free Margin from Equity to Trade (in Percent)
input YN               UseMartin = Yes;              // Select to use Martingale method (Yes) or (No)
input double              lotmp1 = 2.00;             // If use Martingale Input 2nd Lot (2nd x Lots) Multiplier
input double              lotmp2 = 2.00;             // If use Martingale Input 3rd Lot (3rd x 2nd) Multiplier
//--Trade on Specific Time
input group               "=== Trade on Specific Time ==="; // Trade on Specific Time
input YN           trd_time_zone = Yes;              // Select If You Like to Trade on Specific Time Zone
input tm_zone            session = Cus_Session;      // Select Trading Time Zone
input swhour            stsescuh = hr_00;            // Time Hour to Start Trading Custom Session (0-23)
input inmnt             stsescum = mn_15;            // Time Minute to Start Trading Custom Session (0-55)
input swhour            clsescuh = hr_23;            // Time Hour to Stop Trading Custom Session (0-23)
input inmnt             clsescum = mn_55;            // Time Minute to Stop Trading Custom Session (0-55)
//--Day Trading On/Off
input group               "=== Day Trading On/Off ==="; // Day Trading On/Off
input YN                    ttd0 = No;               // Select Trading on Sunday (Yes) or (No)
input YN                    ttd1 = Yes;              // Select Trading on Monday (Yes) or (No)
input YN                    ttd2 = Yes;              // Select Trading on Tuesday (Yes) or (No)
input YN                    ttd3 = Yes;              // Select Trading on Wednesday (Yes) or (No)
input YN                    ttd4 = Yes;              // Select Trading on Thursday (Yes) or (No)
input YN                    ttd5 = Yes;              // Select Trading on Friday (Yes) or (No)
input YN                    ttd6 = No;               // Select Trading on Saturday (Yes) or (No)
//--Trade & Order management Parameter
input group               "=== Trade & Order management Parameter ==="; // Trade & Order management Parameter
input YN                  use_sl = No;               // Use Order Stop Loss (Yes) or (No)
input YN                  autosl = Yes;              // Use Automatic Calculation Stop Loss (Yes) or (No)
input double               SLval = 30.0;             // If Not Use Automatic SL - Input SL value in Pips
input YN                  use_tp = Yes;              // Use Order Take Profit (Yes) or (No)
input YN                  autotp = Yes;              // Use Automatic Calculation Take Profit (Yes) or (No)
input double               TPval = 60.0;             // If Not Use Automatic TP - Input TP value in Pips
input YN            PartialClose = Yes;              // Use Partial Close Profit (Yes) or (No)
input double        profitinpips = 10.0;             // Input Profit in Pips for Partial Close, default 10 Pips
input double         percentlots = 50.0;             // Percentage Lot Size to Partial Close
input YN              TrailingSL = No;              // Use Trailing Stop Loss (Yes) or (No)
input TrType               trlby = byindi;          // Select Trailing Stop Type
input double               TSval = 10.0;             // If Use Trailing Stop by Price Input value in Pips
input double               TSmin = 5.0;              // Minimum Pips to start Trailing Stop
input YN              TrailingTP = No;              // Use Trailing Take Profit (Yes) or (No)
input double               TPmin = 25.0;             // Input Trailing Profit Value in Pips
input YN           Close_by_Opps = Yes;              // Close Trade By Opposite Signal (Yes) or (No)
input YN               SaveOnRev = Yes;              // Close Trade and Save profit due to weak signal (Yes) or (No)
input YN              CheckVSLTP = No;              // Check Virtual SL/TP & Close Loss Trade (Yes) or (No)
//--Others Expert Advisor Parameter
input group               "=== Others Expert Advisor Parameter ==="; // Others EA Parameter
input YN                  alerts = Yes;              // Display Alerts / Messages (Yes) or (No)
input YN           UseEmailAlert = No;               // Email Alert (Yes) or (No)
input YN           UseSendnotify = No;               // Send Notification (Yes) or (No)
input YN      trade_info_display = Yes;              // Select Display Trading Info on Chart (Yes) or (No)
input ulong              magicEA = 20260504;         // Expert ID (Magic Number)
//---
//---------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***
ReportTester-106122652_ADX_Trend_MCEA_01 Results
Figure 2: ReportTester-106122652_ADX_Trend_MCEA_01 Results
ReportTester-106122652_ADX_Trend_MCEA_01 Balance
Figure 3: ReportTester-106122652_ADX_Trend_MCEA_01 Balance
ReportTester-106122652_ADX_Trend_MCEA_01 History
Figure 4: ReportTester-106122652_ADX_Trend_MCEA_01 History
ReportTester-106122652_ADX_Trend_MCEA_01 MFE-MAE
Figure 5: ReportTester-106122652_ADX_Trend_MCEA_01 MFE-MAE
ReportTester-106122652_ADX_Trend_MCEA_01 Min/Max Position Holding Time
Figure 6: ReportTester-106122652_ADX_Trend_MCEA_01 Min/Max Position Holding Time

Strategy Tester Report - 02

MetaQuotes-Demo (Build 5836)

Settings:

Expert: ADX_Trend_MCEA
Symbol: AUDUSD
Period: H4 (2026.03.01 - 2026.05.05)

Inputs Properties:

 
//---
input group               "=== Global Strategy EA Parameter ==="; // Global Strategy EA Parameter
input TFUSE               tfinuse = TFH4;             // Select Expert TimeFrame, default PERIOD_H4
//---
input group               "=== ADX Indicator Input Properties ===";  // ADX Indicator Input Properties
input int              period_ADX = 14;               // Input Period ADX 
//---
input group               "=== Select Pairs to Trade ===";  // Selected Pairs to trading
input MS                trademode = MP;              // Select Trading Pairs Mode (Multi or Single)
input PairsTrade         usepairs = All30;           // Select Pairs to Use
input string         traderwishes = "eg. eurusd,usdchf"; // If Use Trader Wishes Pairs, input pair name here, separate by comma
//--
input group               "=== Money Management Lot Size Parameter ==="; // Money Management Lot Size Parameter
input mmt                  mmlot = DynamLot;         // Money Management Type
input double                Risk = 5.0;              // Percent Equity Risk per Trade (Min=1.0% / Max=10.0%)
input double                Lots = 0.01;             // Input Manual Lot Size FixedLot
input double             maxmrgn = 80.0;             // Input Maximum Free Margin from Equity to Trade (in Percent)
input YN               UseMartin = Yes;              // Select to use Martingale method (Yes) or (No)
input double              lotmp1 = 2.00;             // If use Martingale Input 2nd Lot (2nd x Lots) Multiplier
input double              lotmp2 = 2.00;             // If use Martingale Input 3rd Lot (3rd x 2nd) Multiplier
//--Trade on Specific Time
input group               "=== Trade on Specific Time ==="; // Trade on Specific Time
input YN           trd_time_zone = Yes;              // Select If You Like to Trade on Specific Time Zone
input tm_zone            session = Cus_Session;      // Select Trading Time Zone
input swhour            stsescuh = hr_00;            // Time Hour to Start Trading Custom Session (0-23)
input inmnt             stsescum = mn_15;            // Time Minute to Start Trading Custom Session (0-55)
input swhour            clsescuh = hr_23;            // Time Hour to Stop Trading Custom Session (0-23)
input inmnt             clsescum = mn_55;            // Time Minute to Stop Trading Custom Session (0-55)
//--Day Trading On/Off
input group               "=== Day Trading On/Off ==="; // Day Trading On/Off
input YN                    ttd0 = No;               // Select Trading on Sunday (Yes) or (No)
input YN                    ttd1 = Yes;              // Select Trading on Monday (Yes) or (No)
input YN                    ttd2 = Yes;              // Select Trading on Tuesday (Yes) or (No)
input YN                    ttd3 = Yes;              // Select Trading on Wednesday (Yes) or (No)
input YN                    ttd4 = Yes;              // Select Trading on Thursday (Yes) or (No)
input YN                    ttd5 = Yes;              // Select Trading on Friday (Yes) or (No)
input YN                    ttd6 = No;               // Select Trading on Saturday (Yes) or (No)
//--Trade & Order management Parameter
input group               "=== Trade & Order management Parameter ==="; // Trade & Order management Parameter
input YN                  use_sl = No;               // Use Order Stop Loss (Yes) or (No)
input YN                  autosl = Yes;              // Use Automatic Calculation Stop Loss (Yes) or (No)
input double               SLval = 30.0;             // If Not Use Automatic SL - Input SL value in Pips
input YN                  use_tp = Yes;              // Use Order Take Profit (Yes) or (No)
input YN                  autotp = Yes;              // Use Automatic Calculation Take Profit (Yes) or (No)
input double               TPval = 60.0;             // If Not Use Automatic TP - Input TP value in Pips
input YN            PartialClose = No;               // Use Partial Close Profit (Yes) or (No)
input double        profitinpips = 15.0;             // Input Profit in Pips for Partial Close, default 10 Pips
input double         percentlots = 50.0;             // Percentage Lot Size to Partial Close
input YN              TrailingSL = Yes;              // Use Trailing Stop Loss (Yes) or (No)
input TrType               trlby = byindi;          // Select Trailing Stop Type
input double               TSval = 12.0;             // If Use Trailing Stop by Price Input value in Pips
input double               TSmin = 5.0;              // Minimum Pips to start Trailing Stop
input YN              TrailingTP = No;              // Use Trailing Take Profit (Yes) or (No)
input double               TPmin = 25.0;             // Input Trailing Profit Value in Pips
input YN           Close_by_Opps = Yes;              // Close Trade By Opposite Signal (Yes) or (No)
input YN               SaveOnRev = No;              // Close Trade and Save profit due to weak signal (Yes) or (No)
input YN              CheckVSLTP = No;              // Check Virtual SL/TP & Close Loss Trade (Yes) or (No)
//--Others Expert Advisor Parameter
input group               "=== Others Expert Advisor Parameter ==="; // Others EA Parameter
input YN                  alerts = Yes;              // Display Alerts / Messages (Yes) or (No)
input YN           UseEmailAlert = No;               // Email Alert (Yes) or (No)
input YN           UseSendnotify = No;               // Send Notification (Yes) or (No)
input YN      trade_info_display = Yes;              // Select Display Trading Info on Chart (Yes) or (No)
input ulong              magicEA = 20260504;         // Expert ID (Magic Number)
//---
//---------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***
ReportTester-106122652_ADX_Trend_MCEA_02 Results
Figure 7: ReportTester-106122652_ADX_Trend_MCEA_02 Results
ReportTester-106122652_ADX_Trend_MCEA_02 Balance
Figure 7: ReportTester-106122652_ADX_Trend_MCEA_02 Balance
ReportTester-106122652_ADX_Trend_MCEA_02 History
Figure 8: ReportTester-106122652_ADX_Trend_MCEA_02 History
ReportTester-106122652_ADX_Trend_MCEA_02 MFE-MAE
Figure 9: ReportTester-106122652_ADX_Trend_MCEA_02 MFE-MAE
ReportTester-106122652_ADX_Trend_MCEA_02 Min/Max Position Holding Time
Figure 10: ReportTester-106122652_ADX_Trend_MCEA_02 Min/Max Position Holding Time

Trading Terminal:

MetaQuotes-Demo (Build 5836)

Settings: Default Input Properties

Expert: ADX_Trend_MCEA
Symbol: XADUSD
Period: H4 (2026.05.04 - 2026.05.05)
ADX_Trend_MCEA MetaQuotes Demo Trading Terminal MT5
Figure 11: ADX_Trend_MCEA MetaQuotes Demo MT5 Trading Terminal

Frequently Asked Questions (FAQ)

Q1: Can I use this EA on a standard MetaTrader 4 (MT4) account?

No, the ADX_Trend_MCEA is developed specifically for the MetaTrader 5 (MT5) platform using MQL5. It utilizes MT5-specific features and libraries that are not compatible with MT4. You must have an MT5 trading account to use this EA.

Q2: How many pairs can the EA trade simultaneously?

The EA is designed to trade up to 30 different Forex and Metal pairs simultaneously from a single chart. However, you can configure it to trade fewer pairs or specific groups (e.g., only USD pairs) using the usepairs input parameter.

Q3: Is the Martingale system mandatory?

No, the Martingale system is optional. You can disable it by setting the UseMartin input to "No". In this case, the EA will use a fixed or dynamic lot size for every trade, without increasing the position size after losses.

Q4: Does the EA require a VPS (Virtual Private Server)?

While not strictly mandatory, using a VPS is highly recommended for any MT5 trading robot. A VPS ensures that the EA runs 24/7 without interruption from internet connectivity issues or computer shutdowns, which is crucial for a multi-currency system that monitors markets around the clock.

Q5: Can I customize the trading hours?

Yes, the EA includes extensive time filtering options. You can choose from predefined major market sessions (New York, London, Tokyo, etc.) or define your own custom trading hours using the Cus_Session option. You can also specify which days of the week the EA should trade.

Q6: What is the minimum account balance required?

The minimum balance depends on your lot size settings and leverage. For dynamic lot sizing, the EA calculates the lot size based on your risk percentage. It is generally recommended to start with at least $500-$1000 to allow for proper diversification and margin buffering, especially if using the Martingale feature.

Conclusion

The ADX_Trend_MCEA stands out as a comprehensive and robust solution for traders looking to automate their trend-following strategies across a diverse portfolio of currency pairs. Its ability to monitor and trade up to 30 assets from a single chart offers unparalleled efficiency and diversification, key components for long-term success in the Forex market. By leveraging the power of the ADX indicator for trend detection and combining it with rigorous price action confirmation, the EA minimizes false signals and focuses on high-probability opportunities.

The inclusion of advanced money management features, such as the configurable Martingale System, partial closes, and dynamic lot sizing, provides traders with the flexibility to tailor the EA to their specific risk tolerance. Whether you are a conservative trader seeking steady growth through dynamic lot sizing or an aggressive trader looking to recover drawdowns with Martingale, the ADX_Trend_MCEA offers the tools to achieve your goals. The emphasis on strategic risk management through margin verification and time filtering further enhances its reliability and safety.

Developed by an experienced MQL5 programmer, this Expert Advisor MT5 reflects a deep understanding of both market dynamics and software engineering. Its modular design, clear input parameters, and efficient code structure make it accessible to traders of all levels, from beginners to experts. As with any automated trading system, success depends on proper configuration, realistic expectations, and ongoing monitoring. By understanding the functionalities detailed in this article, you are well-equipped to harness the full potential of the ADX_Trend_MCEA and integrate it effectively into your trading strategy.

In the ever-evolving landscape of Forex trading, having a reliable, versatile, and intelligent multi-currency EA like the ADX_Trend_MCEA can provide a significant competitive edge. It allows you to participate in global market trends 24/5, without being tied to your screen, freeing up your time to focus on strategy refinement and overall portfolio management. Embrace the power of automation, follow the trend, and let the ADX_Trend_MCEA work for you.

⚠️ Important: Risk Disclaimer

  • Demo Testing: You are strongly advised to test this EA on an MT5 Demo Account first to witness how it manages 30 pairs simultaneously.
  • Real Account Trading: If you proceed to use this EA for automated trading on a Real Account, you do so at your own risk. Algorithmic trading involves substantial risk to your capital.
  • Always remember the rules: Never trade with money you cannot afford to lose.
  • Trading foreign exchange on margin carries a high level of risk and may not be suitable for all investors. The high degree of leverage can work against you as well as for you. Before deciding to invest in foreign exchange, you should carefully consider your investment objectives, level of experience, and risk appetite. The ADX_Trend_MCEA logic provided in this article are for educational purposes and do not guarantee profits. Past performance is not indicative of future results.
  • For more details, please read our full Risk Disclaimer and Terms of Service.

Vital Records

We hope that this article and the ADX_Trend_MCEA - MQL5 Multi-Currency Expert Advisor program will be useful for traders in learning and generating new ideas, thereby will be able improving your trading performance.

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 or have a new ideas, please leave your comments below this article.

Thanks for reading this article.

Explore more algorithmic trading resources:

Note: Please see the source program and download at the bottom of this article.

Risk Warning: Trading Forex and CFDs involves significant risk and may not be suitable for all investors. All content provided is for educational purposes only and does not constitute financial advice.


//+------------------------------------------------------------------+
//|                                               ADX_Trend_MCEA.mq5 |
//|        Copyright 2026, Roberto Jacobs (3rjfx) ~ Date: 2026-05-04 |
//|                              https://www.mql5.com/en/users/3rjfx |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Roberto Jacobs (3rjfx) ~ Date: 2026-05-04"
#property link      "https://www.mql5.com/en/users/3rjfx"
#property version   "1.00"
#property strict
#property description "The Expert ADX_Trend_MCEA is the Automated Trading Multi Currency Forex Expert Advisor"
#property description "for MetaTrader 5 by using ADX indicator signal which trade Multiple Pairs in one Chart."
#property description "version: 1.00 ~ Update number: 1 ~ Last update: 2026/05/05 @22:15 (PM) WIT (Western Indonesian Time)"
//#property icon "\\Images\\ADX_Trend_MCEA.ico";
//+------------------------------------------------------------------+
//|                             Include                              |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\AccountInfo.mqh>
#include <Indicators\Indicator.mqh>
//--
CTrade              mc_trade;
CSymbolInfo         mc_symbol;
CPositionInfo       mc_position; 
CAccountInfo        mc_account;
CIndicator          mc_indicator;
//---
//--
enum tm_zone
 {
   Cus_Session,        // Trading on Custom Session
   New_Zealand,        // Trading on New Zealand Session
   Australia,          // Trading on Autralia Sydney Session
   Asia_Tokyo,         // Trading on Asia Tokyo Session
   Europe_London,      // Trading on Europe London Session
   US_New_York         // Trading on US New York Session
 };
//--
enum swhour
  {
    hr_00=0,   // 00:00
    hr_01=1,   // 01:00
    hr_02=2,   // 02:00
    hr_03=3,   // 03:00
    hr_04=4,   // 04:00
    hr_05=5,   // 05:00
    hr_06=6,   // 06:00
    hr_07=7,   // 07:00
    hr_08=8,   // 08:00
    hr_09=9,   // 09:00
    hr_10=10,  // 10:00
    hr_11=11,  // 11:00
    hr_12=12,  // 12:00
    hr_13=13,  // 13:00
    hr_14=14,  // 14:00
    hr_15=15,  // 15:00
    hr_16=16,  // 16:00
    hr_17=17,  // 17:00
    hr_18=18,  // 18:00
    hr_19=19,  // 19:00
    hr_20=20,  // 20:00
    hr_21=21,  // 21:00
    hr_22=22,  // 22:00
    hr_23=23   // 23:00
  };
//--
enum inmnt
  {
    mn_00=0,   // Minute 0
    mn_05=5,   // Minute 5
    mn_10=10,  // Minute 10
    mn_15=15,  // Minute 15
    mn_20=20,  // Minute 20
    mn_25=25,  // Minute 25
    mn_30=30,  // Minute 30
    mn_35=35,  // Minute 35
    mn_40=40,  // Minute 40
    mn_45=45,  // Minute 45
    mn_50=50,  // Minute 50
    mn_55=55   // Minute 55
  };
//--
enum PairsTrade
 {
   All30,  // All Forex 30 Pairs
   TrdWi,  // Trader Wishes Pairs 
   Usds,   // Forex USD Pairs
   Eurs,   // Forex EUR Pairs
   Gbps,   // Forex GBP Pairs
   Auds,   // Forex AUD Pairs
   Nzds,   // Forex NZD Pairs
   Cads,   // Forex CDD Pairs
   Chfs,   // Forex CHF Pairs
   Jpys,   // Forex JPY Pairs
   Metal   // Metal Pairs
 };   
//--
enum YN
  {
   No,
   Yes
  };
//--
enum mmt
  {
   FixedLot,   // Fixed Lot Size
   DynamLot    // Dynamic Lot Size
  };
//--
enum TFUSE
  {
   TFM15,    // PERIOD_M15
   TFM30,    // PERIOD_M30
   TFH1,     // PERIOD_H1
   TFH2,     // PERIOD_H2
   TFH3,     // PERIOD_H3
   TFH4,     // PERIOD_H4
   TFH6,     // PERIOD_H6
   TFH8,     // PERIOD_H8
   TFH12,    // PERIOD_H12
   TFD1      // PERIOD_D1
  };
//--
enum TrType
  {
    byprice, // Trailing Stop by Price
    byindi,  // Trailing Stop by Indicator
    byHiLo   // Trailing Stop in HIGH or LOW bar
  };
//--
enum MS
 {
   SP, // Single Pair
   MP  // Multi Pairs
 };
//--
//---
input group               "=== Global Strategy EA Parameter ==="; // Global Strategy EA Parameter
input TFUSE               tfinuse = TFH4;             // Select Expert TimeFrame, default PERIOD_H4
//---
input group               "=== ADX Indicator Input Properties ===";  // ADX Indicator Input Properties
input int              period_ADX = 14;               // Input Period ADX 
//---
input group               "=== Select Pairs to Trade ===";  // Selected Pairs to trading
input MS                trademode = MP;              // Select Trading Pairs Mode (Multi or Single)
input PairsTrade         usepairs = All30;           // Select Pairs to Use
input string         traderwishes = "eg. eurusd,usdchf"; // If Use Trader Wishes Pairs, input pair name here, separate by comma
//--
input group               "=== Money Management Lot Size Parameter ==="; // Money Management Lot Size Parameter
input mmt                  mmlot = DynamLot;         // Money Management Type
input double                Risk = 5.0;              // Percent Equity Risk per Trade (Min=1.0% / Max=10.0%)
input double                Lots = 0.01;             // Input Manual Lot Size FixedLot
input double             maxmrgn = 80.0;             // Input Maximum Free Margin from Equity to Trade (in Percent)
input YN               UseMartin = Yes;              // Select to use Martingale method (Yes) or (No)
input double              lotmp1 = 2.00;             // If use Martingale Input 2nd Lot (2nd x Lots) Multiplier
input double              lotmp2 = 2.00;             // If use Martingale Input 3rd Lot (3rd x 2nd) Multiplier
//--Trade on Specific Time
input group               "=== Trade on Specific Time ==="; // Trade on Specific Time
input YN           trd_time_zone = Yes;              // Select If You Like to Trade on Specific Time Zone
input tm_zone            session = Cus_Session;      // Select Trading Time Zone
input swhour            stsescuh = hr_00;            // Time Hour to Start Trading Custom Session (0-23)
input inmnt             stsescum = mn_15;            // Time Minute to Start Trading Custom Session (0-55)
input swhour            clsescuh = hr_23;            // Time Hour to Stop Trading Custom Session (0-23)
input inmnt             clsescum = mn_55;            // Time Minute to Stop Trading Custom Session (0-55)
//--Day Trading On/Off
input group               "=== Day Trading On/Off ==="; // Day Trading On/Off
input YN                    ttd0 = No;               // Select Trading on Sunday (Yes) or (No)
input YN                    ttd1 = Yes;              // Select Trading on Monday (Yes) or (No)
input YN                    ttd2 = Yes;              // Select Trading on Tuesday (Yes) or (No)
input YN                    ttd3 = Yes;              // Select Trading on Wednesday (Yes) or (No)
input YN                    ttd4 = Yes;              // Select Trading on Thursday (Yes) or (No)
input YN                    ttd5 = Yes;              // Select Trading on Friday (Yes) or (No)
input YN                    ttd6 = No;               // Select Trading on Saturday (Yes) or (No)
//--Trade & Order management Parameter
input group               "=== Trade & Order management Parameter ==="; // Trade & Order management Parameter
input YN                  use_sl = No;               // Use Order Stop Loss (Yes) or (No)
input YN                  autosl = Yes;              // Use Automatic Calculation Stop Loss (Yes) or (No)
input double               SLval = 30.0;             // If Not Use Automatic SL - Input SL value in Pips
input YN                  use_tp = Yes;              // Use Order Take Profit (Yes) or (No)
input YN                  autotp = Yes;              // Use Automatic Calculation Take Profit (Yes) or (No)
input double               TPval = 60.0;             // If Not Use Automatic TP - Input TP value in Pips
input YN            PartialClose = Yes;              // Use Partial Close Profit (Yes) or (No)
input double        profitinpips = 15.0;             // Input Profit in Pips for Partial Close, default 10 Pips
input double         percentlots = 50.0;             // Percentage Lot Size to Partial Close
input YN              TrailingSL = Yes;              // Use Trailing Stop Loss (Yes) or (No)
input TrType               trlby = byindi;          // Select Trailing Stop Type
input double               TSval = 10.0;             // If Use Trailing Stop by Price Input value in Pips
input double               TSmin = 5.0;              // Minimum Pips to start Trailing Stop
input YN              TrailingTP = Yes;              // Use Trailing Take Profit (Yes) or (No)
input double               TPmin = 25.0;             // Input Trailing Profit Value in Pips
input YN           Close_by_Opps = Yes;              // Close Trade By Opposite Signal (Yes) or (No)
input YN               SaveOnRev = Yes;              // Close Trade and Save profit due to weak signal (Yes) or (No)
input YN              CheckVSLTP = No;              // Check Virtual SL/TP & Close Loss Trade (Yes) or (No)
//--Others Expert Advisor Parameter
input group               "=== Others Expert Advisor Parameter ==="; // Others EA Parameter
input YN                  alerts = Yes;              // Display Alerts / Messages (Yes) or (No)
input YN           UseEmailAlert = No;               // Email Alert (Yes) or (No)
input YN           UseSendnotify = No;               // Send Notification (Yes) or (No)
input YN      trade_info_display = Yes;              // Select Display Trading Info on Chart (Yes) or (No)
input ulong              magicEA = 20260504;         // Expert ID (Magic Number)
//---
//---------//
//+------------------------------------------------------------------+
//| Class for working Expert Advisor                                 |
//+------------------------------------------------------------------+
class MCEA
  {
//---
    private:
    //---- 
    int              x_year;       // Year 
    int              x_mon;        // Month 
    int              x_day;        // Day of the month 
    int              x_hour;       // Hour in a day 
    int              x_min;        // Minutes 
    int              x_sec;        // Seconds
    //--
    int              oBm,
                     oSm,
                     ldig;
    //--- Variables used in prefix and suffix symbols
    int              posCur1,
                     posCur2;
    int              inpre,
                     insuf;
    bool             symbfix;
    string           pre,suf;
    string           prefix,suffix;       
    //--- Variables are used in Trading Time Zone
    int              ishour,
                     onhour;
    int              tftrlst,
                     tfcinws;            
    datetime         rem,
                     znop,
                     zncl,
                     zntm;
    datetime         SesCuOp,
                     SesCuCl,
                     Ses01Op,
                     Ses01Cl,
                     Ses02Op,
                     Ses02Cl,
                     Ses03Op,
                     Ses03Cl,
                     Ses04Op,
                     Ses04Cl,
                     Ses05Op,
                     Ses05Cl,
                     SesNoOp,
                     SesNoCl;
    //--
    string           tz_ses,
                     tz_opn,
                     tz_cls;
    //--
    string           tmopcu,
                     tmclcu,
                     tmop01,
                     tmcl01,
                     tmop02,
                     tmcl02,
                     tmop03,
                     tmcl03,
                     tmop04,
                     tmcl04,
                     tmop05,
                     tmcl05,
                     tmopno,
                     tmclno;      
    //----------------------
    //--
    double           LotPS;
    double           point;
    double           slv,
                     tpv,
                     pip,
                     xpip;
    double           floatprofit,
                     fixclprofit;
    double           LastLotx[];
    double           Lotmpx[2];
    //--
    string           pairs,
                     hariini,
                     daytrade,
                     trade_mode;
    //--
    double           OPEN[],
                     HIGH[],
                     LOW[],
                     CLOSE[];
    datetime         TIME[];
    datetime         closetime;
    //--
    //------------
     
    //------------
    void             SetSymbolNamePS(void);
    void             HandlingSymbolArrays(void);
    void             Set_Time_Zone(void);
    void             Time_Zone(void);
    //--
    bool             Trade_session(void);
    bool             CheckLastOrderIFLoss(const string symbx);
    //--
    int              ThisTime(const int reqmode);
    int              ReqTime(datetime reqtime,const int reqmode);
    int              WPRPlus(const string symbol,const ENUM_TIMEFRAMES stf);
    int              DirectionMove(const string symbol,const ENUM_TIMEFRAMES stf);
    int              ADXSignal(const string symbol);
    int              LotDig(const string symbol);
    //--
    double           MLots(const string symbx);
    double           NonZeroDiv(double val1,double val2);
    double           OrderSLSet(const string xsymb,ENUM_ORDER_TYPE type,double atprice);
    double           OrderTPSet(const string xsymb,ENUM_ORDER_TYPE type,double atprice);
    double           SetOrderSL(const string xsymb,ENUM_POSITION_TYPE type,double atprice);
    double           SetOrderTP(const string xsymb,ENUM_POSITION_TYPE type,double atprice);
    double           TSPrice(const string xsymb,ENUM_POSITION_TYPE ptype,int TS_type);
    double           LotMartingale(const string symbol,double lotinit,double lastlot);
    //--
    string           PosTimeZone(void);
    string           ReqDate(int d,int h,int m);
    string           TF2Str(ENUM_TIMEFRAMES period);
    string           timehr(int hr,int mn);
    string           TradingDay(void);
    string           AccountMode();
    string           GetCommentForOrder(void)             { return(expname); }
    //------------

    public:
    //---
    
    //-- ADX_Trend_MCEA Config --
    string           DIRI[],
                     AS30[],
                     VSym[];
    string           SPC[];
    string           USD[];
    string           EUR[];
    string           GBP[];
    string           AUD[];
    string           NZD[];
    string           CAD[];
    string           CHF[];
    string           JPY[];             
    //--                 
    string           expname;
    //--
    //--- Indicators Handle
    int              hSMA20[];
    int              hADX[];
    //---
    int              ALO,
                     dgts,
                     arrsar,
                     arrsymbx;
    int              sall,
                     arusd,
                     areur,
                     aretc,
                     armet,
                     arspc,
                     arper;
    ulong            slip;        
    //--
    double           profitb[],
                     profits[];
    double           minprofit;
    //--
    int              Buy,
                     Sell;
    int              ccur,
                     psec,
                     xtto,
                     TFArrays,
                     checktml;         
    int              OpOr[],xob[],xos[];         
    //--
    int              year,  // Year 
                     mon,   // Month 
                     day,   // Day 
                     hour,  // Hour 
                     min,   // Minutes 
                     sec,   // Seconds 
                     dow,   // Day of week (0-Sunday, 1-Monday, ... ,6-Saturday) 
                     doy;   // Day number of the year (January 1st is assigned the number value of zero)
    //--
    ENUM_TIMEFRAMES  TFt;
    ENUM_TIMEFRAMES  TFASI[];
    //--
    datetime         PbarB[],
                     TbarB[],
                     PbarS[],
                     TbarS[];
    //--
    bool             PanelExtra;
    //------------
                     MCEA(void);
                     ~MCEA(void);            
    //------------
    //--
    virtual void     ADX_Trend_MCEA_Config(void);
    virtual void     ExpertActionTrade(void);
    //--
    void             ArraySymbolResize(void);
    void             CurrentSymbolSet(const string symbol);
    void             Pips(const string symbol);
    void             TradeInfo(void);
    void             Do_Alerts(const string symbx,string msgText);
    void             CheckOpenPMx(const string symbx);
    void             SetSLTPOrders(void);
    void             CloseAllOrders(void);
    void             CheckClose(const string symbx);
    void             TodayOrders(void);
    void             UpdatePrice(const string symbol,ENUM_TIMEFRAMES xtf,int bars);
    void             RefreshPrice(const string symbx,ENUM_TIMEFRAMES xtf,int bars);
    //--
    bool             CheckEquityBalance(void);
    bool             RefreshTick(const string symbx);  
    bool             TradingToday(void);
    bool             OpenBuy(const string symbol);
    bool             OpenSell(const string symbol);
    bool             ModifyOrderSLTP(double mStop,double ordtp);
    bool             ModifyOrdersSL(const string symbx,int TS_type);
    bool             ModifyOrdersTP(const string symbx);
    bool             PartialCloseOrder(const string symbol);
    bool             CloseAllProfit(void);
    bool             CloseAllLoss(void);
    bool             ManualCloseAllProfit(void);
    bool             CheckProfitLoss(const string symbol);
    bool             CloseBuyPositions(const string symbol);
    bool             CloseSellPositions(const string symbol);
    bool             CheckProfit(const string symbol,ENUM_POSITION_TYPE intype);
    bool             CheckLoss(const string symbol,ENUM_POSITION_TYPE intype,double slc=0.0);
    bool             IFNewBarsB(const string symbol);
    bool             IFNewBarsS(const string symbol);
    bool             GoodMarginTrade(const string symbol,ENUM_ORDER_TYPE _cmd,double lotsz,double atprice);
    //--
    int              PairsIdxArray(const string symbol);
    int              TFIndexArray(ENUM_TIMEFRAMES TF);
    int              ValidatePairs(const string symbol);
    int              GetOpenPosition(const string symbol);
    int              GetClosePosition(const string symbol,int exis);
    int              GetCloseInWeakSignal(const string symbol,int exis);
    //--
    string           getUninitReasonText(int reasonCode);
    //--
    //------------
//---
  }; //-end class MCEA
//---------//
 
MCEA mc;

//---------//

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
MCEA::MCEA(void): x_year(0),
                  x_mon(0),
                  x_day(0),
                  x_hour(0),
                  x_min(0),
                  x_sec(0),
                  year(0),
                  mon(1),
                  day(2),
                  hour(3),
                  min(4),
                  sec(5),
                  dow(6),
                  doy(7),
                  psec(0),
                  Buy(1),
                  Sell(-1),
                  slip(16),
                  arper(125),
                  checktml(0),
                  expname("ADX_Trend_MCEA"),
                  closetime(TimeCurrent())
  {
  }
//---------//

//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
MCEA::~MCEA(void)
  {
  }
//---------//

//+------------------------------------------------------------------+
//| Expert Configuration                                             |
//+------------------------------------------------------------------+
void MCEA::ADX_Trend_MCEA_Config(void) 
  {
//---
    //--
    HandlingSymbolArrays(); // With this function we will handle all pairs that will be traded
    //--
    ENUM_TIMEFRAMES TFs[]={PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H2,PERIOD_H3,PERIOD_H4,PERIOD_H6,PERIOD_H8,PERIOD_H12,PERIOD_D1};
    int arTFs=ArraySize(TFs);
    for(int x=0; x<arTFs; x++) if(tfinuse==x) { TFt=TFs[x]; break; } // TF for calculation signal
    //-- Indicators handle for all symbol
    for(int x=0; x<arrsymbx; x++) 
      {
        hADX[x]   = iADX(DIRI[x],TFt,period_ADX);                 //-- Handle for ADX indicator
        hSMA20[x] = iMA(DIRI[x],TFt,20,0,MODE_SMA,PRICE_MEDIAN);  //-- Handle for the SMA 20 indicator for Trailing Stop
        //--
      }
    //--
    TesterHideIndicators(true);
    minprofit=NormalizeDouble(TSmin/100.0,2);
    //--
    ALO=(int)mc_account.LimitOrders()>sall ? sall : (int)mc_account.LimitOrders();
    if(Close_by_Opps==No) 
      {
        if((int)mc_account.LimitOrders()>=(sall*2)) ALO=sall*2;
        else 
        ALO=(int)(mc_account.LimitOrders()/2);
      }
    //--
    LotPS=(double)ALO;
    Lotmpx[0]=lotmp1;
    Lotmpx[1]=lotmp2;
    //--
    mc_trade.SetExpertMagicNumber(magicEA);
    mc_trade.SetDeviationInPoints(slip);
    mc_trade.SetMarginMode();
    Set_Time_Zone();
    //--
    return;
//---
  } //-end ADX_Trend_MCEA_Config()
//---------//

void MCEA::HandlingSymbolArrays(void)
  {
//---
    string All30[]={"EURUSD","GBPUSD","AUDUSD","NZDUSD","USDCAD","USDCHF","USDJPY","EURGBP",
                    "EURAUD","EURNZD","EURCAD","EURCHF","EURJPY","GBPAUD","GBPNZD","GBPCAD",
                    "GBPCHF","GBPJPY","AUDNZD","AUDCAD","AUDCHF","AUDJPY","NZDCAD","NZDCHF",
                    "NZDJPY","CADCHF","CADJPY","CHFJPY","XAUUSD","XAGUSD"}; // 30 pairs
    string USDs[]={"USDCAD","USDCHF","USDJPY","AUDUSD","EURUSD","GBPUSD","NZDUSD","XAUUSD","XAGUSD"}; // USD pairs
    string EURs[]={"EURAUD","EURCAD","EURCHF","EURGBP","EURJPY","EURNZD","EURUSD"}; // EUR pairs
    string GBPs[]={"GBPAUD","GBPCAD","GBPCHF","EURGBP","GBPJPY","GBPNZD","GBPUSD"}; // GBP pairs
    string AUDs[]={"AUDCAD","AUDCHF","EURAUD","GBPAUD","AUDJPY","AUDNZD","AUDUSD"}; // AUD pairs
    string NZDs[]={"AUDNZD","NZDCAD","NZDCHF","EURNZD","GBPNZD","NZDJPY","NZDUSD"}; // NZD pairs
    string CADs[]={"AUDCAD","CADCHF","EURCAD","GBPCAD","CADJPY","NZDCAD","USDCAD"}; // CAD pairs
    string CHFs[]={"AUDCHF","CADCHF","EURCHF","GBPCHF","NZDCHF","CHFJPY","USDCHF"}; // CHF pairs
    string JPYs[]={"AUDJPY","CADJPY","CHFJPY","EURJPY","GBPJPY","NZDJPY","USDJPY"}; // JPY pairs
    string MTLs[]={"XAUUSD","XAGUSD"}; // METAL pairs
    //--
    sall=ArraySize(All30);
    arusd=ArraySize(USDs);
    areur=ArraySize(EURs);
    aretc=ArraySize(JPYs);
    armet=ArraySize(MTLs);
    ArrayResize(VSym,sall,sall);
    ArrayCopy(VSym,All30,0,0,WHOLE_ARRAY);
    //--
    if(usepairs==TrdWi && StringFind(traderwishes,"eg.",0)<0)
      {
        string to_split=traderwishes; // A string to split into substrings pairs name
        string sep=",";               // A separator as a character 
        ushort u_sep;                 // The code of the separator character 
        //--- Get the separator code 
        u_sep=StringGetCharacter(sep,0);
        //--- Split the string to substrings 
        int p=StringSplit(to_split,u_sep,SPC); 
        if(p>0)
          {
            for(int i=0; i<p; i++) StringToUpper(SPC[i]);
            //--
            for(int i=0; i<p; i++)
              {
                if(ValidatePairs(SPC[i])<0) ArrayRemove(SPC,i,1);
              }
          }
        arspc=ArraySize(SPC);
      }
    //--
    SetSymbolNamePS();      // With this function we will detect whether the Symbol Name has a prefix and/or suffix
    //--
    if(inpre>0 || insuf>0)
      {
        if(usepairs==TrdWi && arspc>0)
          {
            for(int t=0; t<arspc; t++)
              {
                SPC[t]=pre+SPC[t]+suf;
              }
          }
        //--
        for(int t=0; t<sall; t++)
          {
            All30[t]=pre+All30[t]+suf;
          }
        for(int t=0; t<arusd; t++)
          {
            USDs[t]=pre+USDs[t]+suf;
          }
        for(int t=0; t<areur; t++)
          {
            EURs[t]=pre+EURs[t]+suf;
          }
        for(int t=0; t<aretc; t++)
          {
            GBPs[t]=pre+GBPs[t]+suf;
          }
        for(int t=0; t<aretc; t++)
          {
            AUDs[t]=pre+AUDs[t]+suf;
          }
        for(int t=0; t<aretc; t++)
          {
            NZDs[t]=pre+NZDs[t]+suf;
          }
        for(int t=0; t<aretc; t++)
          {
            CADs[t]=pre+CADs[t]+suf;
          }
        for(int t=0; t<aretc; t++)
          {
            CHFs[t]=pre+CHFs[t]+suf;
          }
        for(int t=0; t<aretc; t++)
          {
            JPYs[t]=pre+JPYs[t]+suf;
          }
      }
    //--
    ArrayCopy(VSym,All30,0,0,WHOLE_ARRAY);
    ArrayResize(AS30,sall,sall);
    ArrayCopy(AS30,All30,0,0,WHOLE_ARRAY);
    for(int x=0; x<sall; x++) {SymbolSelect(AS30[x],true);}
    if(ValidatePairs(Symbol())>=0) symbfix=true;
    if(!symbfix) 
      {
        Alert("Expert Advisors will not trade on pairs "+Symbol());
        Alert("-- "+expname+" -- ",Symbol()," -- expert advisor will be Remove from the chart.");
        ExpertRemove();
      }
    //--
    switch(usepairs)
      {
        case 0: // All Forex & Metal 30 Pairs
          {
            ArrayResize(DIRI,sall,sall);
            arrsymbx=sall;
            ArraySymbolResize();
            ArrayCopy(DIRI,All30,0,0,WHOLE_ARRAY);
            pairs="Multi Currency "+string(sall)+" Pairs";
            //--
            break;
          }
        case 1: // Trader wishes pairs
          {
            ArrayResize(DIRI,arspc,arspc);
            arrsymbx=arspc;
            ArraySymbolResize();
            ArrayCopy(DIRI,SPC,0,0,WHOLE_ARRAY);
            pairs="("+string(arspc)+") Trader Wishes Pairs";
            //--
            break;
          }
        case 2: // USD pairs
          {
            ArrayResize(DIRI,arusd,arusd);
            arrsymbx=arusd;
            ArraySymbolResize();
            ArrayCopy(DIRI,USDs,0,0,WHOLE_ARRAY);
            pairs="("+string(arusd)+") Multi Currency USD Pairs";
            //--
            break;
          }
        case 3: // EUR pairs
          {
            ArrayResize(DIRI,areur,areur);
            arrsymbx=aretc;
            ArraySymbolResize();
            ArrayCopy(DIRI,EURs,0,0,WHOLE_ARRAY);
            pairs="("+string(aretc)+") Forex EUR Pairs";
            //--
            break;
          }
        case 4: // GBP pairs
          {
            ArrayResize(DIRI,aretc,aretc);
            arrsymbx=aretc;
            ArraySymbolResize();
            ArrayCopy(DIRI,GBPs,0,0,WHOLE_ARRAY);
            pairs="("+string(aretc)+") Forex GBP Pairs";
            //--
            break;
          }
        case 5: // AUD pairs
          {
            ArrayResize(DIRI,aretc,aretc);
            arrsymbx=aretc;
            ArraySymbolResize();
            ArrayCopy(DIRI,AUDs,0,0,WHOLE_ARRAY);
            pairs="("+string(aretc)+") Forex AUD Pairs";
            //--
            break;
          }
        case 6: // NZD pairs
          {
            ArrayResize(DIRI,aretc,aretc);
            arrsymbx=aretc;
            ArraySymbolResize();
            ArrayCopy(DIRI,NZDs,0,0,WHOLE_ARRAY);
            pairs="("+string(aretc)+") Forex NZD Pairs";
            //--
            break;
          }
        case 7: // CAD pairs
          {
            ArrayResize(DIRI,aretc,aretc);
            arrsymbx=aretc;
            ArraySymbolResize();
            ArrayCopy(DIRI,CADs,0,0,WHOLE_ARRAY);
            pairs="("+string(aretc)+") Forex CAD Pairs";
            //--
            break;
          }
        case 8: // CHF pairs
          {
            ArrayResize(DIRI,aretc,aretc);
            arrsymbx=aretc;
            ArraySymbolResize();
            ArrayCopy(DIRI,CHFs,0,0,WHOLE_ARRAY);
            pairs="("+string(aretc)+") Forex CHF Pairs";
            //--
            break;
          }
        case 9: // JPY pairs
          {
            ArrayResize(DIRI,aretc,aretc);
            arrsymbx=aretc;
            ArraySymbolResize();
            ArrayCopy(DIRI,JPYs,0,0,WHOLE_ARRAY);
            pairs="("+string(aretc)+") Forex JPY Pairs";
            //--
            break;
          }
        case 10: // Metal pairs
          {
            ArrayResize(DIRI,armet,armet);
            arrsymbx=armet;
            ArraySymbolResize();
            ArrayCopy(DIRI,MTLs,0,0,WHOLE_ARRAY);
            pairs="("+string(armet)+") Metal Pairs";
            //--
            break;
          }
      }
    //--
    return;
//---
  } //-end HandlingSymbolArrays()
//---------//

void MCEA::SetSymbolNamePS(void)
  {
//---
   int sym_Lenpre=0;
   int sym_Lensuf=0;
   string sym_pre="";
   string sym_suf="";
   SymbolSelect(Symbol(),true);
   string insymbol=Symbol();
   int inlen=StringLen(insymbol);
   int toseek=-1;
   string dep="";
   string bel="";
   string sym_use ="";
   int pairx=-1;
   string xcur[]={"EUR","GBP","AUD","NZD","USD","CAD","CHF"}; // 7 major currency
   int xcar=ArraySize(xcur);
   //--
   for(int x=0; x<xcar; x++)
     {
       toseek=StringFind(insymbol,xcur[x],0);
       if(toseek>=0)
         {
           pairx=x;
           break;
         }
     }
   if(pairx>=0)
     {
       int awl=toseek-3 <0 ? 0 : toseek-3;
       int sd=StringFind(insymbol,"SD",0);
       if(toseek==0 && sd<4)
         {
           dep=StringSubstr(insymbol,toseek,3);
           bel=StringSubstr(insymbol,toseek+3,3);
           sym_use=dep+bel;
         }
       else
       if(toseek>0)
         {
           dep=StringSubstr(insymbol,toseek,3);
           bel=StringSubstr(insymbol,toseek+3,3);
           sym_use=dep+bel;
         }
       else
         {
           dep=StringSubstr(insymbol,awl,3);
           bel=StringSubstr(insymbol,awl+3,3);
           sym_use=dep+bel;
         }
     }
   //--
   string sym_nmx=sym_use;
   int lensx=StringLen(sym_nmx);
   //--
   if(inlen>lensx && lensx==6)
     {
       sym_Lenpre=StringFind(insymbol,sym_nmx,0);
       sym_Lensuf=inlen-lensx-sym_Lenpre;
       //--
       if(sym_Lenpre>0)
         {
           sym_pre=StringSubstr(insymbol,0,sym_Lenpre);
           for(int i=0; i<xcar; i++)
             if(StringFind(sym_pre,xcur[i],0)>=0) sym_pre="";
         }
       if(sym_Lensuf>0)
         {
           sym_suf=StringSubstr(insymbol,sym_Lenpre+lensx,sym_Lensuf);
           for(int i=0; i<xcar; i++)
             if(StringFind(sym_suf,xcur[i],0)>=0) sym_suf="";
         }
     }
   //--
   pre=sym_pre;
   suf=sym_suf;
   inpre=StringLen(pre);
   insuf=StringLen(suf);
   posCur1=inpre;
   posCur2=posCur1+3;
   //--
   return;
//---
  } //-end SetSymbolNamePS()
//---------//

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit(void)
  {
//---
   mc.ADX_Trend_MCEA_Config();
   //--
   return(INIT_SUCCEEDED);
//---
  } //-end OnInit()
//---------//
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   Comment("");
   //-- Release all handle indicators for all symbols
   for(int x=0; x<mc.arrsymbx; x++) 
     {
       IndicatorRelease(mc.hADX[x]);
       IndicatorRelease(mc.hSMA20[x]);
     }
   //--
   PrintFormat("%s: Deinitialization reason code=%d",__FUNCTION__,reason);
   Print(mc.getUninitReasonText(reason));
   ObjectsDeleteAll(0,0,OBJ_BUTTON);
   ObjectsDeleteAll(0,0,OBJ_LABEL);
   ObjectsDeleteAll(0,0,OBJ_RECTANGLE_LABEL);
   //--
   return;
//---
  } //-end OnDeinit()
//---------//
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick(void)
  {
//---
    mc.ExpertActionTrade();
    //--
    return;
//---
  } //-end OnTick()
//---------//
//+------------------------------------------------------------------+

void MCEA::ExpertActionTrade(void)
  {
//---
    //--Check Trading Terminal
    ResetLastError();
    //--
    if(!MQLInfoInteger(MQL_TRADE_ALLOWED) && mc.checktml==0) //-- Check whether MT5 Algorithmic trading is Allow or Prohibit
      {
        mc.Do_Alerts(Symbol(),"Trading Expert at "+Symbol()+" are NOT Allowed by Setting.");
        mc.checktml=1;  //-- Variable checktml is given a value of 1, so that the alert is only done once.
        return;
      }
    //--
    if(!DisplayManualButton("M","C","R")) DisplayManualButton(); //-- Show the expert manual button panel
    //--
    if(trade_info_display==Yes) mc.TradeInfo(); //-- Displayed Trading Info on Chart
    //---
    //--
    int mcsec=mc.ThisTime(mc.sec); 
    //--
    if(fmod((double)mcsec,5.0)==0) mc.ccur=mcsec;
    //--
    if(mc.ccur!=mc.psec)
      {
        string symbol;
        //-- Here we start with the rotation of the name of all symbol or pairs to be traded
        for(int x=0; x<mc.arrsymbx && !IsStopped(); x++) 
          {
            //--
            switch(trademode)
              {
                case SP:
                  {
                    if(mc.DIRI[x]!=Symbol()) continue;
                    symbol=Symbol();
                    mc.pairs="Single Pair"+" ("+symbol+")";
                    break;
                  }
                case MP:
                  {
                    if(mc.DIRI[x]==Symbol()) symbol=Symbol();
                    else symbol=mc.DIRI[x];
                    break;
                  }
              }
            //--
            mc.CurrentSymbolSet(symbol);
            //--
            if(mc.TradingToday() && mc.Trade_session())
              {
                //--
                mc.OpOr[x]=mc.GetOpenPosition(symbol); //-- Get trading signals to open positions
                //--                                   //-- and store in the variable OpOr[x]
                if(mc.OpOr[x]==mc.Buy) //-- If variable OpOr[x] get result of GetOpenPosition(symbol) as "Buy" (value=1)
                  {
                    //--
                    mc.CheckOpenPMx(symbol);
                    //--
                    if(Close_by_Opps==Yes && mc.xos[x]>0) { mc.CloseSellPositions(symbol); mc.OpenBuy(symbol); }
                    //--
                    if(mc.xob[x]==0 && mc.xtto<mc.ALO && mc.IFNewBarsB(symbol)) mc.OpenBuy(symbol);
                    else
                    if(mc.xtto>=mc.ALO)
                      {
                        //--
                        mc.Do_Alerts(symbol,"Maximum amount of open positions and active pending orders has reached"+
                                            "\n the limit = "+string(mc.ALO)+" Orders ");
                        //--
                        mc.CheckOpenPMx(symbol);
                        //--
                        if(mc.xos[x]>0 && mc.profits[x]<-1.02 && mc.xob[x]==0) { mc.CloseSellPositions(symbol); mc.OpenBuy(symbol); }
                        else
                          mc.CloseAllProfit();
                        //--
                      }
                  }
                if(mc.OpOr[x]==mc.Sell) //-- If variable OpOr[x] get result of GetOpenPosition(symbol) as "Sell" (value=-1)
                  {
                    //--
                    mc.CheckOpenPMx(symbol);
                    //--
                    if(Close_by_Opps==Yes && mc.xob[x]>0) { mc.CloseBuyPositions(symbol); mc.OpenSell(symbol); }
                    //--
                    if(mc.xos[x]==0 && mc.xtto<mc.ALO && mc.IFNewBarsS(symbol)) mc.OpenSell(symbol);
                    else
                    if(mc.xtto>=mc.ALO)
                      {
                        //--
                        mc.Do_Alerts(symbol,"Maximum amount of open positions and active pending orders has reached"+
                                            "\n the limit = "+string(mc.ALO)+" Orders ");
                        //--
                        mc.CheckOpenPMx(symbol);
                        //--
                        if(mc.xob[x]>0 && mc.profitb[x]<-1.02 && mc.xos[x]==0) { mc.CloseBuyPositions(symbol); mc.OpenSell(symbol); }
                        else
                          mc.CloseAllProfit();
                        //--
                      }
                  }
              }
            //--
            mc.CheckOpenPMx(symbol);
            //--
            if(mc.xtto>0)
              {
                //--
                if(PartialClose==Yes) //-- Partial Close Order (Yes)
                  {
                    PartialCloseOrder(symbol);
                  }
                //--
                if(SaveOnRev==Yes) //-- Close Trade and Save profit due to weak signal (Yes)
                  {
                    mc.CheckOpenPMx(symbol);
                    if(mc.profitb[x]>mc.minprofit && mc.xob[x]>0 && mc.GetCloseInWeakSignal(symbol,mc.Buy)==mc.Sell) 
                      {
                        mc.CloseBuyPositions(symbol); 
                        mc.Do_Alerts(symbol,"Close BUY order "+symbol+" to save profit due to weak signal.");
                      }
                    if(mc.profits[x]>mc.minprofit && mc.xos[x]>0 && mc.GetCloseInWeakSignal(symbol,mc.Sell)==mc.Buy)
                      {
                        mc.CloseSellPositions(symbol); 
                        mc.Do_Alerts(symbol,"Close SELL order "+symbol+" to save profit due to weak signal.");
                      }
                  }
                //--
                if(TrailingSL==Yes) mc.ModifyOrdersSL(symbol,trlby); //-- Use Trailing Stop Loss (Yes)
                if(TrailingTP==Yes) mc.ModifyOrdersTP(symbol);       //-- Use Trailing Take Profit (Yes)
              }
            //--
            mc.CheckOpenPMx(symbol);
            if(Close_by_Opps==No && (mc.xob[x]+mc.xos[x]>1))
              {
                mc.CheckProfitLoss(symbol);
                mc.Do_Alerts(symbol,"Close order due stop in loss.");
              }
            //--
            if(use_sl==No && CheckVSLTP==Yes)
              {
                if(!mc.CheckEquityBalance())
                  if(mc.CloseAllLoss())
                    mc.Do_Alerts(symbol,"Close order due stop in loss to secure equity.");
              }
            //--
            mc.CheckClose(symbol);
          }
        //--
        mc.psec=mc.ccur;
      }
    //--
    return;
//---
  } //-end ExpertActionTrade()
//---------//

int MCEA::PairsIdxArray(const string symbol)
  {
//---
    int pidx=-1;
    //--
    for(int x=0; x<arrsymbx; x++)
      {
        if(DIRI[x]==symbol)
          {
            pidx=x;
            break;
          }
      } 
    //--
    return(pidx);
//---
  } //-end PairsIdxArray()
//---------//

int MCEA::TFIndexArray(ENUM_TIMEFRAMES TF)
  {
//---
    int res=-1;
    //--
    for(int x=0; x<TFArrays; x++)
      {
        if(TF==TFASI[x])
          {
            res=x;
            break;
          }
      }
    //--
    return(res);
//---
  } //-end TFIndexArray() 
//---------//

int MCEA::ValidatePairs(const string symbol)
  {
//---
    int pidx=-1;
    //--
    for(int x=0; x<sall; x++)
      {
        if(VSym[x]==symbol)
          {
            pidx=x;
            break;
          }
      } 
    //--
    return(pidx);
//---
  } //-end ValidatePairs()
//---------//

void MCEA::ArraySymbolResize(void)
  {
//---
    ArrayFree(DIRI);
    ArrayFree(xob);
    ArrayFree(xos);
    ArrayFree(OpOr);
    ArrayFree(profitb);
    ArrayFree(profits);
    ArrayFree(hADX);
    ArrayFree(hSMA20);
    ArrayFree(PbarB);
    ArrayFree(TbarB);
    ArrayFree(PbarS);
    ArrayFree(TbarS);
    ArrayFree(LastLotx);
    //--
    ArrayResize(DIRI,arrsymbx,arrsymbx);
    ArrayResize(xob,arrsymbx,arrsymbx);
    ArrayResize(xos,arrsymbx,arrsymbx);
    ArrayResize(OpOr,arrsymbx,arrsymbx);
    ArrayResize(profitb,arrsymbx,arrsymbx);
    ArrayResize(profits,arrsymbx,arrsymbx);
    ArrayResize(hADX,arrsymbx,arrsymbx);
    ArrayResize(hSMA20,arrsymbx,arrsymbx);
    ArrayResize(PbarB,arrsymbx,arrsymbx);
    ArrayResize(TbarB,arrsymbx,arrsymbx);
    ArrayResize(PbarS,arrsymbx,arrsymbx);
    ArrayResize(TbarS,arrsymbx,arrsymbx);
    ArrayResize(LastLotx,arrsymbx,arrsymbx);
    //--
    return;
//---
  } //-end ArraySymbolResize()
//---------//

void MCEA::UpdatePrice(const string symbol,ENUM_TIMEFRAMES xtf,int bars=0)
  {
//---
    int xbar=bars==0 ? arper : bars;
    //--
    ArrayFree(OPEN);
    ArrayFree(HIGH);
    ArrayFree(LOW);
    ArrayFree(CLOSE);
    ArrayFree(TIME);
    //--
    ArrayResize(OPEN,xbar,xbar);
    ArrayResize(HIGH,xbar,xbar);
    ArrayResize(LOW,xbar,xbar);
    ArrayResize(CLOSE,xbar,xbar);
    ArrayResize(TIME,xbar,xbar);
    //--
    ArraySetAsSeries(OPEN,true);
    ArraySetAsSeries(HIGH,true);
    ArraySetAsSeries(LOW,true);
    ArraySetAsSeries(CLOSE,true);
    ArraySetAsSeries(TIME,true);
    //--
    ArrayInitialize(OPEN,0.0);
    ArrayInitialize(HIGH,0.0);
    ArrayInitialize(LOW,0.0);
    ArrayInitialize(CLOSE,0.0);
    ArrayInitialize(TIME,0);    
    //--
    RefreshPrice(symbol,xtf,bars);
    //--
    int co=CopyOpen(symbol,xtf,0,xbar,OPEN);
    int ch=CopyHigh(symbol,xtf,0,xbar,HIGH);
    int cl=CopyLow(symbol,xtf,0,xbar,LOW);
    int cc=CopyClose(symbol,xtf,0,xbar,CLOSE);
    int ct=CopyTime(symbol,xtf,0,xbar,TIME);
   //--
   return;
//---
  } //-end UpdatePrice()
//---------//

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

bool MCEA::RefreshTick(const string symbx)
  {
//---
    mc_symbol.Name(symbx); 
    if(mc_symbol.RefreshRates()) return(true);
    //--
    return(false);
//---
  } //-end RefreshTick()
//---------//

void MCEA::CurrentSymbolSet(const string symbol)
  {
//---
   mc_symbol.Name(symbol);
   mc_symbol.CheckMarketWatch();
   mc_symbol.IsSynchronized();
   mc_trade.SetTypeFillingBySymbol(symbol);
   mc_symbol.Refresh();
   mc_symbol.RefreshRates();
   //--
   return;
//---
  } //-end CurrentSymbolSet()
//---------//

void MCEA::Pips(const string symbol)
  {
//---
   CurrentSymbolSet(symbol);
   //--
   point=mc_symbol.Point();
   dgts=(int)mc_symbol.Digits();
   //--
   xpip=10.0; 
   pip=point*xpip;
   //--
   return;
//---
  } //-end Pips()
//---------//

bool MCEA::IFNewBarsB(const string symbol) // New bar check buy order
  {
//---
    bool Nb=false;
    int xs=PairsIdxArray(symbol);
    //--
    TbarB[xs]=iTime(symbol,TFt,0);
    if(TbarB[xs]!=PbarB[xs]) Nb=true;
    //--
    return(Nb);
//---
  } //-end IFNewBarsB()
//---------//

bool MCEA::IFNewBarsS(const string symbol) // New bar check sell order
  {
//---
    bool Nb=false;
    int xs=PairsIdxArray(symbol);
    //--
    TbarS[xs]=iTime(symbol,TFt,0);
    if(TbarS[xs]!=PbarS[xs]) Nb=true;
    //--
    return(Nb);
//---
  } //-end IFNewBarsS()
//---------//

bool MCEA::GoodMarginTrade(const string symbol,ENUM_ORDER_TYPE _cmd,double lotsz,double atprice)
  {
//---
   bool goodmrgn=true;
   //--
   if((mc_account.FreeMarginCheck(symbol,_cmd,lotsz,atprice)<=0.0)||(mc_account.FreeMargin()<(mc_account.Equity()*maxmrgn/100))) goodmrgn=false;
   //--
   if(!goodmrgn)
     {
       string nomargn="Account Free Margin minimum has reached the specified limit, Order will not opened";
       Do_Alerts(symbol,nomargn);
     }
   //--
   return(goodmrgn);
//---
  } //-end GoodMarginTrade()
//---------//

int MCEA::DirectionMove(const string symbol,const ENUM_TIMEFRAMES stf) // Bar Price Direction 
  {
//---
    int ret=0;
    int rise=1,
        down=-1;
    //--
    Pips(symbol);
    double difud=mc_symbol.NormalizePrice(2.6*pip);
    UpdatePrice(symbol,stf,2);
    //--
    if(CLOSE[0]>OPEN[0]+difud) ret=rise;
    if(CLOSE[0]<OPEN[0]-difud) ret=down;
    //--
    return(ret);
//---
  } //-end DirectionMove()
//---------//

int MCEA::WPRPlus(const string symbol,const ENUM_TIMEFRAMES stf)
  {
//---
    int ret=0;
    int rise=1,
        down=-1;
    //--
    double wprpos=0.0;
    int wperiod=14;
    //--
    UpdatePrice(symbol,stf);
    //--
    double WPRP[];
    double RANGEP[];
    ArrayResize(WPRP,arper,arper);
    ArrayResize(RANGEP,arper,arper);
    ArraySetAsSeries(WPRP,true);
    ArraySetAsSeries(RANGEP,true);
    //--
    for(int i=arper-2; i>=0; i--)
      {
        double RHigh = HIGH[ArrayMaximum(HIGH,i,wperiod)];
        double RLow  = LOW[ArrayMinimum(LOW,i,wperiod)];
        RANGEP[i]=NonZeroDiv((RHigh-CLOSE[i]),(RHigh-RLow))*100;
        WPRP[i]=100-fabs(RANGEP[i]);
        if(i==0) 
          {
            wprpos=NormalizeDouble(WPRP[i],2);
            if(WPRP[0]>WPRP[1] && wprpos<80.00) ret=rise;
            if(WPRP[0]<WPRP[1] && wprpos>20.00) ret=down;
          }
      }
    //--
    return(ret);
//---
  } //-end WPRPlus()
//---------//

int MCEA::ADXSignal(const string symbol) // Stochastic Degree Signal for Open Position
  {
//---
    int ret=0;
    int rise=1,
        down=-1;
    int risex=-2;
    int downx=2;
    int barcalc=arper;
    //--
    double ADIp[];
    double ADIm[];
    //--
    ArrayResize(ADIp,barcalc,barcalc);
    ArrayResize(ADIm,barcalc,barcalc);
    ArraySetAsSeries(ADIp,true);
    ArraySetAsSeries(ADIm,true);
    //--
    int xs=PairsIdxArray(symbol);
    mc_indicator.Refresh(TFt);
    //--
    CopyBuffer(hADX[xs],1,0,barcalc,ADIp);
    CopyBuffer(hADX[xs],2,0,barcalc,ADIm);
    //--
    if(ADIp[2]<=ADIm[2] && ADIp[1]>ADIm[1] && ADIp[0]>=ADIp[1]) ret=rise;
    if(ADIp[2]>=ADIm[2] && ADIp[1]<ADIm[1] && ADIp[0]<=ADIp[1]) ret=down;
    //--
    if(ADIp[0]>ADIm[0] && ADIp[0]<ADIp[1]) ret=risex;
    if(ADIp[0]<ADIm[0] && ADIp[0]>ADIp[1]) ret=downx;
    //--
    return(ret);
//---
  } //-end ADXSignal()
//---------//

int MCEA::GetOpenPosition(const string symbol) // Signal Open Position 
  {
//---
    int ret=0;
    int rise=1,
        down=-1;
    //--
    int WPRMove=WPRPlus(symbol,TFt);
    int dirmove=DirectionMove(symbol,TFt);
    int ADSignal=ADXSignal(symbol);
    //--
    if(ADSignal==rise && dirmove==rise && WPRMove==rise) ret=rise;
    if(ADSignal==down && dirmove==down && WPRMove==down) ret=down;
    //--
    return(ret);
//---
  } //-end GetOpenPosition()
//---------//

int MCEA::GetClosePosition(const string symbol,int exis) // Signal Close Position 
  {
//---
    int ret=0;
    int rise=1,
        down=-1;
    int risex=-2;
    int downx=2;
    //--
    int dirmove=DirectionMove(symbol,TFt);
    int ADSignal=ADXSignal(symbol);
    //--
    if((exis==down) && (ADSignal==downx && dirmove==rise)) ret=rise;
    if((exis==rise) && (ADSignal==risex && dirmove==down)) ret=down;
    //--
    return(ret);
//---
  } //-end GetClosePosition()
//---------//

int MCEA::GetCloseInWeakSignal(const string symbol,int exis) // Signal Indicator Position Close in profit
  {
//---
    int ret=0;
    int rise=1,
        down=-1;
    //--
    if(exis==down && GetClosePosition(symbol,down)) ret=rise;
    if(exis==rise && GetClosePosition(symbol,rise)) ret=down;
    //--
    return(ret);
//---
  } //-end GetCloseInWeakSignal()
//---------//

double MCEA::LotMartingale(const string symbol,double lotinit,double lastlot)
  {
//---
    double lotmart=0.0;
    //--
    double lotx1=NormalizeDouble(lotinit*Lotmpx[0],LotDig(symbol));
    double lotx2=NormalizeDouble(lotx1*Lotmpx[1],LotDig(symbol));
    //--
    if(lastlot>=lotx2) lotmart=lotinit;
    else
    if(lastlot>=lotx1 && lastlot<lotx2) lotmart=lotx2;
    else lotmart=lotx1;
    //--
    return(lotmart);
//---
  } //-end LotMartingale()
//---------//

bool MCEA::OpenBuy(const string symbol) 
  {
//---
    ResetLastError();
    //--
    bool buyopen      = false;
    string ldComm     = GetCommentForOrder()+"_Buy";
    double ldLot      = MLots(symbol);
    ENUM_ORDER_TYPE type_req = ORDER_TYPE_BUY;
    //--
    if(UseMartin==Yes)
      {
        int xs=PairsIdxArray(symbol);
        if(CheckLastOrderIFLoss(symbol))
          {
            double lotmx=LotMartingale(symbol,ldLot,LastLotx[xs]);
            if(lotmx>=ldLot) ldLot=lotmx;
            Do_Alerts(symbol,"Increase Lot size from = "+DoubleToString(LastLotx[xs],LotDig(symbol))+
            " to = "+DoubleToString(ldLot,LotDig(symbol)));
          }
      }
    //--
    if(!GoodMarginTrade(symbol,type_req,ldLot,mc_symbol.Ask())) return(false);
    //--
    MqlTradeRequest req={};
    MqlTradeResult  res={};
    MqlTradeCheckResult check={};
    //-- structure is set to zero
    ZeroMemory(req);
    ZeroMemory(res);
    ZeroMemory(check);
    //--
    CurrentSymbolSet(symbol);
    double SL=OrderSLSet(symbol,type_req,mc_symbol.Bid());
    double TP=OrderTPSet(symbol,type_req,mc_symbol.Ask());
    //--
    if(RefreshTick(symbol))
       buyopen=mc_trade.Buy(ldLot,symbol,mc_symbol.Ask(),SL,TP,ldComm);
    //--
    int error=GetLastError();
    if(buyopen||error==0)
      {
        string bsopen="Open BUY Order for "+symbol+" ~ Ticket= ["+(string)mc_trade.ResultOrder()+"] successfully..!";
        Do_Alerts(symbol,bsopen);
        int xi=PairsIdxArray(symbol);
        PbarB[xi]=iTime(symbol,TFt,0);
      }
    else
      {
        mc_trade.CheckResult(check);
        Do_Alerts(Symbol(),"Open BUY order for "+symbol+" FAILED!!. Return code= "+
                 (string)mc_trade.ResultRetcode()+". Code description: ["+mc_trade.ResultRetcodeDescription()+"]");
        return(false);   
      }
    //--
    return(buyopen);
    //--
//---
  } //-end OpenBuy
//---------//

bool MCEA::OpenSell(const string symbol) 
  {
//---
    ResetLastError();
    //--
    bool selopen      = false;
    string sdComm     = GetCommentForOrder()+"_Sell";
    double sdLot      = MLots(symbol);
    ENUM_ORDER_TYPE type_req = ORDER_TYPE_SELL;
    //--
    if(UseMartin==Yes)
      {
        int xs=PairsIdxArray(symbol);
        if(CheckLastOrderIFLoss(symbol))
          {
            double lotmx=LotMartingale(symbol,sdLot,LastLotx[xs]);
            if(lotmx>=sdLot) sdLot=lotmx;
            Do_Alerts(symbol,"Increase Lot size from = "+DoubleToString(LastLotx[xs],LotDig(symbol))+
            " to = "+DoubleToString(sdLot,LotDig(symbol)));
          }
      }
    //--
    if(!GoodMarginTrade(symbol,type_req,sdLot,mc_symbol.Ask())) return(false);
    //--
    MqlTradeRequest req={};
    MqlTradeResult  res={};
    MqlTradeCheckResult check={};
    //-- structure is set to zero
    ZeroMemory(req);
    ZeroMemory(res);
    ZeroMemory(check);
    //--
    CurrentSymbolSet(symbol);
    double SL=OrderSLSet(symbol,type_req,mc_symbol.Ask());
    double TP=OrderTPSet(symbol,type_req,mc_symbol.Bid());
    //--
    if(RefreshTick(symbol))
       selopen=mc_trade.Sell(sdLot,symbol,mc_symbol.Bid(),SL,TP,sdComm);
    //--
    int error=GetLastError();
    if(selopen||error==0)
      {
        string bsopen="Open SELL Order for "+symbol+" ~ Ticket= ["+(string)mc_trade.ResultOrder()+"] successfully..!";
        Do_Alerts(symbol,bsopen);
        int xi=PairsIdxArray(symbol);
        PbarS[xi]=iTime(symbol,TFt,0);
      }
    else
      {
        mc_trade.CheckResult(check);
        Do_Alerts(Symbol(),"Open SELL order for "+symbol+" FAILED!!. Return code= "+
                 (string)mc_trade.ResultRetcode()+". Code description: ["+mc_trade.ResultRetcodeDescription()+"]");
        return(false);   
      }
    //--
    return(selopen);
    //--
//---
  } //-end OpenSell
//---------//

double MCEA::OrderSLSet(const string xsymb,ENUM_ORDER_TYPE type,double atprice)
  {
//---
    slv=0.0;
    int x=PairsIdxArray(xsymb);
    Pips(xsymb);
    RefreshTick(xsymb);
    //--
    switch(type) 
      { 
       case (ORDER_TYPE_BUY):
         {
           if(use_sl==Yes && autosl==Yes) slv=mc_symbol.NormalizePrice(atprice-38*pip);
           else
           if(use_sl==Yes && autosl==No)  slv=mc_symbol.NormalizePrice(atprice-SLval*pip);
           else slv=0.0;
           //--
           break;
         }
       case (ORDER_TYPE_SELL):
         {
           if(use_sl==Yes && autosl==Yes) slv=mc_symbol.NormalizePrice(atprice+38*pip);
           else
           if(use_sl==Yes && autosl==No)  slv=mc_symbol.NormalizePrice(atprice+SLval*pip);
           else slv=0.0;
         }
      }
    //---
    return(slv);
//---
  } //-end OrderSLSet()
//---------//

double MCEA::OrderTPSet(const string xsymb,ENUM_ORDER_TYPE type,double atprice)
  {
//---
    tpv=0.0;
    int x=PairsIdxArray(xsymb);
    Pips(xsymb);
    RefreshTick(xsymb);
    //--
    switch(type) 
      { 
       case (ORDER_TYPE_BUY):
         {
           if(use_tp==Yes && autotp==Yes) tpv=mc_symbol.NormalizePrice(atprice+50*pip);
           else
           if(use_tp==Yes && autotp==No)  tpv=mc_symbol.NormalizePrice(atprice+TPval*pip);
           else tpv=0.0;
           //--
           break;
         }
       case (ORDER_TYPE_SELL):
         {
           if(use_tp==Yes && autotp==Yes) tpv=mc_symbol.NormalizePrice(atprice-50*pip);
           else
           if(use_tp==Yes && autotp==No)  tpv=mc_symbol.NormalizePrice(atprice-TPval*pip);
           else tpv=0.0;
         }
      }
    //---
    return(tpv);
//---
  } //-end OrderTPSet()
//---------//

void MCEA::CheckOpenPMx(const string symbx) //-- function: CheckOpenTrade.
  {
//---
    int totalorder=PositionsTotal();
    xtto=totalorder;
    //--
    int xi=PairsIdxArray(symbx);
    xob[xi]=0;
    xos[xi]=0;
    profitb[xi]=0.0;
    profits[xi]=0.0;
    double pos_profit = 0.0;
    double pos_swap   = 0.0;
    double pos_comm   = 0.0;
    //--    
    for(int i=0; i<totalorder && !IsStopped(); i++)
      {
        string position_symbol=PositionGetSymbol(i);
        long magic = mc_position.Magic();
        if(position_symbol==symbx && magic==magicEA)
          {
            //--
            ENUM_POSITION_TYPE opstype = mc_position.PositionType();
            if(opstype == POSITION_TYPE_BUY)
              {
                xob[xi]++;
                pos_profit   = mc_position.Profit();
                pos_swap     = mc_position.Swap();
                pos_comm     = mc_position.Commission();
                profitb[xi] += NormalizeDouble(pos_profit+pos_swap+pos_comm,2);
                PbarB[xi]    = iTime(symbx,TFt,0);
              }
            if(opstype == POSITION_TYPE_SELL) 
              {
                xos[xi]++;
                pos_profit   = mc_position.Profit();
                pos_swap     = mc_position.Swap();
                pos_comm     = mc_position.Commission();
                profits[xi] += NormalizeDouble(pos_profit+pos_swap+pos_comm,2);
                PbarS[xi]    = iTime(symbx,TFt,0);
              }
            //--
          }
      }
    //---
    return;
//---
  } //-end CheckOpenPMx()
//---------//

bool MCEA::PartialCloseOrder(const string symbx)
  {
//---
   ResetLastError();
   //--
   double partClsB=0.0;
   double partClsS=0.0;
   bool partcls=false;
   Pips(symbx);
   //--
   int total=PositionsTotal();
   //--        
   for(int i=total-1; i>=0; i--) 
     {
       string symbol=PositionGetSymbol(i);
       if(symbol==symbx && mc_position.Magic()==magicEA)
         {
           ENUM_POSITION_TYPE opstype = mc_position.PositionType();
           if(opstype==POSITION_TYPE_BUY) 
             {
               RefreshTick(symbol);
               double price      = mc_position.PriceCurrent();
               double pos_open   = mc_position.PriceOpen();
               double partClsB   = mc_symbol.NormalizePrice(price-pos_open);
               double pos_vol    = mc_position.Volume();
               double part_vol   = NormalizeDouble((pos_vol*(percentlots/100.0)),LotDig(symbx));
               //--
               double vol_close = pos_vol==mc_symbol.LotsMin() ? pos_vol : (pos_vol-part_vol)>mc_symbol.LotsMin() ? 
                                  part_vol : (pos_vol-part_vol)<mc_symbol.LotsMin() ? pos_vol : (pos_vol-mc_symbol.LotsMin());
               vol_close=NormalizeDouble(vol_close,LotDig(symbx));
               //--
               bool closePartBuy = (partClsB>=(profitinpips*pip));
               //--
               if(closePartBuy) partcls=mc_trade.PositionClosePartial(symbx,vol_close,slip);
               if(partcls) 
                 {
                   string remvol=pos_vol-part_vol > 0.0 ? "\n ~ Remaining Vol: "+DoubleToString(pos_vol-part_vol,LotDig(symbx)) : "";
                   Do_Alerts(symbol, DoubleToString(percentlots,2)+ "% Volume Cut for "+symbx+" Success!"+remvol);  
                   break;
                 }
             }
           if(opstype==POSITION_TYPE_SELL) 
             {
               RefreshTick(symbol);
               double price      = mc_position.PriceCurrent();
               double pos_open   = mc_position.PriceOpen();
               double partClsS   = mc_symbol.NormalizePrice(pos_open-price);
               double pos_vol    = mc_position.Volume();
               double part_vol   = NormalizeDouble((pos_vol*(percentlots/100.0)),LotDig(symbx));
               //--
               double vol_close = pos_vol==mc_symbol.LotsMin() ? pos_vol : (pos_vol-part_vol)>mc_symbol.LotsMin() ? 
                                  part_vol : (pos_vol-part_vol)<mc_symbol.LotsMin() ? pos_vol : (pos_vol-mc_symbol.LotsMin());
               vol_close=NormalizeDouble(vol_close,LotDig(symbx));
               //--
               bool closePartSell = (partClsS>=(profitinpips*pip));
               //--
               if(closePartSell) partcls=mc_trade.PositionClosePartial(symbx,vol_close,slip);
               if(partcls) 
                 {
                   string remvol=pos_vol-part_vol > 0.0 ? "\n ~ Remaining Vol: "+DoubleToString(pos_vol-part_vol,LotDig(symbx)) : "";
                   Do_Alerts(symbol, DoubleToString(percentlots,2)+ "% Volume Cut for "+symbx+" Success!"+remvol);   
                   break;
                 }
             }
         }
     }
    //--
    return(partcls);
//---
  } //-end PartialCloseOrder()
//---------//

double MCEA::TSPrice(const string xsymb,ENUM_POSITION_TYPE ptype,int TS_type)
  {
//---
    int br=2;
    double pval=0.0;
    int x=PairsIdxArray(xsymb);
    Pips(xsymb);
    //--
    switch(TS_type)
      {
        case byprice:
          {
            RefreshTick(xsymb);
            if(ptype==POSITION_TYPE_BUY)  pval=mc_symbol.NormalizePrice(mc_symbol.Bid()-TSval*pip);
            if(ptype==POSITION_TYPE_SELL) pval=mc_symbol.NormalizePrice(mc_symbol.Ask()+TSval*pip);
            break;
          }
        case byindi:
          {
            double SMAML[];
            ArrayResize(SMAML,br,br);
            ArraySetAsSeries(SMAML,true);
            CopyBuffer(hSMA20[x],0,0,br,SMAML);
            RefreshPrice(xsymb,TFt,br);
            //--
            if(ptype==POSITION_TYPE_BUY  && (SMAML[0]<mc_symbol.NormalizePrice(mc_symbol.Bid()-TSval*pip)))
               pval=SMAML[0];
            if(ptype==POSITION_TYPE_SELL && (SMAML[0]>mc_symbol.NormalizePrice(mc_symbol.Ask()+TSval*pip)))
               pval=SMAML[0];
            break;
          }
        case byHiLo:
          {
            UpdatePrice(xsymb,TFt,2);
            //--
            if(ptype==POSITION_TYPE_BUY  && (HIGH[0]>HIGH[1]))
               pval=LOW[1];
            if(ptype==POSITION_TYPE_SELL && (LOW[0]<LOW[1]))
               pval=HIGH[1];
            break;
          }
      }
    //--
    return(pval);
//---
  } //-end TSPrice()
//---------//

bool MCEA::ModifyOrdersSL(const string symbx,int TS_type)
  {
//---
   ResetLastError();
   MqlTradeRequest req={};
   MqlTradeResult  res={};
   MqlTradeCheckResult check={};
   //--
   int TRSP=TS_type;
   bool modist=false;
   int x=PairsIdxArray(symbx);
   Pips(symbx);
   //--
   int total=PositionsTotal();
   //--        
   for(int i=total-1; i>=0; i--) 
     {
       string symbol=PositionGetSymbol(i);
       if(symbol==symbx && mc_position.Magic()==magicEA)
         {
           ENUM_POSITION_TYPE opstype = mc_position.PositionType();
           if(opstype==POSITION_TYPE_BUY) 
             {
               RefreshTick(symbol);
               double price = mc_position.PriceCurrent();
               double vtrsb = mc_symbol.NormalizePrice(TSPrice(symbx,opstype,TRSP));
               double pos_open   = mc_position.PriceOpen();
               double pos_stop   = mc_position.StopLoss();
               double pos_tp     = mc_position.TakeProfit();
               double pos_profit = mc_position.Profit();
               double pos_swap   = mc_position.Swap();
               double pos_comm   = mc_position.Commission();
               double netp=pos_profit+pos_swap+pos_comm;
               double modstart=mc_symbol.NormalizePrice(pos_open+TSmin*pip);
               double modminsl=mc_symbol.NormalizePrice(vtrsb+((TSmin-1.0)*pip));
               double modbuysl=vtrsb;
               bool modbuy = (price>modminsl && modbuysl>modstart && (pos_stop==0.0||modbuysl>pos_stop));
               //--
               if(modbuy && netp>minprofit)
                 {
                   modist=mc_trade.PositionModify(symbol,modbuysl,pos_tp);
                 }  
             }
           if(opstype==POSITION_TYPE_SELL) 
             {
               RefreshTick(symbol);
               double price = mc_position.PriceCurrent();
               double vtrss = mc_symbol.NormalizePrice(TSPrice(symbx,opstype,TRSP));
               double pos_open   = mc_position.PriceOpen();
               double pos_stop   = mc_position.StopLoss();
               double pos_tp     = mc_position.TakeProfit();
               double pos_profit = mc_position.Profit();
               double pos_swap   = mc_position.Swap();
               double pos_comm   = mc_position.Commission();
               double netp=pos_profit+pos_swap+pos_comm;
               double modstart=mc_symbol.NormalizePrice(pos_open-TSmin*pip);
               double modminsl=mc_symbol.NormalizePrice(vtrss-((TSmin+1.0)*pip));
               double modselsl=vtrss;
               bool modsel = (price<modminsl && modselsl<modstart && (pos_stop==0.0||modselsl<pos_stop)); 
               //--
               if(modsel && netp>minprofit)
                 {
                   modist=mc_trade.PositionModify(symbol,modselsl,pos_tp);
                 }  
             }
         }
     }
    //--
    return(modist);
//---
  } //-end ModifyOrdersSL()
//---------//

bool MCEA::ModifyOrdersTP(const string symbx)
  {
//---
   ResetLastError();
   MqlTradeRequest req={};
   MqlTradeResult  res={};
   MqlTradeCheckResult check={};
   //--
   bool modist=false;
   int x=PairsIdxArray(symbx);
   Pips(symbx);
   //--
   int total=PositionsTotal();
   //--        
   for(int i=total-1; i>=0; i--) 
     {
       string symbol=PositionGetSymbol(i);
       if(symbol==symbx && mc_position.Magic()==magicEA)
         {
           ENUM_POSITION_TYPE opstype = mc_position.PositionType();
           if(opstype==POSITION_TYPE_BUY) 
             {
               RefreshTick(symbol);
               double price    = mc_position.PriceCurrent();
               double pos_open = mc_position.PriceOpen();
               double pos_stop = mc_position.StopLoss();
               double pos_tp   = mc_position.TakeProfit();
               double modbuytp = pos_tp==0.0 ? mc_symbol.NormalizePrice(pos_open+TPmin*pip) : pos_tp;
               double modpostp = mc_symbol.NormalizePrice(price+TPmin*pip);
               bool modtpb = (price>pos_open && modbuytp-price<TPmin*pip && pos_tp<modpostp);
               //--
               if(modtpb)
                 {
                   modist=mc_trade.PositionModify(symbol,pos_stop,modpostp);
                 }  
             }
           if(opstype==POSITION_TYPE_SELL) 
             {
               RefreshTick(symbol);
               double price    = mc_position.PriceCurrent();
               double pos_open = mc_position.PriceOpen();
               double pos_stop = mc_position.StopLoss();
               double pos_tp   = mc_position.TakeProfit();
               double modseltp = pos_tp==0.0 ? mc_symbol.NormalizePrice(pos_open-TPmin*pip) : pos_tp;
               double modpostp = mc_symbol.NormalizePrice(price-TPmin*pip);
               bool modtps = (price<pos_open && price-modseltp<TPmin*pip && pos_tp>modpostp);
               //--
               if(modtps)
                 {
                   modist=mc_trade.PositionModify(symbol,pos_stop,modpostp);
                 }  
             }
         }
     }
    //--
    return(modist);
//---
  } //-end ModifyOrdersTP()
//---------//

void MCEA::SetSLTPOrders(void) 
  {
//---
   ResetLastError();
   MqlTradeRequest req={};
   MqlTradeResult  res={};
   MqlTradeCheckResult check={};
   //--
   double modbuysl=0;
   double modselsl=0;
   double modbuytp=0;
   double modseltp=0;
   string position_symbol;
   int totalorder=PositionsTotal();
   //--    
   for(int i=totalorder-1; i>=0; i--) 
     {
       string symbol=PositionGetSymbol(i);
       position_symbol=symbol;
       if(mc_position.Magic()==magicEA)
         {
           ENUM_POSITION_TYPE opstype = mc_position.PositionType();
           if(opstype==POSITION_TYPE_BUY) 
             {
               Pips(symbol);
               RefreshTick(symbol);
               double price    = mc_position.PriceCurrent();
               double pos_open = mc_position.PriceOpen();
               double pos_stop = mc_position.StopLoss();
               double pos_take = mc_position.TakeProfit();
               modbuysl=SetOrderSL(symbol,opstype,pos_open);
               if(price<modbuysl) modbuysl=mc_symbol.NormalizePrice(price-slip*pip);
               modbuytp=SetOrderTP(symbol,opstype,pos_open);
               if(price>modbuytp) modbuytp=mc_symbol.NormalizePrice(price+slip*pip);
               //--
               if(pos_stop==0.0 || pos_take==0.0)
                 {
                   if(!mc_trade.PositionModify(position_symbol,modbuysl,modbuytp))
                     {
                       mc_trade.CheckResult(check);
                       Do_Alerts(symbol,"Set SL and TP for "+EnumToString(opstype)+" on "+symbol+" FAILED!!. Return code= "+
                                (string)mc_trade.ResultRetcode()+". Code description: ["+mc_trade.ResultRetcodeDescription()+"]");
                     }
                 }
             }
           if(opstype==POSITION_TYPE_SELL) 
             {
               Pips(symbol);
               RefreshTick(symbol);
               double price    = mc_position.PriceCurrent();
               double pos_open = mc_position.PriceOpen();
               double pos_stop = mc_position.StopLoss();
               double pos_take = mc_position.TakeProfit();
               modselsl=SetOrderSL(symbol,opstype,pos_open);
               if(price>modselsl) modselsl=mc_symbol.NormalizePrice(price+slip*pip);
               modseltp=SetOrderTP(symbol,opstype,pos_open);
               if(price<modseltp) modseltp=mc_symbol.NormalizePrice(price-slip*pip);
               //--
               if(pos_stop==0.0 || pos_take==0.0)
                 {
                   if(!mc_trade.PositionModify(position_symbol,modselsl,modseltp))
                     {
                       mc_trade.CheckResult(check);
                       Do_Alerts(symbol,"Set SL and TP for "+EnumToString(opstype)+" on "+symbol+" FAILED!!. Return code= "+
                                (string)mc_trade.ResultRetcode()+". Code description: ["+mc_trade.ResultRetcodeDescription()+"]");
                     }
                 }
             }
         }
     }
    //--
    return;
//---
  } //-end SetSLTPOrders
//---------//

double MCEA::SetOrderSL(const string xsymb,ENUM_POSITION_TYPE type,double atprice)
  {
//---
    slv=0.0;
    int x=PairsIdxArray(xsymb);
    Pips(xsymb);
    RefreshTick(xsymb);
    //--
    switch(type) 
      { 
       case (POSITION_TYPE_BUY):
         {
           slv=mc_symbol.NormalizePrice(atprice-SLval*pip);
           //--
           break;
         }
       case (POSITION_TYPE_SELL):
         {
           slv=mc_symbol.NormalizePrice(atprice+SLval*pip);
           //--
           break;
         }
      }
    //---
    return(slv);
//---
  } //-end SetOrderSL()
//---------//

double MCEA::SetOrderTP(const string xsymb,ENUM_POSITION_TYPE type,double atprice)
  {
//---
    tpv=0.0;
    int x=PairsIdxArray(xsymb);
    Pips(xsymb);
    RefreshTick(xsymb);
    //--
    switch(type) 
      { 
       case (POSITION_TYPE_BUY):
         {
           tpv=mc_symbol.NormalizePrice(atprice+TPval*pip);
           //--
           break;
         }
       case (POSITION_TYPE_SELL):
         {
           tpv=mc_symbol.NormalizePrice(atprice-TPval*pip);
         }
      }
    //---
    return(tpv);
//---
  } //-end SetOrderTP()
//---------//

bool MCEA::CloseBuyPositions(const string symbol)
   {
 //---
    //--
    ResetLastError();
    bool buyclose=false;
    int total=PositionsTotal(); // number of open positions
    ENUM_POSITION_TYPE closetype = POSITION_TYPE_BUY;
    ENUM_ORDER_TYPE     type_req = ORDER_TYPE_SELL;
    //--
    MqlTradeRequest req={};
    MqlTradeResult  res={};
    MqlTradeCheckResult check={};
    //--
    int x=PairsIdxArray(symbol);
    //--- iterate over all open positions
    for(int i=total-1; i>=0; i--)
      {
        if(mc_position.SelectByIndex(i))
          {
            //--- Parameters of the order
            string position_Symbol   = PositionGetSymbol(i);
            ulong  position_ticket   = PositionGetTicket(i);
            ENUM_POSITION_TYPE  type = mc_position.PositionType();
            //--- if the MagicNumber matches
            if((position_Symbol==symbol) && (mc_position.Magic()==magicEA))
              { 
                //--
                if(type==closetype)
                  {
                    RefreshTick(position_Symbol);
                    buyclose=mc_trade.PositionClose(position_Symbol,slip);
                    //--- output information about the closure
                    PrintFormat("Close Buy #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type));
                    if(buyclose) PbarB[x]=iTime(symbol,TFt,0);
                  }
              }
          }
      }
   //---
   return(buyclose);
//----
   } //-end CloseBuyPositions()
//---------//

bool MCEA::CloseSellPositions(const string symbol)
  {
    //---
    ResetLastError();
    bool sellclose=false;
    int total=PositionsTotal(); // number of open positions
    ENUM_POSITION_TYPE closetype = POSITION_TYPE_SELL;
    ENUM_ORDER_TYPE     type_req = ORDER_TYPE_BUY;
    //--
    MqlTradeRequest req={};
    MqlTradeResult  res={};
    MqlTradeCheckResult check={};
    //--
    int x=PairsIdxArray(symbol);
    //--- iterate over all open positions
    for(int i=total-1; i>=0; i--)
      {
        if(mc_position.SelectByIndex(i))
          {
            //--- Parameters of the order
            string position_Symbol   = PositionGetSymbol(i);
            ulong  position_ticket   = PositionGetTicket(i);
            ENUM_POSITION_TYPE  type = mc_position.PositionType();
            //--- if the MagicNumber matches
            if((position_Symbol==symbol) && (mc_position.Magic()==magicEA))
              { 
                //--
                if(type==closetype)
                  {
                    RefreshTick(position_Symbol);
                    sellclose=mc_trade.PositionClose(position_Symbol,slip);
                    //--- output information about the closure
                    PrintFormat("Close Sell #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type));
                    if(sellclose) PbarS[x]=iTime(symbol,TFt,0);
                  }
              }
          }
      }
   //---
   return(sellclose);
//----
   } //-end CloseSellPositions()
//---------//

bool MCEA::CloseAllLoss(void)
   {
//----
    ResetLastError();
    //--
    bool orclose=false;
    string isloss="due stop in loss.";
    //--
    MqlTradeRequest req={};
    MqlTradeResult  res={};
    MqlTradeCheckResult check={};
    //--
    int ttlorder=PositionsTotal(); // number of open positions
    //--
    for(int x=0; x<arrsymbx; x++)
       {
         string symbol=DIRI[x];
         Pips(symbol);
         double posloss=mc_symbol.NormalizePrice(SLval*pip);
         orclose=false;
         //--
         for(int i=ttlorder-1; i>=0; i--)
            {
              string position_Symbol   = PositionGetSymbol(i);
              ENUM_POSITION_TYPE  type = mc_position.PositionType();
              if((position_Symbol==symbol) && (mc_position.Magic()==magicEA))
                {
                  double price    = mc_position.PriceCurrent();
                  double pos_open = mc_position.PriceOpen();
                  double posloss  = mc_symbol.NormalizePrice(SLval*pip);
                  double pricegab = mc_symbol.NormalizePrice(fabs(price-pos_open));
                  ulong  position_ticket = PositionGetTicket(i);
                  //---
                  if(type==POSITION_TYPE_BUY && pricegab>posloss)
                    {
                      RefreshTick(position_Symbol);
                      orclose = mc_trade.PositionClose(position_Symbol,slip);
                      //--- output information about the closure
                      PrintFormat("Close Buy %s %s %s",symbol,EnumToString(POSITION_TYPE_BUY),isloss);
                    }
                  if(type==POSITION_TYPE_SELL && pricegab>posloss)
                    {
                      RefreshTick(position_Symbol);
                      orclose = mc_trade.PositionClose(position_Symbol,slip);
                      //--- output information about the closure
                      PrintFormat("Close Sell %s %s %s",symbol,EnumToString(POSITION_TYPE_BUY),isloss);
                    }
                }
            }
       }
     //--
     return(orclose);
//----
   } //-end CloseAllLoss()
//---------//

bool MCEA::CloseAllProfit(void)
   {
//----
    ResetLastError();
    //--
    bool orclose=false;
    //--
    MqlTradeRequest req={};
    MqlTradeResult  res={};
    MqlTradeCheckResult check={};
    //--
    int ttlorder=PositionsTotal(); // number of open positions
    //--
    for(int x=0; x<arrsymbx; x++)
       {
         string symbol=DIRI[x];
         orclose=false;
         //--
         for(int i=ttlorder-1; i>=0; i--)
            {
              string position_Symbol   = PositionGetSymbol(i);
              ENUM_POSITION_TYPE  type = mc_position.PositionType();
              if((position_Symbol==symbol) && (mc_position.Magic()==magicEA))
                {
                  double pos_profit = mc_position.Profit();
                  double pos_swap   = mc_position.Swap();
                  double pos_comm   = mc_position.Commission();
                  double cur_profit = NormalizeDouble(pos_profit+pos_swap+pos_comm,2);
                  ulong  position_ticket = PositionGetTicket(i);
                  //---
                  if(type==POSITION_TYPE_BUY && cur_profit>minprofit)
                    {
                      RefreshTick(position_Symbol);
                      orclose = mc_trade.PositionClose(position_Symbol,slip);
                      //--- output information about the closure
                      PrintFormat("Close #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type));
                      if(orclose) PbarB[x]=iTime(symbol,TFt,0);
                    }
                  if(type==POSITION_TYPE_SELL && cur_profit>minprofit)
                    {
                      RefreshTick(position_Symbol);
                      orclose = mc_trade.PositionClose(position_Symbol,slip);
                      //--- output information about the closure
                      PrintFormat("Close #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type));
                      if(orclose) PbarS[x]=iTime(symbol,TFt,0);
                    }
                }
            }
       }
     //--
     return(orclose);
//----
   } //-end CloseAllProfit()
//---------//

bool MCEA::ManualCloseAllProfit(void)
   {
//----
    ResetLastError();
    //--
    bool orclose=false;
    //--
    MqlTradeRequest req={};
    MqlTradeResult  res={};
    MqlTradeCheckResult check={};
    //--
    int ttlorder=PositionsTotal(); // number of open positions
    //--
    for(int x=0; x<arrsymbx; x++)
       {
         string symbol=DIRI[x];
         orclose=false;
         //--
         for(int i=ttlorder-1; i>=0; i--)
            {
              string position_Symbol   = PositionGetSymbol(i);
              ENUM_POSITION_TYPE  type = mc_position.PositionType();
              if((position_Symbol==symbol) && (mc_position.Magic()==magicEA))
                {
                  double pos_profit = mc_position.Profit();
                  double pos_swap   = mc_position.Swap();
                  double pos_comm   = mc_position.Commission();
                  double cur_profit = NormalizeDouble(pos_profit+pos_swap+pos_comm,2);
                  ulong  position_ticket = PositionGetTicket(i);
                  //---
                  if(type==POSITION_TYPE_BUY && cur_profit>0.02)
                    {
                      RefreshTick(position_Symbol);
                      orclose = mc_trade.PositionClose(position_Symbol,slip);
                      //--- output information about the closure
                      PrintFormat("Close #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type));
                      if(orclose) PbarB[x]=iTime(symbol,TFt,0);
                    }
                  if(type==POSITION_TYPE_SELL && cur_profit>0.02)
                    {
                      RefreshTick(position_Symbol);
                      orclose = mc_trade.PositionClose(position_Symbol,slip);
                      //--- output information about the closure
                      PrintFormat("Close #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type));
                      if(orclose) PbarS[x]=iTime(symbol,TFt,0);
                    }
                }
            }
       }
     //--
     return(orclose);
//----
   } //-end ManualCloseAllProfit()
//---------//

bool MCEA::CheckProfit(const string symbol,ENUM_POSITION_TYPE intype)
   {
//---
     Pips(symbol);
     double posprofit=mc_symbol.NormalizePrice((TPval*0.5)*pip);
     bool inprofit=false;
     //--
     int ttlorder=PositionsTotal(); // number of open positions
     //--
     for(int x=0; x<arrsymbx; x++)
       {
         string symbol=DIRI[x];
         //--
         for(int i=ttlorder-1; i>=0; i--)
            {
              string position_Symbol   = PositionGetSymbol(i);
              ENUM_POSITION_TYPE  type = mc_position.PositionType();
              if((position_Symbol==symbol) && (mc_position.Magic()==magicEA))
                {
                  double price     = mc_position.PriceCurrent();
                  double pos_open  = mc_position.PriceOpen();
                  double posprofit = mc_symbol.NormalizePrice((TPval*0.5)*pip);
                  double pricegab  = mc_symbol.NormalizePrice(fabs(price-pos_open));
                  //---
                  if(type==intype && posprofit<pricegab) inprofit=true;
                }
            }
       }
     //--
     return(inprofit);
//----
   } //-end CheckProfit()
//---------//

bool MCEA::CheckLoss(const string symbol,ENUM_POSITION_TYPE intype,double slc=0.0)
   {
//---
     Pips(symbol);
     bool inloss=false;
     double lossval=slc==0.0 ? (SLval*0.5) : slc;
     double posloss  = mc_symbol.NormalizePrice(slc*pip);
     int ttlorder=PositionsTotal(); // number of open positions
     //--
     for(int x=0; x<arrsymbx; x++)
       {
         string symbol=DIRI[x];
         //--
         for(int i=ttlorder-1; i>=0; i--)
            {
              string position_Symbol   = PositionGetSymbol(i);
              ENUM_POSITION_TYPE  type = mc_position.PositionType();
              if((position_Symbol==symbol) && (mc_position.Magic()==magicEA))
                {
                  double price    = mc_position.PriceCurrent();
                  double pos_open = mc_position.PriceOpen();
                  double posloss  = mc_symbol.NormalizePrice(lossval*pip);
                  double pricegab = mc_symbol.NormalizePrice(fabs(price-pos_open));
                  //---
                  if(type==intype && pricegab>posloss) inloss=true;
                }
            }
       }
     //--
     return(inloss);
//----
   } //-end CheckLoss()
//---------//

bool MCEA::CheckProfitLoss(const string symbol)
   {
//----
     ResetLastError();
     //--
     bool closeinloss=false;
     string isloss="due stop in loss.";
     //--
     int xx=PairsIdxArray(symbol);
     //--
     bool BuyProfitSellLoss=(xob[xx]>0 && CheckProfit(symbol,POSITION_TYPE_BUY)) && (xos[xx]>0 && CheckLoss(symbol,POSITION_TYPE_SELL,0.0));
     bool SellProfitBuyLoss=(xos[xx]>0 && CheckProfit(symbol,POSITION_TYPE_SELL)) && (xob[xx]>0 && CheckLoss(symbol,POSITION_TYPE_BUY,0.0));
     //--
     if(BuyProfitSellLoss && !SellProfitBuyLoss)
       {
         if(CloseSellPositions(symbol))
           {
             PrintFormat("Close Sell %s %s %s",symbol,EnumToString(POSITION_TYPE_BUY),isloss);
             closeinloss=true;
           }
       }
     if(SellProfitBuyLoss && !BuyProfitSellLoss)
       {
         if(CloseBuyPositions(symbol))
           {
             PrintFormat("Close Buy %s %s %s",symbol,EnumToString(POSITION_TYPE_SELL),isloss);
             closeinloss=true;
           }
       }
     //--
     return(closeinloss);
//----
   } //-end CheckProfitLoss()
//---------//

void MCEA::CloseAllOrders(void) //-- function: close all order
   {
//----
    ResetLastError();
    //--
    MqlTradeRequest req={};
    MqlTradeResult  res={};
    MqlTradeCheckResult check={};
    //--
    int total=PositionsTotal(); // number of open positions
    //--- iterate over all open positions
    for(int i=total-1; i>=0; i--)
      {
        //--- if the MagicNumber matches
        if(mc_position.Magic()==magicEA)
          { 
            //--
            string position_Symbol   = PositionGetSymbol(i);  // symbol of the position
            ulong  position_ticket   = PositionGetTicket(i);  // ticket of the the opposite position
            ENUM_POSITION_TYPE  type = mc_position.PositionType();
            RefreshTick(position_Symbol);
            bool closepos = mc_trade.PositionClose(position_Symbol,slip);
            if(closepos && type==POSITION_TYPE_BUY)  PbarB[i]=iTime(position_Symbol,TFt,0);
            if(closepos && type==POSITION_TYPE_SELL) PbarS[i]=iTime(position_Symbol,TFt,0);
            //--- output information about the closure
            PrintFormat("Close #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type));
            //---
          }
      }
   //---
   return;
//----
   } //-end CloseAllOrders()
//---------//

void MCEA::CheckClose(const string symbx)
   {
//---
    //--
    ResetLastError();
    Pips(symbx);
    //--
    datetime to=TimeCurrent();
    datetime from=to-(60);
    closetime=TimeCurrent()-(3); // 3 seconds ago
//--- request the entire history 
    HistorySelect(from,to);
    //--- total number in the list of deals
    int deals=HistoryDealsTotal();
    //--
    datetime deal_time  =0;     // time of a deal execution
    ulong  deal_ticket  =0;     // deal ticket 
    long   deal_magic   =0;     // deal magic number
    long   deal_type    =0;     // Order Type
    double deal_price   =0.0;   // deal/order CLOSE price
    double deal_profit  =0.0;   // deal profit
    double deal_swap    =0.0;   // position swap
    double deal_comm    =0.0;   // position commission
    string deal_symbol  ="";    // symbol of the deal
    ENUM_DEAL_ENTRY deal_entry =0; // enum deal entry
    double profit_loss  =0.0;   // Order profit or loss 
    //--
//--- go through deals in a loop 
    for(int z=deals-1; z>=0 && !IsStopped(); z--)
      {
        deal_ticket = HistoryDealGetTicket(z);
        deal_symbol = HistoryDealGetString(deal_ticket,DEAL_SYMBOL);
        deal_magic  = HistoryDealGetInteger(deal_ticket,DEAL_MAGIC);
        deal_entry  = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(deal_ticket,DEAL_ENTRY);
        deal_type   = (ENUM_DEAL_TYPE)HistoryDealGetInteger(deal_ticket,DEAL_TYPE);
        //--
        if(deal_symbol==symbx && deal_magic==magicEA)
          {
            if((deal_entry==DEAL_ENTRY_OUT)||(deal_entry==DEAL_ENTRY_OUT_BY))
              {
                deal_time = (datetime)HistoryDealGetInteger(deal_ticket,DEAL_TIME);
                if((deal_time>0) && (deal_time>=closetime))
                  {
                    deal_price  = HistoryDealGetDouble(deal_ticket,DEAL_PRICE);
                    deal_profit = HistoryDealGetDouble(deal_ticket,DEAL_PROFIT); 
                    deal_swap   = HistoryDealGetDouble(deal_ticket,DEAL_SWAP); 
                    deal_comm   = HistoryDealGetDouble(deal_ticket,DEAL_COMMISSION);                  
                    profit_loss = NormalizeDouble(deal_profit+deal_swap+deal_comm,2);
                    string xtype = deal_type==DEAL_TYPE_BUY ? "SELL" : deal_type==DEAL_TYPE_SELL ? "BUY": "";
                    //--
                    if(profit_loss>0) 
                      {
                        string ckclose="Close "+xtype+" Position on "+symbx+" at price : "+DoubleToString(deal_price,dgts)+
                                       " OrderCloseTime(): "+TimeToString(deal_time,TIME_DATE|TIME_MINUTES)+
                                       " in profit : "+DoubleToString(profit_loss,2);
                        Do_Alerts(symbx,ckclose);    
                      }
                    if(profit_loss<=0) 
                      {  
                        string ckclose="Close "+xtype+" Position on "+symbx+" at price : "+DoubleToString(deal_price,dgts)+
                                       " OrderCloseTime(): "+TimeToString(deal_time,TIME_DATE|TIME_MINUTES)+
                                       " in loss : "+DoubleToString(profit_loss,2);
                        Do_Alerts(symbx,ckclose);
                      }
                    //--
                    break;
                  }
              }
          }
      }
    //---
    return;
//----
  } //-end CheckClose()
//---------//

bool MCEA::CheckLastOrderIFLoss(const string symbx)
  {
//---
    bool LOloss=false;
    //--
    ResetLastError();
    int xs=PairsIdxArray(symbx);
    LastLotx[xs]=0.0;
    //--
    datetime from=StringToTime(ReqDate(ThisTime(day),0,0));
    datetime to=TimeCurrent();
//--- request the entire history
    HistorySelect(from,to);
    //--- total number in the list of deals
    int deals=HistoryDealsTotal();
    //--
    datetime deal_time  =0;     // time of a deal execution
    ulong  deal_ticket  =0;     // deal ticket 
    long   deal_magic   =0;     // deal magic number
    long   deal_type    =0;     // Order Type
    double deal_profit  =0.0;   // deal profit
    double deal_swap    =0.0;   // position swap
    double deal_comm    =0.0;   // position commission
    double deal_volume  =0.0;   // deal volume
    string deal_symbol  ="";    // symbol of the deal
    ENUM_DEAL_ENTRY deal_entry =0; // enum deal entry
    double profit_loss  =0.0;   // Order profit or loss 
    //--
//--- go through deals in a loop 
    for(int z=deals-1; z>=0 && !IsStopped(); z--)
      {
        deal_ticket = HistoryDealGetTicket(z);
        deal_symbol = HistoryDealGetString(deal_ticket,DEAL_SYMBOL);
        deal_magic  = HistoryDealGetInteger(deal_ticket,DEAL_MAGIC);
        deal_entry  = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(deal_ticket,DEAL_ENTRY);
        deal_type   = (ENUM_DEAL_TYPE)HistoryDealGetInteger(deal_ticket,DEAL_TYPE);
        //--
        if(deal_symbol==symbx && deal_magic==magicEA)
          {
            if((deal_entry==DEAL_ENTRY_OUT)||(deal_entry==DEAL_ENTRY_OUT_BY))
              {
                deal_time = (datetime)HistoryDealGetInteger(deal_ticket,DEAL_TIME);
                if((deal_time>0) && (deal_time>=closetime))
                  {
                    deal_volume = HistoryDealGetDouble(deal_ticket,DEAL_VOLUME);
                    deal_profit = HistoryDealGetDouble(deal_ticket,DEAL_PROFIT); 
                    deal_swap   = HistoryDealGetDouble(deal_ticket,DEAL_SWAP); 
                    deal_comm   = HistoryDealGetDouble(deal_ticket,DEAL_COMMISSION);                  
                    profit_loss = NormalizeDouble(deal_profit+deal_swap+deal_comm,2);
                    //--
                    if(profit_loss<=0.0) 
                      {
                        LastLotx[xs] = deal_volume;
                        LOloss = true;
                      }
                    //--
                    break;
                  }
              }
          }
      } 
    //---
    return(LOloss);
//----
  } //-end CheckLastOrderIFLoss()
//---------//

void MCEA::TodayOrders(void)
  {
//---
    //--
    ResetLastError();
    //--
    datetime from=StringToTime(ReqDate(ThisTime(day),0,0));
    datetime to=TimeCurrent();
//--- request the entire history
    HistorySelect(from,to);
    //--- total number in the list of deals
    int deals=HistoryDealsTotal();
    //--
    datetime deal_time  =0;     // time of a deal execution
    ulong  deal_ticket  =0;     // deal ticket 
    long   deal_magic   =0;     // deal magic number
    long   deal_type    =0;     // Order Type
    double deal_price   =0.0;   // deal/order CLOSE price
    double deal_profit  =0.0;   // deal profit
    double deal_swap    =0.0;   // position swap
    double deal_comm    =0.0;   // position commission
    ENUM_DEAL_ENTRY deal_entry =0; // enum deal entry
    //--
    string pos_symbol   ="";    // Position symbol
    fixclprofit         =0.0;   // Order Close profit
    floatprofit         =0.0;   // float position profit
    oBm=0;                      // Order buy 
    oSm=0;                      // Order sell
    //--
    int totalorder=PositionsTotal();
    //--    
    for(int i=0; i<totalorder && !IsStopped(); i++)
      {
        pos_symbol = PositionGetSymbol(i);
        long magic = mc_position.Magic();
        if(mc_position.Symbol() == pos_symbol && magic==magicEA)
          {
            //--
            ENUM_POSITION_TYPE opstype = mc_position.PositionType();
            if(opstype == POSITION_TYPE_BUY)  {oBm++; floatprofit += mc_position.Profit();}
            if(opstype == POSITION_TYPE_SELL) {oSm++; floatprofit += mc_position.Profit();}
            //--
          }
      }
    xtto=oBm+oSm;
    //--
//--- go through deals in a loop 
    for(int z=0; z<deals && !IsStopped(); z++)
      {
        deal_ticket = HistoryDealGetTicket(z); 
        deal_magic  = HistoryDealGetInteger(deal_ticket,DEAL_MAGIC);
        deal_entry  = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(deal_ticket,DEAL_ENTRY);
        deal_type   = (ENUM_DEAL_TYPE)HistoryDealGetInteger(deal_ticket,DEAL_TYPE);
        if(deal_magic==magicEA)
          {
            if((deal_entry==DEAL_ENTRY_OUT)||(deal_entry==DEAL_ENTRY_OUT_BY))
              {
                deal_time = (datetime)HistoryDealGetInteger(deal_ticket,DEAL_TIME);
                //--
                if((deal_time>0) && (deal_time>=from))
                  {
                    deal_profit = HistoryDealGetDouble(deal_ticket,DEAL_PROFIT); 
                    deal_swap   = HistoryDealGetDouble(deal_ticket,DEAL_SWAP); 
                    deal_comm   = HistoryDealGetDouble(deal_ticket,DEAL_COMMISSION);                  
                    //--
                    fixclprofit += NormalizeDouble(deal_profit+deal_swap+deal_comm,2);
                  }
              }
          }
      }
    //---
    return;
//----
  } //-end TodayOrders()
//---------//

double MCEA::MLots(const string symbx) // function: calculation lots size
  {
//----
   double Lsize=0.0;
   double sym_Lm=0.0;
   string sym_use ="";
   int pil;
   int Lpair;
   int xsym=-1;
   //--
   string sCur1=StringSubstr(symbx,posCur1,3);
   string sCur2=StringSubstr(symbx,posCur2,3);
   //--
   if(sCur1=="EUR"||sCur1=="GBP"||sCur1=="AUD"||sCur1=="NZD") pil=0;
   if(sCur1=="CAD"||sCur1=="CHF") pil=1;
   if(sCur1=="XAU"||sCur1=="XAG") pil=2;
   if(sCur1=="USD") pil=3;
   //--
   switch(pil)
     {
       case 0: sym_use=sCur1+"USD"; break;
       case 1: sym_use="USD"+sCur1; break;
       case 2: sym_use=symbx;       break;
       case 3: sym_use=symbx;       break;
     }
   //--
   xsym=PairsIdxArray(sym_use);
   if(xsym!=-1) sym_use=DIRI[xsym];
   Lpair = StringFind(sym_use,"USD",0);
   //--
   CurrentSymbolSet(sym_use);
   double csize  = mc_symbol.ContractSize();
   double AFMar  = mc_account.FreeMargin();
   double AFLev  = (double)mc_account.Leverage();
   double symbid = mc_symbol.Bid();
   //--
   double Lmaxs  = SymbolInfoDouble(symbx,SYMBOL_VOLUME_MAX);
   double Lmins  = SymbolInfoDouble(symbx,SYMBOL_VOLUME_MIN);
   //--
   double useRisk = (Risk/100.0);
   double PctUse  = ((100.0-Risk)/100.0);
   //--
   double NZ1=NonZeroDiv(AFMar*AFLev,csize);
   double NZ2=NonZeroDiv(AFMar*AFLev,symbid);
   //--
   if(Lpair>=0 && Lpair<posCur2) {sym_Lm = fmin(Lmaxs,NZ1);}
   else {sym_Lm = fmin(Lmaxs,NonZeroDiv(NZ2,csize));}
   //--
   double sym_Lc = NormalizeDouble(sym_Lm*useRisk,LotDig(symbx));
   double asize  = NormalizeDouble(sym_Lc/(double)LotPS,LotDig(symbx));
   //--
   if(mmlot==DynamLot) 
     {
       Lsize = NormalizeDouble(asize*PctUse,LotDig(symbx));
     } 
   else {Lsize = Lots;}
   //--
   if(Lsize < Lmins) Lsize = Lmins;
   if(Lsize > Lmaxs) Lsize = Lmaxs;
   //--
   double lotsize=NormalizeDouble(Lsize,LotDig(symbx));
   //--
   return(lotsize);
//----
  } //-end MLots()
//---------//

int MCEA::LotDig(const string symbx)
  {
//---
   double lots_step=SymbolInfoDouble(symbx,SYMBOL_VOLUME_STEP);
   //--
   if(lots_step==0.01)
      ldig=2;
   //--
   if(lots_step==0.1)
      ldig=1;
   //--
   if(lots_step==1.0)
      ldig=0;
     //---
     return(ldig);
//----
  } //-end LotDig()
//---------//

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

bool MCEA::CheckEquityBalance(void)
  {
//---
   bool isgood=false;
   if((mc_account.Equity()/mc_account.Balance()*100) > (100.00-Risk)) isgood=true;
   //--
   return(isgood);
//---
  } //-end CheckEquityBalance()
//---------//

void MCEA::TradeInfo(void) // function: write comments on the chart
  {
//----
   Pips(Symbol());
   double spread=SymbolInfoInteger(Symbol(),SYMBOL_SPREAD)/xpip;
   rem=zntm-TimeCurrent();
   string postime=PosTimeZone();
   string eawait=" - Waiting for active time..!";
   //--
   string comm="";
   TodayOrders();
   //--
   comm="\n     :: Server Date Time : "+string(ThisTime(year))+"."+string(ThisTime(mon))+"."+string(ThisTime(day))+ "   "+TimeToString(TimeCurrent(),TIME_SECONDS)+
        "\n     ------------------------------------------------------------"+
        "\n      :: Broker               :  "+ TerminalInfoString(TERMINAL_COMPANY)+
        "\n      :: Expert Name      :  "+ expname+
        "\n      :: Acc. Name         :  "+ mc_account.Name()+
        "\n      :: Acc. Number      :  "+ (string)mc_account.Login()+
        "\n      :: Acc. TradeMode :  "+ AccountMode()+
        "\n      :: Acc. Leverage    :  1 : "+ (string)mc_account.Leverage()+
        "\n      :: Acc. Equity       :  "+ DoubleToString(mc_account.Equity(),2)+
        "\n      :: Margin Mode     :  "+ (string)mc_account.MarginModeDescription()+
        "\n      :: Magic Number   :  "+ string(magicEA)+
        "\n      :: Trade on TF      :  "+ EnumToString(TFt)+
        "\n      :: Today Trading   :  "+ TradingDay()+" : "+hariini+
        "\n      :: Trading Session :  "+ tz_ses+
        "\n      :: Trading Time    :  "+ postime;
        if(TimeCurrent()<zntm)
          {
            comm=comm+
            "\n      :: Time Remaining :  "+(string)ReqTime(rem,hour)+":"+(string)ReqTime(rem,min)+":"+(string)ReqTime(rem,sec) + eawait;
          }
        comm=comm+
        "\n     ------------------------------------------------------------"+
        "\n      :: Trading Pairs     :  "+pairs+
        "\n      :: BUY Market      :  "+string(oBm)+
        "\n      :: SELL Market     :  "+string(oSm)+
        "\n      :: Total Order       :  "+string(oBm+oSm)+
        "\n      :: Order Profit      :  "+DoubleToString(floatprofit,2)+
        "\n      :: Fixed Profit       :  "+DoubleToString(fixclprofit,2)+
        "\n      :: Float Money     :  "+DoubleToString(floatprofit,2)+
        "\n      :: Nett Profit        :  "+DoubleToString(floatprofit+fixclprofit,2);
   //--
   Comment(comm);
   ChartRedraw(0);
   return;
//----
  } //-end TradeInfo()  
//---------//

string MCEA::PosTimeZone(void)
  {
//---
    string tzpos="";
    //--
    if(ReqTime(zntm,day)>ThisTime(day))
     {
       tzpos=tz_opn+ " Next day to " +tz_cls + " Next day";
     }
    else
    if(TimeCurrent()<znop)
      {
        if(ThisTime(day)==ReqTime(znop,day) && ThisTime(day)==ReqTime(zncl,day))
          tzpos=tz_opn+" to " +tz_cls+ " Today";
        //else
        if(ThisTime(day)==ReqTime(znop,day) && ThisTime(day)<ReqTime(zncl,day))
          tzpos=tz_opn+ " Today to " +tz_cls+ " Next day";
      }
    else
    if(TimeCurrent()>=znop && TimeCurrent()<zncl)
      {
        if(ThisTime(day)<ReqTime(zncl,day))
          tzpos=tz_opn+ " Today to " +tz_cls+ " Next day";
        else
        if(ThisTime(day)==ReqTime(zncl,day))
          tzpos=tz_opn+" to " +tz_cls+ " Today";
      }
    else
    if(ThisTime(day)==ReqTime(znop,day) && ThisTime(day)<ReqTime(zncl,day))
      {
        tzpos=tz_opn+" Today to " +tz_cls+ " Next day";
      }
    //--
    return(tzpos);
//----
  } //-end PosTimeZone()
//---------//

void MCEA::Set_Time_Zone(void)
  {
//---
    //-- Server Time==TimeCurrent()
    datetime TTS=TimeTradeServer();
    datetime GMT=TimeGMT();
    //--
    MqlDateTime svrtm,gmttm; 
    TimeToStruct(TTS,svrtm); 
    TimeToStruct(GMT,gmttm); 
    int svrhr=svrtm.hour;  // Server time hour
    int gmthr=gmttm.hour;  // GMT time hour
    int difhr=svrhr-gmthr; // Time difference Server time to GMT time
    //--
    int NZSGMT=12;  // New Zealand Session GMT/UTC+12
    int AUSGMT=10;  // Australia Sydney Session GMT/UTC+10
    int TOKGMT=9;   // Asia Tokyo Session GMT/UTC+9
    int EURGMT=0;   // Europe London Session GMT/UTC 0
    int USNGMT=-5;  // US New York Session GMT/UTC-5
    //--
    int NZSStm=8;   // New Zealand Session time start: 08:00 Local Time
    int NZSCtm=17;  // New Zealand Session time close: 17:00 Local Time 
    int AUSStm=7;   // Australia Sydney Session time start: 07:00 Local Time 
    int AUSCtm=17;  // Australia Sydney Session time close: 17:00 Local Time  
    int TOKStm=9;   // Asia Tokyo Session time start: 09:00 Local Time 
    int TOKCtm=18;  // Asia Tokyo Session time close: 18:00 Local Time  
    int EURStm=9;   // Europe London Session time start: 09:00 Local Time 
    int EURCtm=19;  // Europe London Session time close: 19:00 Local Time  
    int USNStm=8;   // US New York Session time start: 08:00 Local Time 
    int USNCtm=17;  // US New York Session time close: 17:00 Local Time  
    //--
    int nzo = (NZSStm+difhr-NZSGMT)<0 ? 24+(NZSStm+difhr-NZSGMT) : (NZSStm+difhr-NZSGMT);
    int nzc = (NZSCtm+difhr-NZSGMT)<0 ? 24+(NZSCtm+difhr-NZSGMT) : (NZSCtm+difhr-NZSGMT);
    //--
    int auo = (AUSStm+difhr-AUSGMT)<0 ? 24+(AUSStm+difhr-AUSGMT) : (AUSStm+difhr-AUSGMT);
    int auc = (AUSCtm+difhr-AUSGMT)<0 ? 24+(AUSCtm+difhr-AUSGMT) : (AUSCtm+difhr-AUSGMT);
    //--
    int tko = (TOKStm+difhr-TOKGMT)<0 ? 24+(TOKStm+difhr-TOKGMT) : (TOKStm+difhr-TOKGMT);
    int tkc = (TOKCtm+difhr-TOKGMT)<0 ? 24+(TOKCtm+difhr-TOKGMT) : (TOKCtm+difhr-TOKGMT);
    //--
    int euo = (EURStm+difhr-EURGMT)<0 ? 24+(EURStm+difhr-EURGMT) : (EURStm+difhr-EURGMT);
    int euc = (EURCtm+difhr-EURGMT)<0 ? 24+(EURCtm+difhr-EURGMT) : (EURCtm+difhr-EURGMT);
    //--
    int uso = (USNStm+difhr-USNGMT)<0 ? 24+(USNStm+difhr-USNGMT) : (USNStm+difhr-USNGMT);
    int usc = (USNCtm+difhr-USNGMT)<0 ? 24+(USNCtm+difhr-USNGMT) : (USNCtm+difhr-USNGMT);
    if(usc==0||usc==24) usc=23;
    //--
    //---Trading on Custom Session
    int _days00=ThisTime(day);
    int _days10=ThisTime(day);
    if(stsescuh>clsescuh) _days10=ThisTime(day)+1;
    tmopcu=ReqDate(_days00,stsescuh,stsescum); 
    tmclcu=ReqDate(_days10,clsescuh,clsescum); 
    //--
    //--Trading on New Zealand Session GMT/UTC+12
    int _days01=ThisTime(hour)<nzc ? ThisTime(day)-1 : ThisTime(day);
    int _days11=ThisTime(hour)<nzc ? ThisTime(day) : ThisTime(day)+1;
    tmop01=ReqDate(_days01,nzo,0);    // start: 08:00 Local Time == 20:00 GMT/UTC
    tmcl01=ReqDate(_days11,nzc-1,59); // close: 17:00 Local Time == 05:00 GMT/UTC
    //--
    //--Trading on Australia Sydney Session GMT/UTC+10
    int _days02=ThisTime(hour)<auc ? ThisTime(day)-1 : ThisTime(day);
    int _days12=ThisTime(hour)<auc ? ThisTime(day) : ThisTime(day)+1;
    tmop02=ReqDate(_days02,auo,0);    // start: 07:00 Local Time == 21:00 GMT/UTC
    tmcl02=ReqDate(_days12,auc-1,59); // close: 17:00 Local Time == 07:00 GMT/UTC
    //--
    //--Trading on Asia Tokyo Session GMT/UTC+9
    int _days03=ThisTime(hour)<tkc ? ThisTime(day) : ThisTime(day)+1;
    int _days13=ThisTime(hour)<tkc ? ThisTime(day) : ThisTime(day)+1;
    tmop03=ReqDate(_days03,tko,0);    // start: 09:00 Local Time == 00:00 GMT/UTC
    tmcl03=ReqDate(_days13,tkc-1,59); // close: 18:00 Local Time == 09:00 GMT/UTC
    //--
    //--Trading on Europe London Session GMT/UTC 00:00
    int _days04=ThisTime(hour)<euc ? ThisTime(day) : ThisTime(day)+1;
    int _days14=ThisTime(hour)<euc ? ThisTime(day) : ThisTime(day)+1;
    tmop04=ReqDate(_days04,euo,0);     // start: 09:00 Local Time == 09:00 GMT/UTC
    tmcl04=ReqDate(_days14,euc-1,59);  // close: 19:00 Local Time == 19:00 GMT/UTC
    //--
    //--Trading on US New York Session GMT/UTC-5
    int _days05=ThisTime(hour)<usc  ? ThisTime(day) : ThisTime(day)+1;
    int _days15=ThisTime(hour)<=usc ? ThisTime(day) : ThisTime(day)+1;
    tmop05=ReqDate(_days05,uso,0);  // start: 08:00 Local Time == 13:00 GMT/UTC
    tmcl05=ReqDate(_days15,usc,59); // close: 17:00 Local Time == 22:00 GMT/UTC
    //--
    //--Not Use Trading Time Zone
    if(trd_time_zone==No)
      {
        tmopno=ReqDate(ThisTime(day),0,15); 
        tmclno=ReqDate(ThisTime(day),23,59);
      }
    //--
    Time_Zone();
    //--
    return;
//---
  } //-end Set_Time_Zone()
//---------//

void MCEA::Time_Zone(void)
  {
//---
   //--
   tz_ses="";
   //--
   switch(session)
     {
       case Cus_Session:
         {
           SesCuOp=StringToTime(tmopcu);
           SesCuCl=StringToTime(tmclcu);
           zntm=SesCuOp;
           znop=SesCuOp;
           zncl=SesCuCl;
           tz_ses="Custom_Session";
           tz_opn=timehr(stsescuh,stsescum);
           tz_cls=timehr(clsescuh,clsescum);
           break;
         }
       case New_Zealand:
         {
           Ses01Op=StringToTime(tmop01);
           Ses01Cl=StringToTime(tmcl01);
           zntm=Ses01Op;
           znop=Ses01Op;
           zncl=Ses01Cl;
           tz_ses="New_Zealand/Oceania";
           tz_opn=timehr(ReqTime(Ses01Op,hour),ReqTime(Ses01Op,min));
           tz_cls=timehr(ReqTime(Ses01Cl,hour),ReqTime(Ses01Cl,min));
           break;
         }
       case Australia:
         {
           Ses02Op=StringToTime(tmop02);
           Ses02Cl=StringToTime(tmcl02);
           zntm=Ses02Op;
           znop=Ses02Op;
           zncl=Ses02Cl;
           tz_ses="Australia Sydney";
           tz_opn=timehr(ReqTime(Ses02Op,hour),ReqTime(Ses02Op,min));
           tz_cls=timehr(ReqTime(Ses02Cl,hour),ReqTime(Ses02Cl,min));
           break;
         }
       case Asia_Tokyo:
         {
           Ses03Op=StringToTime(tmop03);
           Ses03Cl=StringToTime(tmcl03);
           zntm=Ses03Op;
           znop=Ses03Op;
           zncl=Ses03Cl;
           tz_ses="Asia/Tokyo";
           tz_opn=timehr(ReqTime(Ses03Op,hour),ReqTime(Ses03Op,min));
           tz_cls=timehr(ReqTime(Ses03Cl,hour),ReqTime(Ses03Cl,min));
           break;
         }
       case Europe_London:
         {
           Ses04Op=StringToTime(tmop04);
           Ses04Cl=StringToTime(tmcl04);
           zntm=Ses04Op;
           znop=Ses04Op;
           zncl=Ses04Cl;
           tz_ses="Europe/London";
           tz_opn=timehr(ReqTime(Ses04Op,hour),ReqTime(Ses04Op,min));
           tz_cls=timehr(ReqTime(Ses04Cl,hour),ReqTime(Ses04Cl,min));
           break;
         }
       case US_New_York:
         {
           Ses05Op=StringToTime(tmop05);
           Ses05Cl=StringToTime(tmcl05);
           zntm=Ses05Op;
           znop=Ses05Op;
           zncl=Ses05Cl;
           tz_ses="US/New_York";
           tz_opn=timehr(ReqTime(Ses05Op,hour),ReqTime(Ses05Op,min));
           tz_cls=timehr(ReqTime(Ses05Cl,hour),ReqTime(Ses05Cl,min));
           break;
         }
     }
   //--
   if(trd_time_zone==No)
     {
       SesNoOp=StringToTime(tmopno);
       SesNoCl=StringToTime(tmclno);
       zntm=SesNoOp;
       znop=SesNoOp;
       zncl=SesNoCl;
       tz_ses="Not Use Time Zone";
       tz_opn=timehr(ReqTime(SesNoOp,hour),ReqTime(SesNoOp,min));
       tz_cls=timehr(ReqTime(SesNoCl,hour),ReqTime(SesNoCl,min));
     }
   //--
   return;
//---
  } //-end Time_Zone()
//---------//

bool MCEA::Trade_session(void)
  {
//---
   bool trd_ses=false;
   ishour=ThisTime(hour);
   if(ishour!=onhour) Set_Time_Zone();
   datetime tcurr=TimeCurrent(); // Server Time
   //--
   switch(session)
     {
       case Cus_Session:
         {
           if(tcurr>=SesCuOp && tcurr<=SesCuCl) trd_ses=true;
           break;
         }
       case New_Zealand:
         {
           if(tcurr>=Ses01Op && tcurr<=Ses01Cl) trd_ses=true;
           break;
         }
       case Australia:
         {
           if(tcurr>=Ses02Op && tcurr<=Ses02Cl) trd_ses=true;
           break;
         }
       case Asia_Tokyo:
         {
           if(tcurr>=Ses03Op && tcurr<=Ses03Cl) trd_ses=true;
           break;
         }
       case Europe_London:
         {
           if(tcurr>=Ses04Op && tcurr<=Ses04Cl) trd_ses=true;
           break;
         }
       case US_New_York:
         {
           if(tcurr>=Ses05Op && tcurr<=Ses05Cl) trd_ses=true;
           break;
         }
     }
   //--
   if(trd_time_zone==No) 
     {
      if(tcurr>=SesNoOp && tcurr<=SesNoCl) trd_ses=true;
     }
   //--
   onhour=ishour;
   //--
   return(trd_ses);
//---  
  } //-end Trade_session()
//---------//

string MCEA::TradingDay(void)
  {
//---
   int trdday=ThisTime(dow);
   switch(trdday)
     {
        case 0: daytrade="Sunday";    break;
        case 1: daytrade="Monday";    break;
        case 2: daytrade="Tuesday";   break;
        case 3: daytrade="Wednesday"; break;
        case 4: daytrade="Thursday";  break;
        case 5: daytrade="Friday";    break;
        case 6: daytrade="Saturday";  break;
     }
   return(daytrade);
//---
  } //-end TradingDay()  
//---------//

bool MCEA::TradingToday(void)
  {
//---
    bool tradetoday=false;
    int trdday=ThisTime(dow);
    hariini="No";
    //--
    int ttd[];
    ArrayResize(ttd,7);
    ttd[0]=ttd0;
    ttd[1]=ttd1;
    ttd[2]=ttd2;
    ttd[3]=ttd3;
    ttd[4]=ttd4;
    ttd[5]=ttd5;
    ttd[6]=ttd6;
    //--
    if(ttd[trdday]==Yes) {tradetoday=true; hariini="Yes";}
   //--
   return(tradetoday);
//---
  } //-end TradingToday()
//---------//

string MCEA::timehr(int hr,int mn)
  {
//---
    string scon="";
    string men=mn==0 ? "00" : string(mn);
    int shr=hr==24 ? 0 : hr;
    if(shr<10) scon="0"+string(shr)+":"+men;
    else scon=string(shr)+":"+men;
    //--
    return(scon);
//---
  } //-end timehr()
//---------//

string MCEA::ReqDate(int d,int h,int m) 
  { 
//---
   MqlDateTime mdt; 
   datetime t=TimeCurrent(mdt); 
   x_year=mdt.year; 
   x_mon=mdt.mon; 
   x_day=d; 
   x_hour=h; 
   x_min=m;
   x_sec=mdt.sec;
   //--
   string mdr=string(x_year)+"."+string(x_mon)+"."+string(x_day)+"   "+timehr(x_hour,x_min);
   return(mdr);
//---
  } //-end ReqDate()
//---------//

int MCEA::ThisTime(const int reqmode) 
  {
//---
    MqlDateTime tm;
    TimeCurrent(tm);
    int valtm=0;
    //--
    switch(reqmode)
      {
        case 0: valtm=tm.year; break;        // Return Year 
        case 1: valtm=tm.mon;  break;        // Return Month 
        case 2: valtm=tm.day;  break;        // Return Day 
        case 3: valtm=tm.hour; break;        // Return Hour 
        case 4: valtm=tm.min;  break;        // Return Minutes 
        case 5: valtm=tm.sec;  break;        // Return Seconds 
        case 6: valtm=tm.day_of_week; break; // Return Day of week (0-Sunday, 1-Monday, ... ,6-Saturday) 
        case 7: valtm=tm.day_of_year; break; // Return Day number of the year (January 1st is assigned the number value of zero) 
      }
    //--
    return(valtm);
//---
  } //-end ThisTime()
//---------//

int MCEA::ReqTime(datetime reqtime,
                  const int reqmode) 
  {
    MqlDateTime tm;
    TimeToStruct(reqtime,tm);
    int valtm=0;
    //--
    switch(reqmode)
      {
        case 0: valtm=tm.year; break;        // Return Year 
        case 1: valtm=tm.mon;  break;        // Return Month 
        case 2: valtm=tm.day;  break;        // Return Day 
        case 3: valtm=tm.hour; break;        // Return Hour 
        case 4: valtm=tm.min;  break;        // Return Minutes 
        case 5: valtm=tm.sec;  break;        // Return Seconds 
        case 6: valtm=tm.day_of_week; break; // Return Day of week (0-Sunday, 1-Monday, ... ,6-Saturday) 
        case 7: valtm=tm.day_of_year; break; // Return Day number of the year (January 1st is assigned the number value of zero) 
      }
    //--
    return(valtm);
//---
  } //-end ReqTime()
//---------//

string MCEA::AccountMode() // function: to known account trade mode
  {
//----
//--- Demo, Contest or Real account 
   ENUM_ACCOUNT_TRADE_MODE account_type=(ENUM_ACCOUNT_TRADE_MODE)AccountInfoInteger(ACCOUNT_TRADE_MODE);
 //---
   trade_mode="";
   //--
   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()
//---------//

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

string MCEA::TF2Str(ENUM_TIMEFRAMES period)
  {
//---
   switch(period)
     {
       //--
       case PERIOD_M1:   return("M1");
       case PERIOD_M2:   return("M2");
       case PERIOD_M3:   return("M3");
       case PERIOD_M4:   return("M4");
       case PERIOD_M5:   return("M5");
       case PERIOD_M6:   return("M6");
       case PERIOD_M10:  return("M10");
       case PERIOD_M12:  return("M12");
       case PERIOD_M15:  return("M15");
       case PERIOD_M20:  return("M20");
       case PERIOD_M30:  return("M30");
       case PERIOD_H1:   return("H1");
       case PERIOD_H2:   return("H2");
       case PERIOD_H3:   return("H3");
       case PERIOD_H4:   return("H4");
       case PERIOD_H6:   return("H6");
       case PERIOD_H8:   return("H8");
       case PERIOD_H12:  return("H12");
       case PERIOD_D1:   return("D1");
       case PERIOD_W1:   return("W1");
       case PERIOD_MN1:  return("MN1");
       //--
     }
   return(string(period));
//---
  } //-end TF2Str()
//---------//

string MCEA::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()
//---------//

//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
//--- handling CHARTEVENT_CLICK event ("Clicking the chart")
   ResetLastError();
   //--
   ENUM_TIMEFRAMES CCS=mc.TFt;
   //--
   if(id==CHARTEVENT_OBJECT_CLICK) 
     {
       int lensymbol=StringLen(Symbol());
       int lensparam=StringLen(sparam);
       //--
       //--- if "Set SL All Orders" button is click
       if(sparam=="Set SL/TP All Orders") 
         { 
           mc.SetSLTPOrders();
           Alert("-- "+mc.expname+" -- ",Symbol()," -- Set SL/TP All Orders");
           //--- unpress the button 
           ObjectSetInteger(0,"Set SL/TP All Orders",OBJPROP_STATE,false);
           ObjectSetInteger(0,"Set SL/TP All Orders",OBJPROP_ZORDER,0);
           CreateManualPanel();
         }
       //--- if "Close All Order" button is click
       if(sparam=="Close All Order") 
         { 
           mc.CloseAllOrders();
           Alert("-- "+mc.expname+" -- ",Symbol()," -- Close All Orders");
           //--- unpress the button 
           ObjectSetInteger(0,"Close All Order",OBJPROP_STATE,false);
           ObjectSetInteger(0,"Close All Order",OBJPROP_ZORDER,0);
           CreateManualPanel();
         }
       //--- if "Close All Profit" button is click
       if(sparam=="Close All Profit") 
         { 
           mc.ManualCloseAllProfit();
           Alert("-- "+mc.expname+" -- ",Symbol()," -- Close All Profit");
           //--- unpress the button 
           ObjectSetInteger(0,"Close All Profit",OBJPROP_STATE,false);
           ObjectSetInteger(0,"Close All Profit",OBJPROP_ZORDER,0);
           CreateManualPanel();
         }
       //--- if "X" button is click
       if(sparam=="X") 
         { 
           ObjectsDeleteAll(0,0,OBJ_BUTTON);
           ObjectsDeleteAll(0,0,OBJ_LABEL);
           ObjectsDeleteAll(0,0,OBJ_RECTANGLE_LABEL);
           //--- unpress the button 
           ObjectSetInteger(0,"X",OBJPROP_STATE,false);
           ObjectSetInteger(0,"X",OBJPROP_ZORDER,0);
           //--
           DeleteButtonX();
           mc.PanelExtra=false;
           DisplayManualButton();
         }
       //--- if "M" button is click
       if(sparam=="M") 
         { 
           //--- unpress the button 
           ObjectSetInteger(0,"M",OBJPROP_STATE,false);
           ObjectSetInteger(0,"M",OBJPROP_ZORDER,0);
           mc.PanelExtra=true;
           CreateManualPanel();
         }
       //--- if "C" button is click
       if(sparam=="C") 
         { 
           //--- unpress the button 
           ObjectSetInteger(0,"C",OBJPROP_STATE,false);
           ObjectSetInteger(0,"C",OBJPROP_ZORDER,0);
           mc.PanelExtra=true;
           CreateSymbolPanel();
         }
       //--- if "R" button is click
       if(sparam=="R") 
         { 
           Alert("-- "+mc.expname+" -- ",Symbol()," -- expert advisor will be Remove from the chart.");
           ExpertRemove();
           //--- unpress the button 
           ObjectSetInteger(0,"R",OBJPROP_STATE,false);
           ObjectSetInteger(0,"R",OBJPROP_ZORDER,0);
           if(!ChartSetSymbolPeriod(0,Symbol(),Period()))
             ChartSetSymbolPeriod(0,Symbol(),Period());
           DeletePanelButton();
           ChartRedraw(0);
         }
       //--- if Symbol button is click
       if(lensparam==lensymbol)
         {
           int sx=mc.ValidatePairs(sparam);
           ChangeChartSymbol(mc.AS30[sx],CCS);
           mc.PanelExtra=false;
         }
       //--
     }
    //--
    return;
//---
  } //-end OnChartEvent()
//---------//

void ChangeChartSymbol(string c_symbol,ENUM_TIMEFRAMES cstf)
  {
//---
   //--- unpress the button 
   ObjectSetInteger(0,c_symbol,OBJPROP_STATE,false);
   ObjectSetInteger(0,c_symbol,OBJPROP_ZORDER,0);
   ObjectsDeleteAll(0,0,OBJ_BUTTON);
   ObjectsDeleteAll(0,0,OBJ_LABEL);
   ObjectsDeleteAll(0,0,OBJ_RECTANGLE_LABEL);
   //--
   ChartSetSymbolPeriod(0,c_symbol,cstf);
   //--
   ChartRedraw(0);
   //--
   return;
//---
  } //-end ChangeChartSymbol()
//---------//

int WS(int width) // Width Scaling factor wide button
  {
//---
    int res=0;
    int reswidth=0;
    //--- Calculating the scaling factor wide button on a screen
    int scale_factor=(TerminalInfoInteger(TERMINAL_SCREEN_DPI));
    //--- Use of the scaling factor 
    reswidth=(width * scale_factor) / 96;
    double res1=NormalizeDouble(reswidth*1.25,0);
    res=int(res1);
    //--
    return(res);
//---
  } //-end WS()
//---------//

void CreateManualPanel()
  {
//---
    //--
    CreateButtonTemplate(0,"TemplateSL",160,35,STYLE_SOLID,5,BORDER_RAISED,clrNONE,clrBurlyWood,clrWhite,CORNER_RIGHT_UPPER,170,45,true);
    CreateButtonTemplate(0,"TempStatSL",154,30,STYLE_SOLID,3,BORDER_RAISED,clrNONE,clrGreen,clrWhite,CORNER_RIGHT_UPPER,167,48,true);
    CreateButtonClick(0,"Set SL/TP All Orders",143,21,"Bodoni MT Black",10,BORDER_RAISED,"Set SL/TP All Orders",clrNONE,clrRed,clrWhite,ANCHOR_CENTER,CORNER_RIGHT_UPPER,162,56,true,"Set SL/TP All Orders");
//--
    CreateButtonTemplate(0,"TemplateS",160,35,STYLE_SOLID,5,BORDER_RAISED,clrNONE,clrBurlyWood,clrWhite,CORNER_RIGHT_UPPER,170,77,true);
    CreateButtonTemplate(0,"TempStats",154,30,STYLE_SOLID,3,BORDER_RAISED,clrNONE,clrGreen,clrWhite,CORNER_RIGHT_UPPER,167,79,true);
    CreateButtonClick(0,"Close All Order",143,21,"Bodoni MT Black",10,BORDER_RAISED,"Close All Order",clrNONE,clrRed,clrWhite,ANCHOR_CENTER,CORNER_RIGHT_UPPER,162,88,true,"Close All Order");
//--
    CreateButtonTemplate(0,"TemplateC",160,35,STYLE_SOLID,5,BORDER_RAISED,clrNONE,clrBurlyWood,clrWhite,CORNER_RIGHT_UPPER,170,109,true);
    CreateButtonTemplate(0,"TempStatC",154,30,STYLE_SOLID,3,BORDER_RAISED,clrNONE,clrGreen,clrWhite,CORNER_RIGHT_UPPER,167,111,true);
    CreateButtonClick(0,"Close All Profit",143,21,"Bodoni MT Black",10,BORDER_RAISED,"Close All Profit",clrNONE,clrRed,clrWhite,ANCHOR_CENTER,CORNER_RIGHT_UPPER,162,120,true,"Close All Profit");
//--
    DeletePanelButton();
    CreateButtonClick(0,"X",17,15,"Arial Black",12,BORDER_RAISED,"X",clrNONE,clrWhite,clrRed,ANCHOR_CENTER,CORNER_RIGHT_UPPER,27,31,true,"Close panel");
    //--
    ChartRedraw(0);
    //--
    return;
//---
   } //-end CreateManualPanel()
//---------//

void DisplayManualButton(void)
  {
//--
    DeleteButtonX();
    CreateButtonClick(0,"M",17,16,"Arial Black",11,BORDER_FLAT,"M",clrWhite,clrWhite,clrRed,ANCHOR_CENTER,CORNER_RIGHT_UPPER,61,21,true,"Open Manual Panel");
    CreateButtonClick(0,"C",17,16,"Arial Black",11,BORDER_FLAT,"C",clrWhite,clrWhite,clrRed,ANCHOR_CENTER,CORNER_RIGHT_UPPER,41,21,true,"Change Chart Symbol");
    CreateButtonClick(0,"R",17,16,"Arial Black",11,BORDER_FLAT,"R",clrWhite,clrWhite,clrRed,ANCHOR_CENTER,CORNER_RIGHT_UPPER,21,21,true,"Expert Remove");
    ChartRedraw(0);
    //--
    return;
//--
  } //-end DisplayManualButton()
//---------//

bool DisplayManualButton(string a,string b,string c)
  {
//--
   if(ObjectFind(0,a)<0 && ObjectFind(0,b)<0 && ObjectFind(0,c)<0 && !mc.PanelExtra)
      return(false);
   return(true);
//--
  } //-end DisplayManualButton()
//---------//

void DeleteButtonX(void)
  {
//--
    ObjectDelete(0,"X");
    //--
    ChartRedraw(0);
    //--
    return;
//--
  } //-end DeleteButtonX()
//---------//

void DeletePanelButton(void)
  {
//--
    ObjectDelete(0,"M");
    ObjectDelete(0,"C");
    ObjectDelete(0,"R");
    //--
    return;
//--
  } //-end DeletePanelButton()
//---------//

void CreateSymbolPanel()
  {
//---    
    //--
    ResetLastError();
    DeletePanelButton();
    int sydis=83;
    int tsatu=int(mc.sall/2);
    //--
    CreateButtonTemplate(0,"Template",180,367,STYLE_SOLID,5,BORDER_RAISED,clrYellow,clrBurlyWood,clrWhite,CORNER_RIGHT_UPPER,187,45,true);
    CreateButtonTemplate(0,"TempCCS",167,25,STYLE_SOLID,5,BORDER_RAISED,clrYellow,clrBlue,clrWhite,CORNER_RIGHT_UPPER,181,50,true);
    CreateButtonClick(0,"X",14,14,"Arial Black",10,BORDER_FLAT,"X",clrWhite,clrWhite,clrRed,ANCHOR_CENTER,CORNER_RIGHT_UPPER,22,48,true,"Close Symbol Panel");
    //--
    string chsym="Change SYMBOL";
    int cspos=int(181/2)+int(StringLen(chsym)/2);
    CreateButtontLable(0,"CCS","Bodoni MT Black",chsym,11,clrWhite,ANCHOR_CENTER,CORNER_RIGHT_UPPER,cspos,62,true,"Change Chart Symbol");
    //--
    for(int i=0; i<tsatu; i++)
      CreateButtonClick(0,mc.AS30[i],80,17,"Bodoni MT Black",8,BORDER_RAISED,mc.AS30[i],clrYellow,clrBlue,clrWhite,ANCHOR_CENTER,CORNER_RIGHT_UPPER,180,sydis+(i*22),true,"Change to "+mc.AS30[i]);
    //--
    for(int i=tsatu; i<mc.sall; i++)
      CreateButtonClick(0,mc.AS30[i],80,17,"Bodoni MT Black",8,BORDER_RAISED,mc.AS30[i],clrYellow,clrBlue,clrWhite,ANCHOR_CENTER,CORNER_RIGHT_UPPER,94,sydis+((i-tsatu)*22),true,"Change to "+mc.AS30[i]);
    //--
    ChartRedraw(0);
    //--
    return;
//---
   } //-end CreateSymbolPanel()
//---------//

void CreateButtonClick(long   chartid, 
                       string button_name,
                       int    button_x_size,
                       int    button_y_size,
                       string button_font_model,
                       int    button_font_size,
                       int    button_border,
                       string button_name_text,
                       color  button_bord_color,
                       color  button_bg_color,
                       color  button_color,
                       int    button_anchor,
                       int    button_corner,
                       int    button_xdist,
                       int    button_ydist,
                       bool   button_hidden,
                       string tooltip)
  {
//---
    ObjectCreate(chartid,button_name,OBJ_BUTTON,0,0,0); // create button
    ObjectSetInteger(chartid,button_name,OBJPROP_XSIZE,WS(button_x_size)); 
    ObjectSetInteger(chartid,button_name,OBJPROP_YSIZE,button_y_size); 
    ObjectSetString(chartid,button_name,OBJPROP_TEXT,button_name_text); 
    ObjectSetString(chartid,button_name,OBJPROP_FONT,button_font_model);
    ObjectSetInteger(chartid,button_name,OBJPROP_FONTSIZE,button_font_size);
    ObjectSetInteger(chartid,button_name,OBJPROP_BORDER_TYPE,button_border);
    ObjectSetInteger(chartid,button_name,OBJPROP_BORDER_COLOR,button_bord_color);
    ObjectSetInteger(chartid,button_name,OBJPROP_BGCOLOR,button_bg_color); 
    ObjectSetInteger(chartid,button_name,OBJPROP_COLOR,button_color);
    ObjectSetInteger(chartid,button_name,OBJPROP_ANCHOR,button_anchor);
    ObjectSetInteger(chartid,button_name,OBJPROP_CORNER,button_corner); 
    ObjectSetInteger(chartid,button_name,OBJPROP_XDISTANCE,WS(button_xdist));
    ObjectSetInteger(chartid,button_name,OBJPROP_YDISTANCE,button_ydist);
    ObjectSetInteger(chartid,button_name,OBJPROP_HIDDEN,button_hidden);
    ObjectSetString(chartid,button_name,OBJPROP_TOOLTIP,tooltip);
    ChartRedraw(0);
    //--
    return;
//---
  } //-end CreateButtonClick()
//---------//

void CreateButtonTemplate(long chartid,
                          string obj_name,
                          int    x_size,
                          int    y_size,
                          int    style,
                          int    width,
                          int    border,
                          color  bordcolor,
                          color  bgcolor,
                          color  objcolor,
                          int    corner,
                          int    x_dist,
                          int    y_dist,
                          bool   hidden)
  {
//---
    ObjectCreate(chartid,obj_name,OBJ_RECTANGLE_LABEL,0,0,0); // create Rectangle Label
    ObjectSetInteger(chartid,obj_name,OBJPROP_XSIZE,WS(x_size)); 
    ObjectSetInteger(chartid,obj_name,OBJPROP_YSIZE,y_size);
    ObjectSetInteger(chartid,obj_name,OBJPROP_STYLE,style);
    ObjectSetInteger(chartid,obj_name,OBJPROP_WIDTH,width);
    ObjectSetInteger(chartid,obj_name,OBJPROP_BORDER_TYPE,border);
    ObjectSetInteger(chartid,obj_name,OBJPROP_BORDER_COLOR,bordcolor);
    ObjectSetInteger(chartid,obj_name,OBJPROP_BGCOLOR,bgcolor); 
    ObjectSetInteger(chartid,obj_name,OBJPROP_COLOR,objcolor);
    ObjectSetInteger(chartid,obj_name,OBJPROP_CORNER,corner); 
    ObjectSetInteger(chartid,obj_name,OBJPROP_XDISTANCE,WS(x_dist));
    ObjectSetInteger(chartid,obj_name,OBJPROP_YDISTANCE,y_dist);
    ObjectSetInteger(chartid,obj_name,OBJPROP_HIDDEN,hidden);
    ChartRedraw(0);
    //--
    return;
//---
   } //-end CreateButtonTemplate()
//---------//

void CreateButtontLable(long   chartid, 
                        string lable_name, 
                        string lable_font_model,
                        string lable_obj_text,
                        int    lable_font_size,
                        color  lable_color,
                        int    lable_anchor,
                        int    lable_corner,
                        int    lable_xdist,
                        int    lable_ydist,
                        bool   lable_hidden,
                        string tooltip)
  {  
//---
    ObjectDelete(chartid,lable_name);
    ObjectCreate(chartid,lable_name,OBJ_LABEL,0,0,0,0,0); // create Lable 
    ObjectSetInteger(chartid,lable_name,OBJPROP_FONTSIZE,lable_font_size); 
    ObjectSetString(chartid,lable_name,OBJPROP_FONT,lable_font_model);
    ObjectSetString(chartid,lable_name,OBJPROP_TEXT,lable_obj_text);
    ObjectSetInteger(chartid,lable_name,OBJPROP_COLOR,lable_color);
    ObjectSetInteger(chartid,lable_name,OBJPROP_ANCHOR,lable_anchor);
    ObjectSetInteger(chartid,lable_name,OBJPROP_CORNER,lable_corner);
    ObjectSetInteger(chartid,lable_name,OBJPROP_XDISTANCE,WS(lable_xdist));
    ObjectSetInteger(chartid,lable_name,OBJPROP_YDISTANCE,lable_ydist);
    ObjectSetInteger(chartid,lable_name,OBJPROP_HIDDEN,lable_hidden);
    ObjectSetString(chartid,lable_name,OBJPROP_TOOLTIP,tooltip);
    ChartRedraw(0);
    //--
    return;
//---
  } //-end CreateButtontLable()   
//---------//
//--------------------------------------------------------------------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***

Please download the ADX_Trend_MCEA Expert Advisor: ADX_Trend_MCEA

If you want to get the source code of the program, please send your request via the Contact page by mentioning the article and program you want.


© 2026 ADX_Trend_MCEA - Developed by Roberto Jacobs (3rjfx)

Tagged: , , , , , , , , , ,

0 comments:

Post a Comment

Featured Post

Mastering Price Action: Forex Candlestick Patterns (FCP) for MT5

Author: Roberto Jacobs (3rjfx) | Featured on Forex Home Expert Introduction In the world of professional trading, price acti...

Featured Post Image