Bibliotecas: Symbol - página 2

 
Stanislav Korotky:

Devemos acrescentar algo como:

Caso contrário, às vezes apenas as propriedades são necessárias e as barras não.

Todos os métodos da classe são públicos. Portanto, para clonar apenas as propriedades, chame CloneProperties().

 

A biblioteca e o exemplo de uso foram atualizados.

Пример

Ao executar um backtest em cruzamentos, o testador extrai não apenas o símbolo principal, mas também um símbolo auxiliar, que permite a conversão da moeda de lucro do símbolo principal para a moeda da conta. A extração do símbolo auxiliar, a geração de seus ticks e a sincronização com o símbolo principal consomem recursos de computação preciosos (e tempo) nos modos de execução única e, especialmente, de otimização.


Entretanto, essa precisão é quase sempre desnecessária. Portanto, eu gostaria de contornar essa obsessão/imperfeição do testador do MetaTrader 5. No MetaTrader 4 é fácil fazer isso - existe a possibilidade de alterar a moeda da conta diretamente no testador. O MetaTrader 5 não tem essa opção.

O script de demonstração mostra uma maneira de contornar essa limitação do testador - remover cálculos desnecessários. Para isso, é criada uma cópia do símbolo para backtest, mas a moeda do lucro/margem é definida como igual à moeda da conta. Ou seja, não haverá necessidade de reconverter os resultados da negociação. E o lucro será de fato calculado em pips, o que pode ser muito claro em algumas situações.

// Criar uma cópia do símbolo para acelerar o testador
#property script_show_inputs

#include <Symbol.mqh>

void OnStart()
{
  const SYMBOL Symb("TESTER_" + _Symbol); // Criou um símbolo

  if (Symb.IsExist()) // Se o símbolo for criado
  {
    Symb = _Symbol; // Copiar todas as propriedades e o histórico de barras (+ histórico de ticks, se personalizado) do símbolo principal - clone

    // Tornar as moedas do símbolo a moeda da conta
    Symb.SetProperty(SYMBOL_CURRENCY_PROFIT, AccountInfoString(ACCOUNT_CURRENCY));
    Symb.SetProperty(SYMBOL_CURRENCY_MARGIN, AccountInfoString(ACCOUNT_CURRENCY));

    if (Symb.On()) // Incluído no Market Watch
      ChartOpen(Symb.Name, PERIOD_CURRENT); // Abriu um novo gráfico de símbolos
  }
}


Resultado


Dessa forma, obtém-se uma aceleração livre do Tester/Optimizer.


ZЫ Eu o medi minuciosamente no EURGBP. O ganho de tempo é de aproximadamente 2 vezes. As negociações são totalmente compatíveis. De fato, é gratuito!

 

A observação a seguir não se refere apenas à biblioteca.


Se você precisar alterar algumas propriedades de um símbolo personalizado, em alguns casos isso deve ser feito ANTES de importar as citações.

Portanto, para garantir a confiabilidade do resultado, recomendo enfaticamente que você defina todas as propriedades do símbolo primeiro e só depois faça a importação.

Por exemplo, se você quiser definir SYMBOL_TRADE_TICK_VALUE e SYMBOL_TRADE_TICK_SIZE, isso deve ser feito antes de importar ticks/bars.

 

No testador MT5, como regra (forex, por exemplo), as ordens de limite têm derrapagem positiva, o que leva ao autoengano (às vezes até na forma de grails do testador em ticks reais!)



Mas há uma maneira de contornar esse recurso do testador. Abaixo estão instruções detalhadas sobre como fazer isso.


1. Se o símbolo original (gráfico aberto) não for personalizado ou se a conta estiver protegida, execute este script no gráfico do símbolo

#include <Symbol.mqh>

void OnStart()
{
  const SYMBOL Symb(_Symbol + "_Custom"); // Criou um símbolo

  if (Symb.IsExist()) // Se o símbolo for criado
  {
    Symb = _Symbol;   // Copiar todas as propriedades e o histórico de barras (+ histórico de ticks, se personalizado) do símbolo principal - clone

    if (Symb.On())    // Incluído no Market Watch
      ChartOpen(Symb.Name, PERIOD_CURRENT); // Abriu um novo gráfico de símbolos
  }
}


Você obterá esta imagem



2. Se a conta estiver protegida (a palavra Hedge está presente na barra de título da janela do Terminal), vá para qualquer conta de compensação (por exemplo, MetaQuotes-Demo) e recarregue o Terminal.

3. Execute esse script no gráfico atual

// Criação de uma cópia do símbolo para acelerar o testador com a possibilidade de desativar a derrapagem de ordens de limite
#property script_show_inputs

#include <Symbol.mqh>

input bool OrderLimitSlippage = false;

void OnStart()
{
  const SYMBOL Symb("TESTER_" + _Symbol); // Criou um símbolo

  if (Symb.IsExist()) // Se o símbolo for criado
  {
    // https://www.mql5.com/ru/forum/212096/page2#comment_7017794
// Symb = _Symbol; // Copiar todas as propriedades e o histórico de barras (+ histórico de ticks, se personalizado) do símbolo principal - clone

    Symb.CloneProperties(); // Copiar todas as propriedades do símbolo principal

    // Tornar as moedas do símbolo a moeda da conta
    Symb.SetProperty(SYMBOL_CURRENCY_PROFIT, AccountInfoString(ACCOUNT_CURRENCY));
    Symb.SetProperty(SYMBOL_CURRENCY_MARGIN, AccountInfoString(ACCOUNT_CURRENCY));
    Symb.SetProperty(SYMBOL_CURRENCY_BASE, AccountInfoString(ACCOUNT_CURRENCY));
    
    int Answer = IDNO;
    
    // Remover a derrapagem de ordens de limite
    // https://www.mql5.com/ru/forum/212096/page2#comment_7018318
    if (!OrderLimitSlippage &&
        (((ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE) != ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) ||
        ((Answer = MessageBox("You will need to change the account type to netting.\nDo you agree to disable limit order slips?", __FILE__, MB_YESNOCANCEL | MB_ICONQUESTION)) == IDYES)))
    {
      Symb.SetProperty(SYMBOL_TRADE_EXEMODE, SYMBOL_TRADE_EXECUTION_EXCHANGE);
      Symb.SetProperty(SYMBOL_TRADE_CALC_MODE, SYMBOL_CALC_MODE_EXCH_FUTURES);
      
      // Para calcular o lucro
      Symb.SetProperty(SYMBOL_TRADE_TICK_VALUE, 1);
      Symb.SetProperty(SYMBOL_TRADE_TICK_SIZE, Symb.GetProperty(SYMBOL_POINT));
    }
    
    if ((Answer != IDCANCEL) && (Symb.CloneHistory() > 0) && Symb.On()) // Histórico de barras copiado (+ histórico de ticks, se personalizado) do símbolo principal
      ChartOpen(Symb.Name, PERIOD_CURRENT); // Abriu um novo gráfico de símbolos 
  }
}



3. Selecione o símbolo personalizado recebido no Testador


Agora as ordens de limite não deslizarão!

 

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação

Erros, bugs, perguntas

fxsaber, 2018.02.14 14:41 pm.

Erro feio não no Terminal, mas na plataforma MT5
#include <MT4Orders.mqh> // https://www.mql5.com/pt/code/16006

#define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)
#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

void OnStart()
{
  OrderSend(_Symbol, OP_BUY, 1, Ask, 100, 0, Bid);
  
// OrderSend(_Symbol, OP_BUYLIMIT, 1, Ask, 100, 0, 0);
}

Executando no MQ-Demo em algum símbolo de movimento lento. Por exemplo, EURHUF.

O script abre uma posição de COMPRA com TP = Bid. Ou seja, a posição deve ser fechada imediatamente. Mas a TP será verificada quanto à conformidade com a condição de aceitação somente no próximo tick!

O fechamento instantâneo da posição não ocorrerá até o próximo tick. Além disso, se o próximo tick tiver Bid < TP, o TP permanecerá sem aceitação.


O mesmo se aplica às ordens de limite (linha comentada). No Tester, a situação é semelhante.

Sobre o destaque, é preciso dizer que, no post anterior, há o seguinte

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação.

Bibliotecas: Symbol

fxsaber, 2018.04.06 09:21 pm.

2. Se a conta estiver coberta (a palavra Hedge está presente na barra de título da janela do Terminal), vá para qualquer conta de compensação (por exemplo, MetaQuotes-Demo) e recarregue o Terminal.

E nem todos perceberão que as ordens limitadas ao preço atual nos símbolos de câmbio das contas de compensação serão executadas (e no Testador) imediatamente, sem esperar pelo próximo tique.


Observe que não é apenas o símbolo da ação que é importante, mas também a conta de compensação. Por exemplo, você pode usar um símbolo MOEX em um Hedge-MQ-Demo, mas ele não será executado da mesma forma (e no Testador) que no mesmo Netting-MQ-Demo.

Esse é um dos motivos pelos quais os backtests dos mesmos símbolos MOEX completamente idênticos podem ser diferentes, dependendo do tipo de conta.


ZЫ Estou falando sozinho....

 
fxsaber:

ZY Estou falando comigo mesmo...

Não, apenas não tenho nada a acrescentar.

É uma pena que, para realizar o acionamento normal das ordens, você precise dançar com pandeiros.

 
Andrey Khatimlianskii:

É uma pena que, para realizar o acionamento normal das ordens, você precise dançar com pandeiros.

Alterei as instruções, simplificando consideravelmente as danças. Por exemplo, na rede, tudo é feito em um clique - iniciando o script.

 

Apliquei um filtro simples aos ticks reais, que elimina > 90% das informações na variante mais leve. Quanto mais forte for o filtro, mais grosseiro será o resultado do backtest.

Mas foi interessante ver como o filtro mais fraco afeta o resultado e a velocidade.


Qualidade.

Era

final balance 10007242.00 EUR
TESTER_Censored,M1: 6589567 ticks, 60353 bars generated. Environment synchronized in 0:00:00.031. Test passed in 0:00:05.101 (including ticks preprocessing 0:00:00.874).
TESTER_Censored,M1: total time from login to stop testing 0:00:05.132 (including 0:00:00.031 for history data synchronization)
476 Mb memory used including 27 Mb of history data, 192 Mb of tick data


Tornou-se

final balance 10007246.00 EUR
FILTER_Censored,M1: 402622 ticks, 50887 bars generated. Environment synchronized in 0:00:00.030. Test passed in 0:00:00.516 (including ticks preprocessing 0:00:00.078).
FILTER_Censored,M1: total time from login to stop testing 0:00:00.546 (including 0:00:00.030 for history data synchronization)
314 Mb memory used including 27 Mb of history data, 64 Mb of tick data


Velocidade

Era

OnTesterInit
i = 0 Pass = 0 OnTester = 3.881 s.: Count = 6589567, 1697904.4 unit/sec, Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent-127.0.0.1-3000 build = 1795
i = 1 Pass = 1 OnTester = 3.893 s.: Count = 6589567, 1692670.7 unit/sec, Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent-127.0.0.1-3000 build = 1795
i = 2 Pass = 2 OnTester = 3.898 s.: Count = 6589567, 1690499.5 unit/sec, Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent-127.0.0.1-3000 build = 1795
i = 3 Pass = 3 OnTester = 3.842 s.: Count = 6589567, 1715139.8 unit/sec, Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent-127.0.0.1-3000 build = 1795
i = 4 Pass = 4 OnTester = 3.912 s.: Count = 6589567, 1684449.6 unit/sec, Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent-127.0.0.1-3000 build = 1795
iMin = 3 Results[iMin] = 3.842 s.
iMax = 4 Results[iMax] = 3.912 s.
Amount = 5 Mean = 3.885 s. - 84.80%
OnTesterDeinit


Era

OnTesterInit
i = 0 Pass = 0 OnTester = 0.264 s.: Count = 402622, 1525083.3 unit/sec, Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent-127.0.0.1-3000 build = 1795
i = 1 Pass = 1 OnTester = 0.264 s.: Count = 402622, 1525083.3 unit/sec, Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent-127.0.0.1-3000 build = 1795
i = 2 Pass = 2 OnTester = 0.264 s.: Count = 402622, 1525083.3 unit/sec, Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent-127.0.0.1-3000 build = 1795
i = 3 Pass = 3 OnTester = 0.266 s.: Count = 402622, 1513616.5 unit/sec, Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent-127.0.0.1-3000 build = 1795
i = 4 Pass = 4 OnTester = 0.306 s.: Count = 402622, 1315758.2 unit/sec, Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent-127.0.0.1-3000 build = 1795
iMin = 0 Results[iMin] = 0.264 s.
iMax = 4 Results[iMax] = 0.306 s.
Amount = 5 Mean = 0.273 s. - 29.28%
OnTesterDeinit


Resultado

De acordo com os ticks reais, o número de ticks diminuiu 16 vezes (o filtro mais leve), a velocidade da otimização aumentou 14 vezes e a qualidade não sofreu nada (a análise que não foi incluída aqui). Obviamente, isso só pode ser feito quando se escreve o TS de uma determinada maneira. Em particular, com a ausência de análise de barra.

A aceleração universal gratuita anterior proporcionou apenas um aumento de duas vezes. A atual também é gratuita (a qualidade não é afetada), mas é menos universal. No entanto, o retorno é maior que uma ordem de grandeza. Agora otimizo o TC somente dessa forma. Não há erro.


SZY

Ao mesmo tempo, uma breve verificação dessa implementação (apenas o spread da barra é calculado de forma diferente).

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação.

Scripts: ThirdPartyTicks

Automated-Trading, 2018.03.16 09:35 pm.

Баровая история создается с учетом минимальных потерь качества при переходе от режима тестирования "Каждый тик на основе реальных тиков" к "Только цены открытия" - ТС на лимитных ордерах;

Dois modos são comparados: "Todos os ticks" e "OHLC M1".


Todos os ticks

final balance 10006150.00 EUR
TESTER4_Censored,M1: 6576734 ticks, 60353 bars generated. Test passed in 0:00:04.587 (including ticks preprocessing 0:00:00.343).
394 Mb memory used including 27 Mb of history data, 128 Mb of tick data


OHLC M1

final balance 10006119.00 EUR
TESTER_Censored,M1: 240366 ticks, 60353 bars generated. Test passed in 0:00:00.359 (including ticks preprocessing 0:00:00.031).
306 Mb memory used including 27 Mb of history data, 64 Mb of tick data


A qualidade do backtest é a mesma, o desempenho da segunda variante em uma única execução é 12 vezes melhor.

 

Para um não programador, esses scripts precisam ser escritos em um programa Expert Advisor?

É muito tentador acelerar a otimização em 12 vezes.

Haverá essa aceleração ao otimizar por pontos de abertura?

 
Aleksey Panfilov:

Para um não programador, esses scripts precisam ser escritos em um programa EA?

É muito tentador acelerar a otimização em 12 vezes.

Haverá essa aceleração ao otimizar por pontos de abertura?

Infelizmente, é muito difícil explicar todos os aspectos desse processo. Provavelmente, seria necessário um artigo. Portanto, não será possível explicá-lo de forma clara e resumida.