English Русский 中文 Español Deutsch 日本語
preview
Kit de Ferramentos de Negociação MQL5(Parte 8): Como Implementar e Utilizar a Biblioteca History Manager EX5 em sua Base de Código

Kit de Ferramentos de Negociação MQL5(Parte 8): Como Implementar e Utilizar a Biblioteca History Manager EX5 em sua Base de Código

MetaTrader 5Negociação |
12 3
Wanateki Solutions LTD
Kelvin Muturi Muigua

Introdução

Nos artigos anteriores, conduzi você pelo desenvolvimento de uma biblioteca EX5 robusta e abrangente de gerenciamento de histórico, projetada para otimizar a forma como você interage com históricos de negociação no MetaTrader 5. Essa poderosa biblioteca permite que você examine, recupere, classifique, categorize e filtre todos os tipos de históricos de negociação—sejam posições fechadas, ordens pendentes ou históricos de negócios—diretamente da sua conta MetaTrader 5. Com base nessa fundação, este artigo dá o passo final ao mostrar como integrar de forma eficiente a biblioteca History Manager em seus projetos MQL5.

Forneci uma análise detalhada das funções disponíveis na biblioteca EX5, com explicações claras e exemplos práticos Esses casos de uso reais não apenas ajudam você a entender como cada função funciona, mas também demonstram como aplicá-las em suas estratégias de negociação ou ferramentas de análise. Seja você um iniciante buscando aprimorar suas habilidades de programação ou um desenvolvedor experiente procurando otimizar seu fluxo de trabalho, este guia oferece o conhecimento e as ferramentas necessárias para aproveitar ao máximo o potencial da biblioteca History Manager. Ao final deste artigo, você será capaz de implementar essa biblioteca versátil com confiança e começar a utilizar seus recursos para gerenciar históricos de negociação de forma mais eficiente do que nunca.

Benefícios de Utilizar o History Manager no MQL5

Abaixo estão as principais vantagens de integrar o History Manager em seus projetos MQL5:

  • Recuperação de Dados Sem Esforço: A biblioteca fornece funções intuitivas para recuperar dados de histórico de negociações, como negócios (deals), ordens, posições e ordens pendentes, com código mínimo. Isso elimina a necessidade de codificação complexa e repetitiva.
  • Interface Unificada: Todos os dados de histórico de negociação são acessíveis por meio de uma única interface consistente, facilitando o gerenciamento e a análise de diferentes tipos de atividades de negociação.
  • Funções que Economizam Tempo: Com chamadas de função de uma linha, você pode acessar rapidamente dados críticos de negociação, reduzindo o tempo de desenvolvimento e permitindo foco na implementação de estratégias.
  • Processamento Automatizado de Dados: A biblioteca automatiza a recuperação, classificação e filtragem de históricos de negociação, otimizando fluxos de trabalho e melhorando a eficiência geral.
  • Manipulação de Dados Sem Erros: A biblioteca garante a recuperação precisa dos dados de histórico de negociação, minimizando o risco de erros que podem ocorrer com codificação manual.
  • Cobertura Abrangente de Dados: De posições encerradas a ordens pendentes, a biblioteca fornece acesso a todos os tipos de históricos de negociação, garantindo que nenhum dado seja negligenciado.
  • Insights Detalhados: Funções como GetLastClosedPositionData(), GetLastFilledPendingOrderData(), e GetLastClosedProfitablePositionData(), entre muitas outras, fornecem detalhes granulares sobre negociações, permitindo análises mais profundas e melhores tomadas de decisão.
  • Filtros Personalizáveis: Você pode filtrar históricos de negociação por símbolo, número mágico ou intervalo de tempo, permitindo análises direcionadas de acordo com suas necessidades específicas.
  • Fácil Implementação: A biblioteca foi projetada para se integrar perfeitamente a projetos MQL5 existentes, exigindo configuração mínima.
  • Escalabilidade: Seja em um pequeno script ou em um sistema de negociação de grande escala, o History Manager escala facilmente para atender às suas necessidades.
  • Adaptável às Suas Necessidades: O design modular da biblioteca permite utilizar apenas as funções necessárias, tornando-a altamente adaptável a diferentes estilos e estratégias de negociação.
  • Funcionalidade Extensível: Desenvolvedores podem expandir as funções existentes da biblioteca para criar soluções personalizadas para requisitos específicos de negociação.
  • Soluções Prontas: Ao aproveitar as funções pré-construídas da biblioteca, você pode reduzir significativamente o tempo e o custo associados ao desenvolvimento de ferramentas personalizadas de gerenciamento de histórico de negociações.
  • Acessível a Todos os Níveis: Seja você iniciante ou desenvolvedor experiente, o design direto da biblioteca a torna acessível a usuários de todos os níveis de habilidade.
  • Decisões Baseadas em Dados: O acesso a históricos completos de negociação permite tomar decisões informadas ao desenvolver ou refinar estratégias de negociação.
  • Backtesting Histórico: Utilize a biblioteca para recuperar dados históricos de negociação para backtesting, garantindo que suas estratégias sejam robustas e confiáveis.
  • Backtesting Histórico: Utilize a biblioteca para recuperar dados históricos de negociação para backtesting, garantindo que suas estratégias sejam robustas e confiáveis.



Importação e Configuração da Biblioteca History Manager EX5

Antes de começar a utilizar os recursos da biblioteca History Manager EX5, é necessário importá-la e configurá-la corretamente em seu projeto MQL5. Esta seção irá guiá-lo pelo processo passo a passo, garantindo uma configuração simples e sem complicações.

Para utilizar o arquivo de biblioteca HistoryManager.ex5 em seus projetos MQL5, ele precisa ser baixado e colocado no diretório correto dentro da pasta de instalação do MetaTrader 5. Abra o MetaEditor a partir do terminal MetaTrader 5 navegando até Tools > MetaQuotes Language Editor ou pressionando F4 e siga as etapas abaixo:

  • Passo 1. Criar os Diretórios Necessários:

Dentro da pasta Libraries localizada no diretório raiz do MQL5, crie os seguintes subdiretórios caso ainda não existam: "\Wanateki\Toolkit\HistoryManager".
O caminho completo na sua pasta de instalação do MQL5 deve ser semelhante a: "MQL5\Libraries\Wanateki\Toolkit\HistoryManager".

  • Passo 2. Baixar o Arquivo Binário HistoryManager.ex5:

Role até o final deste artigo, localize o arquivo anexado HistoryManager.ex5 e faça o download. Coloque o arquivo dentro da pasta HistoryManager que você criou no Passo 1.
A estrutura de diretórios da pasta Libraries agora deve se assemelhar à imagem abaixo:

Diretório para salvar o arquivo executável da biblioteca HistoryManager.ex5

  • Passo 3. Criar o Arquivo de Cabeçalho da Biblioteca:

1. No MetaEditor IDE, abra o MQL Wizard usando o botão de menu New .

Assistente MQL5 para Novo Arquivo


2. Selecione a opção Include (*.mqh) e clique em Next.

Configuração de novo arquivo de inclusão do assistente MQL5

3. Na janela General properties of the include file, localize o campo Name. Apague todo o texto e insira o seguinte caminho para especificar o diretório e o nome do arquivo include: Include\Wanateki\Toolkit\HistoryManager\HistoryManager.mqh

Configuração do diretório de inclusão de novos arquivos do assistente MQL5

4. Pressione o botão Finish para gerar o arquivo de cabeçalho da biblioteca.



Codificando o Arquivo de Cabeçalho do History Manager (HistoryManager.mqh)

Agora que criamos com sucesso um arquivo include em branco para o cabeçalho da biblioteca HistoryManager.mqh, o próximo passo é preenchê-lo com os componentes necessários que definirão sua funcionalidade. Isso envolve adicionar estruturas de dados para gerenciar e armazenar informações de forma eficiente, incorporar diretivas de macro para simplificar tarefas repetitivas e melhorar a legibilidade do código, além de importar e declarar as funções da biblioteca que servirão como interfaces principais para interagir com as funcionalidades do HistoryManager.ex5.

Sob a #property link, começaremos declarando as estruturas de dados DealData, OrderData, PositionData e PendingOrderData no escopo global. Essas estruturas serão responsáveis ​​por armazenar diversas propriedades do histórico de negociações e poderão ser acessadas de qualquer parte do nosso código-fonte.

struct DealData
  {
  // Add all the DealData members here
  }
  
struct OrderData
  {
  // Add all the OrderData members here
  } 
  
struct PositionData
  {
  // Add all the PositionData members here
  }
  
struct PendingOrderData
  {
  // Add all the PendingOrderData members here
  }

Em seguida, iremos definir várias constantes ou macros para representar períodos-chave de tempo em segundos. Estas incluem NOW, ONE_DAY, ONE_WEEK, ONE_MONTH, ONE_YEAR, EPOCH, TODAY, THIS_WEEK, THIS_MONTH, e THIS_YEAR que irão simplificar os cálculos relacionados ao tempo e melhorar a legibilidade do código.

#define NOW datetime(TimeCurrent())
#define ONE_DAY datetime(TimeCurrent() - PeriodSeconds(PERIOD_D1))
#define ONE_WEEK datetime(TimeCurrent() - PeriodSeconds(PERIOD_W1))
#define ONE_MONTH datetime(TimeCurrent() - PeriodSeconds(PERIOD_MN1))
#define ONE_YEAR datetime(TimeCurrent() - (PeriodSeconds(PERIOD_MN1) * 12))
#define EPOCH 0 // 1st Jan 1970
//--
#define TODAY 12
#define THIS_WEEK 13
#define THIS_MONTH 14
#define THIS_YEAR 15

Também criaremos a macro de string ALL_SYMBOLS para armazenar uma string vazia. Isso servirá como um sinal para indicar que queremos processar o histórico especificado para todos os símbolos. Além disso, definiremos as macros inteiras ALL_POSITIONS, ALL_ORDERS e ALL_DEALS . Elas nos permitirão especificar os tipos de histórico de ordens, negócios e posições que desejamos processar.

#define ALL_SYMBOLS ""
#define ALL_POSITIONS 1110
#define ALL_ORDERS 1111
#define ALL_DEALS 1112

Agora que criamos todas as estruturas de dados necessárias e definimos as diretivas do pré-processador ou macros essenciais, é hora de importar a biblioteca HistoryManager.ex5. Agora que criamos todas as estruturas de dados necessárias e definimos as diretivas do pré-processador ou macros essenciais, é hora de importar a biblioteca HistoryManager.ex5.

#import "Wanateki/Toolkit/HistoryManager/HistoryManager.ex5"

Após a diretiva #import, adicionaremos as declarações das funções da biblioteca e finalizaremos inserindo a diretiva de fechamento #import como a linha final do nosso arquivo de cabeçalho HistoryManager.mqh.

#import "Wanateki/Toolkit/HistoryManager/HistoryManager.ex5"
//--
void PrintDealsHistory(datetime fromDateTime, datetime toDateTime);
void PrintOrdersHistory(datetime fromDateTime, datetime toDateTime);
void PrintPositionsHistory(datetime fromDateTime, datetime toDateTime);
void PrintPendingOrdersHistory(datetime fromDateTime, datetime toDateTime);

//--
bool GetDealsData(DealData &dealsData[], datetime fromDateTime, datetime toDateTime, string symbol, ulong magic);
bool GetOrdersData(OrderData &ordersData[], datetime fromDateTime, datetime toDateTime, string symbol, ulong magic);
bool GetPositionsData(PositionData &positionsData[], datetime fromDateTime, datetime toDateTime, string symbol, ulong magic);
bool GetPendingOrdersData(PendingOrderData &pendingOrdersData[], datetime fromDateTime, datetime toDateTime, string symbol, ulong magic);
//--

// Add all the other function declarations here...

#import

Abaixo estão os trechos de código essenciais que compõem o arquivo de inclusão HistoryManager.mqh. Este arquivo de cabeçalho fornece todos os recursos necessários para importar e integrar a biblioteca History Manager EX5 em seus projetos MQL5. Ao incluí-lo no início do seu arquivo-fonte, você obtém acesso a todas as estruturas de dados e funções da biblioteca, tornando-as prontamente disponíveis para uso imediato. O arquivo-fonte completo HistoryManager.mqh também está anexado ao final deste artigo para você baixar.

struct DealData
  {
   ulong             ticket;
   ulong             magic;
   ENUM_DEAL_ENTRY   entry;
   ENUM_DEAL_TYPE    type;
   ENUM_DEAL_REASON  reason;
   ulong             positionId;
   ulong             order;
   string            symbol;
   string            comment;
   double            volume;
   double            price;
   datetime          time;
   double            tpPrice;
   double            slPrice;
   double            commission;
   double            swap;
   double            profit;
  };  
//--
struct OrderData
  {
   datetime                timeSetup;
   datetime                timeDone;
   datetime                expirationTime;
   ulong                   ticket;
   ulong                   magic;
   ENUM_ORDER_REASON       reason;
   ENUM_ORDER_TYPE         type;
   ENUM_ORDER_TYPE_FILLING typeFilling;
   ENUM_ORDER_STATE        state;
   ENUM_ORDER_TYPE_TIME    typeTime;
   ulong                   positionId;
   ulong                   positionById;
   string                  symbol;
   string                  comment;
   double                  volumeInitial;
   double                  priceOpen;
   double                  priceStopLimit;
   double                  tpPrice;
   double                  slPrice;
  };
//--
struct PositionData
  {
   ENUM_POSITION_TYPE type;
   ulong              ticket;
   ENUM_ORDER_TYPE    initiatingOrderType;
   ulong              positionId;
   bool               initiatedByPendingOrder;
   ulong              openingOrderTicket;
   ulong              openingDealTicket;
   ulong              closingDealTicket;
   string             symbol;
   double             volume;
   double             openPrice;
   double             closePrice;
   datetime           openTime;
   datetime           closeTime;
   long               duration;
   double             commission;
   double             swap;
   double             profit;
   double             tpPrice;
   double             slPrice;
   int                tpPips;
   int                slPips;
   int                pipProfit;
   double             netProfit;
   ulong              magic;
   string             comment;
  };
//--
struct PendingOrderData
  {
   string                  symbol;
   ENUM_ORDER_TYPE         type;
   ENUM_ORDER_STATE        state;
   double                  priceOpen;
   double                  tpPrice;
   double                  slPrice;
   int                     tpPips;
   int                     slPips;
   ulong                   positionId;
   ulong                   ticket;
   datetime                timeSetup;
   datetime                expirationTime;
   datetime                timeDone;
   ENUM_ORDER_TYPE_TIME    typeTime;
   ulong                   magic;
   ENUM_ORDER_REASON       reason;
   ENUM_ORDER_TYPE_FILLING typeFilling;
   string                  comment;
   double                  volumeInitial;
   double                  priceStopLimit;
  };
//--
#define NOW datetime(TimeCurrent())
#define ONE_DAY datetime(TimeCurrent() - PeriodSeconds(PERIOD_D1))
#define ONE_WEEK datetime(TimeCurrent() - PeriodSeconds(PERIOD_W1))
#define ONE_MONTH datetime(TimeCurrent() - PeriodSeconds(PERIOD_MN1))
#define ONE_YEAR datetime(TimeCurrent() - (PeriodSeconds(PERIOD_MN1) * 12))
#define EPOCH 0 // 1st Jan 1970
//--
#define TODAY 12
#define THIS_WEEK 13
#define THIS_MONTH 14
#define THIS_YEAR 15
//--
#define ALL_SYMBOLS ""
#define ALL_POSITIONS 1110
#define ALL_ORDERS 1111
#define ALL_DEALS 1112
//--

#import "Wanateki/Toolkit/HistoryManager/HistoryManager.ex5"
//--
void PrintDealsHistory(datetime fromDateTime, datetime toDateTime);
void PrintOrdersHistory(datetime fromDateTime, datetime toDateTime);
void PrintPositionsHistory(datetime fromDateTime, datetime toDateTime);
void PrintPendingOrdersHistory(datetime fromDateTime, datetime toDateTime);

//--
bool GetDealsData(DealData &dealsData[], datetime fromDateTime, datetime toDateTime, string symbol, ulong magic);
bool GetOrdersData(OrderData &ordersData[], datetime fromDateTime, datetime toDateTime, string symbol, ulong magic);
bool GetPositionsData(PositionData &positionsData[], datetime fromDateTime, datetime toDateTime, string symbol, ulong magic);
bool GetPendingOrdersData(PendingOrderData &pendingOrdersData[], datetime fromDateTime, datetime toDateTime, string symbol, ulong magic);
//--

bool GetDealsData(DealData &dealsData[], datetime fromDateTime, datetime toDateTime);
bool GetOrdersData(OrderData &ordersData[], datetime fromDateTime, datetime toDateTime);
bool GetPositionsData(PositionData &positionsData[], datetime fromDateTime, datetime toDateTime);
bool GetPendingOrdersData(PendingOrderData &pendingOrdersData[], datetime fromDateTime, datetime toDateTime);

//--
bool GetAllDealsData(DealData &dealsData[]);
bool GetAllOrdersData(OrderData &ordersData[]);
bool GetAllPositionsData(PositionData &positionsData[]);
bool GetAllPendingOrdersData(PendingOrderData &pendingOrdersData[]);
//--
bool GetAllDealsData(DealData &dealsData[], string symbol, ulong magic);
bool GetAllOrdersData(OrderData &ordersData[], string symbol, ulong magic);
bool GetAllPositionsData(PositionData &positionsData[], string symbol, ulong magic);
bool GetAllPendingOrdersData(PendingOrderData &pendingOrdersData[], string symbol, ulong magic);

//--
bool GetLastClosedPositionData(PositionData &lastClosedPositionInfo);
bool LastClosedPositionType(ENUM_POSITION_TYPE &lastClosedPositionType);
bool LastClosedPositionVolume(double &lastClosedPositionVolume);
bool LastClosedPositionSymbol(string &lastClosedPositionSymbol);
bool LastClosedPositionTicket(ulong &lastClosedPositionTicket);
bool LastClosedPositionProfit(double &lastClosedPositionProfit);
bool LastClosedPositionNetProfit(double &lastClosedPositionNetProfit);
bool LastClosedPositionPipProfit(int &lastClosedPositionPipProfit);
bool LastClosedPositionClosePrice(double &lastClosedPositionClosePrice);
bool LastClosedPositionOpenPrice(double &lastClosedPositionOpenPrice);
bool LastClosedPositionSlPrice(double &lastClosedPositionSlPrice);
bool LastClosedPositionTpPrice(double &lastClosedPositionTpPrice);
bool LastClosedPositionSlPips(int &lastClosedPositionSlPips);
bool LastClosedPositionTpPips(int &lastClosedPositionTpPips);
bool LastClosedPositionOpenTime(datetime &lastClosedPositionOpenTime);
bool LastClosedPositionCloseTime(datetime &lastClosedPositionCloseTime);
bool LastClosedPositionSwap(double &lastClosedPositionSwap);
bool LastClosedPositionCommission(double &lastClosedPositionCommission);
bool LastClosedPositionInitiatedByPendingOrder(bool &lastClosedPositionInitiatedByPendingOrder);
bool LastClosedPositionInitiatingOrderType(ENUM_ORDER_TYPE &lastClosedPositionInitiatingOrderType);
bool LastClosedPositionId(ulong &lastClosedPositionId);
bool LastClosedPositionOpeningOrderTicket(ulong &lastClosedPositionOpeningOrderTicket);
bool LastClosedPositionOpeningDealTicket(ulong &lastClosedPositionOpeningDealTicket);
bool LastClosedPositionClosingDealTicket(ulong &lastClosedPositionClosingDealTicket);
bool LastClosedPositionMagic(ulong &lastClosedPositionMagic);
bool LastClosedPositionComment(string &lastClosedPositionComment);
bool LastClosedPositionDuration(long &lastClosedPositionDuration);

//--
bool GetLastClosedProfitablePositionData(PositionData &lastClosedProfitablePositionInfo);
bool GetLastClosedLossPositionData(PositionData &lastClosedLossPositionData);

//--
bool GetLastFilledPendingOrderData(PendingOrderData &getLastFilledPendingOrderData);
bool LastFilledPendingOrderType(ENUM_ORDER_TYPE &lastFilledPendingOrderType);
bool LastFilledPendingOrderSymbol(string &lastFilledPendingOrderSymbol);
bool LastFilledPendingOrderTicket(ulong &lastFilledPendingOrderTicket);
bool LastFilledPendingOrderPriceOpen(double &lastFilledPendingOrderPriceOpen);
bool LastFilledPendingOrderSlPrice(double &lastFilledPendingOrderSlPrice);
bool LastFilledPendingOrderTpPrice(double &lastFilledPendingOrderTpPrice);
bool LastFilledPendingOrderSlPips(int &lastFilledPendingOrderSlPips);
bool LastFilledPendingOrderTpPips(int &lastFilledPendingOrderTpPips);
bool LastFilledPendingOrderTimeSetup(datetime &lastFilledPendingOrderTimeSetup);
bool LastFilledPendingOrderTimeDone(datetime &lastFilledPendingOrderTimeDone);
bool LastFilledPendingOrderExpirationTime(datetime &lastFilledPendingOrderExpirationTime);
bool LastFilledPendingOrderPositionId(ulong &lastFilledPendingOrderPositionId);
bool LastFilledPendingOrderMagic(ulong &lastFilledPendingOrderMagic);
bool LastFilledPendingOrderReason(ENUM_ORDER_REASON &lastFilledPendingOrderReason);
bool LastFilledPendingOrderTypeFilling(ENUM_ORDER_TYPE_FILLING &lastFilledPendingOrderTypeFilling);
bool LastFilledPendingOrderTypeTime(datetime &lastFilledPendingOrderTypeTime);
bool LastFilledPendingOrderComment(string &lastFilledPendingOrderComment);

//--
bool GetLastCanceledPendingOrderData(PendingOrderData &getLastCanceledPendingOrderData);
bool LastCanceledPendingOrderType(ENUM_ORDER_TYPE &lastCanceledPendingOrderType);
bool LastCanceledPendingOrderSymbol(string &lastCanceledPendingOrderSymbol);
bool LastCanceledPendingOrderTicket(ulong &lastCanceledPendingOrderTicket);
bool LastCanceledPendingOrderPriceOpen(double &lastCanceledPendingOrderPriceOpen);
bool LastCanceledPendingOrderSlPrice(double &lastCanceledPendingOrderSlPrice);
bool LastCanceledPendingOrderTpPrice(double &lastCanceledPendingOrderTpPrice);
bool LastCanceledPendingOrderSlPips(int &lastCanceledPendingOrderSlPips);
bool LastCanceledPendingOrderTpPips(int &lastCanceledPendingOrderTpPips);
bool LastCanceledPendingOrderTimeSetup(datetime &lastCanceledPendingOrderTimeSetup);
bool LastCanceledPendingOrderTimeDone(datetime &lastCanceledPendingOrderTimeDone);
bool LastCanceledPendingOrderExpirationTime(datetime &lastCanceledPendingOrderExpirationTime);
bool LastCanceledPendingOrderPositionId(ulong &lastCanceledPendingOrderPositionId);
bool LastCanceledPendingOrderMagic(ulong &lastCanceledPendingOrderMagic);
bool LastCanceledPendingOrderReason(ENUM_ORDER_REASON &lastCanceledPendingOrderReason);
bool LastCanceledPendingOrderTypeFilling(ENUM_ORDER_TYPE_FILLING &lastCanceledPendingOrderTypeFilling);
bool LastCanceledPendingOrderTypeTime(datetime &lastCanceledPendingOrderTypeTime);
bool LastCanceledPendingOrderComment(string &lastCanceledPendingOrderComment);

//*
//--
bool GetLastClosedPositionData(PositionData &lastClosedPositionInfo, string symbol, ulong magic);
bool LastClosedPositionType(ENUM_POSITION_TYPE &lastClosedPositionType, string symbol, ulong magic);
bool LastClosedPositionVolume(double &lastClosedPositionVolume, string symbol, ulong magic);
bool LastClosedPositionSymbol(string &lastClosedPositionSymbol, string symbol, ulong magic);
bool LastClosedPositionTicket(ulong &lastClosedPositionTicket, string symbol, ulong magic);
bool LastClosedPositionProfit(double &lastClosedPositionProfit, string symbol, ulong magic);
bool LastClosedPositionNetProfit(double &lastClosedPositionNetProfit, string symbol, ulong magic);
bool LastClosedPositionPipProfit(int &lastClosedPositionPipProfit, string symbol, ulong magic);
bool LastClosedPositionClosePrice(double &lastClosedPositionClosePrice, string symbol, ulong magic);
bool LastClosedPositionOpenPrice(double &lastClosedPositionOpenPrice, string symbol, ulong magic);
bool LastClosedPositionSlPrice(double &lastClosedPositionSlPrice, string symbol, ulong magic);
bool LastClosedPositionTpPrice(double &lastClosedPositionTpPrice, string symbol, ulong magic);
bool LastClosedPositionSlPips(int &lastClosedPositionSlPips, string symbol, ulong magic);
bool LastClosedPositionTpPips(int &lastClosedPositionTpPips, string symbol, ulong magic);
bool LastClosedPositionOpenTime(datetime &lastClosedPositionOpenTime, string symbol, ulong magic);
bool LastClosedPositionCloseTime(datetime &lastClosedPositionCloseTime, string symbol, ulong magic);
bool LastClosedPositionSwap(double &lastClosedPositionSwap, string symbol, ulong magic);
bool LastClosedPositionCommission(double &lastClosedPositionCommission, string symbol, ulong magic);
bool LastClosedPositionInitiatingOrderType(ENUM_ORDER_TYPE &lastClosedPositionInitiatingOrderType, string symbol, ulong magic);
bool LastClosedPositionId(ulong &lastClosedPositionId, string symbol, ulong magic);
bool LastClosedPositionInitiatedByPendingOrder(bool &lastClosedPositionInitiatedByPendingOrder, string symbol, ulong magic);
bool LastClosedPositionOpeningOrderTicket(ulong &lastClosedPositionOpeningOrderTicket, string symbol, ulong magic);
bool LastClosedPositionOpeningDealTicket(ulong &lastClosedPositionOpeningDealTicket, string symbol, ulong magic);
bool LastClosedPositionClosingDealTicket(ulong &lastClosedPositionClosingDealTicket, string symbol, ulong magic);
bool LastClosedPositionMagic(ulong &lastClosedPositionMagic, string symbol, ulong magic);
bool LastClosedPositionComment(string &lastClosedPositionComment, string symbol, ulong magic);
bool LastClosedPositionDuration(long &lastClosedPositionDuration, string symbol, ulong magic);

//--
bool GetLastClosedProfitablePositionData(PositionData &lastClosedProfitablePositionInfo, string symbol, ulong magic);
bool GetLastClosedLossPositionData(PositionData &lastClosedLossPositionData, string symbol, ulong magic);

//--
bool GetLastFilledPendingOrderData(PendingOrderData &lastFilledPendingOrderData, string symbol, ulong magic);
bool LastFilledPendingOrderType(ENUM_ORDER_TYPE &lastFilledPendingOrderType, string symbol, ulong magic);
bool LastFilledPendingOrderSymbol(string &lastFilledPendingOrderSymbol, string symbol, ulong magic);
bool LastFilledPendingOrderTicket(ulong &lastFilledPendingOrderTicket, string symbol, ulong magic);
bool LastFilledPendingOrderPriceOpen(double &lastFilledPendingOrderPriceOpen, string symbol, ulong magic);
bool LastFilledPendingOrderSlPrice(double &lastFilledPendingOrderSlPrice, string symbol, ulong magic);
bool LastFilledPendingOrderTpPrice(double &lastFilledPendingOrderTpPrice, string symbol, ulong magic);
bool LastFilledPendingOrderSlPips(int &lastFilledPendingOrderSlPips, string symbol, ulong magic);
bool LastFilledPendingOrderTpPips(int &lastFilledPendingOrderTpPips, string symbol, ulong magic);
bool LastFilledPendingOrderTimeSetup(datetime &lastFilledPendingOrderTimeSetup, string symbol, ulong magic);
bool LastFilledPendingOrderTimeDone(datetime &lastFilledPendingOrderTimeDone, string symbol, ulong magic);
bool LastFilledPendingOrderExpirationTime(datetime &lastFilledPendingOrderExpirationTime, string symbol, ulong magic);
bool LastFilledPendingOrderPositionId(ulong &lastFilledPendingOrderPositionId, string symbol, ulong magic);
bool LastFilledPendingOrderMagic(ulong &lastFilledPendingOrderMagic, string symbol, ulong magic);
bool LastFilledPendingOrderReason(ENUM_ORDER_REASON &lastFilledPendingOrderReason, string symbol, ulong magic);
bool LastFilledPendingOrderTypeFilling(ENUM_ORDER_TYPE_FILLING &lastFilledPendingOrderTypeFilling, string symbol, ulong magic);
bool LastFilledPendingOrderTypeTime(datetime &lastFilledPendingOrderTypeTime, string symbol, ulong magic);
bool LastFilledPendingOrderComment(string &lastFilledPendingOrderComment, string symbol, ulong magic);

//--
bool GetLastCanceledPendingOrderData(PendingOrderData &lastCanceledPendingOrderData, string symbol, ulong magic);
bool LastCanceledPendingOrderType(ENUM_ORDER_TYPE &lastCanceledPendingOrderType, string symbol, ulong magic);
bool LastCanceledPendingOrderSymbol(string &lastCanceledPendingOrderSymbol, string symbol, ulong magic);
bool LastCanceledPendingOrderTicket(ulong &lastCanceledPendingOrderTicket, string symbol, ulong magic);
bool LastCanceledPendingOrderPriceOpen(double &lastCanceledPendingOrderPriceOpen, string symbol, ulong magic);
bool LastCanceledPendingOrderSlPrice(double &lastCanceledPendingOrderSlPrice, string symbol, ulong magic);
bool LastCanceledPendingOrderTpPrice(double &lastCanceledPendingOrderTpPrice, string symbol, ulong magic);
bool LastCanceledPendingOrderSlPips(int &lastCanceledPendingOrderSlPips, string symbol, ulong magic);
bool LastCanceledPendingOrderTpPips(int &lastCanceledPendingOrderTpPips, string symbol, ulong magic);
bool LastCanceledPendingOrderTimeSetup(datetime &lastCanceledPendingOrderTimeSetup, string symbol, ulong magic);
bool LastCanceledPendingOrderTimeDone(datetime &lastCanceledPendingOrderTimeDone, string symbol, ulong magic);
bool LastCanceledPendingOrderExpirationTime(datetime &lastCanceledPendingOrderExpirationTime, string symbol, ulong magic);
bool LastCanceledPendingOrderPositionId(ulong &lastCanceledPendingOrderPositionId, string symbol, ulong magic);
bool LastCanceledPendingOrderMagic(ulong &lastCanceledPendingOrderMagic, string symbol, ulong magic);
bool LastCanceledPendingOrderReason(ENUM_ORDER_REASON &lastCanceledPendingOrderReason, string symbol, ulong magic);
bool LastCanceledPendingOrderTypeFilling(ENUM_ORDER_TYPE_FILLING &lastCanceledPendingOrderTypeFilling, string symbol, ulong magic);
bool LastCanceledPendingOrderTypeTime(datetime &lastCanceledPendingOrderTypeTime, string symbol, ulong magic);
bool LastCanceledPendingOrderComment(string &lastCanceledPendingOrderComment, string symbol, ulong magic);

//--
string BoolToString(bool boolVariable);
datetime GetPeriodStart(int periodType);

#import
//+------------------------------------------------------------------+



Implementação Prática e Visão Geral da Biblioteca History Manager EX5

Agora iremos examinar as funções da biblioteca, organizando-as em suas respectivas categorias para melhor clareza e usabilidade. Ao longo do processo, descreveremos suas funções e forneceremos casos de uso simples para demonstrar como elas podem ser utilizadas para realizar diversas tarefas.

1. Imprimindo Históricos de Negociação para um Intervalo de Tempo Especificado

Essas funções permitem imprimir dados do histórico de negociações diretamente no log dos terminais MetaTrader 5, tornando conveniente a consulta rápida e a depuração. Elas são do tipo void, o que significa que não retornam nenhum valor, e aceitam dois parâmetros do tipo datetime , que são usados para especificar o intervalo de tempo do histórico a ser processado:

Definição do Protótipo da Função Descrição Exemplo de Caso de Uso
void PrintDealsHistory(
   datetime fromDateTime,
   datetime toDateTime
);


Imprime os detalhes de todos os negócios dentro de um intervalo de tempo especificado.
// Print the deals history for the last 24 hours (1 day)
PrintDealsHistory(ONE_DAY, NOW);
void PrintOrdersHistory(
   datetime fromDateTime,
   datetime toDateTime
);

Imprime os detalhes de todas as ordens dentro de um intervalo de tempo especificado.
// Print the orders history for the last 24 hours (1 day)
PrintOrdersHistory(ONE_DAY, NOW);


void PrintPositionsHistory(
   datetime fromDateTime,
   datetime toDateTime
);


Imprime os detalhes de todas as posições fechadas dentro de um intervalo de tempo especificado.
// Print the positions history for the last 24 hours (1 day)
PrintPositionsHistory(ONE_DAY, NOW);
void PrintPendingOrdersHistory(
   datetime fromDateTime,
   datetime toDateTime
);

Imprime os detalhes de todas as ordens pendentes dentro de um intervalo de tempo especificado.
// Print the pending orders history for the last 24 hours (1 day)
PrintPendingOrdersHistory(ONE_DAY, NOW);


2. Recuperando Dados do Histórico de Negociação para um Intervalo de Tempo Especificado

Essas funções permitem recuperar programaticamente os dados do histórico de negociações, filtrados por símbolo e número mágico , para um período especificado. Os dados recuperados são armazenados em arrays de estruturas de dados, permitindo análises ou processamentos adicionais:

Definição do Protótipo da Função Descrição Exemplo de Caso de Uso
bool GetDealsData(
   DealData &dealsData[], // [out]
   datetime fromDateTime,
   datetime toDateTime,
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);


Esta função busca e recupera dados de negócios dentro de um intervalo de tempo especificado. Além disso, oferece a opção de filtrar os dados recuperados por símbolo e número mágico, permitindo um processamento mais direcionado.
// Print the total account net profit for the last 7 days
DealData dealsData[];
if(
   GetDealsData(
      dealsData,
      ONE_WEEK, NOW,
      ALL_SYMBOLS, 0
   ) &&
   ArraySize(dealsData) > 0
)
  {
   double totalGrossProfit = 0.0,
          totalSwap = 0.0,
          totalCommission = 0.0;
   int totalDeals = ArraySize(dealsData);
   for(int k = 0; k < totalDeals; k++)
     {
      if(dealsData[k].entry == DEAL_ENTRY_OUT)
        {
         totalGrossProfit += dealsData[k].profit;
         totalSwap += dealsData[k].swap;
         totalCommission += dealsData[k].commission;
        }
     }
   double totalExpenses = totalSwap + totalCommission;
   double totalNetProfit = totalGrossProfit - MathAbs(totalExpenses);

   Print("-------------------------------------------------");
   Print(
      "Account No: ", AccountInfoInteger(ACCOUNT_LOGIN),
      " [ 7 DAYS NET PROFIT ]"
   );
   Print(
      "Total Gross Profit: ",
      DoubleToString(totalGrossProfit, 2),
      " ", AccountInfoString(ACCOUNT_CURRENCY)
   );
   Print(
      "Total Swap: ", DoubleToString(totalSwap, 2),
      " ", AccountInfoString(ACCOUNT_CURRENCY)
   );
   Print(
      "Total Commission: ", DoubleToString(totalCommission, 2),
      " ", AccountInfoString(ACCOUNT_CURRENCY)
   );
   Print(
      "Total Net Profit: ",
      DoubleToString(totalNetProfit, 2), " ",
      AccountInfoString(ACCOUNT_CURRENCY)
   );
  }
bool GetOrdersData(
   OrderData &ordersData[], // [out]
   datetime fromDateTime,
   datetime toDateTime,
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Esta função consulta e recupera dados de ordens dentro de um intervalo de tempo especificado. Além disso, oferece a opção de filtrar os dados recuperados por símbolo e número mágico.
// Print the total BUY Orders filled in the last 7 days
OrderData ordersData[];
if(
   GetOrdersData(ordersData, ONE_WEEK, NOW) &&
   ArraySize(ordersData) > 0
)
  {
   int totalBuyOrdersFilled = 0,
       totalOrders = ArraySize(ordersData);
   for(int w = 0; w < totalOrders; w++)
     {
      if(ordersData[w].type == ORDER_TYPE_BUY)
         ++totalBuyOrdersFilled;
     }
   Print("");
   Print("-------------------------------------------------");
   Print("Account No: ", AccountInfoInteger(ACCOUNT_LOGIN));
   Print(totalBuyOrdersFilled, " BUY Orders Filled in the last 7 days!");
  }


bool GetPositionsData(
   PositionData &positionsData[], // [out]
   datetime fromDateTime,
   datetime toDateTime,
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);


Esta função busca e recupera dados do histórico de posições fechadas dentro de um intervalo de tempo especificado. Você tem a opção de filtrar os dados recuperados pelos valores de símbolo e número mágico.
// Print total pips earned in last 24hrs for specified symbol and magic
string symbol = _Symbol;
long magic = 0;
PositionData positionsData[];
if(
   GetPositionsData(positionsData, ONE_DAY, NOW, symbol, magic) &&
   ArraySize(positionsData) > 0
)
  {
   int totalPipsEarned = 0,
       totalPositions = ArraySize(positionsData);
   for(int k = 0; k < totalPositions; k++)
     {
      totalPipsEarned += positionsData[k].pipProfit;
     }
   Print("");
   Print("-------------------------------------------------");
   Print("Account No: ", AccountInfoInteger(ACCOUNT_LOGIN));
   Print(
      totalPipsEarned, " pips earned in the last 24hrs for ", symbol,
      " with magic no. ", magic
   );
  }

 
bool GetPendingOrdersData(
   PendingOrderData &pendingOrdersData[], // [out]
   datetime fromDateTime,
   datetime toDateTime,
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Esta função obtém os dados do histórico de ordens pendentes dentro de um intervalo de tempo especificado. Ela também oferece a opção de filtrar os dados do histórico de ordens pendentes por símbolo e número mágico.
// Print total number of buy and sell stops filled for symbol and magic
// in the last 7 days
string symbol = _Symbol;
long magic = 0;
PendingOrderData pendingOrdersData[];
if(
   GetPendingOrdersData(pendingOrdersData, ONE_WEEK, NOW, symbol, magic) &&
   ArraySize(pendingOrdersData) > 0
)
  {
   int totalBuyStopsFilled = 0, totalSellStopsFilled = 0,
       totalPendingOrders = ArraySize(pendingOrdersData);
   for(int k = 0; k < totalPendingOrders; k++)
     {
      if(pendingOrdersData[k].type == ORDER_TYPE_BUY_STOP)
         ++totalBuyStopsFilled;
      if(pendingOrdersData[k].type == ORDER_TYPE_SELL_STOP)
         ++totalSellStopsFilled;
     }
   Print("");
   Print("-------------------------------------------------");
   Print("Account No: ", AccountInfoInteger(ACCOUNT_LOGIN), ", Magic No = ", magic);
   Print(
      symbol, " --> Total Filled - (Buy Stops = ", totalBuyStopsFilled,
      ") (Sell Stops = ", totalSellStopsFilled, ") in the last 7 days."
   );
  }


3. Recuperando Todo o Histórico de Negociação

Essas funções fornecem uma maneira abrangente de obter todos os dados disponíveis do histórico de negociações na conta, com filtros opcionais por símbolo e número mágico, sem a necessidade de inserir um intervalo de tempo específico:

Definição do Protótipo da Função
Descrição
Exemplo de Caso de Uso
bool GetAllDealsData(
   DealData &dealsData[], // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

A função recupera todos os dados de negócios, com a opção de filtrar os dados do histórico de negócios por símbolo e número mágico.
// Find and list total deposited funds in the account
DealData dealsData[];
if(GetAllDealsData(dealsData) && ArraySize(dealsData) > 0)
  {
   double totalDeposits = 0.0;
   int totalDeals = ArraySize(dealsData);
   Print("");
   for(int k = 0; k < totalDeals; k++)
     {
      if(dealsData[k].type == DEAL_TYPE_BALANCE)
        {
         totalDeposits += dealsData[k].profit;
         Print(
            dealsData[k].profit, " ", AccountInfoString(ACCOUNT_CURRENCY),
            " --> Cash deposit on: ", dealsData[k].time
         );
        }
     }
   Print("-------------------------------------------------");
   Print(
      "Account No: ", AccountInfoInteger(ACCOUNT_LOGIN),
      " Total Cash Deposits: ", totalDeposits, " ", 
      AccountInfoString(ACCOUNT_CURRENCY)
   );
  }

bool GetAllOrdersData(
   OrderData &ordersData[], // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Esta função obtém todos os dados de ordens, oferecendo a opção de filtrar o histórico de ordens por símbolo e número mágico.
// Find if the account has ever gotten a Stop Out/Margin Call
OrderData ordersData[];
if(GetAllOrdersData(ordersData) && ArraySize(ordersData) > 0)
  {
   int totalStopOuts = 0;
   int totalOrders = ArraySize(ordersData);
   Print("");
   for(int k = 0; k < totalOrders; k++)
     {
      if(ordersData[k].reason == ORDER_REASON_SO)
        {
         ++totalStopOuts;
         Print(
            EnumToString(ordersData[k].type),
            " --> on: ", ordersData[k].timeDone
         );
        }
     }
   Print("-------------------------------------------------");
   Print("Account No: ", AccountInfoInteger(ACCOUNT_LOGIN));
   Print("Total STOP OUT events: ", totalStopOuts);
  }

bool GetAllPositionsData(
   PositionData &positionsData[], // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

A função obtém todos os dados do histórico de posições, com a opção de filtrar os dados de posições fechadas por símbolo e número mágico.
// Find the average trade duration in seconds
PositionData positionsData[];
if(GetAllPositionsData(positionsData) && ArraySize(positionsData) > 0)
  {
   long totalTradesDuration = 0; 
   int totalPositions = ArraySize(positionsData);
   Print("");
   for(int k = 0; k < totalPositions; k++)
     {
      totalTradesDuration += positionsData[k].duration;
     }
   long averageTradesDuration = totalTradesDuration / totalPositions;
   Print("-------------------------------------------------");
   Print("Account No: ", AccountInfoInteger(ACCOUNT_LOGIN));
   Print("Average trade duration: ", averageTradesDuration, " seconds.");
  }

bool GetAllPendingOrdersData(
   PendingOrderData &pendingOrdersData[], // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Esta função recupera todos os dados de ordens pendentes, com a opção de filtrar os dados do histórico de ordens pendentes por símbolo e número mágico.
// Find the total expired pending orders in the account
PendingOrderData pendingOrdersData[];
if(GetAllPendingOrdersData(pendingOrdersData) && ArraySize(pendingOrdersData) > 0)
  {
   int totalExpiredPendingOrders = 0;
   int totalPendingOrders = ArraySize(pendingOrdersData);
   Print("");
   Print("-- EXPIRED PENDING ORDERS --");
   for(int k = 0; k < totalPendingOrders; k++)
     {
      if(pendingOrdersData[k].state == ORDER_STATE_EXPIRED)
        {
         ++totalExpiredPendingOrders;
         Print("Symbol = ", pendingOrdersData[k].symbol);
         Print("Time Setup = ", pendingOrdersData[k].timeSetup);
         Print("Ticket = ", pendingOrdersData[k].ticket);
         Print("Price Open = ", pendingOrdersData[k].priceOpen);
         Print(
            "SL Price = ", pendingOrdersData[k].slPrice,
            ", TP Price = ", pendingOrdersData[k].tpPrice
         );
         Print("Expiration Time = ", pendingOrdersData[k].expirationTime);
         Print("");
        }
     }
   Print("-------------------------------------------------");
   Print("Account No: ", AccountInfoInteger(ACCOUNT_LOGIN));
   Print("Total Expired Pending Orders: ", totalExpiredPendingOrders);
  }


4. Analisando as Últimas Posições Fechadas

Essas funções são projetadas para obter detalhes abrangentes sobre as posições mais recentemente fechadas, fornecendo informações sobre aspectos-chave como lucro ou prejuízo, volume de negociação e o momento de fechamento de cada posição. Cada função atende a um propósito específico, garantindo acesso a todos os aspectos críticos da sua última negociação. As funções também oferecem a opção de filtrar os dados do histórico de posições a serem processados por símbolo e número mágico :

Definição do Protótipo da Função
Descrição
Exemplo de Caso de Uso
bool GetLastClosedPositionData(
   PositionData &lastClosedPositionInfo, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

A função obtém uma visão completa da última posição fechada, incluindo todos os detalhes relevantes. Você tem a opção de filtrar o resultado por símbolo e número mágico.
// Get the last closed position in the account
PositionData lastClosedPositionInfo;
if(
   GetLastClosedPositionData(lastClosedPositionInfo) &&
   lastClosedPositionInfo.ticket > 0
)
  {
   // Process the last closed position data
   Print("---LAST CLOSED POSITION--");
   Print("Symbol: ", lastClosedPositionInfo.symbol);
   Print("Type: ", EnumToString(lastClosedPositionInfo.type));
   Print("Open Time: ", lastClosedPositionInfo.openTime);
   Print("Close Time: ", lastClosedPositionInfo.closeTime);
   Print("Profit: ", lastClosedPositionInfo.profit);
   // Place more position properties analysis code....
  }
//-
// Get the last closed position for GBPUSD and magic 0
PositionData lastClosedPositionInfo;
string symbol = "GBPUSD";
if(
   GetLastClosedPositionData(lastClosedPositionInfo, symbol, 0) &&
   lastClosedPositionInfo.ticket > 0
)
  {
   // Process the last closed position data
   Print("---LAST CLOSED POSITION FOR ", symbol, " --");
   Print("Symbol: ", lastClosedPositionInfo.symbol);
   Print("Type: ", EnumToString(lastClosedPositionInfo.type));
   Print("Open Time: ", lastClosedPositionInfo.openTime);
   Print("Close Time: ", lastClosedPositionInfo.closeTime);
   Print("Profit: ", lastClosedPositionInfo.profit);
   // Place more position properties analysis code....
  }


bool LastClosedPositionType(
   ENUM_POSITION_TYPE &lastClosedPositionType, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Esta função revela se a última posição foi uma operação de compra ou venda. Ela possui a opção de filtrar os dados por símbolo e número mágico.
// Get the last closed position type in the account
ENUM_POSITION_TYPE lastClosedPositionType;
LastClosedPositionType(lastClosedPositionType);
Print(
   "Account's last closed position type: ",
   EnumToString(lastClosedPositionType)
);
//--
// Get the last closed position type for EURUSD and magic 0
ENUM_POSITION_TYPE lastClosedPositionType;
LastClosedPositionType(lastClosedPositionType, "EURUSD", 0);
Print(
   "EURUSD: last closed position type: ",
   EnumToString(lastClosedPositionType)
);

bool LastClosedPositionVolume(
   double &lastClosedPositionVolume, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Esta função fornece o volume de negociação da posição mais recentemente fechada. A função também oferece a opção de filtrar os dados por símbolo e número mágico.
// Get the last closed position volume in the account
double lastClosedPositionVolume;
LastClosedPositionVolume(lastClosedPositionVolume);
Print(
   "Account's last closed position volume: ",
   lastClosedPositionVolume
);
//--
// Get the last closed position volume for GBPUSD and magic 0
double lastClosedPositionVolume;
LastClosedPositionVolume(lastClosedPositionVolume, "GBPUSD", 0);
Print(
   "GBPUSD: last closed position volume: ",
   lastClosedPositionVolume
);

bool LastClosedPositionSymbol(
   string &lastClosedPositionSymbol, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

A função obtém o símbolo da posição mais recentemente fechada. Oferece a opção de filtrar o resultado por símbolo e número mágico.
// Get the last closed position's symbol in the account
string lastClosedPositionSymbol;
LastClosedPositionSymbol(lastClosedPositionSymbol);
Print(
   lastClosedPositionSymbol, " is the last closed position symbol ", 
   "in the account"
);
//--
// Get the last closed position's symbol for magic 0
string lastClosedPositionSymbol;
LastClosedPositionSymbol(lastClosedPositionSymbol, ALL_SYMBOLS, 0);
Print(
   lastClosedPositionSymbol, " is the last closed position symbol ",
   "for magic no: 0."
);

bool LastClosedPositionTicket(
   ulong &lastClosedPositionTicket, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Esta função recupera o número do ticket da posição mais recentemente fechada. A função também oferece a opção de filtrar o resultado por símbolo e número mágico.
// Get the last closed position's ticket in the account
long lastClosedPositionTicket;
LastClosedPositionTicket(lastClosedPositionTicket);
Print(
   "Account's last closed position's ticket: ",
   lastClosedPositionTicket
);
//--
// Get the last closed position's ticket for EURUSD and magic 0
long lastClosedPositionTicket;
LastClosedPositionTicket(lastClosedPositionTicket, "EURUSD", 0);
Print(
   "EURUSD: last closed position's ticket: ",
   lastClosedPositionTicket
);

bool LastClosedPositionProfit(
   double &lastClosedPositionProfit, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Esta função fornece o lucro bruto gerado pela última negociação. Você também tem a opção de filtrar os dados por símbolo e número mágico.
// Get the last closed position's profit in the account
double lastClosedPositionProfit;
LastClosedPositionProfit(lastClosedPositionProfit);
Print(
   "Account's last closed position's profit: ",
   lastClosedPositionProfit, " ", AccountInfoString(ACCOUNT_CURRENCY)
);
//--
// Get the last closed position's profit for EURUSD and magic 0
//double lastClosedPositionProfit;
LastClosedPositionProfit(lastClosedPositionProfit, "EURUSD", 0);
Print(
   "EURUSD: last closed position's profit: ",
   lastClosedPositionProfit, " ", AccountInfoString(ACCOUNT_CURRENCY)
);

Aqui estão as demais funções da biblioteca responsáveis por recuperar as propriedades da última posição fechada. Para detalhes de implementação, consulte os exemplos de código acima, incluindo funções como LastClosedPositionVolume(), LastClosedPositionType() e outras, pois todas seguem uma abordagem semelhante.

Definição do Protótipo da Função
Descrição
bool LastClosedPositionNetProfit(
   double &lastClosedPositionNetProfit, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Calcula o lucro líquido da última negociação, levando em consideração swaps e comissões. A função oferece a opção de filtrar os dados por símbolo e número mágico.
bool LastClosedPositionPipProfit(
   int &lastClosedPositionPipProfit, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Obtém o lucro medido em pips da posição final fechada. Os dados podem ser filtrados por símbolo e número mágico.
bool LastClosedPositionClosePrice(
   double &lastClosedPositionClosePrice, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Recupera o preço no qual a posição foi fechada. A função oferece a opção de filtrar o resultado por símbolo e número mágico.
bool LastClosedPositionOpenPrice(
   double &lastClosedPositionOpenPrice, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Revela o preço no qual a posição foi inicialmente aberta. Você pode opcionalmente filtrar os dados por símbolo e número mágico.
bool LastClosedPositionSlPrice(
   double &lastClosedPositionSlPrice, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Obtém o preço de stop-loss definido para a última posição fechada. A função oferece a opção de filtrar o resultado por símbolo e número mágico.
bool LastClosedPositionTpPrice(
   double &lastClosedPositionTpPrice, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Fornece o preço de take-profit atribuído à última negociação fechada. Também é fornecida a opção de filtrar os dados por símbolo e número mágico.
bool LastClosedPositionSlPips(
   int &lastClosedPositionSlPips, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Indica a distância do stop-loss em pips para a última posição fechada. Também há suporte para filtragem dos dados por símbolo e número mágico.
bool LastClosedPositionTpPips(
   int &lastClosedPositionTpPips, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Mostra a distância do take-profit em pips para a negociação mais recentemente fechada. A função também pode opcionalmente filtrar o resultado por símbolo e número mágico.
bool LastClosedPositionOpenTime(
   datetime &lastClosedPositionOpenTime, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);


Recupera o timestamp de quando a última posição fechada foi aberta. Também é possível filtrar os dados por símbolo e número mágico.
bool LastClosedPositionCloseTime(
   datetime &lastClosedPositionCloseTime, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Fornece o momento exato em que a posição mais recentemente fechada foi encerrada. Você também pode opcionalmente filtrar o resultado por símbolo e número mágico.
bool LastClosedPositionSwap(
   double &lastClosedPositionSwap, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Revela o valor de swap associado à última posição fechada. As informações também podem ser opcionalmente filtradas por valores de símbolo e número mágico.
bool LastClosedPositionCommission(
   double &lastClosedPositionCommission, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Obtém a comissão cobrada pela última negociação fechada. Também há suporte para filtragem por símbolo e número mágico.
bool LastClosedPositionInitiatingOrderType(
   ENUM_ORDER_TYPE &lastClosedPositionInitiatingOrderType, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Identifica o tipo de ordem que iniciou a última posição fechada. Você pode opcionalmente filtrar o resultado por símbolo e número mágico.
bool LastClosedPositionId(
   ulong &lastClosedPositionId, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Recupera o identificador único da posição mais recente fechada. Os parâmetros de símbolo e número mágico são opcionais e só são necessários quando você precisa filtrar o resultado.
bool LastClosedPositionInitiatedByPendingOrder(
   bool &lastClosedPositionInitiatedByPendingOrder, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);


Verifica se a última posição fechada foi acionada ou iniciada por uma ordem pendente. Você pode opcionalmente filtrar os dados por símbolo e número mágico.
bool LastClosedPositionOpeningOrderTicket(
   ulong &lastClosedPositionOpeningOrderTicket, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Fornece o número do ticket da ordem que abriu a posição. A função também pode opcionalmente filtrar os dados por símbolo e número mágico.
bool LastClosedPositionOpeningDealTicket(
   ulong &lastClosedPositionOpeningDealTicket, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Obtém o número do ticket do negócio que iniciou a posição. Você tem a opção de filtrar o resultado por símbolo e número mágico.
bool LastClosedPositionClosingDealTicket(
   ulong &lastClosedPositionClosingDealTicket, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Recupera o número do ticket do negócio que fechou a posição. A filtragem dos dados por símbolo e número mágico também é uma opção.
bool LastClosedPositionMagic(
   ulong &lastClosedPositionMagic, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Revela o número mágico associado à última posição fechada. Você tem a opção de filtrar os dados por símbolo e número mágico.
 
bool LastClosedPositionComment(
   string &lastClosedPositionComment, // [Out]
   string symbol,  // Optional parameter
   ulong magic // Optional parameter
);

Recupera quaisquer comentários ou anotações anexadas à negociação mais recentemente fechada. A filtragem do resultado por símbolo e número mágico também é uma opção disponível.
 
bool LastClosedPositionDuration(
   long &lastClosedPositionDuration, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Calcula a duração total (em segundos) que a posição permaneceu aberta. Você tem a opção de filtrar o resultado por símbolo e número mágico.


5. Analisando as Últimas Posições Fechadas com Lucro e com Prejuízo

Quando você precisa recuperar as propriedades da última posição fechada com lucro ou com prejuízo, a biblioteca History Manager fornece duas funções dedicadas para essa tarefa. Essas funções permitem acessar rapidamente todos os detalhes relevantes com uma única chamada de função, possibilitando analisar a posição mais recentemente fechada com base em sua lucratividade. Ao fornecer dados essenciais, elas ajudam na avaliação do desempenho das negociações e no refinamento de estratégias. Além disso, essas funções oferecem a flexibilidade de filtrar os resultados por um símbolo específico e número mágico , permitindo que você foque em negociações específicas e avalie o desempenho de estratégias ou ativos individuais de forma mais eficaz.

Definição do Protótipo da Função Descrição Exemplo de Caso de Uso
bool GetLastClosedProfitablePositionData(
   PositionData &lastClosedProfitablePositionInfo, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Recupera os detalhes e propriedades da posição mais recentemente fechada que foi encerrada com lucro. A função também oferece a opção de filtrar os resultados por símbolo e número mágico.
// Get the symbol, ticket, and net and pip profit of
// the last closed profitable position
PositionData lastClosedProfitablePosition;
if(
   GetLastClosedProfitablePositionData(lastClosedProfitablePosition) &&
   lastClosedProfitablePosition.ticket > 0
)
  {
   Print("-------------------------------------------------");
   Print(
      lastClosedProfitablePosition.symbol,
      " --> LAST CLOSED PROFITABLE POSITION"
   );
   Print("Ticket = ", lastClosedProfitablePosition.ticket);
   Print(
      "Net Profit = ", lastClosedProfitablePosition.netProfit, " ",
      AccountInfoString(ACCOUNT_CURRENCY)
   );
   Print("Pip Profit = ", lastClosedProfitablePosition.pipProfit);
  }
//--
// Get the ticket, and net and pip profit of
// the last closed profitable position for EURUSD and magic 0
PositionData lastClosedProfitablePosition;
if(
   GetLastClosedProfitablePositionData(
      lastClosedProfitablePosition, "EURUSD", 0
   ) &&
   lastClosedProfitablePosition.ticket > 0
)
  {
   Print("-------------------------------------------------");
   Print("EURUSD --> LAST CLOSED PROFITABLE POSITION");
   Print("Ticket = ", lastClosedProfitablePosition.ticket);
   Print(
      "Net Profit = ", lastClosedProfitablePosition.netProfit, " ",
      AccountInfoString(ACCOUNT_CURRENCY)
   );
   Print("Pip Profit = ", lastClosedProfitablePosition.pipProfit);
  }

bool GetLastClosedLossPositionData(
   PositionData &lastClosedLossPositionData,  // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Recupera os detalhes e propriedades da posição mais recentemente fechada que foi encerrada ou resultou em prejuízo. A função também permite filtrar opcionalmente os resultados por símbolo e número mágico.
// Get the symbol, ticket, and net and pip profit of
// the last closed loss position
PositionData lastClosedLossPosition;
if(
   GetLastClosedLossPositionData(lastClosedLossPosition) &&
   lastClosedLossPosition.ticket > 0
)
  {
   Print("-------------------------------------------------");
   Print(
      lastClosedLossPosition.symbol,
      " --> LAST CLOSED LOSS POSITION"
   );
   Print("Ticket = ", lastClosedLossPosition.ticket);
   Print(
      "Net Profit = ", lastClosedLossPosition.netProfit, " ",
      AccountInfoString(ACCOUNT_CURRENCY)
   );
   Print("Pip Profit = ", lastClosedLossPosition.pipProfit);
  }
//--
// Get the ticket, and net and pip profit of
// the last closed loss position for GBPUSD and magic 0
PositionData lastClosedLossPosition;
if(
   GetLastClosedLossPositionData(
      lastClosedLossPosition, "GBPUSD", 0
   ) &&
   lastClosedLossPosition.ticket > 0
)
  {
   Print("-------------------------------------------------");
   Print("GBPUSD --> LAST CLOSED LOSS POSITION");
   Print("Ticket = ", lastClosedLossPosition.ticket);
   Print(
      "Net Profit = ", lastClosedLossPosition.netProfit, " ",
      AccountInfoString(ACCOUNT_CURRENCY)
   );
   Print("Pip Profit = ", lastClosedLossPosition.pipProfit);
  }


6. Analisando as Últimas Ordens Pendentes Executadas e Canceladas

Para recuperar informações detalhadas sobre a ordem pendente mais recentemente executada ou cancelada, a biblioteca History Manager fornece funções especializadas para esse propósito. Essas funções permitem obter todos os detalhes relevantes da ordem com uma única chamada de função, facilitando a análise da execução ou cancelamento de ordens pendentes. Ao fornecer dados-chave, elas ajudam na avaliação do tratamento de ordens, eficiência de execução e ajustes na estratégia de negociação. Além disso, essas funções oferecem a flexibilidade de filtrar os resultados por um símbolo específico e número mágico , permitindo que você foque em ordens específicas e refine sua abordagem com base em dados históricos precisos.

Como as funções de última ordem pendente executada e cancelada são importadas e implementadas utilizando a mesma abordagem das que processam os dados do histórico da última posição fechada, apenas seus protótipos de função e breves descrições serão fornecidos. Se você precisar de um exemplo de como implementar essas funções, consulte a seção "Analisando as Últimas Posições Fechadas" acima.

Para obter detalhes completos da última ordem pendente executada, a função GetLastFilledPendingOrderData() recupera todas as propriedades relevantes, oferecendo uma visão abrangente da execução da ordem. Se você precisar apenas de atributos específicos, as seguintes funções dedicadas permitirão extrair detalhes ou propriedades individuais:

Definição do Protótipo da Função Descrição
bool GetLastFilledPendingOrderData(
   PendingOrderData &lastFilledPendingOrderData, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Esta função recupera todos os detalhes pertinentes da ordem pendente mais recente que foi executada, fornecendo uma visão completa de como a ordem foi executada.
bool LastFilledPendingOrderType(
   ENUM_ORDER_TYPE &lastFilledPendingOrderType, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Obtém o tipo de ordem, ajudando você a determinar se foi uma ordem de compra stop, uma ordem de venda limite ou outra variante de ordem pendente.
bool LastFilledPendingOrderSymbol(
   string &lastFilledPendingOrderSymbol, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Identifica o instrumento de negociação, permitindo focar em ordens associadas a um ativo específico.
bool LastFilledPendingOrderTicket(
   ulong &lastFilledPendingOrderTicket, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Fornece o ticket único da ordem, essencial para referência ou rastreamento de uma ordem executada específica.
bool LastFilledPendingOrderPriceOpen(
   double &lastFilledPendingOrderPriceOpen, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Recupera o preço no qual a ordem foi acionada, crucial para analisar as condições de entrada.
bool LastFilledPendingOrderSlPrice(
   double &lastFilledPendingOrderSlPrice, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);
bool LastFilledPendingOrderTpPrice(
   double &lastFilledPendingOrderTpPrice, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Essas funções retornam os níveis de stop-loss e take-profit, respectivamente, garantindo que você possa avaliar as configurações de gerenciamento de risco.
bool LastFilledPendingOrderSlPips(
   int &lastFilledPendingOrderSlPips, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);
bool LastFilledPendingOrderTpPips(
   int &lastFilledPendingOrderTpPips, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Essas funções expressam as distâncias de stop-loss e take-profit em pips, proporcionando uma visão mais clara da relação risco-retorno da negociação.
bool LastFilledPendingOrderTimeSetup(
   datetime &lastFilledPendingOrderTimeSetup, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);
bool LastFilledPendingOrderTimeDone(
   datetime &lastFilledPendingOrderTimeDone, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

LastFilledPendingOrderTimeSetup() registra quando a ordem foi colocada, enquanto LastFilledPendingOrderTimeDone() registra quando ela foi executada. Isso ajuda a analisar o intervalo de tempo entre o momento em que a ordem pendente foi configurada e quando foi acionada ou executada.
bool LastFilledPendingOrderExpirationTime(
   datetime &lastFilledPendingOrderExpirationTime, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Verifica e fornece o tempo de expiração, útil para estratégias de negociação sensíveis ao tempo.
bool LastFilledPendingOrderPositionId(
   ulong &lastFilledPendingOrderPositionId, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Recupera o ID da posição, que é essencial para vincular a ordem à sua posição correspondente, garantindo um rastreamento preciso.
bool LastFilledPendingOrderMagic(
   ulong &lastFilledPendingOrderMagic, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Recupera o número mágico, permitindo filtrar ordens com base em estratégias automatizadas ou robôs de negociação.
bool LastFilledPendingOrderReason(
   ENUM_ORDER_REASON &lastFilledPendingOrderReason, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Captura o motivo da execução, oferecendo uma visão sobre o processamento de ordens iniciado pelo sistema ou manualmente.
bool LastFilledPendingOrderTypeFilling(
   ENUM_ORDER_TYPE_FILLING &lastFilledPendingOrderTypeFilling, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);
bool LastFilledPendingOrderTypeTime(
   datetime &lastFilledPendingOrderTypeTime, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

LastFilledPendingOrderTypeFilling() e LastFilledPendingOrderTypeTime() definem o método de execução da ordem e o modelo de tempo, respectivamente, auxiliando na análise de execução.
bool LastFilledPendingOrderComment(
   string &lastFilledPendingOrderComment, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Obtém quaisquer comentários associados à última ordem pendente executada, o que pode ser útil para rotular e categorizar negociações.

Da mesma forma, se você precisar examinar a última ordem pendente cancelada, a função GetLastCanceledPendingOrderData() recupera todos os detalhes em uma única chamada. Alternativamente, você pode extrair propriedades individuais usando as seguintes funções especializadas:

Definição do Protótipo da Função Descrição
bool GetLastCanceledPendingOrderData(
   PendingOrderData &lastCanceledPendingOrderData, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Esta função fornece um registro completo da ordem pendente mais recentemente cancelada, incluindo todas as suas propriedades e atributos.
bool LastCanceledPendingOrderType(
   ENUM_ORDER_TYPE &lastCanceledPendingOrderType, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Recupera e especifica o tipo da última ordem pendente cancelada.
bool LastCanceledPendingOrderSymbol(
   string &lastCanceledPendingOrderSymbol, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Obtém e identifica o símbolo de negociação da ordem pendente mais recentemente cancelada, permitindo uma análise direcionada.
bool LastCanceledPendingOrderTicket(
   ulong &lastCanceledPendingOrderTicket, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Fornece o número de ticket único da última ordem pendente cancelada para referência.
bool LastCanceledPendingOrderPriceOpen(
   double &lastCanceledPendingOrderPriceOpen, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Obtém e armazena o preço de entrada originalmente pretendido da última ordem pendente cancelada.
bool LastCanceledPendingOrderSlPrice(
   double &lastCanceledPendingOrderSlPrice, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);
bool LastCanceledPendingOrderTpPrice(
   double &lastCanceledPendingOrderTpPrice, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

LastCanceledPendingOrderSlPrice() e LastCanceledPendingOrderTpPrice() recuperam os níveis de preço de stop-loss e take-profit da ordem pendente mais recentemente cancelada.
bool LastCanceledPendingOrderSlPips(
   int &lastCanceledPendingOrderSlPips, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);
bool LastCanceledPendingOrderTpPips(
   int &lastCanceledPendingOrderTpPips, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

LastCanceledPendingOrderSlPips() e LastCanceledPendingOrderTpPips() expressam as distâncias de stop-loss e take-profit da última ordem pendente cancelada em pips.
bool LastCanceledPendingOrderTimeSetup(
   datetime &lastCanceledPendingOrderTimeSetup, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);
bool LastCanceledPendingOrderTimeDone(
   datetime &lastCanceledPendingOrderTimeDone, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

LastCanceledPendingOrderTimeSetup() fornece o momento em que a última ordem pendente cancelada foi colocada, enquanto LastCanceledPendingOrderTimeDone() registra o momento em que ela foi removida por cancelamento.
bool LastCanceledPendingOrderExpirationTime(
   datetime &lastCanceledPendingOrderExpirationTime, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Recupera e armazena o tempo em que a ordem pendente cancelada foi definida para expirar.
bool LastCanceledPendingOrderMagic(
   ulong &lastCanceledPendingOrderMagic, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Obtém e armazena o número mágico associado à última ordem pendente cancelada, permitindo a filtragem com base em identificadores de estratégias automatizadas.
bool LastCanceledPendingOrderReason(
   ENUM_ORDER_REASON &lastCanceledPendingOrderReason, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Recupera o motivo da ordem da última ordem pendente cancelada e permite identificar em qual plataforma a ordem foi iniciada.
bool LastCanceledPendingOrderTypeFilling(
   ENUM_ORDER_TYPE_FILLING &lastCanceledPendingOrderTypeFilling, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);
bool LastCanceledPendingOrderTypeTime(
   datetime &lastCanceledPendingOrderTypeTime, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

LastCanceledPendingOrderTypeFilling() e LastCanceledPendingOrderTypeTime() recuperam e armazenam as configurações de tipo de execução e tipo de tempo da última ordem pendente cancelada.
bool LastCanceledPendingOrderComment(
   string &lastCanceledPendingOrderComment, // [Out]
   string symbol, // Optional parameter
   ulong magic // Optional parameter
);

Obtém quaisquer comentários definidos pelo usuário salvos ao abrir a última ordem pendente cancelada para fins de rastreamento.


7. Funções Utilitárias
Definição do Protótipo da Função Descrição
string BoolToString(bool boolVariable);

A função utilitária converte um valor booleano em uma string ("TRUE" ou "FALSE") para facilitar a leitura e o registro.
 
datetime GetPeriodStart(int periodType);

Esta função utilitária retorna o valor datetime para o início do ano, mês, semana (iniciando no domingo), ou dia, dependendo do tipo de entrada. Ela aceita macros predefinidas do arquivo de cabeçalho como entrada, nomeadamente TODAY, THIS_WEEK, THIS_MONTH e THIS_YEAR. Esta função simplifica o processo de obtenção do valor datetime para esses períodos, permitindo que você faça isso com uma única linha de código.

Na próxima seção, exploraremos exemplos práticos demonstrando como a biblioteca de gerenciamento de histórico pode ser utilizada para gerar análises de negociação relevantes. Além disso, desenvolveremos um Expert Advisor que utiliza a biblioteca de histórico para determinar o volume ou lote ideal e a direção da posição para executar novas negociações. Isso destacará como os dados históricos podem ser incorporados de forma eficaz em sistemas de negociação automatizados, melhorando tanto a execução da estratégia quanto a tomada de decisão.


Como Calcular o Fator de Lucro, Lucro/Prejuízo Bruto e Lucro Médio e Prejuízo Médio por Negociação de um Expert Advisor ou Símbolo

Ao avaliar o desempenho de um Expert Advisor ou de uma estratégia de negociação no MetaTrader 5, uma das métricas mais importantes a considerar é o Fator de Lucro. O Fator de Lucro é uma razão que mede o lucro bruto em relação ao prejuízo bruto ao longo de um período específico. Ele fornece uma indicação clara de quão lucrativa é uma estratégia de negociação ao comparar os ganhos totais com as perdas totais.

Um Fator de Lucro alto indica que a estratégia está gerando mais lucros em relação às suas perdas, o que é uma característica desejável para qualquer sistema de negociação. Por outro lado, um Fator de Lucro baixo sugere que a estratégia pode não ser tão eficaz e pode precisar de otimização adicional.

O Fator de Lucro é calculado usando a seguinte fórmula:
Fator de Lucro = Lucro Bruto / Prejuízo Bruto

Onde:

  • Lucro Bruto é o valor total de dinheiro obtido de todas as negociações lucrativas.
  • Prejuízo Bruto é o valor total de dinheiro perdido em todas as negociações com prejuízo.

Um Fator de Lucro maior que 1 indica que a estratégia é lucrativa, pois o lucro bruto excede o prejuízo bruto. Um Fator de Lucro igual a 1 significa que o lucro bruto e o prejuízo bruto são iguais, sugerindo um cenário de equilíbrio. Um Fator de Lucro menor que 1 indica que a estratégia está perdendo dinheiro, pois o prejuízo bruto excede o lucro bruto.

Compreender e calcular o Fator de Lucro é fundamental para que traders e desenvolvedores tomem decisões informadas sobre a viabilidade e o desempenho de suas estratégias de negociação.

Neste exemplo, utilizarei a biblioteca HistoryManager.ex5 para demonstrar como é simples implementar esse cálculo no seu código MQL5.

Comece criando um novo Expert Advisor e nomeie-o como GetProfitFactor.mq5. Salve-o no seguinte caminho de pasta: Experts\Wanateki\HistoryManager\GetProfitFactor.mq5. Observe que o diretório onde você salva o Expert Advisor é importante, pois influenciará o caminho utilizado para incluir o arquivo de cabeçalho que contém as definições dos protótipos das funções da biblioteca.

O Expert Advisor GetProfitFactor.mq5 ajudará você a analisar o desempenho de suas estratégias de negociação calculando métricas-chave, como lucro bruto, prejuízo bruto e o próprio fator de lucro.

Primeiro, precisamos incluir a biblioteca HistoryManager.ex5 e definir uma enumeração que será usada para inserir o valor da string de símbolo no nosso Expert Advisor. A enumeração symbolName permitirá especificar se queremos analisar o símbolo do gráfico atual ou todos os símbolos na conta. Essa enumeração, juntamente com a entrada de número mágico , permitirá filtrar os resultados de acordo com os símbolos e Expert Advisors desejados.

#include <Wanateki/Toolkit/HistoryManager/HistoryManager.mqh>
//--
enum symbolName
  {
   CURRENT_CHART_SYMBOL,
   ALL_ACCOUNT_SYMBOLS,
  };

Em seguida, definimos os parâmetros de entrada que o usuário do Expert Advisor utilizará para filtrar a saída.

//--- input parameters
input ulong  magicNo = 0;          //Magic Number (0 to disable)
input symbolName getSymbolName = ALL_ACCOUNT_SYMBOLS;

Inicializamos as variáveis que serão usadas para armazenar nossos cálculos e exibir os resultados.

string currency = " " + AccountInfoString(ACCOUNT_CURRENCY);
double totalGrossProfit = 0.0, totalGrossLoss = 0.0,
       averageGrossProfit = 0.0, averageGrossLoss = 0.0,
       averageProfitOrLossPerTrade = 0.0,
       profitFactor = 0.0;
int totalTrades = 0,
    totalLossPositions = 0, totalProfitPositions = 0;
string symbol, printedSymbol, profitFactorSummery,
       commentString;

Na função OnInit(), utilizaremos uma instrução switch para determinar o símbolo a ser analisado. Uma vez identificado o símbolo , chamaremos a função CalcProfitFactor(), que é responsável por calcular o Fator de Lucro. Como primeira tarefa quando o Expert Advisor for carregado, exibiremos todos os resultados no gráfico utilizando a função Comment().

int OnInit()
  {
//---
   switch(getSymbolName)
     {
      case CURRENT_CHART_SYMBOL:
         symbol = _Symbol;
         break;
      case ALL_ACCOUNT_SYMBOLS:
         symbol = ALL_SYMBOLS;
         break;
      default:
         symbol = ALL_SYMBOLS;
     }
   printedSymbol = symbol;
   if(symbol == "")
      printedSymbol = "ALL_SYMBOLS";
//--
   CalcProfitFactor();
   Comment(commentString);
//---
   return(INIT_SUCCEEDED);
  }

Antes de prosseguirmos, vamos codificar a função CalcProfitFactor(), pois ela contém a maior parte do código que executa o Expert Advisor GetProfitFactor

Começaremos a função CalcProfitFactor() codificando a assinatura da função e, em seguida, redefinindo todas as variáveis para seus valores iniciais. Isso garante que quaisquer cálculos anteriores não interfiram na análise atual.

   totalGrossProfit = 0.0;
   totalGrossLoss = 0.0;
   averageProfitOrLossPerTrade = 0.0;
   averageGrossProfit = 0.0;
   averageGrossLoss = 0.0;
   profitFactor = 0.0;
   totalTrades = 0;
   totalLossPositions = 0;
   totalProfitPositions = 0;

Em seguida, utilizamos a função GetAllPositionsData() para recuperar os dados históricos de negociação. Essa função preenche o array positionsData com todas as posições de negociação com base no símbolo e número mágico especificados. Da mesma forma, verificamos se a função retorna true e se o tamanho do array é maior que zero para garantir que temos dados válidos para processar. Essa etapa é essencial para acessar as informações necessárias para realizar nossos cálculos.

if(GetAllPositionsData(positionsData, symbol, magicNo) && ArraySize(positionsData) > 0)
     {
      //--
     }

Em seguida, percorremos cada negociação no array positionsData para calcular o lucro bruto total e o prejuízo. Para cada negociação, verificamos se o lucro é maior que zero para determinar se é uma negociação lucrativa. Se for, incrementamos o contador totalProfitPositions e adicionamos o lucro a totalGrossProfit. Se o lucro for menor ou igual a zero, incrementamos o contador totalLossPositions e adicionamos o valor absoluto do lucro a totalGrossLoss. Esse loop nos ajuda a acumular os ganhos e perdas totais de todas as negociações.

      totalTrades = ArraySize(positionsData);
      for(int r = 0; r < totalTrades; r++)
        {
         if(positionsData[r].profit > 0) // profitable trade
           {
            ++totalProfitPositions;
            totalGrossProfit += positionsData[r].profit;
           }
         else  // loss trade
           {
            ++totalLossPositions;
            totalGrossLoss += MathAbs(positionsData[r].profit);
           }
        }
      // Calculate the profit factor and other data
      if(totalGrossProfit > 0 || totalGrossLoss > 0)
         averageProfitOrLossPerTrade = NormalizeDouble(
                                          (totalGrossProfit + totalGrossLoss) / totalTrades, 2
                                       );
      if(totalGrossProfit > 0)
         averageGrossProfit = NormalizeDouble(
                                 (totalGrossProfit / totalProfitPositions), 2
                              );
      if(totalGrossLoss > 0)
         averageGrossLoss = NormalizeDouble(
                               (totalGrossLoss / totalLossPositions), 2
                            );
      //--
      if(totalGrossLoss == 0.0)
         profitFactor = 0.0; // Avoid division by zero, indicating no losses
      profitFactor = totalGrossProfit / totalGrossLoss;
     }

Após acumular o lucro bruto total e o prejuízo, prosseguimos para calcular várias métricas. Primeiro, calculamos o lucro ou prejuízo médio por negociação dividindo a soma do lucro bruto total e do prejuízo pelo número total de negociações. Em seguida, calculamos o lucro bruto médio dividindo o lucro bruto total pelo número de negociações lucrativas. Da mesma forma, calculamos o prejuízo bruto médio dividindo o prejuízo bruto total pelo número de negociações com prejuízo. Por fim, calculamos o fator de lucro dividindo o lucro bruto total pelo prejuízo bruto total. Essas métricas fornecem uma visão abrangente do desempenho da estratégia de negociação.

   profitFactorSummery = "Profit Factor = " + DoubleToString(profitFactor, 2);
   if(profitFactor > 2.0)
     {
      profitFactorSummery = profitFactorSummery +
                            "\nThe trading strategy is HIGHLY PROFITABLE and efficient.";
     }
   else
      if(profitFactor > 1.5)
        {
         profitFactorSummery = profitFactorSummery +
                               "\nThe trading strategy is profitable and well-balanced.";
        }
      else
         if(profitFactor > 1.0)
           {
            profitFactorSummery = profitFactorSummery +
                                  "\nThe trading strategy is slightly profitable but may need improvement.";
           }
         else
            if(profitFactor == 1.0)
              {
               profitFactorSummery = profitFactorSummery +
                                     "\nThe strategy is break-even with no net gain or loss.";
              }
            else
              {
               profitFactorSummery = profitFactorSummery +
                                     "\nThe trading strategy is unprofitable and needs optimization.";
              }

Analisamos o fator de lucro para gerar uma string de resumo que descreve o desempenho da estratégia de negociação. Veja como interpretamos o fator de lucro:

  • Fator de Lucro > 2.0: A estratégia é altamente lucrativa e eficiente.
  • Fator de Lucro entre 1.0 e 1.5: A estratégia é ligeiramente lucrativa, mas pode precisar de melhorias.
  • Fator de Lucro = 1.0: A estratégia está em equilíbrio, sem ganho ou perda líquida.
  • Fator de Lucro < 1.0: A estratégia não é lucrativa e requer otimização.

Essa análise do fator de lucro fornece uma compreensão rápida da eficácia geral da estratégia de negociação.

Por fim, geramos uma string de comentário detalhada que inclui todas as métricas calculadas e o resumo do fator de lucro. Essa string é formatada para exibir o símbolo analisado, o número mágico , o número total de negociações, a quantidade de negociações lucrativas e com prejuízo, o lucro bruto total e o prejuízo, o lucro ou prejuízo médio por negociação, o lucro bruto médio e o prejuízo médio, além do resumo do fator de lucro.

Aqui está a função completa CalcProfitFactor() com todos os trechos de código em seus devidos lugares.

void CalcProfitFactor()
  {
   totalGrossProfit = 0.0;
   totalGrossLoss = 0.0;
   averageProfitOrLossPerTrade = 0.0;
   averageGrossProfit = 0.0;
   averageGrossLoss = 0.0;
   profitFactor = 0.0;
   totalTrades = 0;
   totalLossPositions = 0;
   totalProfitPositions = 0;
//--
   PositionData positionsData[];
   if(GetAllPositionsData(positionsData, symbol, magicNo) && ArraySize(positionsData) > 0)
     {
      totalTrades = ArraySize(positionsData);
      for(int r = 0; r < totalTrades; r++)
        {
         if(positionsData[r].profit > 0) // profitable trade
           {
            ++totalProfitPositions;
            totalGrossProfit += positionsData[r].profit;
           }
         else  // loss trade
           {
            ++totalLossPositions;
            totalGrossLoss += MathAbs(positionsData[r].profit);
           }
        }
      // Calculate the profit factor and other data
      if(totalGrossProfit > 0 || totalGrossLoss > 0)
         averageProfitOrLossPerTrade = NormalizeDouble(
                                          (totalGrossProfit + totalGrossLoss) / totalTrades, 2
                                       );
      if(totalGrossProfit > 0)
         averageGrossProfit = NormalizeDouble(
                                 (totalGrossProfit / totalProfitPositions), 2
                              );
      if(totalGrossLoss > 0)
         averageGrossLoss = NormalizeDouble(
                               (totalGrossLoss / totalLossPositions), 2
                            );
      //--
      if(totalGrossLoss == 0.0)
         profitFactor = 0.0; // Avoid division by zero, indicating no losses
      profitFactor = totalGrossProfit / totalGrossLoss;
     }

// Analyze the Profit Factor result
   profitFactorSummery = "Profit Factor = " + DoubleToString(profitFactor, 2);
   if(profitFactor > 2.0)
     {
      profitFactorSummery = profitFactorSummery +
                            "\nThe trading strategy is HIGHLY PROFITABLE and efficient.";
     }
   else
      if(profitFactor > 1.5)
        {
         profitFactorSummery = profitFactorSummery +
                               "\nThe trading strategy is profitable and well-balanced.";
        }
      else
         if(profitFactor > 1.0)
           {
            profitFactorSummery = profitFactorSummery +
                                  "\nThe trading strategy is slightly profitable but may need improvement.";
           }
         else
            if(profitFactor == 1.0)
              {
               profitFactorSummery = profitFactorSummery +
                                     "\nThe strategy is break-even with no net gain or loss.";
              }
            else
              {
               profitFactorSummery = profitFactorSummery +
                                     "\nThe trading strategy is unprofitable and needs optimization.";
              }

   commentString =
      "\n\n-----------------------------------------------------------------------------------------------------" +
      "\n  HistoryManager.ex5 --- PROFIT FACTOR ANALYTICS ---" +
      "\n-----------------------------------------------------------------------------------------------------" +
      "\n   -> Symbol   = " + printedSymbol +
      "\n   -> Magic No = " + IntegerToString(magicNo) +
      "\n-----------------------------------------------------------------------------------------------------" +
      "\n-----------------------------------------------------------------------------------------------------" +
      "\n" + profitFactorSummery +
      "\n-----------------------------------------------------------------------------------------------------" +
      "\n-----------------------------------------------------------------------------------------------------" +
      "\n   -> Total Trades Analysed   = " + IntegerToString(totalTrades) +
      "\n   -> Total Profitable Trades = " + IntegerToString(totalProfitPositions) +
      "\n   -> Total Loss Trades       = " + IntegerToString(totalLossPositions) +
      "\n   --------------------------------------------------------" +
      "\n   -> Total Gross Profit = " + DoubleToString(totalGrossProfit, 2) + currency +
      "\n   -> Total Gross Loss   = -" + DoubleToString(totalGrossLoss, 2) + currency +
      "\n   ----------------------------------" +
      "\n   -> Total Gross (Profit - Loss) = " + DoubleToString(totalGrossProfit - totalGrossLoss, 2) + currency +
      "\n   --------------------------------------------------------" +
      "\n   -> Average Profit or Loss Per Trade = (-/+)" + DoubleToString(averageProfitOrLossPerTrade, 2) + currency +
      "\n   --------------------------------------------------------" +
      "\n   -> Average Gross Profit = " + DoubleToString(averageGrossProfit, 2) + currency +
      "\n   -> Average Gross Loss   = -" + DoubleToString(averageGrossLoss, 2) + currency +
      "\n   --------------------------------------------------------" +
      "\n-----------------------------------------------------------------------------------------------------";
//--
  }

Também colocamos a função dentro da função padrão OnTrade() para executá-la e recalcular o Fator de Lucro após cada operação de negociação.

void OnTrade()
  {
//---
   CalcProfitFactor();
  }

Para garantir que estamos exibindo dados atualizados no gráfico, utilizaremos a função Comment() para imprimir a commentString que contém todas as informações sobre o Fator de Lucro atualizado e exibi-la a cada novo tick recebido na função padrão OnTick().

void OnTick()
  {
//---
   Comment(commentString);
  }

Aqui está a saída do Expert Advisor GetProfitFactor na janela de gráfico do MetaTrader 5.

GetProfitFactor EA desenvolvido por HistoryManager.ex5

O arquivo-fonte GetProfitFactor.mq5 está anexado ao final deste artigo para sua conveniência.



Como Calcular o Lucro Bruto e Líquido Monetário da Semana Atual para um Expert Advisor ou Símbolo Específico

Neste exemplo, iremos criar um script em MQL5 que fornecerá uma visão abrangente do desempenho financeiro da semana atual, incluindo lucro bruto, trocas, comissões e lucro líquido. Isso ajudará a demonstrar como você pode utilizar a biblioteca History Manager para avaliar rapidamente o desempenho semanal de toda a conta, de um símbolo específico ou do número mágico de um Expert Advisor diretamente no terminal MetaTrader 5.

Começamos criando um novo script chamado GetNetProfitThisWeek.mq5 e salvando-o nesta pasta: (Scripts\Wanateki\HistoryManager\GetNetProfitThisWeek.mq5). No novo arquivo de script, comece incluindo a biblioteca HistoryManager.mqh, que nos dará acesso a todas as funções da biblioteca.

#include <Wanateki/Toolkit/HistoryManager/HistoryManager.mqh>

Em seguida, colocaremos todo o nosso código dentro da função OnStart() para manter tudo simples e organizado O primeiro trecho do script será inicializar uma variável do tipo string para armazenar a moeda da conta. Isso será utilizado para formatar a saída das métricas financeiras.

string currency = " " + AccountInfoString(ACCOUNT_CURRENCY);

Antes de iniciar qualquer cálculo, precisamos primeiro determinar o tempo inicial da semana atual. Isso foi simplificado, pois a biblioteca HistoryManager.ex5 contém a função utilitária GetPeriodStart(), que utilizaremos para obter o valor datetime de quando a semana atual começa. Para obter esse valor, basta invocar a função GetPeriodStart() com o parâmetro THIS_WEEK como entrada. Isso nos ajudará a filtrar os negócios que ocorreram dentro da semana atual.

datetime thisWeekStartTime = GetPeriodStart(THIS_WEEK);

Declaramos um array para armazenar os dados de negócios e utilizamos a função GetDealsData() para preenchê-lo com os negócios que ocorreram entre o início da semana atual e o momento atual (NOW). Da mesma forma, filtramos os negócios para todos os símbolos com número mágico igual a 0.

if(
      GetDealsData(
         dealsData,
         thisWeekStartTime, NOW,
         ALL_SYMBOLS, 0
      ) &&
      ArraySize(dealsData) > 0
   )

Inicializamos variáveis para armazenar o lucro bruto total, total de swaps e total de comissões. Essas variáveis serão utilizadas para acumular os respectivos valores dos dados de negócios.

double totalGrossProfit = 0.0,
             totalSwap = 0.0,
             totalCommission = 0.0;

Percorremos cada negócio no array dealsData . Para cada negócio, verificamos se ele é um negócio de fechamento (DEAL_ENTRY_OUT). Se for, adicionamos o lucro, troca e comissão às suas respectivas variáveis totais.

int totalDeals = ArraySize(dealsData);
for(int k = 0; k < totalDeals; k++)
  {
   if(dealsData[k].entry == DEAL_ENTRY_OUT)
     {
      totalGrossProfit += dealsData[k].profit;
      totalSwap += dealsData[k].swap;
      totalCommission += dealsData[k].commission;
     }
  }

Calculamos o total de despesas somando o total de troca e comissão. Em seguida, calculamos o lucro líquido total subtraindo o total de despesas do lucro bruto total.

double totalExpenses = totalSwap + totalCommission;
double totalNetProfit = totalGrossProfit - MathAbs(totalExpenses);

Utilizamos a função Print() para exibir os resultados no log do MetaTrader 5. Isso inclui o lucro bruto total, total de swaps, total de comissões e lucro líquido total da semana atual. Além disso, também utilizamos a função Comment() para exibir os resultados diretamente na janela do gráfico. Isso inclui um resumo detalhado das métricas financeiras da semana atual.

HistoryManager.ex5 - Obter o Lucro Líquido Total da Semana Atual

Aqui está a função completa OnStart() com todos os trechos de código em sua sequência correta e completa.

void OnStart()
  {
//---
   string currency = " " + AccountInfoString(ACCOUNT_CURRENCY);
   datetime thisWeekStartTime = GetPeriodStart(THIS_WEEK);
   DealData dealsData[];
   if(
      GetDealsData(
         dealsData,
         thisWeekStartTime, NOW,
         ALL_SYMBOLS, 0
      ) &&
      ArraySize(dealsData) > 0
   )
     {
      double totalGrossProfit = 0.0,
             totalSwap = 0.0,
             totalCommission = 0.0;
      int totalDeals = ArraySize(dealsData);
      for(int k = 0; k < totalDeals; k++)
        {
         if(dealsData[k].entry == DEAL_ENTRY_OUT)
           {
            totalGrossProfit += dealsData[k].profit;
            totalSwap += dealsData[k].swap;
            totalCommission += dealsData[k].commission;
           }
        }
      double totalExpenses = totalSwap + totalCommission;
      double totalNetProfit = totalGrossProfit - MathAbs(totalExpenses);

      Print("-------------------------------------------------");
      Print(
         "Account No: ", AccountInfoInteger(ACCOUNT_LOGIN),
         " [ THIS WEEK'S NET PROFIT ]"
      );
      Print(
         "Total Gross Profit This Week: ",
         DoubleToString(totalGrossProfit, 2),
         " ", currency
      );
      Print(
         "Total Swaps This Week: ", DoubleToString(totalSwap, 2),
         " ", currency
      );
      Print(
         "Total Commission This Week: ", DoubleToString(totalCommission, 2),
         " ", currency
      );
      Print(
         "Total Net Profit This Week: ",
         DoubleToString(totalNetProfit, 2), " ",
         currency
      );
      
     //--
     Comment(
         "\n\n-----------------------------------------------------------------------------------------------------" +
         "-------------------------------------------------------------------" +
         "\n  HistoryManager.ex5 --- TOTAL NET PROFIT THIS WEEK ---" +
         "\n-----------------------------------------------------------------------------------------------------" +
         "------------------------------------------------------" +
         "\n DATE = ( From: " + TimeToString(thisWeekStartTime) + ", to: " + TimeToString(NOW) + " )" +
         "\n Account No  = " + IntegerToString(AccountInfoInteger(ACCOUNT_LOGIN)) +
         "\n------------------------------------------------------" +
         "\n   -> Total Gross Profit =  " + DoubleToString(totalGrossProfit, 2) +
         currency +
         "\n   -> Total Swaps        =  " + DoubleToString(totalSwap, 2) +
         currency +
         "\n   -> Total Commission   =  " + DoubleToString(totalCommission, 2) +
         currency +
         "\n-----------------------------------------------------------------------------------------------------" +
         "------------------------------------------------------" +
         "\n   -> TOTAL NET PROFIT   =  " + DoubleToString(totalNetProfit, 2) +
         currency +
         "\n-----------------------------------------------------------------------------------------------------" +
         "------------------------------------------------------" +         
         "\n-----------------------------------------------------------------------------------------------------" +
         "-------------------------------------------------------------------"
      );
     }
  }

Para o código-fonte completo do script, faça o download do arquivo GetNetProfitThisWeek.mq5 anexado ao final deste artigo.


Como Calcular a Relação Lucro/Prejuízo em Pips para um Símbolo ou Expert Advisor Específico

Neste exemplo, exploraremos como calcular a relação de lucro/prejuízo em pips para um símbolo de negociação específico ou para um Expert Advisor completo utilizando MQL5. Esse cálculo é uma ferramenta essencial para avaliar o desempenho de uma estratégia de negociação, pois fornece uma métrica clara e quantificável para determinar se a estratégia é lucrativa, está em equilíbrio ou é não lucrativa com base nos pips ganhos ou perdidos. O código fornecido foi projetado para analisar dados históricos de negociações, calcular a relação e apresentar os resultados em um formato amigável e de fácil interpretação.

Nomearemos o Expert Advisor como GetSymbolPipsProfitToLossRatio.mq5, salvaremos na pasta apropriada e começaremos incluindo a biblioteca HistoryManager.mqh como a primeira e mais importante linha do nosso arquivo-fonte. Em seguida, criaremos um enum para armazenar o nome do símbolo e definiremos os parâmetros de entrada (símbolo </i>e número mágico </i>). Esses parâmetros permitirão ao usuário filtrar os resultados dos dados conforme suas preferências: se deseja analisar todas as posições fechadas de um símbolo específico, posições fechadas de um símbolo específico que incluam um determinado número mágico, ou todas as posições com um número mágico específico, independentemente do símbolo.

Na função OnInit(), iremos recuperar a moeda da conta e determinar o(s) símbolo(s) a serem analisados com base na entrada do usuário. Se o usuário selecionar CURRENT_CHART_SYMBOL, nosso Expert Advisor irá focar no símbolo do gráfico atual. Se selecionar ALL_ACCOUNT_SYMBOLS, ele analisará todos os símbolos negociados na conta.

Utilizaremos a função GetAllPositionsData() para obter os dados históricos de negociação para o(s) símbolo(s) especificado(s) e número mágico. Esses dados serão armazenados em um array de estruturas PositionData . Da mesma forma, iremos percorrer o array para categorizar as negociações como lucrativas ou com prejuízo. Durante esse processo, calcularemos o total de pips ganhos em negociações lucrativas (totalPipsProfit) e o total de pips perdidos em negociações com prejuízo (totalPipsLoss).

Para calcular a relação lucro/prejuízo em pips, dividiremos o total de pips ganhos pelo total de pips perdidos. Além disso, utilizaremos o valor absoluto para garantir que a relação seja sempre positiva. Se não houver negociações com prejuízo (totalPipsLoss == 0), a relação será indefinida, e o Expert Advisor exibirá uma mensagem indicando que a estratégia não possui negociações com prejuízo. O Expert Advisor interpretará a relação da seguinte forma:

  • Relação > 1.0: A estratégia é lucrativa, pois ganha mais pips do que perde.
  • Relação == 1.0: A estratégia está em equilíbrio em termos de pips.
  • Proporção < 1,0: A estratégia não é lucrativa, pois perde mais pips do que ganha.

Utilizaremos a função Comment() para exibir os resultados da análise diretamente no gráfico. A saída incluirá: o(s) símbolo(s) analisado(s), o número mágico utilizado (se houver), o número total de negociações analisadas, a quantidade de negociações lucrativas e com prejuízo, juntamente com o total de pips ganhos e perdidos, e a relação lucro/prejuízo em pips calculada, bem como sua interpretação.

HistoryManager.ex5 Relação Lucro/Prejuízo em Pips EA

Na função OnDeinit(), realizaremos uma limpeza simples removendo os comentários do gráfico quando o Expert Advisor for removido ou desinicializado, garantindo um ambiente de trabalho limpo. Deixaremos a função OnTick() vazia, pois a análise é realizada apenas uma vez durante a inicialização. No entanto, você pode expandir essa função para realizar cálculos ou atualizações em tempo real, se necessário.

Aqui estão todos os trechos de código apresentados em sua sequência correta:

//--
#include <Wanateki/Toolkit/HistoryManager/HistoryManager.mqh>
//--
enum symbolName
  {
   CURRENT_CHART_SYMBOL,
   ALL_ACCOUNT_SYMBOLS,
  };
//--- input parameters
input ulong  magicNo = 0;          //Magic Number (0 to disable)
input symbolName getSymbolName = CURRENT_CHART_SYMBOL;
int OnInit()
  {
//---
   string currency = " " + AccountInfoString(ACCOUNT_CURRENCY);
   string symbol, printedSymbol;

   switch(getSymbolName)
     {
      case CURRENT_CHART_SYMBOL:
         symbol = _Symbol;
         break;
      case ALL_ACCOUNT_SYMBOLS:
         symbol = ALL_SYMBOLS;
         break;
      default:
         symbol = ALL_SYMBOLS;
     }
   printedSymbol = symbol;
   if(symbol == "")
      printedSymbol = "ALL_SYMBOLS";
//--
   int totalTrades = 0;
   int totalLossPositions = 0;
   int totalProfitPositions = 0;
   double totalPipsProfit = 0;
   double totalPipsLoss = 0;
   string interpretation;
   double pipsProfitToLossRatio = 0;
//--
   PositionData positionsData[];
   if(GetAllPositionsData(positionsData, symbol, magicNo) && ArraySize(positionsData) > 0)
     {
      totalTrades = ArraySize(positionsData);
      for(int r = 0; r < totalTrades; r++)
        {
         if(positionsData[r].profit > 0) // profitable trade
           {
            ++totalProfitPositions;
            totalPipsProfit += positionsData[r].pipProfit;
           }
         else  // loss trade
           {
            ++totalLossPositions;
            totalPipsLoss += positionsData[r].pipProfit;
           }
        }
      // Calculate the pip profit loss ratioInterpretation
      if(totalPipsLoss == 0)
        {
         interpretation = "Pips Profit-to-Loss Ratio: Undefined (Total pips loss is zero)." +
                          "The strategy has no losing trades.";
        }
      else
        {
         pipsProfitToLossRatio = fabs(totalPipsProfit / totalPipsLoss);

         switch(pipsProfitToLossRatio > 1.0 ? 1 : pipsProfitToLossRatio == 1.0 ? 0 : -1)
           {
            case 1:
               interpretation = "Pips Profit-to-Loss Ratio: " + DoubleToString(pipsProfitToLossRatio, 2) +
                                ". The strategy is profitable as it gains more pips than it loses.";
               break;
            case 0:
               interpretation = "Pips Profit-to-Loss Ratio: " + DoubleToString(pipsProfitToLossRatio, 2) +
                                ". The strategy breaks even in terms of pips.";
               break;
            case -1:
               interpretation = "Pips Profit-to-Loss Ratio: " + DoubleToString(pipsProfitToLossRatio, 2) +
                                ". The strategy is unprofitable as it loses more pips than it gains.";
               break;
           }
        }

      Comment(
         "\n\n-----------------------------------------------------------------------------------------------------" +
         "---------------------------" +
         "\n  HistoryManager.ex5 --- PIPS PROFIT TO LOSS RATIO ---" +
         "\n-----------------------------------------------------------------------------------------------------" +
         "---------------------------" +
         "\n   -> Symbol   = " + printedSymbol +
         "\n   -> Magic No = " + IntegerToString(magicNo) +
         "\n-----------------------------------------------------------------------------------------------------" +
         "---------------------------" +
         "\n-----------------------------------------------------------------------------------------------------" +
         "---------------------------" +
         "\n" + interpretation +
         "\n-----------------------------------------------------------------------------------------------------" +
         "---------------------------" +
         "\n-----------------------------------------------------------------------------------------------------" +
         "---------------------------" +
         "\n   -> Total Trades Analysed     = " + IntegerToString(totalTrades) +
         "\n   -> Total Profitable Trades   = " + IntegerToString(totalProfitPositions) +
         " ( " + DoubleToString(totalPipsProfit, 0) + " Pips )" +
         "\n   -> Total Loss Trades         = " + IntegerToString(totalLossPositions) +
         " ( " + DoubleToString(totalPipsLoss, 0) + " Pips )" +
         "\n   --------------------------------------------------------------------------" +
         "\n   -> PIPS PROFIT TO LOSS RATIO = " + DoubleToString(pipsProfitToLossRatio, 2) +
         "\n   --------------------------------------------------------------------------" +
         "\n-----------------------------------------------------------------------------------------------------" +
         "---------------------------"
      );
     }

//---
   return(INIT_SUCCEEDED);
  }

Você pode baixar o arquivo-fonte completo GetSymbolPipsProfitToLossRatio.mq5 na parte inferior deste artigo.


Como Obter o Valor Total em Dinheiro dos Depósitos da Conta

Nesta seção, criaremos um script MQL5 simples chamado GetTotalDeposits.mq5 que utiliza a função GetAllDealsData() da nossa biblioteca para recuperar e analisar dados de negociações, ajudando você a obter uma visão clara do histórico de depósitos da sua conta. Esta é uma ferramenta valiosa para quando você deseja, de forma automatizada, acompanhar o total de fundos depositados na sua conta de negociação, auditar o histórico de financiamento da conta para fins de registro ou fiscais, ou simplesmente verificar transações de depósito para garantir sua precisão.

Utilizaremos a função GetAllDealsData() para obter todos os dados históricos de negociações da conta. Esses dados serão armazenados em um array de estruturas DealData. Em seguida, inicializaremos uma variável para armazenar o valor do depósito total e percorreremos os dados de negociações. Identificaremos transações de depósito verificando se o tipo de negociação é DEAL_TYPE_BALANCE. Somaremos os valores de lucro dessas negociações para calcular o total de depósitos.

Após calcular e armazenar todos os dados desejados, iremos imprimir o valor total de depósitos no terminal e exibi-lo no gráfico utilizando a função Comment(). Isso fornece um resumo amigável do histórico de depósitos da conta.

#include <Wanateki/Toolkit/HistoryManager/HistoryManager.mqh>
void OnStart()
  {
//---
// Find and list total deposited funds in the account
   DealData dealsData[];
   if(GetAllDealsData(dealsData) && ArraySize(dealsData) > 0)
     {
      double totalDeposits = 0.0;
      int totalDeals = ArraySize(dealsData);
      Print("");
      for(int k = 0; k < totalDeals; k++)
        {
         if(dealsData[k].type == DEAL_TYPE_BALANCE)
           {
            totalDeposits += dealsData[k].profit;
            Print(
               dealsData[k].profit, " ", AccountInfoString(ACCOUNT_CURRENCY),
               " --> Cash deposit on: ", dealsData[k].time
            );
           }
        }
      Print("-------------------------------------------------");
      Print(
         "Account No: ", AccountInfoInteger(ACCOUNT_LOGIN),
         " Total Cash Deposits: ", totalDeposits, " ",
         AccountInfoString(ACCOUNT_CURRENCY)
      );

      Comment(
         "\n\n-----------------------------------------------------------------------------------------------------" +
         "---------------------------------------------------------" +
         "\n  HistoryManager.ex5 --- TOTAL ACCOUNT DEPOSITS ---" +
         "\n-----------------------------------------------------------------------------------------------------" +
         "------------------------------------------------------" +
         "\n   -> Account No  = " + IntegerToString(AccountInfoInteger(ACCOUNT_LOGIN)) +
         "\n   -> Total Cash Deposits =  " + DoubleToString(totalDeposits, 2) +
         AccountInfoString(ACCOUNT_CURRENCY) +
         "\n-----------------------------------------------------------------------------------------------------" +
         "------------------------------------------------------"
      );
     }
  }

Você pode baixar o arquivo-fonte completo GetTotalDeposits.mq5 na parte inferior deste artigo.


Como Criar um Expert Advisor Orientado por Dados de Preço com a Biblioteca History Manager EX5

Para o exemplo final deste artigo, criaremos um Expert Advisor simples, porém poderoso, orientado por dados de preço chamado PriceTrader_EA, utilizando as bibliotecas PositionsManager.ex5 e HistoryManager.ex5. Este Expert Advisor possui um potencial significativo de geração de lucro, especialmente quando utilizado em contas maiores e após testes e otimizações adequados. Você perceberá que o código-fonte do PriceTrader_EA é conciso e eficiente, graças ao uso das bibliotecas previamente desenvolvidas PositionsManager.ex5 e HistoryManager.ex5. Essas bibliotecas permitem reduzir o código mantendo confiabilidade e consistência.

O PriceTrader_EA foi projetado para tomar decisões de negociação com base em dados de preço e desempenho histórico das negociações. Ele incorpora os seguintes recursos principais:

  • Dimensionamento Dinâmico de Lote: O Expert Advisor ajusta os tamanhos de lote com base no resultado das negociações anteriores, dobrando o tamanho do lote após uma negociação com prejuízo para recuperar perdas (dentro de limites predefinidos).
  • Direção de Negociação Baseada na Ação de Preço:PriceTrader_EA abre negociações na direção da tendência predominante, conforme determinado pela ação de preço no timeframe H1.
  • Gerenciamento de Risco: Os níveis de stop-loss (SL) e take-profit (TP) são calculados dinamicamente com base no spread atual, garantindo adaptação às condições de mercado.

Começaremos incluindo os arquivos de cabeçalho das bibliotecas HistoryManager.mqh e PositionsManager.mqh na seção de cabeçalho do nosso arquivo-fonte.

#include <Wanateki/Toolkit/HistoryManager/HistoryManager.mqh>
#include <Wanateki/Toolkit/PositionsManager/PositionsManager.mqh>

Em seguida, definiremos os parâmetros de entrada para o PriceTrader_EA. Esses parâmetros nos permitem configurar o número mágico, os multiplicadores de spread para TP e SL, e o aumento máximo do tamanho do lote.

input ulong magicNo = 101010;
input int tpSpreadMulti = 70;
input int slSpreadMulti = 90;
input int maxLotIncrease = 1000;

Inicializaremos variáveis-chave para armazenar informações como o spread atual, tamanho do lote e o número de posições abertas. Essas variáveis serão utilizadas ao longo da lógica do Expert Advisor.

bool eaJustLoaded = true;
double spread;
int spreadPips;
long minSLTP = SymbolInfoInteger(Symbol(), SYMBOL_TRADE_STOPS_LEVEL);
long freezeLevel = SymbolInfoInteger(Symbol(), SYMBOL_TRADE_FREEZE_LEVEL);
double lotSize;
int sl, tp;
int totalOpenPositions, totalBuyPositionsOpen, totalSellPositionsOpen;
//--
PositionData lastClosedPositionInfo;

Na função OnInit(), calcularemos o spread atual e inicializaremos os níveis de TP e SL com base nos multiplicadores de spread. Também reproduziremos um som para indicar que o PriceTrader_EA foi carregado com sucesso.

int OnInit()
  {
//---
   spread = SymbolInfoDouble(_Symbol, SYMBOL_ASK) - SymbolInfoDouble(_Symbol, SYMBOL_BID);
   spread = NormalizeDouble(spread, _Digits);
   spreadPips = int(spread / _Point);
   tp = spreadPips * tpSpreadMulti;
   sl = spreadPips * slSpreadMulti;
//--
   PlaySound("connect.wav");
//---
   return(INIT_SUCCEEDED);
  }

Na função OnDeinit(), limparemos os comentários do gráfico e reproduziremos um som para indicar que o PriceTrader_EA foi descarregado e removido do gráfico.

void OnDeinit(const int reason)
  {
//---
   Comment("");
   PlaySound("disconnect.wav");
  }

A função OnTick() contém a lógica principal do PriceTrader_EA. Veja o que faremos nesta função:

  • Recuperar o tamanho atual do lote e o número de posições abertas.
  • Verificar se o PriceTrader_EA acabou de ser carregado e abrir uma negociação inicial com base na ação de preço no H1.
  • Ajustar o tamanho do lote e a direção da negociação com base no resultado da última negociação fechada.
  • Abrir negociações consecutivas para aproveitar tendências lucrativas ou recuperar perdas.

void OnTick()
  {
//---
   lotSize = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
//--
   totalOpenPositions = SymbolPositionsTotal(_Symbol, magicNo);
   totalBuyPositionsOpen = SymbolBuyPositionsTotal(_Symbol, magicNo);
   totalSellPositionsOpen = SymbolSellPositionsTotal(_Symbol, magicNo);

   if(eaJustLoaded && totalOpenPositions == 0)
     {
      //--
      GetLastClosedPositionData(lastClosedPositionInfo, _Symbol, magicNo);
      if(lastClosedPositionInfo.ticket > 0 && lastClosedPositionInfo.profit < 0)
        {
         if(lastClosedPositionInfo.volume * 2 < lotSize * maxLotIncrease)
            lotSize = lastClosedPositionInfo.volume * 2; // double lot size
        }
      //--
      if(iOpen(_Symbol, PERIOD_H1, 0) < iClose(_Symbol, PERIOD_H1, 0))
        {
         OpenBuyPosition(magicNo, _Symbol, lotSize, sl, tp, "Initial_Position");
        }
      else
        {
         OpenSellPosition(magicNo, _Symbol, lotSize, sl, tp, "Initial_Position");
        }
      if(totalOpenPositions > 0)
         eaJustLoaded = false;
     }
   else
     {
      eaJustLoaded = false;
     }

   if(totalOpenPositions == 0 && !eaJustLoaded)
     {
      if(GetLastClosedPositionData(lastClosedPositionInfo, _Symbol, magicNo))
        {
         if(lastClosedPositionInfo.profit > 0) // PROFITABLE TRADE
           {
            if(lastClosedPositionInfo.type == POSITION_TYPE_BUY)
              {
               OpenBuyPosition(magicNo, _Symbol, lotSize, sl, tp, "Consecutive Profit");
              }
            else  // SELL POSITION
              {
               OpenSellPosition(magicNo, _Symbol, lotSize, sl, tp, "Consecutive Profit");
              }
           }
         else   // LOSS TRADE
           {
            if(lastClosedPositionInfo.volume * 2 < lotSize * maxLotIncrease)
               lotSize = lastClosedPositionInfo.volume * 2; // double lot size
            //--
            if(lastClosedPositionInfo.type == POSITION_TYPE_BUY)
              {
               // Reverse trade direction
               OpenSellPosition(magicNo, _Symbol, lotSize, sl, tp, "Loss Recovery");
              }
            else  // SELL POSITION
              {
               OpenBuyPosition(magicNo, _Symbol, lotSize, sl, tp, "Loss Recovery");
              }
           }
        }
     }

O PriceTrader_EA é ideal para quem busca uma estratégia automatizada simples, porém eficaz, baseada em tendência, com gerenciamento de risco dinâmico. Este EA foi projetado para recuperar perdas rapidamente por meio do ajuste adaptativo do tamanho do lote, garantindo que sua estratégia permaneça robusta mesmo em condições de mercado desfavoráveis. Além disso, você perceberá que o PriceTrader_EA foi inteligentemente desenvolvido para tornar o backtesting no MetaTrader 5 simples e eficiente. As entradas do usuário para tamanho do lote, stop loss e take profit são ajustadas automaticamente com base no símbolo carregado, eliminando a necessidade de ajustes manuais e garantindo desempenho otimizado em diferentes instrumentos.

Você encontrará o arquivo-fonte completo PriceTrader_EA.mq5 na parte inferior deste artigo, bem como a biblioteca PositionsManager.ex5.


Backtesting do Expert Advisor Price Trader

Vamos executar um backtest no testador de estratégias do MetaTrader 5 para verificar como essa estratégia de negociação simples se comporta ao longo dos últimos quatorze meses.
Aqui estão as configurações que aplicaremos no testador de estratégias:

  • Corretora: Deriv

  • Servidor: Deriv-Demo

  • Símbolo: Volatility 50 (1s) Index

  • Período: Diário

  • Período de Teste (Data): 1 ano e 2 meses (Jan 2024 a Fev 2025)

  • Modelagem: Cada tick baseado em ticks reais

  • Depósito: 5.000 USD

  • Alavancagem: 1:1000

Configurações de Backtest do Wanateki PriceTrader_EA

Configurações de entrada:

Entradas do Backtest do Wanateki PriceTrader_EA

Aqui estão os resultados do backtest para o PriceTrader_EA:

Relatório de Backtest do Wanateki PriceTrader_EA

Relatório de Backtest do Wanateki PriceTrader_EA


Relatório de Backtest do Wanateki PriceTrader_EA

Relatório de Backtest do Wanateki PriceTrader_EA

Relatório de Backtest do Wanateki PriceTrader_EA

Relatório de Backtest do Wanateki PriceTrader_EA

Analisando nossos resultados de backtest, PriceTrader_EA apresentou um lucro impressionante de mais de 129% de retorno, mantendo um baixo drawdown de capital de apenas 29%. Essa estratégia simples, porém eficaz, demonstra um potencial significativo e pode ser ainda mais refinada e otimizada para alcançar resultados ainda melhores. Como o PriceTrader_EA ajusta dinamicamente seus parâmetros—como tamanho do lote, stop loss, e take profit—com base no símbolo ou ativo que está sendo negociado, você pode testá-lo facilmente em uma conta demo. Basta carregá-lo em um gráfico e observar seu desempenho ao longo de um dia ou mais para verificar se ele gera lucros, assim como ocorreu durante nossas avaliações no testador de estratégias. Essa flexibilidade o torna uma excelente ferramenta tanto para testes quanto para negociação ao vivo.


Conclusão

Como demonstrado neste artigo final da série, a biblioteca HistoryManager.ex5 é uma ferramenta poderosa e eficiente que simplifica o processamento de históricos de negociação no MetaTrader 5. Com sua ampla gama de funções, essa biblioteca permite acessar e gerenciar facilmente dados relacionados a negócios, ordens, posições e ordens pendentes—tudo por meio de chamadas de função simples em uma única linha. Essa abordagem otimizada economiza tempo e esforço, permitindo que você se concentre no desenvolvimento e na otimização de suas estratégias de negociação.

Ao longo deste artigo, forneci exemplos práticos de código para ajudá-lo a aproveitar todo o potencial da biblioteca HistoryManager.ex5. Esses exemplos, combinados com o conhecimento compartilhado nesta série, fornecem as ferramentas e os recursos necessários para processar, de forma algorítmica, qualquer tipo de dado histórico gerado a partir das suas atividades de negociação no MetaTrader 5 utilizando MQL5. Como um presente final para todos os leitores que acompanharam até aqui, criei o PriceTrader_EA, um Expert Advisor básico, porém eficaz, que demonstra a aplicação prática de alguns desses conceitos.

Obrigado por acompanhar esta jornada no desenvolvimento em MQL5. Sua dedicação em aprender e explorar essas ferramentas demonstra seu compromisso em dominar a arte do trading algorítmico. Como sempre, desejo a você muito sucesso na sua busca por compreender as complexidades dos mercados e alcançar resultados através de seus desenvolvimentos em MQL5. Bons códigos, e que suas estratégias sempre prosperem!


Recursos e Arquivos-Fonte

Todo o código mencionado neste artigo é fornecido abaixo para sua conveniência. A tabela incluída apresenta as bibliotecas EX5 e arquivos-fonte correspondentes, facilitando o acesso, implementação e exploração dos exemplos discutidos.

Nome do Arquivo Descrição
HistoryManager.ex5 Biblioteca EX5 projetada para processar e gerenciar históricos de negociação.
PositionsManager.ex5 Biblioteca EX5 para gerenciar e processar posições e ordens.
HistoryManager.mqh Arquivo de cabeçalho utilizado para importar estruturas de dados e funções protótipo da biblioteca HistoryManager.ex5 para seus arquivos-fonte.
PositionsManager.mqh Arquivo de cabeçalho utilizado para importar funções protótipo da biblioteca PositionsManager.ex5 para seus arquivos-fonte.
GetProfitFactor.mq5 Expert Advisor que analisa o desempenho de suas estratégias de negociação calculando métricas-chave como lucro bruto, prejuízo bruto e fator de lucro.
GetNetProfitThisWeek.mq5 Script que calcula o lucro líquido da semana atual.
GetSymbolPipsProfitToLossRatio.mq5 Expert Advisor que calcula a relação lucro/prejuízo em pips para um símbolo específico ou para um Expert Advisor completo.
GetTotalDeposits.mq5 Script que recupera e analisa dados de negociações para fornecer uma visão clara do histórico de financiamento ou depósitos da sua conta.
PriceTrader_EA.mq5 Um Expert Advisor orientado por dados de preço que utiliza dados de histórico de negociações para detectar a direção do preço e recuperar perdas. Desenvolvido com as bibliotecas PositionsManager.ex5 e HistoryManager.ex5.



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

Últimos Comentários | Ir para discussão (3)
hini
hini | 5 jul. 2025 em 15:31
Olá autor, obrigado por seu código. Você testou o desempenho dele? Qual é a velocidade dele com um grande número de pedidos?
Wanateki Solutions LTD
Kelvin Muturi Muigua | 6 jul. 2025 em 23:03
Olá hini, obrigado por seu interesse no artigo. Ele é rápido, pois retorna os resultados consultados em milissegundos, mesmo quando se trabalha com um grande número de ordens históricas, mas isso depende da velocidade de seu computador.
hini
hini | 7 jul. 2025 em 00:18
Kelvin Muturi Muigua #:
Olá hini, obrigado por seu interesse no artigo. Ele é rápido, pois retorna os resultados consultados em milissegundos, mesmo quando se trabalha com um grande número de ordens históricas, mas isso depende da velocidade de seu computador.
Obrigado!
Automatizando Estratégias de Trading em MQL5 (Parte 11): Desenvolvendo um Sistema de Trading em Grade Multi-Nível Automatizando Estratégias de Trading em MQL5 (Parte 11): Desenvolvendo um Sistema de Trading em Grade Multi-Nível
Neste artigo, desenvolvemos um Expert Advisor de sistema de trading em grade multi-nível usando MQL5, com foco na arquitetura e no design de algoritmo por trás das estratégias de grid trading. Exploramos a implementação de lógica de grade em múltiplas camadas e técnicas de gerenciamento de risco para lidar com diferentes condições de mercado. Por fim, fornecemos explicações detalhadas e dicas práticas para guiá-lo na construção, teste e refinamento do sistema de trading automatizado.
Desenvolvimento de um Kit de Ferramentas para análise de ação de preço (Parte 17): Ferramenta TrendLoom EA Desenvolvimento de um Kit de Ferramentas para análise de ação de preço (Parte 17): Ferramenta TrendLoom EA
Como observador e trader de análise de preços, notei que quando uma tendência é confirmada por múltiplos períodos de tempo, ela geralmente continua nessa direção. O que pode variar é quanto tempo a tendência dura, e isso depende do tipo de trader que você é, se mantém posições no longo prazo ou realiza operações de scalping. Os prazos que você escolher para a confirmação desempenham um papel crucial. Confira este artigo para conhecer um sistema rápido e automatizado que ajuda você a analisar a tendência geral em diferentes períodos com apenas um clique ou atualizações regulares.
Está chegando o novo MetaTrader 5 e MQL5 Está chegando o novo MetaTrader 5 e MQL5
Esta é apenas uma breve resenha do MetaTrader 5. Eu não posso descrever todos os novos recursos do sistema por um período tão curto de tempo - os testes começaram em 09.09.2009. Esta é uma data simbólica, e tenho certeza que será um número de sorte. Alguns dias passaram-se desde que eu obtive a versão beta do terminal MetaTrader 5 e MQL5. Eu ainda não consegui testar todos os seus recursos, mas já estou impressionado.
Otimização por Comunidade de Cientistas - Community of Scientist Optimization (CoSO): Teoria Otimização por Comunidade de Cientistas - Community of Scientist Optimization (CoSO): Teoria
Os segredos da otimização eficiente de estratégias de trading em abordagens metaheurísticas. Community of Scientist Optimization é um novo algoritmo populacional inspirado nos mecanismos de funcionamento da comunidade de cientistas. Diferentemente das metáforas naturais tradicionais, o CoSO modela aspectos únicos da atividade científica humana: a publicação de resultados em periódicos, a competição por financiamentos de pesquisa e a formação de grupos de pesquisa.