Você tem alguma questão sobre Metatrader 5! Pergunte Aqui! - página 266

Trader_Patinhas
1164
Trader_Patinhas  
ABettega:
Então, eu até concordaria com essa questão de alta volatilidade, mas em outras plataformas consigo executar a mesma operação, nos mesmos momentos, sem o slippage, tanto no Tryd quanto no Profit Chart. Essa questão que me dá medo, que me diz que talvez possa ser algo no código mesmo.

No MT5 vc está operando por robô, enquanto que no Tryd e no Profit a operação é manual, correto? (se vc estiver operando manualmente também no MT5, então não sei o que te responder, a única coisa que eu poderia dizer é que isso não acontece comigo).

Se estiver operando por robô, vale investigar o código, pois, como o @Joscelino Celso de Oliveira colocou, somente em momentos de volatilidade muito alta vai ocorrer slippage de 25 pontos no índice (estou presumindo que seja o índice, com base nas cotações que vc mencionou).

A maior parte do tempo o slippage no WIN costuma ser 0 ou 5 pontos, chegando a 10 uma vez ou outra (isso é apenas uma impressão minha, posso estar errado, pois nunca cheguei a fazer um experimento controlado para apurar a distribuição estatística do slippage no IND/WIN).

Acredito que, se vc estiver tendo slippage acima de 10 pontos com muita frequência, ou é porque a sua estratégia só atua em momentos de volatilidade muito alta, ou então pode ter algum problema no código do seu robô. 

Trader_Patinhas
1164
Trader_Patinhas  
Thiago Peixoto:
Estou usando o metatrader5 simulador e estou me decepcionando muito com os atrasos do gráfico com relação ao mercado. Chega a ter atrasos de 10 min. O q devo fazer para não ter mais esses atrasos? Uso internet fibra de 50Mb. 

Oi @Thiago Peixoto

Não vi nada errado nos seus gráficos. 

Em todos os casos, a hora correspondente à ultima barra do gráfico está alinhada com a hora que aparece no relógio do Windows.

Talvez o que esteja te confundindo seja o posicionamento dos rótulos de horário no eixo horizontal do gráfico.

O horário que aparece no eixo horizontal corresponde à barra que está no início (extremidade esquerda) do rótulo.

Por exemplo, se o rótulo for "9 abr 10:05", isso significa que a barra de 10:05 é a barra que aparece acima do "9" e as barras à direita do "9" serão 10:06, 10:07, etc.

Vamos considerar a primeira imagem:

- o relógio do Windows marca 13:28

- no gráfico do WINJ19, a barra que aparece no início do rótulo "1 abr 13:28" é justamente a última barra do gráfico, que é a de 13:28 (tudo ok)

- já no gráfico do WDOK19, o último rótulo é "1 abr 13:18", portanto, a barra que está no início desse rotulo (logo acima do "1" de "1 abr ...") é a de 13:18 e, a partir daí, indo pra direita, aparecem as barras de 13:19, 13:20 ... e a última barra é a de 13:28, que coincide com a hora do Windows

Seguindo essa mesma lógica, vc verá que nas outras imagens a última barra de cada gráfico também coincide certinho com a hora do Windows. Não há atraso.

Era isso que estava te confundindo?

obs: uma maneira simples de verificar se o gráfico está sincronizado é posicionar o mouse em cima da última barra do gráfico e observar o horário da barra na janela flutuante que surge.

ABettega
10
ABettega  
Trader_Patinhas:

No MT5 vc está operando por robô, enquanto que no Tryd e no Profit a operação é manual, correto? (se vc estiver operando manualmente também no MT5, então não sei o que te responder, a única coisa que eu poderia dizer é que isso não acontece comigo).

Se estiver operando por robô, vale investigar o código, pois, como o @Joscelino Celso de Oliveira colocou, somente em momentos de volatilidade muito alta vai ocorrer slippage de 25 pontos no índice (estou presumindo que seja o índice, com base nas cotações que vc mencionou).

A maior parte do tempo o slippage no WIN costuma ser 0 ou 5 pontos, chegando a 10 uma vez ou outra (isso é apenas uma impressão minha, posso estar errado, pois nunca cheguei a fazer um experimento controlado para apurar a distribuição estatística do slippage no IND/WIN).

Acredito que, se vc estiver tendo slippage acima de 10 pontos com muita frequência, ou é porque a sua estratégia só atua em momentos de volatilidade muito alta, ou então pode ter algum problema no código do seu robô. 

Acredito sim que pode ser algo no código. Estou fazendo o seguinte para colocar a ordem de venda:

      MqlTradeRequest request = {0};
      MqlTradeResult result = {0};
      request.action = TRADE_ACTION_PENDING;
      request.symbol = _Symbol;
      request.volume = contractAmount;
      request.deviation = 5;
      request.magic = 12345;
      request.type = ORDER_TYPE_SELL_STOP;
      request.price = entradaCompra;
      request.sl = entradaCompra + slTarget;
      request.tp = entradaCompra - tpTarget;
      request.type_filling = SYMBOL_FILLING_IOC;
      request.type_time = ORDER_TIME_DAY;
      bool ticket = OrderSend(request, result);
      Alert("Ticket: ", ticket);
      Alert("Result: ", result.retcode);


      trade.SellStop(contractAmount, normalizePrice(bid-entrada*_Point), _Symbol, normalizePrice(bid+(slTarget-entrada)*_Point), normalizePrice(bid-(tpTarget+entrada)*_Point), ORDER_TIME_GTC, 0, 0);

São duas vendas diferentes, não executo as duas ao mesmo tempo, sempre que vou fazer um teste eu comento a outra para não ter conflito. Com o MqlTradeRequest eu acredito que seja o meio correto, minha suposição é que seja um erro com o request.type, tipo eu deveria usar ORDER_TYPE_SELL_STOP_LIMIT talvez, mas não consegui chegar a uma resolução quanto a isso. O request.type_filling não altera nada, todos os testes resultam nesse problema.

O trade.SellStop é o CTrade básico.

Trader_Patinhas
1164
Trader_Patinhas  
ABettega:

Acredito sim que pode ser algo no código. Estou fazendo o seguinte para colocar a ordem de venda:

São duas vendas diferentes, não executo as duas ao mesmo tempo, sempre que vou fazer um teste eu comento a outra para não ter conflito. Com o MqlTradeRequest eu acredito que seja o meio correto, minha suposição é que seja um erro com o request.type, tipo eu deveria usar ORDER_TYPE_SELL_STOP_LIMIT talvez, mas não consegui chegar a uma resolução quanto a isso. O request.type_filling não altera nada, todos os testes resultam nesse problema.

O trade.SellStop é o CTrade básico.

No OrderSend vc não teria que multiplicar o slTarget e o tpTarget por _Point ? Ou já estão convertidos em pontos? (no trade.SellStop vc multiplica) 
ABettega
10
ABettega  
Trader_Patinhas:
No OrderSend vc não teria que multiplicar o slTarget e o tpTarget por _Point ? Ou já estão convertidos em pontos? (no trade.SellStop vc multiplica) 

A multiplicação é artefato de primeiras iterações do código, não utilizo a multiplicação mais. Acredito que isso não seja o problema porque quando eu vejo a aba de Negociação, os pontos de TP e SL estão corretos como parametrizado nos inputs.

Thiago Peixoto
10
Thiago Peixoto  
Trader_Patinhas:

Oi @Thiago Peixoto

Não vi nada errado nos seus gráficos. 

Em todos os casos, a hora correspondente à ultima barra do gráfico está alinhada com a hora que aparece no relógio do Windows.

Talvez o que esteja te confundindo seja o posicionamento dos rótulos de horário no eixo horizontal do gráfico.

O horário que aparece no eixo horizontal corresponde à barra que está no início (extremidade esquerda) do rótulo.

Por exemplo, se o rótulo for "9 abr 10:05", isso significa que a barra de 10:05 é a barra que aparece acima do "9" e as barras à direita do "9" serão 10:06, 10:07, etc.

Vamos considerar a primeira imagem:

- o relógio do Windows marca 13:28

- no gráfico do WINJ19, a barra que aparece no início do rótulo "1 abr 13:28" é justamente a última barra do gráfico, que é a de 13:28 (tudo ok)

- já no gráfico do WDOK19, o último rótulo é "1 abr 13:18", portanto, a barra que está no início desse rotulo (logo acima do "1" de "1 abr ...") é a de 13:18 e, a partir daí, indo pra direita, aparecem as barras de 13:19, 13:20 ... e a última barra é a de 13:28, que coincide com a hora do Windows

Seguindo essa mesma lógica, vc verá que nas outras imagens a última barra de cada gráfico também coincide certinho com a hora do Windows. Não há atraso.

Era isso que estava te confundindo?

obs: uma maneira simples de verificar se o gráfico está sincronizado é posicionar o mouse em cima da última barra do gráfico e observar o horário da barra na janela flutuante que surge.

Agradeço muito a sua análise e a sua dica de verificação da sincronização, Trader_Patinhas... vou observar melhor daqui por diante!!! Fico mais tranquilo! Muito obrigado!!! 
Trader_Patinhas
1164
Trader_Patinhas  
ABettega:

A multiplicação é artefato de primeiras iterações do código, não utilizo a multiplicação mais. Acredito que isso não seja o problema porque quando eu vejo a aba de Negociação, os pontos de TP e SL estão corretos como parametrizado nos inputs.

Se vc já verificou que os pontos de TP e SL estão corretos, então não vejo nada de errado no seu código.

Segue o mistério sobre por que vc está tendo slippages tão altos e frequentes.

Deixo para outros colegas opinarem.

Em tempo: já que estamos na "estaca zero", talvez valha a pena vc fazer um teste usando ORDER_TYPE_SELL_STOP_LIMIT, só pra confirmar se o problema é slippage mesmo, ou se é outra coisa. Nesse tipo de ordem o slippage será zero. Portanto, se com esse tipo de ordem vc continuar observando discrepâncias entre o preço da ordem e o preço de execução da mesma, saberemos que é algum outro tipo de problema (não faço ideia qual!), e não slippage. Vale lembrar que com ordem STOP_LIMIT há uma chance significativa de seu stop-loss ser "pulado" de vez em quando, pois a execução da ordem não é garantida (não use isso em conta real sem vc estar tomando conta do robô!).

Rogerio Figurelli
Moderador
58817
Rogerio Figurelli  
ABettega:

Acredito sim que pode ser algo no código. Estou fazendo o seguinte para colocar a ordem de venda:

São duas vendas diferentes, não executo as duas ao mesmo tempo, sempre que vou fazer um teste eu comento a outra para não ter conflito. Com o MqlTradeRequest eu acredito que seja o meio correto, minha suposição é que seja um erro com o request.type, tipo eu deveria usar ORDER_TYPE_SELL_STOP_LIMIT talvez, mas não consegui chegar a uma resolução quanto a isso. O request.type_filling não altera nada, todos os testes resultam nesse problema.

O trade.SellStop é o CTrade básico.

Olá @ABettega apenas meus dois centavos sobre essa questão.

Minha primeira sugestão é você começar controlando o escorregamento de preços e a operação da corretora forçando ela em zero (como abaixo):

request.deviation = 0;

Em tese, e em condições normais de temperatura e pressão, digamos assim, a corretora deveria garantir slippage zero dessa forma, ou não executar a operação, ou seja, como comentado aqui pelos colegas, justamente nos momentos de maior volatilidade você terá uma proteção programática.

A segunda sugestão é testar seus parâmetros de OrderSend() antes de realmente enviar a ordem, utilizando a função OrderCheck(), analisando os erros para facilitar identificar os possíveis problemas.

Note também que, no mundo real, nem todas corretoras conseguem de fato seguir essas regras (não sei se é o seu caso), porque esse roteamento é feito de fato pela comunicação entre o servidor MT5 e OMS na corretora, e isso depende muito das regras e alinhamento de ajustes estabelecidos no setup dos dois servidores, além claro da política de segurança da área de risco.

Tendo sucesso nesses testes, e só nesse momento, aí você pode ajustar melhor seu slippage acima, dentro do custo/benefício de sua estratégia. Por exemplo, em estratégias de HFT, esse escorregamento pode ser vital para o retorno do robô, e somente no mercado real será possível avaliar de fato a eficácia do ajuste.

Sds.,
Rogério Figurelli

ABettega
10
ABettega  
Trader_Patinhas:

Em tempo: já que estamos na "estaca zero", talvez valha a pena vc fazer um teste usando ORDER_TYPE_SELL_STOP_LIMIT, só pra confirmar se o problema é slippage mesmo, ou se é outra coisa. Nesse tipo de ordem o slippage será zero. Portanto, se com esse tipo de ordem vc continuar observando discrepâncias entre o preço da ordem e o preço de execução da mesma, saberemos que é algum outro tipo de problema (não faço ideia qual!), e não slippage. Vale lembrar que com ordem STOP_LIMIT há uma chance significativa de seu stop-loss ser "pulado" de vez em quando, pois a execução da ordem não é garantida (não use isso em conta real sem vc estar tomando conta do robô!).

Se eu usar o ORDER_TYPE_SELL_STOP_LIMIT, recebo Invalid Price, retcode 10015. Eu havia encontrado esse erro no começo do desenvolvimento, ao usar por exemplo BuyStop ao invés de BuyLimit, e encontrei a resposta num post seu, inclusive hehe


Rogerio Figurelli:

Olá @ABettega apenas meus dois centavos sobre essa questão.

Minha primeira sugestão é você começar controlando o escorregamento de preços e a operação da corretora forçando ela em zero (como abaixo):

Em tese, e em condições normais de temperatura e pressão, digamos assim, a corretora deveria garantir slippage zero dessa forma, ou não executar a operação, ou seja, como comentado aqui pelos colegas, justamente nos momentos de maior volatilidade você terá uma proteção programática.

A segunda sugestão é testar seus parâmetros de OrderSend() antes de realmente enviar a ordem, utilizando a função OrderCheck(), analisando os erros para facilitar identificar os possíveis problemas.

Note também que, no mundo real, nem todas corretoras conseguem de fato seguir essas regras (não sei se é o seu caso), porque esse roteamento é feito de fato pela comunicação entre o servidor MT5 e OMS na corretora, e isso depende muito das regras e ajustes estabelecidos, além claro da política de segurança da área de risco.

Tendo sucesso nesses testes, e só nesse momento, aí você pode ajustar melhor seu slippage acima, dentro do custo/benefício de sua estratégia. Por exemplo, em estratégias de HFT, esse escorregamento pode ser vital para o retorno do robô, e somente no mercado real será possível avaliar de fato a eficácia do ajuste.

Sds.,
Rogério Figurelli

Rogerio, boa tarde.

Tentei já utilizar o deviation como 0, não afetou nada, se eu colocar 0, 5, ou até 100, o resultado é o mesmo.

Não estou encontrando uma maneira legal de utilizar o OrderCheck - consigo apenas pegar o Retcode, é isso? Em caso de ORDER_TYPE_SELL_STOP, o retcode é 10009 (TRADE_RETCODE_DONE), e em caso de SELL_STOP_LIMIT, é 10015 (TRADE_RETCODE_INVALID_PRICE).

Agora, um aside aqui: No backtest vai funcionar exatamente igual funcionaria em execução real, ou eu realmente só consigo debugar em uma conta real? Eu estava trabalhando sob a premissa que o backtest deveria também executar sem esse slippage.

Trader_Patinhas
1164
Trader_Patinhas  
ABettega:

Se eu usar o ORDER_TYPE_SELL_STOP_LIMIT, recebo Invalid Price, retcode 10015. Eu havia encontrado esse erro no começo do desenvolvimento, ao usar por exemplo BuyStop ao invés de BuyLimit, e encontrei a resposta num post seu, inclusive hehe

Deve ser pq vc não está preenchendo o campo "stoplimit" da estrutura MqlTradeRequest, que é ignorado no caso de ordem STOP, mas obrigatório para ordem STOP_LIMIT.

Na ordem STOP_LIMIT o campo "price" é o preço de disparo da ordem limite e o campo "stoplimit" é o preço da ordem limite enviada quando o preço de disparo é atingido.

Verifique se é isso.

Quanto ao 10009 (TRADE_RETCODE_DONE) no caso da ordem STOP, este é o código esperado normalmente no retorno do OrderSend. Significa que a ordem foi enviada com sucesso para o servidor (não significa ainda que será aceita, tem que acompanhar a evolução do status da ordem pra saber).