English Русский 中文 Español Deutsch 日本語
Os projetos permitem que criar robôs de negociação lucrativos!  Mas não é exatamente isso

Os projetos permitem que criar robôs de negociação lucrativos! Mas não é exatamente isso

MetaTrader 5Negociação | 12 junho 2020, 12:47
4 415 0
MetaQuotes
MetaQuotes

A criação de um robô de negociação sempre começa com um arquivo pequeno que, por sua vez, gradualmente se torna maior, sendo preenchido com conjuntos de funções e objetos. A maioria dos desenvolvedores de robôs lida com esse problema por meio de arquivos de inclusão (MQH). Mas, o melhor é começar imediatamente a escrever os programas de negociação em projetos, pois isso é benéfico em todos os aspectos.


Vantagens de trabalhar usando projetos

O projeto é um arquivo separado com a extensão "MQPROJ", que armazena as configurações do programa, parâmetros de compilação e informações sobre todos os arquivos usados. Para trabalhar facilmente com o projeto, existe uma guia separada no Navegador. Ela mostra todos os arquivos usados por categorias: incluídos, de recurso, de cabeçalhos, etc.

Exemplo de projeto

Assim, um projeto, em vez de ser apenas um conjunto de arquivos e pastas num diretório separado, também é um recurso que permite dividir um programa complexo numa estrutura bem pensada, na qual são visíveis as relações e todos os dados estão à mão, a saber:

  • arquivos set com parâmetros de entrada para teste e otimização,
  • códigos fonte de programas Opencl,
  • arquivos de mídia com imagens e sons,
  • recursos, etc.

Por isso, ao trabalhar num projeto, você sempre sabe onde está localizada qualquer parte do seu programa e pode navegar rapidamente por todos os arquivos usados. Além disso, os projetos permitem o desenvolvimento colaborativo com ajuda do repositório embutido MQL5 Storage.


Criando um projeto

Cada novo projeto é criado como um programa MQL5 comum com ajuda do Assistente MQL5. Clique em "Novo projeto" e siga todas as etapas como de costume: defina o nome do programa, adicione parâmetros de entrada, especifique os manipuladores de eventos usados. Após o Assistente MQL5 concluir o trabalho, será aberto um arquivo MQPROJ para gerenciar as propriedades do projeto.

Propriedades do projeto>


Aqui você pode especificar a versão, definir uma descrição do programa, adicionar um ícone e também gerenciar opções adicionais:

  1. Maximum optimization — otimização do arquivo EX5 executável para obter o máximo desempenho. Ao desabilitar esta opção, será acelerada a compilação do código fonte, mas o arquivo EX5 resultante poderá funcionar muito mais devagar.
  2. Check floating point dividers — verifica se números reais do tipo double e float são zero nas operações de divisão. Ao desabilitar esta opção, pode aumentar a velocidade do trabalho, sendo que isso deve ser feito conscientemente.
  3. Use tester optimization cache — por padrão a opção está ativada e o testador salva todos os resultados de passagens concluídas no cache de otimização que são usados em recálculos. Se necessário, o cache pode ser desativado com ajuda da propriedade tester_no_cache, mas no projeto isso é feito desmarcando.

Se o arquivo do projeto estiver fechado, ele sempre poderá ser reaberto usando o comando do menu de contexto "Propriedades". Para uma compreensão mais profunda do conteúdo do arquivo MQPROJ, abra-o em formato de texto usando o comando "Abrir". Isso ajudará a entender como os projetos são organizados por dentro.

{
  "platform"    :"mt5",
  "program_type":"expert",
  "copyright"   :"Copyright 2019, MetaQuotes Software Corp.",
  "link"        :"https:\/\/www.mql5.com",
  "version"     :"1.00",
  "description" :"The mean reversion strategy: the price breaks the channel border outwards and reverts back towards the average. The channel is represented by Bollinger Bands. The Expert Advisor enters the market using limit orders, which can only be opened in the trend direction.",
  "icon"        :"Mean Reversion.ico",
  "optimize"    :"1",
  "fpzerocheck" :"1",
  "tester_no_cache":"0",
  "tester_everytick_calculate":"0",

  "files":
  [
    {
      "path":".\\Mean Reversion.mq5",
      "compile":"true",
      "relative_to_project":"true"
    },
    {
      "path":"MQL5\\Include\\Trade\\Trade.mqh",
      "compile":"false",
      "relative_to_project":"false"
    },
....


    Regras de negociação

    Sigamos regras clássicas simples: entremos no mercado quando o preço atingir a banda de Bollinger. Este é um dos tipos de negociação com base no retorno à média.

    Entrada no mercado com base nas bandas de Bollinger

    Entraremos apenas usando ordens pendentes limitadas. Além disso, adicionamos uma regra adicional, negociamos apenas seguindo a direção da tendência. Isso significa que, se a tendência for de alta, definiremos apenas Buy Limit na borda inferior do canal; se for de baixa, definiremos Sell Limit na borda superior.

    A direção da tendência pode ser determinada de várias maneiras, usamos a opção mais simples, isto é, pela posição relativa dos duas médias móveis. Se a média móvel rápida (Fast EMA) for maior que a lenta, teremos uma tendência de alta. Caso contrário, uma de baixa.

    Definição da tendência com ajuda de duas médias móveis

    Essa regra tão simples pode ter a desvantagem de sempre termos uma tendência de alta ou uma de baixa. Além disso, esse sistema mostrará muitas entradas falsas durante um mercado sem tendências fortes. Por isso, adicionamos uma melhoria, isto é, colocaremos ordens pendentes só se a distância entre as bandas de Bollinger for grande o suficiente. O melhor é medir a largura do canal em valores relativos e não, em pontos. Para isso, pegamos o indicador ATR, que mede a volatilidade em pontos.

    • Se a largura do canal for menor que k*ATR, teremos um mercado sem tendências fortes e a colocação de ordens pendentes será proibida.
    • Se a largura do canal for maior que k*ATR, colocaremos uma ordem de limite pendente na borda do canal seguindo a direção da tendência.

    Aqui, k é um certo coeficiente que precisa ser selecionado.

    Cálculo da largura do canal de Bollinger com ajuda do indicador ATR


    Assim, ao criar um projeto, precisamos especificar 8 parâmetros de entrada para determinar os sinais de negociação. O EA sempre negociará com um lote fixo, cujo tamanho será definido pelo parâmetro InpLot. Além disso, existe também um parâmetro não otimizável de serviço InpMagicNumber, para que o EA trabalhe apenas com suas ordens e posições.

    //--- Parâmetros do canal
    input int             InpBBPeriod   =20;           // período do indicador Bollinger
    input double          InpBBDeviation=2.0;          // desviação das bandas de Bollinger em relação à média
    //-- período da EMA para calcular a tendência 
    input int             InpFastEMA    =12;           // período da Fast EMA
    input int             InpSlowEMA    =26;           // período da Slow EMA
    //-- ATR parameters
    input int             InpATRPeriod  =14;           // período do indicador ATR
    input double          InpATRCoeff   =1.0;          // coeficiente do ATR para definir a tendência lateral
    //--- gerenciamento de capital
    input double          InpLot        =0.1;          // volume de negociação em lotes
    //--- parâmetros do período gráfico
    input ENUM_TIMEFRAMES InpBBTF       =PERIOD_M15;   // período gráfico em que são tomados os valores do indicador Bollinger
    input ENUM_TIMEFRAMES InpMATF       =PERIOD_M15;   // período gráfico em que a tendência é determinada
    //--- identificador do EA para transações
    input long            InpMagicNumber=245600;       // Magic Number
    

    Para não selecionar manualmente o período gráfico para determinar a tendência e a largura do canal, foram adicionados os parâmetros de entrada InpBBTF e InpMATF. Isso permite procurar, diretamente durante a otimização, períodos gráficos adequados e evitar operações desnecessárias. Ou seja, podemos iniciar o EA no período gráfico M1, enquanto ele usa o indicador Bollinger Bands em M15 e as médias móveis em M30. Para o indicador ATR, introduzimos um parâmetro de entrada separado para o período gráfico, para não aumentar o número de parâmetros.


    Escrevamos as funções

    Bem, o projeto está criado e está na hora de escrever o EA. Apresentamos apenas três funções fundamentais que descrevem as regras.

    O cálculo da largura do canal Bollinger é simples, basta copiarmos os valores dos buffers do indicador.

    //+------------------------------------------------------------------+
    //| Obtém os valores dos limites do canal                                  |
    //+------------------------------------------------------------------+
    bool ChannelBoundsCalculate(double &up, double &low)
      {
    //--- obtemos os valores do indicador Bollinger Bands 
       double bbup_buffer[];
       double bblow_buffer[];
       if(CopyBuffer(ExtBBHandle, 1, 1, 1, bbup_buffer)==-1)
         {
          PrintFormat("%s: Failed CopyBuffer(ExtBBHandle,0,1,2,bbup_buffer), code=%d", __FILE__, GetLastError());
          return(false);
         }
    
       if((CopyBuffer(ExtBBHandle, 2, 1, 1, bblow_buffer)==-1))
         {
          PrintFormat("%s: Failed CopyBuffer(ExtBBHandle,0,1,2,bblow_buffer), code=%d", __FILE__, GetLastError());
          return(false);
         }
       low=bblow_buffer[0];
       up =bbup_buffer[0];
    //--- com sucesso
       return(true);
      }
    

    Determinar se o mercado não tem tendências fortes também não causa problemas. Primeiro obtemos os valores dos limites do canal, depois calculamos a largura e comparamos com o valor do indicador ATR multiplicado pelo coeficiente InpATRCoeff.

    //+------------------------------------------------------------------+
    //|  Retorna true, se o canal for muito estreito                     |
    //|  (indica um mercado sem tendências fortes)                       |
    //+------------------------------------------------------------------+
    int IsRange()
      {
    //--- obtemos o valor do ATR na última barra concluída
       double atr_buffer[];
       if(CopyBuffer(ExtATRHandle, 0, 1, 1, atr_buffer)==-1)
         {
          PrintFormat("%s: Failed CopyBuffer(ExtATRHandle,0,1,2,atr_buffer), code=%d", __FILE__, GetLastError());
          return(NO_VALUE);
         }
       double atr=atr_buffer[0];
    //--- obtemos as bordas do canal
       if(!ChannelBoundsCalculate(ExtUpChannel, ExtLowChannel))
          return(NO_VALUE);
       ExtChannelRange=ExtUpChannel-ExtLowChannel;
    //--- se a largura do canal for menor que o coeficiente*ATR, teremos uma tendência lateral
       if(ExtChannelRange<InpATRCoeff*atr)
          return(true);
    //--- tendência lateral não detectada
       return(false);
      }
    

    Como o código mostra, em alguns casos, é retornado o valor da macro NO_VALUE, o que nos indica que não foi possível calcular nenhum parâmetro.

    #define NO_VALUE      INT_MAX                      // valor inválido ao calcular o Sinal ou Tendência

    A função para determinar a tendência resultou ser a de maior volume.

    //+------------------------------------------------------------------+
    //| Retorna 1 para UpTrend ou -1 para DownTrend (0 = sem tendência)  |
    //+------------------------------------------------------------------+
    int TrendCalculate()
      {
    //--- primeiro, verificamos se existe uma tendência lateral 
       int is_range=IsRange();
    //--- verifique o resultado
       if(is_range==NO_VALUE)
         {
          //--- se a verificação não for bem-sucedida, saímos com o valor "no value"
          return(NO_VALUE);
         }
    //--- durante a tendência lateral não calculamos a tendência
       if(is_range==true) // intervalo estreito, retornamos "flat"
          return(0);
    //--- obtemos o valor do ATR na última barra concluída
       double atr_buffer[];
       if(CopyBuffer(ExtBBHandle, 0, 1, 1, atr_buffer)==-1)
         {
          PrintFormat("%s: Failed CopyBuffer(ExtATRHandle,0,1,2,atr_buffer), code=%d", __FILE__, GetLastError());
          return(NO_VALUE);
         }
    //--- obtemos o valor Fast EMA na última barra concluída
       double fastma_buffer[];
       if(CopyBuffer(ExtFastMAHandle, 0, 1, 1, fastma_buffer)==-1)
         {
          PrintFormat("%s: Failed CopyBuffer(ExtFastMAHandle,0,1,2,fastma_buffer), code=%d", __FILE__, GetLastError());
          return(NO_VALUE);
         }
    //--- obtemos o valor Slow EMA na última barra concluída
       double slowma_buffer[];
       if(CopyBuffer(ExtSlowMAHandle, 0, 1, 1, slowma_buffer)==-1)
         {
          PrintFormat("%s: Failed CopyBuffer(ExtSlowMAHandle,0,1,2,slowma_buffer), code=%d", __FILE__, GetLastError());
          return(NO_VALUE);
         }
    //--- por padrão, a tendência não está definida
       int trend=0;
    //--- se a EMA rápida for maior que a lenta
       if(fastma_buffer[0]>slowma_buffer[0])
          trend=1;   // tendência de alta (uptrend)
    //--- se a EMA rápida for mendo que a lenta
       if(fastma_buffer[0]<slowma_buffer[0])
          trend=-1;  // tendência de baixa (downtrend)
    //--- retorna a direção da tendência
       return(trend);
      }
    

    A última função do algoritmo de negociação consiste em definir uma nova barra. Ela é escrita de tal maneira que calcula a direção da tendência somente quando aparece uma nova barra.

    //+------------------------------------------------------------------+
    //| Checks the emergence of a new bar on the current timeframe,      |
    //| also calculates the trend and the signal                         |
    //+------------------------------------------------------------------+
    bool IsNewBar(int &trend)
      {
    //--- aqui é constantemente armazenado o tempo de abertura da barra atual entre as chamadas de função
       static datetime timeopen=0;
    //--- obtemos o tempo de abertura da barra atual 
       datetime time=iTime(NULL, InpMATF, 0);
    //--- se o tempo não mudar é porque a barra não é nova, portanto, saímos com o valor false
       if(time==timeopen)
          return(false);
    //--- como a barra é nova, significa que é preciso calcular a direção da tendência
       trend=TrendCalculate();
    //--- se não for possível obter a direção da tendência, sairemos e tentaremos na próxima chamada
       if(trend==NO_VALUE)
          return(false);
    //--- todas as verificações foram bem-sucedidas, uma vez que foram recebidas a barra é nova e a direção da tendência
       timeopen=time; // lembremos o tempo de abertura da barra atual para as próximas chamadas.
    //---
       return(true);
      }
    

    Isso permite que você organize o trabalho do EA de forma que todas as operações de negociação sejam realizadas apenas uma vez durante toda a barra. Por isso, os resultados do teste não dependerão do modo de geração de ticks.

    Todo o algoritmo de negociação é apresentado no manipulador OnTick():

    • Primeiro, são determinadas tanto a aparência da nova barra como a direção da tendência.
    • Se não houver tendência ou for aberta uma posição, será feita uma tentativa de excluir as ordens pendentes com a saída do manipulador.
    • Se houver uma tendência direcionada e não for colocada uma ordem pendente, será feita uma tentativa de colocar uma ordem limite na borda do canal.
    • Se houver uma ordem e ainda não tiver sido modificada na nova barra, será feita uma tentativa de movê-la para a borda atual do canal.
    //+------------------------------------------------------------------+
    //| Expert tick function                                             |
    //+------------------------------------------------------------------+
    void OnTick()
      {
       static bool order_sent    =false;    // não foi possível definir uma ordem limite na barra atual
       static bool order_deleted =false;    // falha ao excluir a ordem limite na barra atual
       static bool order_modified=false;    // falha ao modificar a ordem limite na barra atual
    //--- se os parâmetros de entrada forem inválidos, paramos de testar no primeiro tick
       if(!ExtInputsValidated)
          TesterStop();
    //--- verificamos o surgimento de uma nova barra e a direção da tendência
       if(IsNewBar(ExtTrend))
         {
          //--- redefinimos os valores das variáveis estáticas para seu estado original
          order_sent    =false;
          order_deleted =false;
          order_modified=false;
         }
    //--- criamos variáveis auxiliares para que as verificações sejam chamadas apenas uma vez na barra atual
       bool order_exist   =OrderExist();
       bool trend_detected=TrendDetected(ExtTrend);
    //--- se não houver tendência ou houver uma posição aberta, excluímos ordens pendentes
       if(!trend_detected || PositionExist())
          if(!order_deleted)
            {
             order_deleted=DeleteLimitOrders();
             //--- se as ordens foram excluídas com sucesso, não será necessária nenhuma outra operação na barra atual
             if(order_deleted)
               {
                //--- restringimos a instalação e modificação de ordens
                order_sent    =true;
                order_modified=true;
                return;
               }
            }
    
    //--- existe uma tendência
       if(trend_detected)
         {
          //--- definimos a ordem na borda do canal, se ainda não estiver
          if(!order_exist && !order_sent)
            {
             order_sent=SendLimitOrder(ExtTrend);
             if(order_sent)
                order_modified=true;
            }
          //--- tentamos mover a ordem para a borda do canal, se ainda não tiver sido feita na barra atual
          if(order_exist && !order_modified)
             order_modified=ModifyLimitOrder(ExtTrend);
         }
    //---
      }
    

    As outras funções de negociação do EA são bastante padrão e não serão descritas. Os códigos fonte do projeto estão incluídos no terminal MetaTrader 5 e estão localizados no diretório MQL5\Experts\Examples.

    Localização do projeto MeanReversion no Navegador


    Otimizando parâmetros e adicionando arquivos set

    Depois de escrever o EA, precisamos encontrar os valores ideais para os parâmetros de entrada no testador de estratégia. Poucas pessoas sabem que o testador facilita a cópia dos valores das guias Configurações e Parâmetros na área de transferência com ajuda da combinação padrão Ctr+C. Isso permite que você transfira rapidamente suas configurações para outra pessoa, por exemplo, para um cliente via bate-papo Freelance, sem precisar salvá-las num arquivo set. O cliente pode copiar esses dados para a área de transferência e colá-los no testador na guia Configurações com ajuda da operação reversa Ctr+V.

    Certamente, o salvamento das configurações no arquivo set ainda continua a funcionar, e muitos Vendedores no Mercado acompanham seus EAs por meio desses arquivos para facilitar a vida dos clientes, que podem fazer o download imediato do conjuntos de parâmetros correto para teste e otimização com base no instrumento necessário. Para cada instrumento, é necessário criar um arquivo set separado; se houver muitos EAs e esses arquivos, será possível iniciá-lo facilmente. Os projetos permitem que os compradores de seus robôs trabalhem apenas com seus conjuntos de parâmetros de entrada e não os procurem no disco ao mudar de símbolo.

    Vamos mostrar um exemplo de como os projetos permitem adicionar os conjuntos de parâmetros necessários diretamente ao arquivo EX5 do EA. Selecione o instrumento em que será realizada a otimização, por exemplo, EURUSD. Defina os valores Start, Step e Stop para os parâmetros a serem otimizados e inicie a otimização. No final, na guia Otimização, clique duas vezes na passagem que você achar melhor: os valores dos parâmetros de entrada da passagem em questão serão colocados na guia Parâmetros e será iniciado um teste único. Agora você pode salvar os parâmetros encontrados num arquivo set, sendo que não será mais necessário transferi-lo separadamente. Salve o conjunto de parâmetros com o nome EURUSD.set, o que significa que os parâmetros estão projetados especificamente para este símbolo, e não para GBPJPY.

    Salvando configurações de parâmetros de entrada num arquivo set

    Execute esta operação para cada símbolo no qual seu EA possa trabalhar. Assim, você pode ter um conjunto de 9 arquivos set. Agora basta adicionar esses arquivos ao seu projeto, para isso, crie a pasta "Settings and files\Set", para que eles sejam armazenados separadamente dos códigos fonte iniciais. Os projetos permitem manter a ordem com ajuda da estrutura de arquivo correta.

    Adicionando arquivos set ao projeto


    Agora compile o projeto e abra o testador de estratégia com o EA MeanReversion. Na guia Parâmetros do menu de contexto, será exibido o item "Carregar desde Expert Advisor", onde serão oferecidas todas as variações do seu conjunto de arquivos set.

    Carregando parâmetros de entrada desde o Expert Advisor

    Assim, o arquivo compilado do Expert Advisor EX5 acaba sendo um produto completo, uma vez que ele possui conjuntos de parâmetros prontos para começar a verificar estratégias sem pensar nos limites nem na etapa de alteração de cada símbolo necessários. Usuários e compradores de seus EAs apreciarão tal nível de conveniência.


    Verificando estratégias com base em dados reais

    Em setembro de 2019, o EA MeanReversion foi iniciado numa conta demo para verificar erros de software e negociação em tempo real. Além disso, o EA arrancou no modo de portfólio com negociação usando vários símbolos, conforme planejado durante a otimização. Foi alugado um VPS embutida e foi criado o sinal privado Many MeanReversion Optimized para monitoramento on-line. 

    Resultados de negociação de 9 meses

    Somente no primeiro mês, após a inicialização do EA, ele mostrou resultados positivos; depois, durante 5 meses consecutivos, houve perdas. Como na hospedagem virtual esteve ativada a renovação automática do aluguel, o EA inciado, sem avisar ninguém, consistentemente perdeu a totalidade do depósito. Porém, em março, houve algumas mudanças no mercado de moedas e o EA de repente mostrou um lucro recorde. Nos próximos 2 meses, os resultados foram contraditórios, talvez não veremos mais tal crescimento.

    A análise de transações e resultados por símbolos mostra que os pares de 3 ienes e AUDUSD não são rentáveis. O EA não mostrou resultados impressionantes, mas, mesmo com essa lógica de negociação simples, ele conseguiu aguentar 9 meses, graças ao trabalho no modo de portfólio (as perdas em alguns instrumentos são compensadas pelo lucro em outros).

    Distribuição por símbolos

    Vale ressaltar que, desde que o EA foi iniciado para negociação, seus parâmetros de entrada nunca mudaram e nem foi feita nenhuma migração. Ou seja, o EA compilado há 9 meses foi enviado para negociação em 8 gráficos no VPS embutido e vem trabalhando desde então sem intervenção. Agora, podemos recordar porquê de 9 conjuntos sets apenas 8 foram usados para trabalhar, e podemos nos lembrar de como e quais parâmetros foram usados. No entanto, o projeto do EA MeanReversion criado para fins educacionais ainda permanece ativo mostrando lucro em 10 de junho de 2020.


    Comece a usar projetos, é rentálvel!

    Os projetos permitem criar programas de qualquer nível de complexidade e realizar desenvolvimentos conjuntos. O trabalho em equipe com pessoas afins acelera o desenvolvimento de aplicativos, permite trocar ideias e habilidades úteis, bem como melhorar a qualidade do código.

    As regras de negociação deste EA são muito simples, mas podem ser usadas como modelo para a criação de muitos outros robôs de negociação. Você só precisa alterar as funções que determinam a direção da tendência, o estado da tendência lateral, os níveis e os métodos de entrada, por exemplo, em vez de ordens limitadas, use ordens a mercado. Talvez seja mais bem-sucedido negociar apenas durante uma tendência lateral, pois não há função de trailing-stop, não há configuração separada para gerenciar os níveis StopLoss e TakeProfit. Em geral, há uma enorme margem para pesquisa.

    Com ajuda do Expert Advisor MeanReversion que vem com o MetaTrader 5, você pode estudar e avaliar todas as vantagens de trabalhar com projetos. Basta criar ou copiá-lo para uma nova pasta e começar a experimentar. Use projetos, pois é conveniente e lucrativo de muitas maneiras!

    Traduzido do russo pela MetaQuotes Ltd.
    Artigo original: https://www.mql5.com/ru/articles/7863

    Otimização Walk Forward Contínua (Parte 4): Gerenciamento de Otimização (Otimizador Automático) Otimização Walk Forward Contínua (Parte 4): Gerenciamento de Otimização (Otimizador Automático)
    O principal objetivo do artigo é descrever o mecanismo de trabalho com nosso aplicativo e seus recursos. Assim, o artigo pode ser tratado como instruções sobre como utilizar o aplicativo. Ele cobre todas as possíveis dificuldades e detalhes do uso do aplicativo.
    Previsão de séries temporais (parte 2): método de vetores de suporte por mínimos quadrados (LS-SVM) Previsão de séries temporais (parte 2): método de vetores de suporte por mínimos quadrados (LS-SVM)
    O artigo estuda a teoria e a aplicação prática de um algoritmo de previsão de séries temporais com base no método de vetores de suporte, além disso, propõe sua implementação em MQL5 e fornece indicadores de teste e EAs. Embora este abordagem ainda não tenha sido implementada em MQL, em primeiro lugar, precisamos conhecer determinado modelo matemático.
    Trabalhando com séries temporais na biblioteca DoEasy (Parte 36): objeto das séries temporais de todos os períodos usados do símbolo Trabalhando com séries temporais na biblioteca DoEasy (Parte 36): objeto das séries temporais de todos os períodos usados do símbolo
    No artigo, veremos como combinar listas de objetos-barras para cada período usado no objeto da série temporal do símbolo. Consequentemente, teremos para cada símbolo um objeto pronto armazenando as listas de todos os períodos usados da série temporal.
    Trabalhando com séries temporais na biblioteca DoEasy (Parte 35): Objeto "Barra" e lista-série temporal do símbolo Trabalhando com séries temporais na biblioteca DoEasy (Parte 35): Objeto "Barra" e lista-série temporal do símbolo
    Neste artigo, estamos lançando uma nova série de descrições de criação de bibliotecas DoEasy para criação simples e rápida de programas. Hoje começaremos a preparar a funcionalidade da biblioteca para acessar e trabalhar com dados de séries temporais de símbolos. Criaremos um objeto "Barra" que armazenará os dados básicos e avançados da barra da série temporal e colocaremos os objetos-barras na lista de séries temporais para facilitar a pesquisa e a classificação desses objetos.