Expert Advisor Universal: Acessando as Propriedades do Símbolo (Parte 8)
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:
- O Expert Advisor é carregado em qualquer símbolo de futuro. Ele analisa o nome do símbolo e carrega todos os futuros relacionados.
- Cada símbolo de futuros carregados representa um objeto da CSymbol que é colocado na lista de símbolos.
- Quando um novo tick é recebido, o EA trabalha com a coleção de símbolos. Ele encontra um ativo subjacente para cada símbolo.
- 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.
- 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 pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/3270
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso