Download MetaTrader 5

Expert Advisor Universal: Acessando as Propriedades do Símbolo (Parte 8)

31 agosto 2017, 09:33
Vasiliy Sokolov
0
657

Introdução

Algum tempo se passou desde a publicação da parte anterior do artigo dedicado ao módulo de negociação CStrategy. Este tempo dedicado foi necessário para realizar o caminho de desenvolvimento da CStrategy de uma pequena biblioteca auxiliar de negociação para uma biblioteca complexa com recursos completos de negociação, que inclui as ferramentas mais usadas para a criação de uma estratégia de negociação plena. Este momento ajudou a compreender as formas de desenvolvimento da CStrategy. O uso prático da CStrategy durante esse período também ajudou a revelar algumas desvantagens nas últimas versões do módulo. A correção dessas desvantagens deu origem a novos artigos na série "Expert Advisor Universal". Na oitava parte atual, nós discutiremos o trabalho com instrumentos de negociação através da classe orientada a objetos CStrategy. 

Uma visão geral das versões anteriores da CStrategy

O ambiente de negociação do Expert Advisor é diversificado. Ele inclui informações da conta, dados de preços, funções para trabalhar com o tempo e informações sobre os símbolos de negociação disponíveis no terminal. A maioria dessas informações está disponível nas funções relacionadas ao símbolo de negociação, como receber as cotações atuais e trabalhar com as propriedades do símbolo. Como regra geral, todos os Expert Advisors de negociação trabalham ativamente com os dados de preços. Eles usam os últimos dados de preços para calcular um padrão ou um sinal de negociação, com base no qual eles realizam uma negociação. A fim de fornecer uma geração adequada de uma ordem de negociação, eles também usam informações sobre as propriedades do símbolo atual, como o volume mínimo de uma negociação ou o nível de congelamento, ou seja, a faixa do preço atual na qual as ordens pendentes não podem ser colocadas.

Estes dados devem ser facilmente acessíveis e sempre "à mão" do trader. Foi assim nas versões anteriores do CStrategy? Vamos nos referir ao histórico para descobrir. Abaixo está a descrição de como as versões anteriores do módulo funcionavam com um símbolo de negociação. Na terceira parte do artigo, nós discutimos o acesso as cotações através de um indexador tradicional []. Algumas classes auxiliares foram incluídas na CStrategy, como a COpen, CHigh, CLow, CClose, CVolume, CTime. Cada uma delas retornava um valor apropriado ao índice solicitado. Assim, a informação sobre o símbolo atual pode ser convenientemente recebida no código do Expert Advisor. Por exemplo, o preço de fechamento da barra atual pode ser obtida usando o seguinte código simples:

...
double close = Close[0];
...


No entanto, o acesso aos preços no formato OHLC não foi suficiente, assim, os métodos adicionais Ask(), Bid(), Last() foram adicionados. No entanto, foram necessários mais métodos, por exemplo, o FreezeLevel() para obter as informações básicas sobre o instrumento atual. O tamanho da classe base CStrategy começou a crescer. A grande quantidade de métodos dentro da CStrategy começou a confundir. As principais dificuldades começaram na tentativa de criar um Expert Advisor negociando vários símbolos. A CStrategy é formalmente uma ferramenta multi-símbolo. Isso significa que ela pode ser usada para criar vários Expert Advisors negociando diferentes símbolos independentemente, ou um Expert Advisor negociando dois ou mais instrumentos financeiros. Mas o último caso foi difícil de implementar, porque exigiu a reconfiguração das classes de série temporal em tempo real, por definir alternadamente os diferentes símbolos utilizados:

string symbol1 = "EURUSD";
string symbol2 = "GBPUSD";
Close.Symbol(symbol1);
double close_eurusd = Close[0];
Close.Symbol(symbol2);
double close_gbpusd = Close[0];
...

Essas dificuldades levaram a uma conclusão de que, devido a uma grande quantidade de informações sobre o símbolo utilizado, a CStrategy diretamente não pode implementá-la. A classe CStrategy executa um trabalho complexo ao organizar uma sequência de ações de negociação, e qualquer funcionalidade adicional pode prejudicar a capacidade de gerenciamento do código. Assim, o método para trabalhar com o símbolo deve ser melhor implementado em uma classe separada - CSymbol.

O primeiro contato com o objeto WS e a classe CSymbol

Agora, em vez de separar os métodos Ask(), Bid() e Last() e as classes adicionais, como CHIGH e CLow, a classe base de estratégia de negociação CStrategy pode acessar o objeto WS criado especialmente com base na classe CSymbol. Esta classe pertence ao conjunto de bibliotecas da CStrategy e inclui uma série de métodos que o tornam semelhante à classe padrão СSymbolInfo. Mas a classe é diferente. Além de trabalhar com as propriedades dos símbolos, ela pode obter as cotações de símbolos, incluindo informações sobre ordens limitadas (Profundidade do Mercado). O nome do objeto WS é uma abreviação de "Working Symbol". O objeto está disponível no código da estratégia. O uso de um nome abreviado é conveniente. Muitas vezes, nós precisamos acessar várias propriedades dos símbolos, enquanto a abreviação de dois caracteres permite manter o código compacto e expressivo. 

Foi mencionado nas partes anteriores do artigo que, antes do controle ser passado para um Expert Advisor, o mecanismo de negociação da CStrategy realiza uma série de inicializações dos objetos do ambiente interno. Ela salva o nome do símbolo de trabalho e o tempo gráfico, e também cria classes que acompanham a chegada de novos eventos (os eventos padrão são um novo tick e uma nova barra). Ele também habilita o registro e define as flags do modo de operação. Além disso, o objeto WS da classe CSymbol é inicializado. Sua estrutura interna é bem simples. Ele contém dois campos internos: o símbolo e seu tempo gráfico, bem como os objetos especiais que permitem o acesso as cotações dos símbolos. O objeto WS é inicializado no método InitSeries. Conhecendo o símbolo de trabalho e o tempo gráfico do Expert Advisor, nós podemos inicializá-lo facilmente:

CStrategy::CStrategy(void)
{
   WS.InitSeries(ExpertSymbol(), Timeframe());
}

Uma vez que o objeto é inicializado, você pode usá-lo para obter a propriedade necessária do símbolo. Por exemplo, para obter a máxima do preço da barra atual, escreva o seguinte:

double max = WS.High[0];

O objeto WS é fornecido com uma série de propriedades adicionais que o tornam uma ferramenta conveniente e autossuficiente para uso direto nos cálculos. Vamos considerar um caso comum: você deseja colocar uma ordem BuyStop acima do preço da máxima da barra anterior. Vamos supor que estamos operando o par EURUSD e que desejemos colocar uma ordem do tipo stop a uma distância de três pontos de cinco dígitos da Máxima da barra anterior. Nós precisamos escrever o seguinte código:

void CMovingAverage::InitBuy(const MarketEvent &event)
{
   ...
   Trade.BuyStop(1.0, WS.High[1] + WS.StepToPrice(3), WS.Name());
   ...
}

Esse código de linha única inclui muitas ações:

  • recebendo o valor extremo da barra anterior (WS.High [1]);
  • multiplicando o valor de um ponto por três para obter a distância necessária de três pontos (WS.StepToPrice(3));
  • somando o resultado da distância do preço à máxima (WS.High [1] + WS.StepToPrice (3));
  • enviando uma ordem BuyStop com o preço de disparo no valor resultante, enquanto que o instrumento negociado é igual ao símbolo atual (WS.Name ()).

O método StepToPrice pode parecer bem diferente do sistema de nomes adotado no MetaTrader. Em outras plataformas de negociação, um passo do preço é a variação mínima do preço. Seu conceito equivalente no MetaTrader é a SYMBOL_TRADE_TICK_SIZE. Este nome pode ser facilmente confundido com o tamanho do tick ou o valor SYMBOL_TRADE_TICK_VALUE, então, a CSymbol usa um nome diferente para este parâmetro. No entanto, a maioria dos outros nomes dos métodos da CSymbol coincidem com os modificadores e métodos do sistema MQL5, embora nem sempre sejam idênticos (por exemplo, StepToPrice). O objetivo principal da CSymbol é fornecer um conjunto simples e intuitivo de métodos para obter informações completas sobre um instrumento de negociação.

A estrutura da classe CSymbol. Uma tabela comparativa dos métodos

Na MetaTrader, um símbolo de negociação é fornecido junto de um grande conjunto de propriedades. Em primeiro lugar, todas as propriedades podem ser divididas condicionalmente em valores do tipo inteiro, real e string. As propriedades do tipo inteiro incluem os valores do tipo bool, modificadores do sistema na forma de enumerações (enum), data e hora (datetime) e propriedades do tipo inteiro (int e long). As propriedades do tipo dos reais incluem vários valores fracionários (double). As propriedades do tipo string de caracteres incluem as propriedades que retornam os valores de string, como o nome do símbolo, a descrição da string, etc. Além disso, um símbolo pode ter propriedades específicas de determinados segmentos do mercado. Por exemplo, as propriedades adicionais da sessão de negociação atual estão disponíveis para os símbolos da FORTS. As opções também possuem propriedades únicas específicas. A classe CSymbol define as propriedades da sessão atual de negociação da FORTS na classe interna adicional da SessionInfo. O resto das propriedades não são separadas com base em seus tipos. Eles estão disponíveis "como estão" na forma de métodos com os nomes apropriados.

Além disso, a classe CSymbol contém as coleções adicionais que permitem o acesso as cotações dos símbolos. Por exemplo, as classes definidas publicamente COpen, CHigh, CLow, CClose, CVolume são usadas ​​para acessar a série OHLCV, enquanto que a profundidade do mercado pode ser acessada usando a classe especial CMarketWatch. A descrição detalhada da CMarketWatch é fornecida no artigo: "MQL5 Cookbook: Implementando seu próprio Depth of Market (Book de Ofertas)". Além dos métodos e classes de indexação com os nomes apropriados, como a CClose, a classe CSymbol contém alguns métodos que não possuem análogos na classe SymbolInfo. Vamos descrevê-los com mais detalhes.

Disponível: o método retorna verdadeiro se existir um símbolo com o nome fornecido no terminal. Se esse símbolo não for encontrado, é retornado false.

IndexByTime: retorna o índice da barra que corresponde ao tempo especificado. Por exemplo, no código a seguir, o valor de 1 é atribuído à variável 'index':

int index = WS.IndexByTime(WS.Time[1]);
// index = 1;

Este método é conveniente usar se conhecemos o horário e queremos obter o índice da barra correspondente a esse horário. Suponha que o EA deve fechar uma posição depois de mantê-la durante BarsHold barras. A seguir está um código que implementa esta função:

//+------------------------------------------------------------------+
//| Gerenciando uma posição comprada de acordo com a Média Móvel     |
//+------------------------------------------------------------------+
void CImpulse::SupportBuy(const MarketEvent &event,CPosition *pos)
{
   int bar_open = WS.IndexByTime(pos.TimeOpen());
   if(bar_open >= BarsHold)
      pos.CloseAtMarket("Exit by time hold");
}

StepToPrice é o valor mínimo da variação do preço expresso em pontos do símbolo. Uma descrição do propósito do método foi fornecida anteriormente.

A lista completa de métodos da CSymbol é fornecida em uma tabela abaixo. O campo Descrição contém uma breve descrição do método. Na maioria dos casos, ele corresponde à descrição oficial de uma propriedade do símbolo semelhante na seção correspondente da documentação. Alguns métodos são fornecidos com uma descrição mais adequada.

O campo Tipo de Retorno exibe o tipo do valor retornado por um método ou coleção.

O campo Função MQL5 ou o Identificador do Sistema contém o nome de um identificador ou função do sistema MQL5 apropriado que é usado para fins semelhantes. Se uma função do sistema for especificada, os parênteses são adicionados no final do seu nome, por exemplo CopyOpen() ou MarketBookGet(). Um modificador do sistema é um dos três modificadores que devem ser especificados ao chamar a função SymbolInfoInteger, SymbolInfoDouble ou SymbolInfoString. O modificador deve pertencer a uma das três enumerações do sistema apropriadas: ENUM_SYMBOL_INFO_INTEGER, ENUM_SYMBOL_INFO_DOUBLE ou ENUM_SYMBOL_INFO_STRING. Por exemplo, se o modificador SYMBOL_TRADE_STOPS_LEVEL for especificado na "Função MQL5 ou Identificador do Sistema", isso significa que você deve chamar a SymbolInfoInteger para obter essa propriedade:

int stop_level = SymbolInfoInteger(Symbol(), SYMBOL_TRADE_STOPS_LEVEL);

A coluna Nome do Método da CSymbol contém o nome do método que retorna a propriedade correspondente. Por exemplo, para obter o dia da semana em que o swap triplo é cobrado, o seguinte método deve ser chamado

ENUM_DAY_OF_WEEK day = WS.DayOfSwap3x();

Aqui está a tabela de métodos:

Descrição Tipo de Retorno Função MQL5 ou Identificador do Sistema Nome do Método da CSymbol
 ACESSO ÀS COTAÇÕES HISTÓRICAS DO SÍMBOLO      
   Obtendo o preço de abertura para o índice de barras especificado, com um tempo gráfico do símbolo predefinido  double  CopyOpen()  Open[]
   Obtendo a máxima do preço para o índice de barras especificado, com um tempo gráfico do símbolo predefinido  double  CopyHigh()  High[]
   Obtendo a mínima do preço para o índice de barras especificado, com um tempo gráfico do símbolo predefinido  double  CopyLow()  Low[]
   Obtendo o preço de fechamento para o índice de barras especificado, com um tempo gráfico do símbolo predefinido  double  CopyClose()  Close[]
   Obtendo o volume da barra com o índice especificado  double  CopyVolume()  Volume[]
   Obtendo as propriedades da Profundidade do Mercado (Book de ofertas) do símbolo - DMA2  MqlBookInfo  MarketBookGet()  MarketBook
 PROPRIEDADES DO TIPO INTEIRO DO SÍMBOLO      
   Uma indicação de que o símbolo existe no terminal  bool  Sem análogos  Available
   O número de barras para este símbolo e período de tempo  int  Bars()   BarsTotal
   O tempo gráfico do símbolo  ENUM_TIMEFRAMES  Period()  Period
   Uma indicação de que o símbolo está selecionado no Market Watch  bool  SYMBOL_SELECT  SelectInMarketWatch
   Uma indicação do spread flutuante  bool  SYMBOL_SPREAD_FLOAT  SpreadFloat
   Valor do spread em pontos  int  SYMBOL_SPREAD  Spread
   Distância mínima em pontos do preço de fechamento atual para a definição de ordens do tipo Stop  int  SYMBOL_TRADE_STOPS_LEVEL  StopLevel
   Distância de congelamento das operações de negociação (em pontos)  int  SYMBOL_TRADE_FREEZE_LEVEL  FreezeLevel
   Flags de modos de expiração de ordem permitidos  int  SYMBOL_EXPIRATION_MODE  FlagsExpirationOrders
   Flags dos modos de execução das ordens permitidas  int  SYMBOL_FILLING_MODE  FlagsExecutionOrders
   Flags dos tipos de ordens permitidos  int  SYMBOL_ORDER_MODE  FlagsAllowedOrders
   Retorna o índice da barra cujo tempo aberto corresponde ao argumento passado  int  Sem análogos  IndexByTime
   Modo de cálculo do preço do contrato  ENUM_SYMBOL_CALC_MODE  SYMBOL_TRADE_CALC_MODE  CalcContractType
   Tipo de execução da ordem  ENUM_SYMBOL_TRADE_MODE  SYMBOL_TRADE_MODE  ExecuteOrderType
   Modo de execução da negociação  ENUM_SYMBOL_TRADE_EXECUTION  SYMBOL_TRADE_EXEMODE  ExecuteDealsType
   Modelo de cálculo do Swap  ENUM_SYMBOL_SWAP_MODE  SYMBOL_SWAP_MODE  CalcSwapMode
   Dia em que é cobrado o Swap de três dias
 ENUM_DAY_OF_WEEK  SYMBOL_SWAP_ROLLOVER3DAYS  DayOfSwap3x
   Tipo da Opção  ENUM_SYMBOL_OPTION_MODE  SYMBOL_OPTION_MODE  OptionType
   Direito da Opção (Call/Put)  ENUM_SYMBOL_OPTION_RIGHT  SYMBOL_OPTION_RIGHT  OptionRight
   Hora da última cotação  datetime  SYMBOL_TIME  TimeOfLastQuote
   Data de início da negociação do símbolo (geralmente usado para futuros)  datetime  SYMBOL_START_TIME  StartDate
   Data de término da negociação do símbolo (normalmente usada para futuros)  datetime  SYMBOL_EXPIRATION_TIME  ExpirationDate
PROPRIEDADES DA SESSÃO DE NEGOCIAÇÃO ATUAL DOS SÍMBOLOS DE FUTUROS DA MOEX

 
   O número de negócios na sessão atual  long  SYMBOL_SESSION_DEALS  SymbolInfo.DealsTotal
   O número total de ordens de compra no momento  long  SYMBOL_SESSION_BUY_ORDERS  SymbolInfo.BuyOrdersTotal
   O número total de ordens de venda no momento  long  SYMBOL_SESSION_SELL_ORDERS  SymbolInfo.SellOrdersTotal
   O maior volume durante a sessão de negociação atual  long  SYMBOL_VOLUMEHIGH  SymbolInfo.HighVolume
   O menor volume durante a sessão de negociação atual  long  SYMBOL_VOLUMELOW  SymbolInfo.LowVolume
   O preço da maior oferta de compra do dia  double  SYMBOL_BIDHIGH  SymbolInfo.BidHigh
   O da maior oferta de venda do dia  double  SYMBOL_ASKHIGH  SymbolInfo.AskHigh
   O menor preço da oferta de compra do dia  double  SYMBOL_BIDLOW  SymbolInfo.BidLow
   O menor preço da oferta de venda do dia  double  SYMBOL_ASKLOW  SymbolInfo.AskLow
   O maior último preço do dia  double  SYMBOL_LASTHIGH  SymbolInfo.LastHigh
   O menor último preço do dia  double  SYMBOL_LASTLOW  SymbolInfo.LastLow
   O volume total de negócios na sessão atual  double  SYMBOL_SESSION_VOLUME  SymbolInfo.VolumeTotal
   O volume de negócios total na sessão atual  double  SYMBOL_SESSION_TURNOVER  SymbolInfo.TurnoverTotal
   O volume total de posições abertas  double  SYMBOL_SESSION_INTEREST  SymbolInfo.OpenInterestTotal
   O volume total de ordens de compra no momento  double  SYMBOL_SESSION_BUY_ORDERS_VOLUME  SymbolInfo.BuyOrdersVolume
   O volume total de ordens de venda no momento  double  SYMBOL_SESSION_SELL_ORDERS_VOLUME  SymbolInfo.SellOrdersVolume
   O preço de abertura da sessão  double  SYMBOL_SESSION_OPEN  SymbolInfo.PriceSessionOpen
   O preço de fechamento da sessão  double  SYMBOL_SESSION_CLOSE  SymbolInfo.PriceSessionClose
   O preço médio ponderado da sessão  double  SYMBOL_SESSION_AW  SymbolInfo.PriceSessionAverage
   O preço de liquidação da sessão atual  double  SYMBOL_SESSION_PRICE_SETTLEMENT  SymbolInfo.PriceSettlement
   O valor máximo de preço permitido para a sessão  double  SYMBOL_SESSION_PRICE_LIMIT_MAX  SymbolInfo.PriceLimitMax
   O valor mínimo de preço permitido para a sessão  double  SYMBOL_SESSION_PRICE_LIMIT_MIN  SymbolInfo.PriceLimitMin
PROPRIEDADES DO SÍMBOLO DO TIPO REAL       
   Ask, o melhor preço no qual um instrumento pode ser comprado (oferta de compra)  double  SYMBOL_ASK  Ask
   Bid, o melhor preço no qual um instrumento pode ser vendido (oferta de venda)  double  SYMBOL_BID  Bid
   O preço no qual a última operação foi executada  double  SYMBOL_LAST  Last
   O valor mínimo da variação de preço multiplicado pelo número passado de passos do preço  double  Sem análogos  StepToPrice
   O valor de um ponto (tick)  double  SYMBOL_POINT  PriceStep
   O valor de um ponto (tick) expresso na moeda de depósito  double  SYMBOL_TRADE_TICK_VALUE  TickValue
   Preço de execução da Opção  double  SYMBOL_OPTION_STRIKE  OptionStrike
   Tamanho do contrato de negociação  double  SYMBOL_TRADE_CONTRACT_SIZE  ContractSize
   Volume mínimo para a execução do negócio  double  SYMBOL_VOLUME_MIN  VolumeContractMin
   Volume máximo para a execução do negócio  double  SYMBOL_VOLUME_MAX  VolumeContractMax
   O passo da variação mínima do volume para a execução do contrato  double  SYMBOL_VOLUME_STEP  VolumeContractStep
   O volume total máximo permitido de uma posição aberta e das ordens pendentes em uma direção (quer seja compra ou venda) para este símbolo.  double  SYMBOL_VOLUME_LIMIT  VolumeContractLimit
   O valor de swap cobrado por manter uma posição comprada com o volume de um contrato  double  SYMBOL_SWAP_LONG  SwapLong
   O valor de swap cobrado por manter uma posição vendida com o volume de um contrato  double  SYMBOL_SWAP_SHORT  SwapShort
   A margem necessária para abrir uma posição de um lote  double  SYMBOL_MARGIN_INITIAL  MarginInit
   A margem necessária para manter um lote de uma posição aberta  double  SYMBOL_MARGIN_MAINTENANCE  MarginMaintenance
   A margem necessária para manter um lote de uma posição de hedge  double  SYMBOL_MARGIN_HEDGED  MarginHedged
 PROPRIEDADES DO SÍMBOLO DO TIPO STRING      
   Nome do símbolo  string  Symbol()  Nome
   O nome do ativo subjacente para um derivativo do símbolo  string  SYMBOL_BASIS  NameBasisSymbol
   A moeda base de um instrumento  string  SYMBOL_CURRENCY_BASE  NameBasisCurrency
   Lucro da moeda  string  SYMBOL_CURRENCY_PROFIT  NameCurrencyProfit
   Margem da moeda  string  SYMBOL_CURRENCY_MARGIN  NameCurrencyMargin
   A fonte da cotação atual  string  SYMBOL_BANK  NameBank
   A descrição do texto de um símbolo  string  SYMBOL_DESCRIPTION  Descrição
   O nome de um símbolo de negociação no sistema internacional de números de identificação de títulos (ISIN)  string  SYMBOL_ISIN  NameISIN
   Caminho na árvore de símbolos  string  SYMBOL_PATH  SymbolPath

Usando vários símbolos ao mesmo tempo

A CSymbol é uma classe regular, portanto, você pode criar um número ilimitado de objetos desta classe dentro do seu EA. WS é apenas um desses objetos criados pelo módulo da CStrategy, e indica o símbolo de trabalho e o tempo gráfico do Expert Advisor. O EA também pode criar um objeto adicional que fornece acesso a qualquer outro símbolo. Suponha que nosso EA negocia no Mercado de Derivativos da Moscow Exchange e simultaneamente monitora dois símbolos, Si e Brent. Nós podemos usar dois objetos da CSymbol no código do EA. Vamos chamá-los de Si e Brent:

//+------------------------------------------------------------------+
//|                                                EventListener.mqh |
//|           Copyright 2017, Vasiliy Sokolov, St-Petersburg, Russia |
//|                                https://www.mql5.com/en/users/c-4 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, Vasiliy Sokolov."
#property link      "https://www.mql5.com/en/users/c-4"
#include <Strategy\Strategy.mqh>

//+-------------------------------------------------------------------------+
//| O modelo de uma estratégia trabalhando com dois símbolos ao mesmo tempo |
//+-------------------------------------------------------------------------+
class CIntRate : public CStrategy
  {
   CSymbol           Si;         // Rublo-Dólar
   CSymbol           Brent;      // Petróleo Brent
public:
   virtual void      OnEvent(const MarketEvent& event);
   virtual bool      OnInit();
  };
//+------------------------------------------------------------------+
//| Inicializa os símbolos do rublo e do petróleo                    |
//+------------------------------------------------------------------+
bool CIntRate::OnInit(void)
  {
   Si.InitSeries("Si Splice", Timeframe());
   Brent.InitSeries("BR Splice", Timeframe());
   return true;
  }

//+------------------------------------------------------------------+
//| O preço do Brent expresso em rublos                              |
//+------------------------------------------------------------------+
void CIntRate::OnEvent(const MarketEvent &event)
  {
   double brent_in_rub = Brent.Last()*Si.Last()/Si.ContractSize();
  }

//+------------------------------------------------------------------+


O código do Expert Advisor recebe os últimos preços dos futuros do Brent e do rublo e, em seguida, calcula a fórmula do preço Brent expressa em rublos. Um contrato de futuros de Si é igual a $1000, então nós precisamos dividir o resultado pelo tamanho de um contrato. É uma operação bastante simples, porque todas as propriedades de símbolos estão disponíveis em uma única classe. O resto do código também é simples e expressivo. O principal não é esquecer de inicializar os objetos Si e Brent no método OnInit no lançamento do EA.

Criando um perfil de taxa de juros usando a CSymbol

O último exemplo de uso da CSymbol que nós vamos considerar é um pouco mais complicado e também é mais interessante. Os contratos de futuros são conhecidos por serem negociados com algum contango em relação ao ativo subjacente. Isso significa que o preço futuro de uma commodity é maior do que o preço à vista. Essa diferença determina a taxa de juros do mercado em uma commodity ou um bem em particular. Consideremos um exemplo com os futuros do rublo/dólar. Seu preço à vista no momento da escrita deste artigo é de 56.2875 rublos por 1 dólar, e o preço do contrato de futuros Si-6.17 mais próximo é de 56.682 rublos por $1000 ou 56.682 rublos por 1 dólar. Portanto, a diferença entre o preço à vista e o preço futuro após 30 dias (em 16.05.2017, a expiração de Si-6.17 é de 30 dias) é de 0.395 rublos ou 39.5 kopeks. Ou seja, o mercado espera que o rublo se deprecie por 39.5 kopeks, ou seja, 0.7% do seu preço à vista. Nós podemos calcular facilmente que a inflação de 12 meses esperada pelo mercado é de 8.42%. Mas este é o nível de inflação calculado para os futuros mais próximos. Se nós usarmos o Si-9.17 em vez do Si-6.17, a inflação será menor, cerca de 7.8% ao ano. Ao comparar todos os futuros do Si com o preço do ativo subjacente, nós podemos obter o perfil de juro. Este perfil será exibido como uma tabela que mostra as expectativas dos investidores, dependendo do tempo. Por exemplo, nós conheceremos a taxa de juros para os próximos 30, 100, 200, 300, 400 e 500 dias.

Nós precisamos usar ativamente várias propriedades dos símbolos e a lista de símbolos para calcular todos esses valores. Como o perfil de juro é calculado:

  1. O Expert Advisor é carregado em qualquer símbolo de futuro. Ele analisa o nome do símbolo e carrega todos os futuros relacionados.
  2. Cada símbolo de futuros carregados representa um objeto da CSymbol que é colocado na lista de símbolos.
  3. Quando um novo tick é recebido, o EA trabalha com a coleção de símbolos. Ele encontra um ativo subjacente para cada símbolo.
  4. Em seguida, o EA calcula a diferença entre o preço do símbolo selecionado e o preço do seu ativo subjacente. Essa diferença é convertida em um juro, que é convertido em um juro anual. Para este fim, a vida útil restante do contrato de futuros é levada em consideração.
  5. A diferença resultante é exibida no painel como uma linha da tabela. Cada linha é exibida como "Nome do Futuros — Dias antes do vencimento — Taxa de juros".

Como pode ser visto a partir da descrição, o algoritmo na verdade não é tão simples como parece. No entanto, o módulo da CStrategy e o objeto CSymbol ajudam a reduzir significativamente a complexidade de cálculo para o EA. O código abaixo é implementado sob a forma de um EA, embora o EA não realize qualquer ação de negociação. Em vez disso, ele exibirá os valores de juro no painel. Aqui está o código resultante:

//+------------------------------------------------------------------+
//|                                                EventListener.mqh |
//|           Copyright 2017, Vasiliy Sokolov, St-Petersburg, Russia |
//|                                https://www.mql5.com/en/users/c-4 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, Vasiliy Sokolov."
#property link      "https://www.mql5.com/en/users/c-4"
#include <Strategy\Strategy.mqh>
#include <Arrays\ArrayObj.mqh>
#include "Panel.mqh"

//+------------------------------------------------------------------+
//| Perfil da taxa de juros                                          |
//+------------------------------------------------------------------+
class CIntRate : public CStrategy
  {
   CArrayObj         Symbols;    // The list of symbols
   CPercentPanel     Panel;      // Painel para exibir a taxa de juros
   double            BaseRate(CSymbol* fut);
public:
   virtual void      OnEvent(const MarketEvent& event);
   virtual bool      OnInit();
  };
//+-------------------------------------------------------------------------+
//| Adiciona os futuros necessários para calcular o perfil da taxa de juros |
//+-------------------------------------------------------------------------+
bool CIntRate::OnInit(void)
  {
   string basis = WS.NameBasisSymbol();
   for(int i = 0; i < SymbolsTotal(false); i++)
   {
      string name = SymbolName(i, false);
      int index = StringFind(name, basis, 0);
      if(index != 0)
         continue;
      CSymbol* Fut = new CSymbol(name, Timeframe());
      if(Fut.ExpirationDate() == 0 || Fut.ExpirationDate() < TimeCurrent())
      {
         delete Fut;
         continue;
      }
      string text = "Add new symbol " + Fut.Name() + " in symbols list";
      CMessage* msg = new CMessage(MESSAGE_INFO, __FUNCTION__, text);
      Log.AddMessage(msg);
      Symbols.Add(Fut);
   }
   string text = "Total add symbols " + (string)Symbols.Total();
   CMessage* msg = new CMessage(MESSAGE_INFO, __FUNCTION__, text);
   Log.AddMessage(msg);
   if(Symbols.Total() > 0)
   {
      Panel.Show();
   }
   return true;
  }

//+------------------------------------------------------------------+
//| Calcula o perfil e o exibe em uma tabela                         |
//+------------------------------------------------------------------+
void CIntRate::OnEvent(const MarketEvent &event)
  {
   double sec_one_day = 60*60*24;   //86 400
   for(int i = 0; i < Symbols.Total(); i++)
   {
      CSymbol* Fut = Symbols.At(i);
      double brate = BaseRate(Fut);
      double days = (Fut.ExpirationDate()-TimeCurrent())/sec_one_day;
      if(Fut.Last() == 0.0)
         continue;
      double per = (Fut.Last() - brate)/brate*100.0;
      double per_in_year = per/days*365;
      Panel.SetLine(i, Fut.NameBasisSymbol() + " " + DoubleToString(days, 0) + " Days:", DoubleToString(per_in_year, 2)+"%");
   }

  }
//+------------------------------------------------------------------+
//| Retorna a cotação a vista dos futuros                            |
//+------------------------------------------------------------------+
double CIntRate::BaseRate(CSymbol* fut)
{
   string name = fut.NameBasisSymbol();
   if(StringFind(name, "Si", 0) == 0)
      return SymbolInfoDouble("USDRUB_TOD", SYMBOL_LAST)*fut.ContractSize();
   return SymbolInfoDouble(name, SYMBOL_LAST)*fut.ContractSize();
}
//+------------------------------------------------------------------+


A funcionalidade básica é implementada no método da OnInit. Este método recebe o nome do ativo subjacente utilizando WS.NameBasisSymbol() e verifica todos os símbolos para encontrar todos os futuros correspondentes a este ativo subjacente. Cada um desses símbolos de futuros é convertido em um objeto CSymbol e é adicionado à lista de símbolos da CArrayObj. Antes disso, ele verifica se o contrato de futuros é válido. O tempo de expiração de um contrato de futuros apropriado deve ser no futuro.

A taxa de juros de cada futuro da coleção Symbols é calculada no método da OnEvent. O número de dias antes do vencimento e o delta entre os futuros e o preço à vista são calculados. A diferença de preço é convertida em uma porcentagem, que é então normalizada de acordo com o retorno anual. O valor resultante é escrito na tabela do Painel (usando o método SetLine).

A tabela em si é simples e baseia-se em um conjunto de classes gráficas semelhantes ao painel da CStrategy que aparece com o Expert Advisor. O código do componente gráfico do EA está abaixo:

//+------------------------------------------------------------------+
//|                                                        Panel.mqh |
//|                                 Copyright 2017, Vasiliy Sokolov. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, Vasiliy Sokolov."
#property link      "https://www.mql5.com"
#include <Panel\ElChart.mqh>

class CPercentPanel : public CElChart
{
private:
   CArrayObj  m_fields;
   CArrayObj  m_values;
public:
   
   CPercentPanel(void);
   void SetLine(int index, string field, string value);
};
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CPercentPanel::CPercentPanel(void) : CElChart(OBJ_RECTANGLE_LABEL)
{
   Width(200);
   Height(200);
}
//+------------------------------------------------------------------+
//| Define a linha                                                   |
//+------------------------------------------------------------------+
void CPercentPanel::SetLine(int index,string field,string value)
{
   if(m_fields.Total() <= index)
   {
      CElChart* sfield = new CElChart(OBJ_LABEL);
      sfield.XCoord(XCoord()+10);
      sfield.YCoord(YCoord()+21*index+10);
      sfield.Text(field);
      m_fields.Add(sfield);
      m_elements.Add(sfield);
      
      CElChart* svalue = new CElChart(OBJ_LABEL);
      svalue.YCoord(YCoord()+21*index+10);
      svalue.XCoord(XCoord()+132);
      svalue.Text(value);
      svalue.TextColor(clrGreen);
      m_values.Add(svalue);
      m_elements.Add(svalue);
      if(IsShowed())
      {
         sfield.Show();
         svalue.Show();
      }
      Height(m_fields.Total()*20 + m_fields.Total()*2 + 10);
   }
   else
   {
      CElChart* el = m_fields.At(index);
      el.Text(field);
      el = m_values.At(index);
      el.Text(value);
   }
   ChartRedraw();
}

Uma vez que o Expert Advisor é compilado e lançado ao gráfico de um dos contratos de futuros da Si, a seguinte tabela deve aparecer:

O perfil de juro do Rublo/Dólar em uma tabela

Como pode ser visto a partir da tabela, as taxas de juros em praticamente todas as seções de tempo são iguais e equivalem a pouco mais de 7% ao ano. O contrato de futuros mais próximo mostra uma taxa ligeiramente maior. 

Nota importante: antes de iniciar o Expert Advisor em um gráfico, verifique se as cotações de todos os contratos de futuros necessários estão disponíveis e foram pré-carregadas. Caso contrário, o resultado pode ser indefinido.

Conclusão

Nós revisamos a nova classe CSymbol incluída no motor de negociação da CStrategy. Esta classe simplifica o trabalho com os instrumentos de negociação, fornecendo acesso a várias propriedades dos símbolos. A CSymbol nos ajudou a criar um indicador bastante interessante e não trivial do perfil de taxa de juros. Este foi um exemplo muito demonstrativo. Muitas propriedades dos símbolos foram facilmente obtidas a partir dos objetos da CSymbol, e o cálculo não foi muito complicado. O Expert Advisor trabalhou simultaneamente com seis símbolos financeiros, enquanto que isso não afetou o comprimento do código. A CStrategy é herdada da CObject e as instâncias podem ser facilmente adicionadas às coleções padrão para tornar o processamento de dados escalável e versátil. Além disso, as funcionalidades específicas foram transferidas da CStrategy para a CSymbol, o que tornou a CStrategy mais leve e gerenciável.


Traduzido do russo por MetaQuotes Software Corp.
Artigo original: https://www.mql5.com/ru/articles/3270

Arquivos anexados |
Teste de padrões que surgem ao negociar cestas de pares de moedas. Parte I Teste de padrões que surgem ao negociar cestas de pares de moedas. Parte I

Nós começamos a testar os padrões e tentamos os métodos descritos nos artigos sobre a negociação de cestas de pares de moedas. Veja como os padrões de rompimento dos níveis de sobrevenda/sobrecompra são aplicados na prática.

Expert Advisor Multiplataforma: Filtros de Tempo Expert Advisor Multiplataforma: Filtros de Tempo

Este artigo discute a implementação de vários métodos de filtragem de tempo de um Expert Advisor multiplataforma. As classes de filtro de tempo são responsáveis ​​por verificar se um determinado momento corresponde a uma determinada configuração de tempo definida.

Padrão de bandeira Padrão de bandeira

No artigo, são examinados os padrões de Bandeira, Flâmula, Cunha, Retângulo, Triângulo contrativo, Triângulo expansivo. São analisadas suas similaridades e diferenças, são criados tanto indicadores para pesquisá-los no gráfico quanto um indicador-testador para avaliar sua eficácia.

Classificador Bayesiano Ingênuo para sinais de um conjunto de indicadores Classificador Bayesiano Ingênuo para sinais de um conjunto de indicadores

O artigo analisa a aplicação da fórmula de Bayes para melhorar a fiabilidade dos sistemas de negociação através do uso dos sinais de vários indicadores independentes. Os cálculos teóricos são verificados com um EA universal simples, personalizado para trabalhar com indicadores exploratórios ou customizados.