Discussão do artigo "Expert Advisor Multiplataforma: As classes CExpertAdvisor e CExpertAdvisors"

 

Novo artigo Expert Advisor Multiplataforma: As classes CExpertAdvisor e CExpertAdvisors foi publicado:

Este artigo aborda principalmente as classes CExpertAdvisor e CExpertAdvisors, que servem como contêiner para todos os outros componentes descritos nesta série de artigos sobre expert advisors multiplataforma.

O método OnTick da CExpertAdvisor é a função mais utilizada dentro da classe. É a partir deste método onde ocorre a maior parte da ação. A operação principal deste método é mostrada no seguinte diagrama:


CExpertAdvisorBase OnTick

Autor: Enrico Lambino

 

Oi Enrico. Parece que você concluiu seu projeto. Estava dando uma olhada no seu último artigo e notei o que acredito ser um erro:

bool CExpertAdvisorBase::Init(string symbol,int period,int magic,bool every_tick=true,bool one_trade_per_candle=true,bool position_reverse=true)
  {
   m_symbol_name=symbol;
   CSymbolInfo *instrument;
   if((instrument=new CSymbolInfo)==NULL)
      return false;
   if(symbol==NULL) symbol=Symbol();
   if(!instrument.Name(symbol))
      return false;
   instrument.Refresh();
   m_symbol_man.Add(instrument);
   m_symbol_man.SetPrimary(m_symbol_name);
   m_period=(ENUM_TIMEFRAMES)period;
   m_every_tick=every_tick;
   m_order_man.Magic(magic);
   m_position_reverse=position_reverse;
   m_one_trade_per_candle=one_trade_per_candle;
   CCandle *candle=new CCandle();
   candle.Init(instrument,m_period);
   m_candle_man.Add(candle);
   Magic(magic);
   return false;
  }

Destaquei em laranja acima. Acho que a instrução de retorno deveria ser true em vez de false. Estou reiniciando meu PC, peguei um vírus muito ruim que arruinou meu dia, então decidi ler um pouco. Seu trabalho é uma das melhores leituras do fórum. Você se superou com esse projeto, muito bem.

Minha ideia é semelhante à sua e peguei algumas ideias realmente ótimas do seu trabalho, obrigado. Quando eu terminar, reservarei um tempo para compartilhá-la aqui.

 
Shephard Mukachi:

Oi Enrico. Parece que você concluiu seu projeto. Estava dando uma olhada no seu último artigo e notei o que acredito ser um erro:

Destaquei em laranja acima. Acho que a instrução de retorno deveria ser true em vez de false. Estou reiniciando meu PC, peguei um vírus muito ruim que arruinou meu dia, então decidi ler um pouco. Seu trabalho é uma das melhores leituras do fórum. Você se superou com esse projeto, muito bem.

Minha ideia é semelhante à sua e peguei algumas ideias realmente ótimas de seu trabalho, obrigado. Quando eu terminar, reservarei um tempo para compartilhá-la aqui.

 

Oi Shep,

Shephard Mukachi:

Oi Enrico. Parece que você concluiu seu projeto. Estava dando uma olhada no seu último artigo e notei o que acredito ser um erro:

Destaquei em laranja acima. Acho que a instrução de retorno deveria ser true em vez de false. Estou reiniciando meu PC, peguei um vírus muito ruim que arruinou meu dia, então decidi ler um pouco. Seu trabalho é uma das melhores leituras do fórum. Você se superou com esse projeto, muito bem.

Minha ideia é semelhante à sua e peguei algumas ideias realmente ótimas de seu trabalho, obrigado. Quando eu terminar, reservarei um tempo para compartilhá-la aqui.

Lamento saber o que aconteceu, mas obrigado por seu feedback. Sim, você está certo. Eu não havia notado isso até agora. Vou corrigi-lo. A chamada ao método Init() nos exemplos não é verificada, mas parte dos meus planos futuros para a biblioteca é tornar as chamadas de funções e métodos mais formais (como na biblioteca padrão), bem como um modelo de EA para facilitar a codificação. Posteriormente, farei o upload da versão mais recente da biblioteca na base de código e tornarei o repositório público. Seus comentários e solicitações de pull são bem-vindos.

De nada e estou ansioso para ver sua biblioteca.

 
Enrico Lambino:

Oi Shep,

Lamento saber o que aconteceu, mas agradeço seu feedback. Sim, você está certo. Eu não havia notado isso até agora. Vou corrigi-lo. A chamada para o método Init() nos exemplos não é verificada, mas parte dos meus planos futuros para a biblioteca é tornar as chamadas de funções e métodos mais formais (como na biblioteca padrão), bem como um modelo de EA para facilitar a codificação. Posteriormente, farei o upload da versão mais recente da biblioteca na base de código e tornarei o repositório público. Seus comentários e solicitações de pull são bem-vindos.

De nada e estou ansioso para ver sua biblioteca.


Olá, Enrico. Finalmente estou prestes a concluir a instalação de um novo sistema. Tive dificuldades durante horas na noite passada, pois não conseguia controlar o meu sistema, mas agora está quase pronto. Estou usando meu tablet para navegar e fazer algumas leituras. Sua biblioteca é realmente um ótimo trabalho. Agora que ela está completa, posso ver toda a lógica - uau!

Então, minha ideia é a seguinte.

- O EA cria uma lista de robôs (como uma entidade de IA) com base em uma combinação de Magic, Symbol e Timeframe (usando a Watch Window)

- Em seguida, a entidade de IA entra em um conjunto de truques (os sinais - MA, PSAR, etc.) e determina o melhor sinal ou uma combinação de sinais. O melhor aqui é baseado em um mecanismo interno de back-testing que permite a comparação entre os sinais.

- Em seguida, a IA adiciona o(s) sinal(is) em uma lista e negocia com base nisso, reaprendendo se necessário.

- Cada IA terá objetos de Stop, Ordem e Posição, que serão gerenciados individualmente, e acesso a um objeto otimizador (GA) para aprendizado. Pensei em usar a Teoria da Utilidade para a tomada de decisões da IA (semelhante à ponderação usada no MQL5 EA System), mas não gostei da natureza arbitrária aplicada, por isso optei por aprender por meio de negociações virtuais, dando à IA um comportamento quase real.


Tive dificuldade para entender como implementar algumas das ideias, e a leitura de artigos como o seu e muitos outros artigos no fórum e livros me levou a um ponto em que estou prestes a concluir um projeto muito legal - pelo menos é o que penso.

Um dos principais problemas que você mencionou é a serialização. Como uma ordem ou posição ativa não tem todos os atributos do objeto que a abriu, uma falha no sistema colocará os IAs em um estado inválido, deixando muitas negociações órfãs. Pensei em usar o comentário da ordem. Assim, ao enviar uma ordem, criei um comentário com Timeframe, SignalName e SignalSettings concatenados. Logo percebi que isso se tornava difícil de manejar muito rapidamente e estava sujeito a problemas de implementação. Portanto, escrever em um arquivo parece ser a única coisa que faz sentido.


Bem, se estiver interessado, eu o informarei sobre meu progresso. Mas seu trabalho é realmente excelente, obrigado por dedicar seu tempo ao projeto.


Shep

 

Oi Shep,

Shephard Mukachi:

Olá, Enrico. Finalmente estou prestes a concluir a instalação de um novo sistema. Tive dificuldades durante horas na noite passada, pois não conseguia controlar o sistema, mas agora está quase pronto. Estou usando meu tablet para navegar e fazer algumas leituras. Sua biblioteca é realmente um ótimo trabalho. Agora que ela está completa, posso ver toda a lógica - uau!

Então, minha ideia é a seguinte.

- O EA cria uma lista de robôs (como uma entidade de IA) com base em uma combinação de Magic, Symbol e Timeframe (usando a Watch Window)

- Em seguida, a entidade de IA entra em um conjunto de truques (os sinais - MA, PSAR, etc.) e determina o melhor sinal ou uma combinação de sinais. O melhor aqui é baseado em um mecanismo interno de back-testing que permite a comparação entre os sinais.

- Em seguida, a IA adiciona o(s) sinal(is) em uma lista e negocia com base nisso, reaprendendo se necessário.

- Cada IA terá objetos de Stop, Ordem e Posição, que serão gerenciados individualmente, e acesso a um objeto otimizador (GA) para aprendizado. Pensei em usar a Teoria da Utilidade para a tomada de decisões da IA (semelhante à ponderação usada no MQL5 EA System), mas não gostei da natureza arbitrária aplicada, por isso optei por aprender por meio de negociações virtuais, dando à IA um comportamento quase real.


Tive dificuldade para entender como implementar algumas das ideias, e a leitura de artigos como o seu e muitos outros artigos no fórum e livros me levou a um ponto em que estou prestes a concluir um projeto muito legal - pelo menos é o que penso.

Um dos principais problemas que você mencionou é a serialização. Como uma ordem ou posição ativa não tem todos os atributos do objeto que a abriu, uma falha no sistema colocará os IAs em um estado inválido, deixando muitas negociações órfãs. Pensei em usar o comentário da ordem. Assim, ao enviar uma ordem, criei um comentário com Timeframe, SignalName e SignalSettings concatenados. Logo percebi que isso se tornava difícil de manejar muito rapidamente e estava sujeito a problemas de implementação. Portanto, escrever em um arquivo parece ser a única coisa que faz sentido.


Bem, se estiver interessado, eu o informarei sobre meu progresso. Mas seu trabalho é realmente excelente, obrigado por dedicar seu tempo ao projeto.


Shep

Esse parece ser um projeto interessante. Entretanto, parece ser um projeto muito grande (provavelmente maior e mais desafiador do que este). Permita-me compartilhar algumas de minhas ideias que, acredito, poderão ajudá-lo:

Uma vez escrevi um script de backtester. Consegui fazer com que ele funcionasse como eu queria com negociações virtuais, mas seu desempenho seria lento se fosse usado em um EA real (para não mencionar um auto-otimizado!). Você poderá ter mais sucesso em seu trabalho se puder, de alguma forma, fazer com que os outros núcleos da CPU (ou mesmo a GPU) também façam cálculos (ou seja, DLL ou OpenCL).

A lista de robôs funciona, mas tem uma falha importante: eles não são executados em paralelo. A defasagem é boa se o número for apenas de alguns ou vários, mas se você tiver mais, os que estiverem no final da lista serão processados por último. E esses também teriam que competir com os recursos que o EA precisa para realizar seu trabalho real.

A negociação virtual pode criar bons modelos, mas não capta o ruído real do mercado (ou seja, as notícias). Aprendi isso da maneira mais difícil.

Compartilho as mesmas ideias com você em relação ao sistema de pesagem usado na classe CSignal da biblioteca padrão. Na minha opinião, o sistema é muito propenso a se ajustar demais se for colocado em um otimizador. Tenho um bot de formador de mercado que usa um modelo de pontuação de mercado (LMSR, mas ainda estou trabalhando para melhorar o risco de estoque). Acredito que essa seja uma alternativa muito boa, pois o peso dos sinais de compra e venda (e até mesmo nenhum sinal) pode ser levado em consideração coletivamente, e os resultados são em termos de probabilidades. E é muito menos intensivo em recursos do que a aprendizagem profunda.

Salvar em um arquivo é provavelmente a melhor opção no momento para salvar dados voláteis. Usar GVs é outra opção, mas pode ficar ainda mais confuso do que usar comentários de ordens. Além disso, algumas corretoras inserem outros códigos nos comentários de ordens (por exemplo, opções binárias), portanto, esse também não é um método muito bom, na minha opinião. Outra opção é salvar todos os dados em um objeto de dicionário, o que evita a necessidade de escrever linhas de código implementando vários métodos Load e Save, mas também é necessário salvar no disco. Mas há um grande problema quando o usuário deseja iniciar uma nova sessão com um EA. Isso precisa ser resolvido manualmente (excluindo o arquivo salvo ou atribuindo um novo nome de arquivo salvo).

Quebrei algumas regras de OOP ao implementar as classes de arquivo nessa biblioteca. Tive um problema em que o identificador de arquivo perdia seu valor (tornando-se INVALID_HANDLE) quando era passado por métodos e funções (mesmo com o qualificador const). Não tenho certeza se esse ainda é o caso agora, mas estou bastante satisfeito com a solução atual. Para ser honesto, o uso de um descendente de CFile na biblioteca não foi muito elegante, mas funciona e resulta em muito menos código.

Tudo de bom,

Enrico

 

Muito obrigado por sua contribuição. Suas ideias são sempre bem-vindas.

Sim, você está certo de que será um projeto grande e espero que não seja maior do que o seu, pois é muito trabalhoso e estressante. No entanto, adoro programar, e pensar que, na verdade, sou um analista financeiro. Comecei a programar por necessidade, pois precisava automatizar alguns dos modelos financeiros mais complexos. Tenho uma capacidade estranha de ter ideias malucas e bizarras. Se ao menos eu pudesse programar tão bem quanto você!

No momento, estou analisando Dictionaries e Lists<T>. List<T> especificamente como um meio mais fácil de compartilhar as listas de objetos, mas também para vinculação. E Dictionary para armazenamento e serialização. Tenho experimentado algumas ideias para tornar minha base de código mais leve, mas também para ter um sistema que seja rápido, leve em termos de manutenção e que seja literalmente livre de problemas quando colocado em um gráfico. Sua observação sobre as listas é realmente valiosa, portanto, essa ideia pode não ser tão ideal.

Você está certo com relação à escória de processamento se eu não usar execuções paralelas - e mesmo assim é lento. Esse é um dos problemas que descobri em meus testes. Os últimos objetos da lista estão muito atrasados, especialmente se o mercado for realmente volátil, o OnTick pode ser chamado várias vezes antes mesmo de os primeiros objetos da lista serem chamados. Como você sugeriu, dei uma olhada no OpenCL como possível solução. Terei que investir em um sistema personalizado.

De fato, a negociação virtual cria ótimos modelos que podem limpar completamente sua conta em mercados barulhentos. Um dia, observei em pânico meu EA lutando para colocar e muito menos fechar as negociações durante as notícias. Essa é a dura e fria realidade da negociação, mas temos que tentar.

Sim, concordo com você que a abordagem do modelo de pontuação é melhor. O LMSR é definitivamente uma abordagem superior, especialmente considerando que os movimentos de alta e de baixa são muito diferentes para cada instrumento. Uma abordagem ponderada de probabilidade definitivamente melhora a precisão.

Com o autoaprendizado, sim, ele será bastante lento. Ele só será usado no início para configurar os agentes de IA, para armá-los com os sinais apropriados e, depois, em determinados intervalos, digamos, no final do dia para os agentes de 5 minutos e em uma sexta-feira para os agentes de 1 hora. De fato, isso traz a questão que você levantou sobre o treinamento virtual que gera bilhões apenas para perder todo o seu dinheiro em negociações reais. Portanto, para mim, é importante encontrar sinais que sejam muito simples e rápidos para que eu não perca muita velocidade. Quero que o sistema faça o scalp, digamos, por alguns pips após o spread e a comissão. Isso significa que as negociações precisam ser configurações de probabilidade realmente alta, como o martelo que está na mínima das últimas 20 barras ou algo parecido.

Como quero me concentrar no scalping, talvez não precise monitorar tanto as negociações. Os agentes apenas verificarão a configuração e, em seguida, farão a ordem com Stop e Takeprofit, que será interrompida ou fechada com lucro. Mais uma vez, ainda estou fazendo experiências com isso.

Ainda tenho muito trabalho, experimentando ideias em torno dos sinais. Quando encontrar algo com resultados realmente excelentes, compartilharei com você.

Você quebrou algumas regras, mas não é essa a beleza da programação? É incrível como você pode se ater às regras e ficar completamente preso e sentir que pode escalar a parede. E, às vezes, quebrar as regras é o que você precisa para progredir. Seu trabalho é excelente e, por isso, tenho muito respeito por você. Enrico, programar é um trabalho árduo. É bom quando está tudo bem, mas é muito chato quando não está funcionando de acordo com o planejado.

Muito obrigado por sua contribuição. Sou extremamente grato e com certeza o manterei informado.

Mais uma vez, obrigado,

Shep

 
Shephard Mukachi:

Muito obrigado por sua contribuição. Suas ideias são sempre bem-vindas.

Sim, você está certo de que será um projeto grande e espero que não seja maior do que o seu, pois é muito trabalhoso e estressante. No entanto, adoro programar, e pensar que, na verdade, sou um analista financeiro. Comecei a programar por necessidade, porque precisava automatizar alguns dos modelos financeiros mais complexos. Tenho uma capacidade estranha de ter ideias malucas e bizarras. Se ao menos eu pudesse programar tão bem quanto você!

No momento, estou analisando Dictionaries e Lists<T>. List<T> especificamente como um meio mais fácil de compartilhar as listas de objetos, mas também para vinculação. E Dictionary para armazenamento e serialização. Tenho experimentado algumas ideias para tornar minha base de código mais leve, mas também para ter um sistema que seja rápido, leve em termos de manutenção e que seja literalmente livre de problemas quando colocado em um gráfico. Sua observação sobre as listas é realmente valiosa, portanto, essa ideia pode não ser tão ideal.

Você está certo com relação à escória de processamento se eu não usar execuções paralelas - e mesmo assim é lento. Esse é um dos problemas que descobri em meus testes. Os últimos objetos da lista estão muito atrasados, especialmente se o mercado for realmente volátil, o OnTick pode ser chamado várias vezes antes mesmo de os primeiros objetos da lista serem chamados. Como você sugeriu, dei uma olhada no OpenCL como possível solução. Terei que investir em um sistema personalizado.

De fato, a negociação virtual cria ótimos modelos que podem limpar completamente sua conta em mercados barulhentos. Um dia, observei em pânico meu EA se esforçar para colocar e muito menos fechar as negociações durante as notícias. Essa é a dura e fria realidade da negociação, mas temos que tentar.

Sim, concordo com você que a abordagem do modelo de pontuação é melhor. O LMSR é definitivamente uma abordagem superior, especialmente considerando que os movimentos de alta e de baixa são muito diferentes para cada instrumento. Uma abordagem ponderada de probabilidade definitivamente melhora a precisão.

Com o autoaprendizado, sim, ele será bastante lento. Ele só será usado no início para configurar os agentes de IA, para armá-los com os sinais apropriados e, depois, em determinados intervalos, digamos, no final do dia para os agentes de 5 minutos e em uma sexta-feira para os agentes de 1 hora. De fato, isso traz a questão que você levantou sobre o treinamento virtual que gera bilhões apenas para perder todo o seu dinheiro em negociações reais. Portanto, para mim, é importante encontrar sinais que sejam muito simples e rápidos para que eu não perca muita velocidade. Quero que o sistema faça o scalp, digamos, por alguns pips após o spread e a comissão. Isso significa que as negociações precisam ser configurações de probabilidade realmente alta, como o martelo que está na mínima das últimas 20 barras ou algo parecido.

Como quero me concentrar no scalping, talvez não precise monitorar tanto as negociações. Os agentes apenas verificarão a configuração e, em seguida, farão a ordem com Stop e Takeprofit, que será interrompida ou fechada com lucro. Mais uma vez, ainda estou fazendo experiências com isso.

Ainda tenho muito trabalho, experimentando ideias em torno dos sinais. Quando encontrar algo com resultados realmente excelentes, compartilharei com você.

Você quebrou algumas regras, mas não é essa a beleza da programação? É incrível como você pode se ater às regras e ficar completamente preso e sentir que pode escalar a parede. E, às vezes, quebrar as regras é o que você precisa para progredir. Seu trabalho é excelente e, por isso, tenho muito respeito por você. Enrico, programar é um trabalho árduo. É bom quando está tudo bem, mas é muito chato quando não está funcionando de acordo com o planejado.

Muito obrigado por sua contribuição. Sou extremamente grato e com certeza o manterei informado.

Mais uma vez, obrigado,

Shep

De nada e obrigado também por compartilhar. Além disso, recentemente, comecei a trabalhar com o Dictionary<T> enquanto trabalhava com armazenamento de dados (para ser específico, com controles gráficos criados dinamicamente). Ele usa FNV1-a como função hash e pode armazenar primitivos e ponteiros para objetos (mas não structs). As partes de salvamento e carregamento ainda não foram concluídas, mas eu as compartilharei no CodeBase assim que estiverem prontas. Se você programar a otimização para cada agente (em vez de processar todos ao mesmo tempo), acredito que poderá aumentar a velocidade de execução obtendo agentes por hash e processando-os em um thread separado. Para isso, você precisaria de um objeto de dicionário ou de alguma estrutura de dados relacionada. E, sim, se o seu objetivo for escalonar, você realmente precisará do máximo de velocidade possível.
 

Olá, Enrico,

Você tem alguma ideia de como posso adicionar um comentário específico à ordem/posição, dependendo do sinal no qual a negociação foi acionada? Digamos que o sinal 1 funcionou - comentário "Sinal A" e assim por diante.

Obrigado.

 

Não é fácil para mim acompanhar porque estou apenas começando, mas agradeço a todos que me permitem progredir por meio de seu conhecimento

 

Muito trabalho foi feito.

Muito obrigado!