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