Librerías: Virtual - página 8

 

Tras los cambios lingüísticos del último año, mi versión de Virtual dejó de funcionar. Cambié de nuevo a la suya.
Pero realmente echaba de menos una comisión que tuviera en cuenta los cambios de precio. Especialmente para cripto, donde el precio cambia muchas veces durante las pruebas.
En mi antigua versión era preciso, pero lento cálculo con operaciones de cadena y consulta de precios por instrumento. Probablemente de esta ralentización que no quería añadir a su propio.

Esta vez hice un cálculo simple y rápido para instrumentos como EURUSD, AUDUSD ... con divisa de depósito USD y para todas las criptomonedas, allí todo a USDT. Es decir, si divisa de cotización == divisa de cuenta, el cálculo será correcto.

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

La comisión simplemente se multiplica por OpenPrice o ClosePrice. Para instrumentos como USDJPY o si la moneda de depósito no es USD(T), la opción puede ser desactivada, ya que no será exacta (como su opción actual).

#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 // COMISIÓN_SOBRE_PRECIO
#endif// COMISIÓN_PEDIDO

Esto es lo que obtuve en EURUSD:

DC:
Virtual c * por precio
Virtual sin * por precio

Como se puede ver, con la opción añadida la comisión difiere sólo en 18 centavos para 140 operaciones. Y sin ella en 42 dólares. Por supuesto, usted puede seleccionar en su variante el multiplicador medio no 4, pero 4.305 por ejemplo (comisión media para la prueba), pero tendrá que ser hecho manualmente para cada instrumento y recompilar.

Las ediciones no son grandes, espero que usted quiera agregar esta opción al código de la biblioteca. O tal vez usted va a pensar en algo más universal.


Archivos adjuntos:
Order.mqh  36 kb
 
Forester de depósito USD y para todas las criptomonedas, allí todo a USDT. Es decir, si la divisa de cotización == divisa de cuenta, el cálculo será correcto.

De hecho, esta fórmula siempre funciona.

Commission = 0.002%; // por lado.

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

Por supuesto, usted puede elegir en su variante el multiplicador medio no 4, pero 4.305 por ejemplo (comisión media para la prueba), pero tendrá que hacerse manualmente para cada instrumento y volver a compilar.

Otra variante.

input double inCommission = 0;
// .....
#define  ORDER_COMMISSION inCommission // OrderCommission() = OrderLots() * (ORDER_COMMISSION)), incluida la opción dinámica.

Las ediciones no son grandes, espero que usted querrá añadir esta variante al código de la biblioteca. O tal vez usted va a pensar en algo más universal.

Totalmente de acuerdo en que la edición es útil y debe hacerse. Debería comprobarse para cierre parcial (OrderClose no para todo el lote) y CloseBy. Para comprobarlo, basta con escribir un script donde se abran dos posiciones dirigidas de forma diferente en el mismo tick y se haga un cierre parcial y CloseBy a la vez. Todavía no estoy preparado para hacerlo yo mismo. Si usted proporciona tal script con resultados correctos, haré sus correcciones más rápido.

 
fxsaber #:

De hecho, esta fórmula funciona siempre.

Es más fácil para ti, siempre estás en ello. Yo no lo hago todo el tiempo. Por primera vez desde julio, decidí probar algo de nuevo....

Sobre
OrderClosePrice
- probablemente hay algunos centros de corretaje que toman comisión sólo en la apertura - para ellos es mejor no tenerlo en cuenta. Para pipsing la diferencia será pequeña, pero para grandes objetivos será notable.
 
fxsaber #:
Totalmente de acuerdo en que la edición es útil y debe hacerse. Es necesario comprobar el cierre parcial (OrderClose no para todo el lote) y CloseBy. Para comprobarlo, basta con escribir un script en el que se abran dos posiciones dirigidas de forma diferente en el mismo tick y se realice un cierre parcial y CloseBy a la vez. Todavía no estoy preparado para hacerlo yo mismo. Si me envías un script de este tipo con un resultado correcto, te haré las correcciones más rápido.
Probé lo que está comentado y lo dejé como versión de trabajo. Pero ahora se me ha olvidado todo. CloseBy - No lo uso, normalmente tengo ideas más simples. Tampoco tengo tiempo para ello. Mientras haya entusiasmo, haré estrategia.
 

Virtual añade una comisión a los límites incumplidos:


Al parecer tenemos que hacer una comprobación de tipo
 
Forester #:

Virtual añade una comisión a los límites no ejecutados:

Aparentemente hay que hacer una comprobación de tipo
#define ORDER_COMMISSION -5 // OrderCommission() = OrderLots() * (ORDER_COMMISSION)), incluida la opción dinámica.
#include <fxsaber\Virtual\Virtual.mqh> // https://www.mql5.com/es/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 correctamente. Aparentemente, estas ediciones requieren una comprobación adicional.

 
fxsaber #:

Funciona correctamente. Al parecer, estas ediciones requieren una verificación adicional.

Usted tiene razón.

En ToClose() añadí cálculo de comisiones fuera if (this.IsPosition()){

Corregido, adjunto el archivo

Archivos adjuntos:
Order.mqh  37 kb
 

Leo la equidad y el balance de Virtual en cada tick y creo un gráfico. No se notaba hasta hoy, pero hoy han puesto swaps enormes de -66.

El gráfico se ve así.



Debería ser como el registro de MT5.

El beneficio final, como podéis ver, difiere en unos céntimos debido a errores en el redondeo de comisiones (he aplicado comisiones reales, no en puntos) y swaps (sigo sin entender cómo los redondea MT - no mediante round()).

La suma de swaps hoy para este cálculo es -5208,97. Sólo el tamaño del salto en el gráfico. Creo que los swaps no se suman al capital y al saldo durante el cálculo, sino que se aplican sólo al final, por eso se ve así.

Llamo a VIRTUAL::CalcSwaps(...) en OnTester() ¿Se puede hacer esto en el comercio virtual? Sería demasiado costoso en cada tick. Quizás debería hacerse al principio de cada día. Quizás ya está programado y habría que habilitarlo por algún defyne? Recuerdo que en mi versión hacía swaps para cada día, como tu hay algo diferente. Si no lo has hecho en su día, te puedo enviar mi código para que veas un ejemplo.

 
Aleksei Kuznetsov #:

A lo mejor ya está programado y habría que habilitarlo por algún defyne? Recuerdo que en mi versión hacía swaps para cada día, como tú lo tienes diferente. Si no lo has hecho en su día te puedo enviar mi código para que te sirva de ejemplo.

Yo no lo he hecho. Pero para el problema del trazado de Balance/Equity-Curve, yo haría CalcSwaps una vez en OnTester y luego el correspondiente ajuste de una pasada de Balance[]/Equity[] después de eso. Es super barato y preciso.

Todo el asunto de los swaps en MT5 parece defectuoso, ya que no hay historial de swaps. Y en un historial grande los resultados son horriblemente torcidos cuando se tienen en cuenta los swaps. Puede suceder que usted optimizó en el fin de semana y entonces los mejores funcionamientos de opt-files demuestran valores totalmente diversos, si se hacen en días laborables.

Aún así, MT5-tester no es un benchmark.