Bibliotecas: Virtual - página 8

 

Após as mudanças de idioma no último ano, minha versão do Virtual parou de funcionar. Voltei a usar a sua.
Mas realmente senti falta de uma comissão que levasse em conta as mudanças de preço. Especialmente para criptografia, em que o preço muda muitas vezes durante o teste.
Em minha versão antiga, o cálculo era preciso, mas lento, com operações de cadeia de caracteres e consulta de preços por instrumento. Provavelmente, devido a essa lentidão, você não quis adicioná-lo à sua própria versão.

Desta vez, fiz um cálculo simples e rápido para instrumentos como EURUSD, AUDUSD ... com moeda de depósito em USD e para todas as criptomoedas, todas em USDT. Ou seja, se a moeda de cotação == moeda da conta, o cálculo estará correto.

#define COMMISSION_TO_PRICE 2 // умножить полученную комиссию на цену, например для EURUSD *=1.12345; 1 - комиссия берется только при входе, 2 - комиссия берется 2 раза и при входе и при выходе

A comissão é simplesmente multiplicada por OpenPrice ou ClosePrice. Para instrumentos como USDJPY ou se a moeda de depósito não for USD(T), a opção pode ser desativada, pois não será precisa (como sua opção atual).

#ifdef  ORDER_COMMISSION
 this.Commission = this.Lots * (ORDER_COMMISSION);
 #ifdef  COMMISSION_TO_PRICE
   this.Commission *= this.OpenPrice + (COMMISSION_TO_PRICE==2 ? this.ClosePrice : 0.0);
 #endif // COMMISSION_TO_PRICE
#endif// ORDER_COMMISSION

Aqui está o que obtive no EURUSD:

DC:
Virtual c * por preço
Virtual sem * no preço

Como você pode ver, com a opção adicionada, a comissão difere apenas em 18 centavos para 140 negociações. E sem ela, em 42 dólares. É claro que você pode selecionar em sua variante o multiplicador médio não 4, mas 4,305, por exemplo (comissão média para o teste), mas isso terá de ser feito manualmente para cada instrumento e recompilar.

As edições não são grandes, espero que você queira adicionar essa opção ao código da biblioteca. Ou talvez você pense em algo mais universal.


Arquivos anexados:
Order.mqh  36 kb
 
Forester moeda de depósito USD e para todas as criptomoedas, tudo para USDT. Ou seja, se a moeda de cotação == moeda da conta, o cálculo estará correto.

De fato, essa fórmula sempre funciona.

Commission = 0.002%; // por lado.

OrderCommission = (OrderOpenPrice + OrderClosePrice) * Commission * OrderLots * TickValue / TickSize;

É claro que você pode escolher em sua variante o multiplicador médio não 4, mas 4,305, por exemplo (comissão média para o teste), mas isso terá que ser feito manualmente para cada instrumento e recompilar.

Outra variante.

input double inCommission = 0;
// .....
#define  ORDER_COMMISSION inCommission // OrderCommission() = OrderLots() * (ORDER_COMMISSION)), incluindo a opção dinâmica.

As edições não são grandes, espero que você queira adicionar essa variante ao código da biblioteca. Ou talvez você pense em algo mais universal.

Concordo plenamente que a edição é útil e deve ser feita. Ela deve ser verificada para fechamento parcial (OrderClose não para todo o lote) e CloseBy. Para verificar isso, basta escrever um script em que duas posições direcionadas de forma diferente sejam abertas no mesmo tick e um fechamento parcial e CloseBy sejam feitos de uma só vez. Ainda não estou pronto para fazer isso sozinho. Se você fornecer esse script com resultados corretos, farei suas correções mais rapidamente.

 
fxsaber #:

De fato, essa fórmula funciona o tempo todo.

É mais fácil para você, você está sempre no topo das coisas. Eu não faço isso o tempo todo. Pela primeira vez desde julho, decidi testar algo novamente....

Sobre
OrderClosePrice
- provavelmente há algumas corretoras que cobram comissão somente na abertura - para elas, é melhor não levar isso em conta. Para pipsing, a diferença será pequena, mas para metas grandes, será perceptível.
 
fxsaber #:
Concordo plenamente que a edição é útil e deve ser feita. É necessário verificar se há fechamento parcial (OrderClose não para todo o lote) e CloseBy. Para verificar isso, basta escrever um script em que duas posições direcionadas de forma diferente sejam abertas no mesmo tick e um fechamento parcial e CloseBy sejam feitos de uma só vez. Ainda não estou pronto para fazer isso sozinho. Se você me enviar um script desse tipo com um resultado correto, farei suas correções mais rapidamente.
Testei o que foi comentado e o deixei como uma versão funcional. Mas agora me esqueci de tudo. CloseBy - Não o utilizo, geralmente tenho ideias mais simples. Também não tenho tempo para isso. Enquanto houver entusiasmo, farei a estratégia.
 

A Virtual adiciona uma comissão aos limites de inadimplência:


Aparentemente, precisamos fazer uma verificação de tipo
 
Forester #:

O Virtual adiciona uma comissão aos limites não executados:

Aparentemente, precisamos fazer uma verificação de tipo
#define ORDER_COMMISSION -5 // OrderCommission() = OrderLots() * (ORDER_COMMISSION)), incluindo a opção dinâmica.
#include <fxsaber\Virtual\Virtual.mqh> // https://www.mql5.com/pt/code/22577

void OnStart()
{
  if (VIRTUAL::SelectByHandle(VIRTUAL::Create()))
  {
    VIRTUAL::NewTick();
    
    OrderDelete(OrderSend(_Symbol, OP_BUYLIMIT, 1, 0.01, 0, 0, 0));
    
    Print(VIRTUAL::ToString(1));
  }
}


Resultado.

#2 2025.11.25 19:23:11.105 buy limit 1.00 EURGBP.pro 0.01000 0.00000 0.00000 2025.11.25 19:23:11.105 0.87715 0.00 0.00 0.00 0 - 00:00:00


Funciona corretamente. Aparentemente, essas edições exigem uma verificação adicional.

 
fxsaber #:

Ele funciona corretamente. Aparentemente, essas edições exigem verificação adicional.

Você está certo.

Em ToClose(), adicionei o cálculo de comissões externas if (this.IsPosition()){

Corrigido, anexei o arquivo

Arquivos anexados:
Order.mqh  37 kb
 

Leio o patrimônio líquido e o saldo do Virtual em cada tick e crio um gráfico. Isso não era perceptível até hoje, mas hoje eles fizeram swaps enormes de -66.

O gráfico tem a seguinte aparência.



Ele deve ser como o registro do MT5.

O lucro final, como você pode ver, difere em alguns centavos devido a erros no arredondamento das comissões (apliquei comissões reais, não em pontos) e swaps (ainda não entendi como o MT os arredonda - não por meio de round()).

A soma dos swaps hoje para esse cálculo é de -5208,97. Apenas o tamanho do salto no gráfico. Acho que os swaps não são adicionados ao patrimônio líquido e ao saldo durante o cálculo, mas são aplicados somente no final, por isso essa aparência.

Eu chamo VIRTUAL::CalcSwaps(...) em OnTester() Isso pode ser feito na negociação virtual? Seria muito caro a cada tick. Talvez devesse ser feito no início de cada dia. Talvez isso já esteja programado e deva ser ativado por algum desafio? Lembro-me de que, em minha versão, fiz swaps para cada dia, pois você tem algo diferente. Se não tiver feito isso no passado, posso enviar meu código como exemplo.

 
Aleksei Kuznetsov #:

Talvez isso já esteja programado e deva ser ativado por algum desafio? Lembro-me de que, na minha versão, fiz trocas para cada dia, já que você o fez de forma diferente. Se não tiver feito isso no passado, posso enviar meu código como exemplo.

Eu não fiz. Mas, para o problema de plotagem da curva de saldo/patrimônio, eu faria o CalcSwaps uma vez no OnTester e, depois disso, o ajuste correspondente de uma passagem do Balance[]/Equity[]. É muito econômico e preciso.

Todo o processo de swaps no MT5 parece falho, pois não há histórico de swaps. E em um histórico grande, os resultados são terrivelmente distorcidos quando os swaps são levados em consideração. Pode acontecer de você ter otimizado no fim de semana e as melhores execuções dos arquivos de opções mostrarem valores completamente diferentes, se forem feitas em dias de semana.

Ainda assim, o MT5-tester não é uma referência.