Discussão do artigo "Cálculo de expressões matemáticas (Parte 2). Analisadores Pratt e estação de triagem"

 

Novo artigo Cálculo de expressões matemáticas (Parte 2). Analisadores Pratt e estação de triagem foi publicado:

O artigo aborda os princípios de análise e cálculo de expressões matemáticas com ajuda de analisadores baseados na precedência de operadores. Implementa analisadores Pratt e estação de triagem, geração de bytecode cálculos com base nele. Mostra o uso de indicadores como funções em expressões e como aplicá-los ao configurar sinais de negociação em EAs.

Se executarmos o Expert Advisor no testador, provavelmente teremos um relatório com indicadores abaixo da média, mas algo mais é importante é que o trading estará sendo realizado e é gerenciado por analisadores. Eles não proporcionam sistemas lucrativos prontos, mas, sim, uma ferramenta adicional para buscá-los.

Exemplo de negociação usando sinais calculados por expressões

Exemplo de negociação usando sinais calculados por expressões

Autor: Stanislav Korotky

 
Quando você comparar o desempenho, compare-o com o MQL puro.
 

A comparação de desempenho levando em conta a MQL5 nativa é a seguinte:

ExpresSParserS (EURUSD,D1)      Evaluation: 105109
ExpresSParserS (EURUSD,D1)      Compilation: 26090
ExpresSParserS (EURUSD,D1)      Pratt bytecode: 24030
ExpresSParserS (EURUSD,D1)      Pratt: 26567
ExpresSParserS (EURUSD,D1)      ShuntingYard: 23884
ExpresSParserS (EURUSD,D1)      MQL5: 12901

O MQL5 é cerca de 2 vezes mais rápido do que os analisadores mais rápidos apresentados.

Código de teste adicionado:

class FuncCalc
{
  private:
    double a;
    double b;
    double c;
  public:
    void setup(double _a, double _b, double _c)
    {
      a = _a;
      b = _b;
      c = _c;
    }
    double execute()
    {
      return (a + b) * (c > 10000 ? c / 4 : c * 4);
    }
};

ulong testMQL5(const int n)
{
  ulong ul = 0, total = 0;
  double r;
  FuncCalc f;

  for(int i = 0; i < n; i++)
  {
    f.setup(rand(), rand(), rand());
    ul = GetMicrosecondCount();
    r = f.execute();
    total += GetMicrosecondCount() - ul;
  }
  return total;
}

Essa é uma estimativa aproximada. Ainda há muito espaço para pesquisa (por exemplo, com diferentes tipos de expressões) e otimização do analisador.

 

Agora só posso elogiar.

É claro que eu deveria ter mencionado Dijkstra, pois historicamente o Shooting Yard está mais associado a ele.

Eu tive a ideia de fazer um artigo semelhante, estava até digitando o material para mim mesmo, você me adiantou (sobre a parte 2), mas eu tinha o hábito de enrolar tudo em máquinas fortes e empilhadas.

você conseguiu não enrolar o artigo nele (ou no lisp)!

A cereja do bolo seria o combinador Y.

PS: Mas os bytecodes que você criou acabaram sendo "largos" e mortos por classes. Você pode assobiar e tolerar 64 bits. Bem, o chefe é o chefe :-)

 
Maxim Kuznetsov:

Agora só posso elogiar.

Bem, é claro que valeria a pena mencionar Dijkstra, pois historicamente o Shooting Yard está mais associado a ele

Eu tive a ideia de fazer um artigo semelhante, estava até digitando o material para mim mesmo, você me venceu (sobre a parte 2), mas eu tinha todas as coisas habituais enroladas no forte e nas máquinas de empilhar

você conseguiu não enrolar o artigo nele (ou no lisp)!

A cereja do bolo seria o Y-combinator.

PS: Mas seus bytecodes parecem "muito amplos" e mortos por classes. Você pode assobiar e tolerar 64 bits. Bem, o chefe é o chefe :-)

Você pode escrever uma continuação com redução de bytecodes, aceleração e novos tipos de analisadores. Não consegui cobrir tudo; na verdade, eu esperava escrever um artigo, mas, como sempre, não coube.

 
Stanislav Korotky:

Você pode escrever uma sequência com redução de byte-code, aceleração e novos tipos de analisadores. Não consegui cobrir tudo, na verdade, esperava escrever um artigo, mas, como sempre, não coube.

O bytecode depende da máquina virtual. Por um lado, estou tentado a dar 128 bits ou mais para o código de operação "adição de dois números" ....

e novos tipos de analisadores ainda não foram inventados, todos eles têm anos de idade ;-) e existem apenas 2 e meio deles.

PS: a estação de classificação para as necessidades dos usuários de terminal é ultrapassada - você pode inserir uma fórmula familiar no campo de entrada e obter o resultado.

 
Ao contrário de alguns dos outros artigos, esses dois artigos são muito bons. Claros, detalhados e acessíveis. Muito obrigado.
 
A versão atualizada das calculadoras 1.1 está anexada ao artigo sobre otimização por enxame de partículas. Além disso, há uma pequena correção de bug na discussão.
Параллельная оптимизация методом роя частиц (Particle Swarm Optimization)
Параллельная оптимизация методом роя частиц (Particle Swarm Optimization)
  • www.mql5.com
Как известно, MetaTrader 5 позволяет оптимизировать торговые стратегии с помощью встроенного тестера на основе двух алгоритмов: прямого перебора входных параметров и генетики (генетический алгоритм - ГА). Генетическая оптимизация является одной из разновидностей эволюционных алгоритмов, которые предоставляют значительное ускорение процесса...
 
Mostre como usar um analisador dessa cadeia de caracteres.
"(EURUSD^2) / (GBPUSD * AUDUSD)"

A dificuldade é que precisamos determinar automaticamente em que caso e onde substituir o bid/ask.

No exemplo acima, deveria ser assim.

Value_Bid = (EURUSD_Bid * EURUSD_Bid / (GBPUSD_Ask * AUDUSD__Ask);
Value_Ask = (EURUSD_Ask * EURUSD_Ask / (GBPUSD_Bid * AUDUSD__Bid);


O algoritmo para determinar o Bid/Ask é o seguinte. Usando o mesmo exemplo.

F(EURUSD, GBPUSD, AUDUSD) = (EURUSD^2) / (GBPUSD * AUDUSD);

bool EURUSD_flag = (F(1, 1, 1) < F(2, 1, 1));
bool GBPUSD_flag = (F(1, 1, 1) < F(1, 2, 1));
bool AUDUSD_flag = (F(1, 1, 1) < F(1, 1, 2));

Value_Bid = F(EURUSD_flag ? EURUSD_Bid : EURUSD_Ask,
              GBPUSD_flag ? GBPUSD_Bid : GBPUSD_Ask,
              AUDUSD_flag ? AUDUSD_Bid : AUDUSD_Ask);

Value_Ask = F(EURUSD_flag ? EURUSD_Ask : EURUSD_Bid,
              GBPUSD_flag ? GBPUSD_Ask : GBPUSD_Bid,
              AUDUSD_flag ? AUDUSD_Ask : AUDUSD_Bid);
 
fxsaber:
Por favor, mostre-me como usar o analisador para essa string.

A principal dificuldade é determinar os nomes de todas as variáveis na expressão. Para que você possa escrever algo semelhante.

TestSuiteEvaluator evaluator("EURUSD=1.5;GBPUSD=2.5;AUDUSD=5");
 
Do ponto de vista do analisador, uma variável não pode ter dois valores: compra e venda. Provavelmente é possível envolver os componentes em funções (introduzir as funções Bid(symbol), Ask(symbol) ou toda a função "basket" se o número de componentes for predefinido). Basicamente, o problema original não está claro: se estivermos falando de uma cesta/sintética de três símbolos, cada componente será adquirido sem ambiguidade por Ask ou Bid, dependendo da direção. Você também pode considerar a opção de expressões diferentes, dependendo da direção das transações.