English Русский Español Deutsch 日本語
preview
Criando um Expert Advisor simples multimoeda usando MQL5 (Parte 3): Prefixos/sufixos de símbolos e sessão de negociação

Criando um Expert Advisor simples multimoeda usando MQL5 (Parte 3): Prefixos/sufixos de símbolos e sessão de negociação

MetaTrader 5Negociação | 24 abril 2024, 11:37
114 0
Roberto Jacobs
Roberto Jacobs

Introdução

Recebi comentários de vários colegas traders sobre como usar o Expert Advisor multimoedas que estou considerando com corretoras que usam prefixos e/ou sufixos com nomes de símbolos, bem como sobre como implementar fusos horários de negociação ou sessões de horário de negociação nesse Expert Advisor multimoedas.

Aqui, criarei e descreverei uma função que será incluída no Expert Advisor FXSAR_MTF_MCEA descrito no artigo anterior. A função foi projetada para detectar automaticamente símbolos de corretores com prefixos e/ou sufixos, bem como fusos horários de negociação.


Características

1. Pares de negociação.

O robô investidor negociará nos seguintes pares: 

Forex:

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 = 28 pares

Mais 2 pares de metais: XAUUSD (ouro) e XAGUSD (prata).

Total de 30 pares.


No artigo anterior, eu disse que esse EA multimoedas não ia funcionar com corretoras cujos símbolos ou pares tenham prefixos ou sufixos.

Ao usar Expert Advisors que trabalham somente com moedas individuais (um par, um EA), não deve haver problemas com corretoras cujos símbolos tenham prefixos e/ou sufixos.

Mas no EA multimoeda que criei, registramos 30 pares para serem negociados com símbolos padrão cujos nomes são comumente usados por muitas corretoras. Esse é o método mais fácil e rápido em comparação com o fato de inserir os nomes dos pares um a um nas propriedades do EA. Pode acontecer que haja erros de digitação.

Os traders ou programadores que usarão os princípios do EA descritos podem editar manualmente todos os 30 pares listados e isso não causará nenhum problema.

Mas eu (como provavelmente muitos de vocês) para uma operação perfeita preferiria usar a função para tratar automaticamente os nomes de símbolos que têm prefixos e/ou sufixos.

Uma desvantagem do recurso para detectar nomes com prefixos e sufixos é que ele só funciona para Forex e metais no MetaTrader 5, mas não funcionará com símbolos e índices personalizados.

Nesta versão, como estamos adicionando uma sessão de negociação (fuso horário de negociação), também adicionaremos 10 pares de opções para operar de acordo com o horário do pregrão.

Um dos 10 pares de opções que serão negociados é o Trader Wishes Pairs, em cujo caso os pares negociados devem ser inseridos manualmente pelo operador nas propriedades do EA.

Nota: O nome do par inserido já deve estar na lista de 30 pares.



2. Sessão de negociação (fuso horário).

Como sabemos, a plataforma Metatrader tem duas versões: MetaTrader 4 e MetaTrader 5, que foram criados pela MetaQuotes Software Corporation em 2005 e 2010, respectivamente. Essa empresa é de origem russa e é líder no mercado de software financeiro.

A configuração de horário do MetaTrader 5 é diferente para cada corretora, dependendo de seu fuso horário (GMT/UTC). Você pode ver a configuração de compensação de tempo do corretor para o servidor de negociação no canto superior esquerdo da plataforma MetaTrader 5. Normalmente, o horário do servidor de negociação da corretora está vinculado ao horário da Bolsa de Valores de Nova York (NYEM). Quando o MetaTrader 5 mostra 00:00, a NYEM está fechada.

O mercado Forex está aberto 24 horas por dia, 5 dias por semana, em todo o mundo. O mercado abre na segunda-feira na Nova Zelândia às 8h00, horário local ou 20h00 GMT/UTC, seguido pelo início da sessão de mercado em Sydney às 9h00 da manhã de segunda-feira, horário local, que é 21h00 GMT/UTC de domingo. (Deslocamento de horário padrão)

Para obter o fuso horário de negociação, primeiro precisamos descobrir a hora mais recente a partir da hora atual do servidor de negociação. Então, também precisamos saber a diferença de horário (em horas) entre o horário do servidor do trader e o horário GMT/UTC. A alteração do horário em 1 hora no verão não afeta o horário do servidor de negociação, pois o horário do servidor de negociação da MetaTrader 5 também será adiantado em 1 hora.

Existem 5 fusos horários de Forex que são mais amplamente utilizados pelos traders:

  • A Nova Zelândia abre às 20:00 e fecha às 05:00 GMT/UTC, que é 8:00 e 17:00 no horário local.
  • Sydney abre às 21h e fecha às 7h GMT/UTC, ou seja, 9h e 17h no horário local.
  • Tóquio abre às 00:00 e fecha às 9:00 GMT/UTC, que é 8:00 e 18:00 no horário local.
  • Londres abre às 9:00 e fecha às 19:00 GMT/UTC, ou seja, 9:00 e 19:00 no horário local.
  • Nova York abre às 13:00 e fecha às 22:00 GMT/UTC, ou seja, 9:00 e 19:00 no horário local.


    Implementação em um programa MQL5

    1. Título do programa e parâmetros de entrada.

    Inclusão do arquivo de cabeçalho em MQL5

    //+------------------------------------------------------------------+
    //|                             Include                              |
    //+------------------------------------------------------------------+
    #include <Trade\Trade.mqh>
    #include <Trade\PositionInfo.mqh>
    #include <Trade\SymbolInfo.mqh>
    #include <Trade\AccountInfo.mqh>
    //--
    CTrade              mc_trade;
    CSymbolInfo         mc_symbol;
    CPositionInfo       mc_position; 
    CAccountInfo        mc_account;
    //---


    Enumeração para uso do fuso horário

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


    Enumeração para seleção de horas

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


    Enumeração para seleção de atas

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


    Listagem para selecionar 10 pares de opções para negociar

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


    A enumeração YN é usada para opções (Yes) ou (No) nos parâmetros do EA.

    //--
    enum YN
      {
       No,
       Yes
      };
    //--


    A enumeração para usar o tamanho do lote na gestão de capital

    //--
    enum mmt
      {
       FixedLot,   // Fixed Lot Size
       DynamLot    // Dynamic Lot Size
      };
    //--


    Parâmetros de entrada do EA:

    //---
    input group               "=== Select Pairs to Trade ===";  // Selected Pairs to trading
    input PairsTrade         usepairs = All30;           // Select Pairs to Use
    input string         traderwishes = "eg. eurusd,usdchf,gbpusd,gbpchf"; // 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 = 10.0;             // Percent Equity Risk per Trade (Min=1.0% / Max=10.0%)
    input double                Lots = 0.01;             // Input Manual Lot Size FixedLot
    //--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;               // 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 = 10;               // If Not Use Automatic TP - Input TP value in Pips
    input YN            TrailingSLTP = Yes;              // Use Trailing SL/TP (Yes) or (No)
    input YN                 autotrl = Yes;              // Use Automatic Trailing (Yes) or (No)
    input double               TSval = 5;                // If Not Use Automatic Trailing Input Trailing value in Pips
    input double               TSmin = 5;                // Minimum Pips to start Trailing Stop
    input double               TPmin = 25;               // 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)
    //--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 = 2023102;          // Expert ID (Magic Number)
    //---


    No grupo de propriedades de entrada Trade on Specific Time do Advisor, o trader pode selecionar:

    Negociar em um fuso horário específico - Negocie em um fuso horário específico (Yes) ou (No).

    Se Yes, você deve selecionar os parâmetros de enumeração:

    • Negociação em sessão personalizada
    • Negociação na sessão da Nova Zelândia
    • Negociação na sessão de Sydney da Austrália
    • Negociação na sessão asiática de Tóquio
    • Negociação na sessão da Europa em Londres (sessão de Londres)
    • Negociação na sessão de Nova York da América (sessão de Nova York)

    Ao selecionar uma sessão personalizada:

    Os traders devem definir um horário ou horas e minutos para iniciar a negociação e horas e minutos para fechar a negociação. Assim, o Expert Advisor só executará ações durante o tempo especificado.

    Em outros casos, os horários de início e término da negociação são escolhidos pelo Expert Advisor.


    2. Uma classe para a operação do EA.

    Para declarar todas as variáveis, objetos e funções necessários neste EA multimoeda, criaremos uma classe para especificar a estrutura e as configurações operacionais do EA.

    Especificamente, criamos as variáveis usadas na função para definir nomes de símbolos com prefixo e/ou sufixo e cálculos de fuso horário na classe MCEA.

    //+------------------------------------------------------------------+
    //| 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;
        string           pre,suf;           
        //--- Variables are used in Trading Time Zone
        int              ishour,
                         onhour;
        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           slv,
                         tpv,
                         pip,
                         xpip;
        double           differ;                 
        double           floatprofit,
                         fixclprofit;
        //--
        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);
        string           PosTimeZone(void);
        int              ThisTime(const int reqmode);
        int              ReqTime(datetime reqtime,const int reqmode);
        //--
        int              DirectionMove(const string symbol);
        int              GetPSARSignalMTF(string symbol);
        int              PARSAR05(const string symbol);
        int              PARSARMTF(const string symbol,ENUM_TIMEFRAMES mtf);
        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);
        //--
        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:
        //---
        
        //-- FXSAR_MTF_MCEA_sptz 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;
        //--
        int              hPar05[];
        int              hPSAR[][5];
        int              ALO,
                         dgts,
                         arrsar,
                         arrsymbx;
        int              sall,
                         arusd,
                         aretc,
                         arspc,
                         arper;
        ulong            slip;        
        //--
        double           SARstep,
                         SARmaxi;
        double           profitb[],
                         profits[];
        //--
        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,
                         TFT05,
                         TFSAR[];
        //--
        bool             PanelExtra;
        //------------
                         MCEA(void);
                         ~MCEA(void);            
        //------------
        //--
        virtual void     FXSAR_MTF_MCEA_sptz_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             CloseBuyPositions(const string symbol);
        void             CloseSellPositions(const string symbol);
        void             CloseAllOrders(void);
        void             CheckClose(const string symbx);
        void             TodayOrders(void);
        void             UpdatePrice(const string symbol,ENUM_TIMEFRAMES xtf);
        void             RefreshPrice(const string symbx,ENUM_TIMEFRAMES xtf,int bars);
        //--
        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             ModifySLTP(const string symbx,int TS_type);          
        bool             CloseAllProfit(void);
        bool             ManualCloseAllProfit(void);
        //--
        int              PairsIdxArray(const string symbol);
        int              ValidatePairs(const string symbol);
        int              TFIndexArray(ENUM_TIMEFRAMES TF);
        int              GetOpenPosition(const string symbol);
        int              GetCloseInWeakSignal(const string symbol,int exis);
        //--
        string           getUninitReasonText(int reasonCode);
        //--
        //------------
    //---
      }; //-end class MCEA
    //---------//


    A primeira e mais importante função na operação de um EA multimoeda, chamada a partir de OnInit(), é FXSAR_MTF_MCEA_sptz_Config().

    A função FXSAR_MTF_MCEA_sptz_Config() configura todos os símbolos usados, todos os indicadores de controle usados e algumas funções importantes do cabeçalho do arquivo include.

    //+------------------------------------------------------------------+
    //| Expert Configuration                                             |
    //+------------------------------------------------------------------+
    void MCEA::FXSAR_MTF_MCEA_sptz_Config(void) 
      {
    //---
        //--
        HandlingSymbolArrays(); // With this function we will handle all pairs that will be traded
        //--
        TFT05=PERIOD_M5;
        ENUM_TIMEFRAMES TFA[]={PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H4,PERIOD_D1};
        TFArrays=ArraySize(TFA);
        ArrayResize(TFSAR,TFArrays,TFArrays);
        ArrayCopy(TFSAR,TFA,0,0,WHOLE_ARRAY);
        //--
        TFt=TFSAR[2];
        //--
        //-- iSAR Indicators handle for all symbol
        for(int x=0; x<arrsymbx; x++) 
          {
            hPar05[x]=iSAR(DIRI[x],TFT05,SARstep,SARmaxi);
            //--
            for(int i=0; i<TFArrays; i++)
              {
                hPSAR[x][i]=iSAR(DIRI[x],TFSAR[i],SARstep,SARmaxi);
              }
          }
        //--
        ALO=(int)mc_account.LimitOrders()>arrsymbx ? arrsymbx : (int)mc_account.LimitOrders();
        //--
        LotPS=(double)ALO;
        //--
        mc_trade.SetExpertMagicNumber(magicEA);
        mc_trade.SetDeviationInPoints(slip);
        mc_trade.SetMarginMode();
        Set_Time_Zone();
        //--
        return;
    //---
      } //-end FXSAR_MTF_MCEA_sptz_Config()
    //---------//


    Para configurar o par negociado, vamos chamar a função HandlingSymbolArrays().

    Usando a função HandlingSymbolArrays(), trataremos todos os pares negociados.

    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
        //--
        sall=ArraySize(All30);
        arusd=ArraySize(USDs);
        aretc=ArraySize(EURs);
        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<aretc; 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);}
        //--
        switch(usepairs)
          {
            case 0: // All Forex 30 Pairs
              {
                ArrayResize(DIRI,sall,sall);
                arrsymbx=sall;
                ArraySymbolResize();
                ArrayCopy(DIRI,All30,0,0,WHOLE_ARRAY);
                pairs="Multi Currency 30 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,aretc,aretc);
                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;
              }
          }
        //--
        return;
    //---
      } //-end HandlingSymbolArrays()
    //---------// 


    Dentro da função HandlingSymbolArrays(), chamamos a função SetSymbolNamePS().

    Com ela , poderemos detectar e processar nomes de símbolos que tenham prefixos e/ou sufixos.

    void MCEA::SetSymbolNamePS(void)
      {
    //---
       int sym_Lenpre=0;
       int sym_Lensuf=0;
       string sym_pre="";
       string sym_suf="";
       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()
    //---------//


    3. Função Expert tick.

    Na função Expert tick (OnTick()), chamaremos uma das funções principais do EA multimoeda, a saber, a função ExpertActionTrade().

    //+------------------------------------------------------------------+
    //| Expert tick function                                             |
    //+------------------------------------------------------------------+
    void OnTick(void)
      {
    //---
        mc.ExpertActionTrade();
        //--
        return;
    //---
      } //-end OnTick()
    //---------//


    A sequência do EA dentro dessa função.

    A função ExpertActionTrade() executará todas as ações e gerenciará a negociação automática, incluindo a abertura/fechamento de ordens, trailing-stop, trailing take-profit, e outras ações adicionais.

    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++) 
              {
                //-- 
                if(mc.DIRI[x]==Symbol()) symbol=Symbol();
                else symbol=mc.DIRI[x];
                //--
                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);
                        //--
                        if(mc.xob[x]==0 && mc.xtto<mc.ALO) 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
                            if(SaveOnRev==Yes) 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);
                        //--
                        if(mc.xos[x]==0 && mc.xtto<mc.ALO) 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
                            if(SaveOnRev==Yes) mc.CloseAllProfit();
                          }
                      }
                  }
                //--
                mc.CheckOpenPMx(symbol);
                //--
                if(mc.xtto>0)
                  {
                    //--
                    if(SaveOnRev==Yes) //-- Close Trade and Save profit due to weak signal (Yes)
                      {
                        mc.CheckOpenPMx(symbol);
                        if(mc.profitb[x]>0.02 && 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]>0.02 && 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(TrailingSLTP==Yes) //-- Use Trailing SL/TP (Yes)
                      {
                        if(autotrl==Yes) mc.ModifySLTP(symbol,1); //-- If Use Automatic Trailing (Yes)
                        if(autotrl==No)  mc.ModifySLTP(symbol,0); //-- Use Automatic Trailing (No)
                      }
                  }
                //--
                mc.CheckClose(symbol);
              }
            //--
            mc.psec=mc.ccur;
          }
        //--
        return;
    //---
      } //-end ExpertActionTrade()
    //---------//


    Uma chamada da função lógica Trade Session() foi adicionada à função ExpertActionTrade(), especialmente para fusos horários de negociação.

    Quando Trade_session() for true, o EA funcionará até o encerramento e, quando for false, o EA só executará as tarefas Close Trade e Save Profit devido a sinal fraco (Yes) e Trailing stop (Yes).

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


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

    Algumas funções de suporte para cálculos de tempo são:

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


    4. Recuperação de sinais de negociação para abrir/fechar posições

    No artigo anterior, usei sinais multi-timeframe baseados em 5 períodos de tempo.

    void MCEA::FXSAR_MTF_MCEA_Config(void) 
      {
        //---
    
        ENUM_TIMEFRAMES TFA[]={PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H4,PERIOD_D1};
        TFArrays=ArraySize(TFA);
        ArrayResize(TFSAR,TFArrays,TFArrays);
        ArrayCopy(TFSAR,TFA,0,0,WHOLE_ARRAY);
    
        //--
        return;
    //---
      } //-end FXSAR_MTF_MCEA_Config()
    //---------//
    


    Mas, neste artigo, mudei os quatro períodos de tempo base do sinal de vários períodos de tempo para M5, M30, H1 e, finalmente, H4.

    void MCEA::FXSAR_MTF_MCEA_sptz_Config(void) 
      {
    //---
        //--
        ENUM_TIMEFRAMES TFA[]={PERIOD_M5,PERIOD_M30,PERIOD_H1,PERIOD_H4};
        TFArrays=ArraySize(TFA);
        ArrayResize(TFSAR,TFArrays,TFArrays); // TFArrays now the value of array size is 4
        ArrayCopy(TFSAR,TFA,0,0,WHOLE_ARRAY);
    
        //--
        return;
    //---
      } //-end FXSAR_MTF_MCEA_sptz_Config()
    //---------//


    Para obter um sinal PSAR multi-timeframe, chamaremos GetPSARSignalMTF() para obter a posição do indicador ParabolicSAR no timeframe solicitado:

    int MCEA::GetPSARSignalMTF(string symbol)
      {
    //---
        int mv=0;
        int rise=1,
            down=-1;
        //--
        int sarup=0,
            sardw=0;
        //--    
        for(int x=0; x<TFArrays; x++)  // The TFArrays variable has a value of 54which is taken from the number of time frames from TF_M5, M30, H1 and H4.
          {
            if(PARSARMTF(symbol,TFSAR[x])>0) sarup++;
            if(PARSARMTF(symbol,TFSAR[x])<0) sardw++;
          }   
        //--
        if(sarup==TFArrays) mv=rise;
        if(sardw==TFArrays) mv=down;
        //--
        return(mv);
    //---
      } //- end GetPSARSignalMTF()
    //---------//


    Então, o descritor do indicador correspondente é chamado para obter o valor do buffer do indicador iSAR desse timeframe solicitado.

    int MCEA::PARSARMTF(const string symbol,ENUM_TIMEFRAMES mtf) // formula Parabolic SAR in set timeframe
      {
    //---
        int ret=0;
        int rise=1,
            down=-1;
        //--
        int br=2;
        //--
        double PSAR[];
        ArrayResize(PSAR,br,br);
        ArraySetAsSeries(PSAR,true);
        int xx=PairsIdxArray(symbol);
        int tx=TFIndexArray(mtf);
        CopyBuffer(hPSAR[xx][tx],0,0,br,PSAR);
        //--
        double OPN0=iOpen(symbol,TFSAR[tx],0);
        double HIG0=iHigh(symbol,TFSAR[tx],0);
        double LOW0=iLow(symbol,TFSAR[tx],0);
        double CLS0=iClose(symbol,TFSAR[tx],0);
        //--
        if(PSAR[0]<LOW0 && CLS0>OPN0) ret=rise;
        if(PSAR[0]>HIG0 && CLS0<OPN0) ret=down;
        //--
        return(ret);
    //---
      } //-end PARSARMTF()
    //---------//


    A função GetPSARSignalMTF é chamada a partir de GetOpenPosition() para obter um sinal de negociação para abrir uma posição.

    int MCEA::GetOpenPosition(const string symbol) // Signal Open Position 
      {
    //---
        int ret=0;
        int rise=1,
            down=-1;
        //--
        int dirmov=DirectionMove(symbol);
        int parsOp=GetPSARSignalMTF(symbol);
        //--
        if(parsOp==rise && dirmov==rise) ret=rise;
        if(parsOp==down && dirmov==down) ret=down;
        //--
        return(ret);
    //---
      } //-end GetOpenPosition()
    //---------//


    A função GetPSARSignalMTF() chamará a função PARSARMTF(), que calcula o sinal iSAR de acordo com o timeframe solicitado.

    Como você pode ver, dentro da função PARSARMTF(), usamos e chamamos duas funções:

    1. int xx= PairsIdxArray(symbol)

    A função PairsIdxArray() é usada para obter o nome do símbolo solicitado.

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

    2. int tx=TFIndexArray(mtf).

    A função TFIndexArray() é usada para recuperar a sequência do array do período de tempo solicitado.

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


    5. Função ChartEvent

    Para maior eficiência dos EAs multimoedas, criaremos vários botões para gerenciar ordens e alterar gráficos ou símbolos. Como essa versão usa 10 variantes de pares de negociação, a função OnChartEvent foi ligeiramente modificada.

    //+------------------------------------------------------------------+
    //| 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()
    //---------//


    Para alterar os símbolos do gráfico com um clique do mouse, ao pressionar em um dos nomes dos símbolos, o evento OnChartEvent() será chamado pela função ChangeChartSymbol().

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


    Quando adicionamos uma sessão de negociação ou um fuso horário de negociação e parâmetros de pares negociados, precisamos adicionar novos dados às informações de negociação exibidas no gráfico.

    Para isso, fizemos alterações na função TradeInfo().

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


    Adicionar uma função para explicar a hora de acordo com as condições do fuso horário de negociação

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


    A exibição de TradeInfo() terá a seguinte aparência.

    waiting_time


    Nota: Para as outras funções e algoritmos, o procedimento permanece o mesmo do Expert Advisor multimoeda do artigo anterior.


    Como você pode ver, sob o nome do Expert Advisor FXSAR_MTF_MCEA, existem botões M, C e R.

    Ao pressionar M ou C, um painel de controle manual é exibido.

    MCR_Combine

    Ao pressionar M, o painel de controle manual é exibido, após isso o trader pode gerenciar ordens:

    1. Set SL/TP All Orders (estabelecer stop-loss/take-profit para todas as ordens)
    2. Close All Orders (fechar todas as ordens)
    3. Close All Profits (fechar todas as ordens lucrativas)

    Ao pressionar C, um botão do painel com 30 nomes de símbolos ou pares é exibido, e os traders podem clicar em um dos nomes dos pares ou símbolos. Ao pressionar qualquer um deles, o símbolo do gráfico será imediatamente substituído pelo indicado no botão pressionado.

    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-15)*22),true,"Change to "+mc.AS30[i]);
        //--
        ChartRedraw(0);
        //--
        return;
    //---
       } //-end CreateSymbolPanel()
    //---------//

    Ao pressionar R, o EA multimoeda FXSAR_MTF_MCEA é removido do gráfico.


    Testador de estratégias

    Fiz alguns testes de histórico, experimentando vários fusos horários e pares que poderiam ser negociados.

    Os resultados no testador de estratégia podem ser vistos na imagem abaixo.

    No teste de histórico abaixo, foi selecionado o fuso horário de Nova York.

    FXSAR_MTF_MCEA_sptz_01


    No teste de histórico abaixo, o fuso horário selecionado é Tóquio.

    FXSAR_MTF_MCEA_sptz_02


    No teste de histórico abaixo, um fuso horário personalizado é selecionado

    FXSAR_MTF_MCEA_sptz_03


    Considerações finais

    1. O problema dos nomes de símbolos que têm prefixos e/ou sufixos em EAs de várias moedas pode ser facilmente resolvido no MQL5 sem a criação de símbolos personalizados.
    2. Com a introdução de uma sessão de negociação ou fuso horário de negociação e a adição de 10 pares de opções para negociação, espera-se que os traders obtenham uma estratégia melhor negociando apenas em determinados pares e em determinados horários ou sessões.
    3. Esse EA multimoeda é apenas um exemplo para estudo e desenvolvimento de ideias; assim sendo, se você tiver ideias para aprimoramento, poderá modificar o código do EA de acordo com seus desejos.

    Espero que o artigo e o EA multimoeda sejam úteis para os traders no estudo e desenvolvimento de ideias. Obrigado pela atenção!


    Traduzido do Inglês pela MetaQuotes Ltd.
    Artigo original: https://www.mql5.com/en/articles/13705

    Arquivos anexados |
    Redes neurais de maneira fácil (Parte 63): pré-treinamento do transformador de decisões não supervisionado (PDT) Redes neurais de maneira fácil (Parte 63): pré-treinamento do transformador de decisões não supervisionado (PDT)
    Continuamos nossa análise, desta vez, explorando a família de transformadores de decisão. Em trabalhos anteriores, já observamos que o treinamento do transformador subjacente à arquitetura desses métodos é bastante desafiador e requer uma grande quantidade de dados de treinamento rotulados. Neste artigo, consideramos um algoritmo para usar trajetórias não rotuladas com o objetivo de pré-treinar modelos.
    Padrões de projeto no MQL5 (Parte I): Padrões criacionais (creational patterns) Padrões de projeto no MQL5 (Parte I): Padrões criacionais (creational patterns)
    Existem métodos que podem ser usados para resolver problemas típicos. Depois de entender como usar esses métodos, você pode então escrever programas de maneira prática e aplicar o conceito DRY ("Don't Repeat Yourself" - "Não se Repita"). Neste contexto, os padrões de projeto são extremamente úteis, pois apresentam soluções para problemas bem descritos e recorrentes.
    Ciência de Dados e Aprendizado de Máquina (Parte 15): SVM — uma ferramenta útil no arsenal do trader Ciência de Dados e Aprendizado de Máquina (Parte 15): SVM — uma ferramenta útil no arsenal do trader
    Neste artigo, exploraremos o papel que o método de máquinas de vetores de suporte (<i>support vector machines</i>, SVM) desempenha na formação do futuro do trading. Este artigo pode ser visto como um guia detalhado que explica como usar o SVM para melhorar estratégias de trading, otimizar a tomada de decisões e descobrir novas oportunidades nos mercados financeiros. Você mergulhará no mundo do SVM através de aplicações reais, instruções passo a passo e avaliações de especialistas. Talvez essa ferramenta indispensável o ajude a entender as complexidades do trading moderno. De qualquer forma, o SVM se tornará uma ferramenta muito útil no arsenal de cada trader.
    Algoritmos de otimização populacionais: algoritmo de gotas de água inteligentes (Intelligent Water Drops, IWD) Algoritmos de otimização populacionais: algoritmo de gotas de água inteligentes (Intelligent Water Drops, IWD)
    Neste artigo é analisado um algoritmo interessante chamado de gotas de água inteligentes (IWD), inspirado na natureza inanimada, que simula o processo de formação do leito de um rio. As ideias desse algoritmo permitiram melhorar significativamente o líder anterior da classificação, o SDS, e o novo líder (SDSm modificado), como de costume, pode ser encontrado no arquivo do artigo.