Bibliotecas: MT4Orders - página 19

 
Jeka77769:

Hola! La descripción dice: "En consecuencia, OrderSelect en el modo SELECT_BY_TICKET en MT5 en casos raros (en el probador) puede seleccionar no lo que estaba previsto en MT4. "¿Puede explicar en qué casos exactamente?

Cuando los tickets de posición/comercio/orden coinciden.

 
Otro ejemplo(descripción) de código multiplataforma

Foro sobre trading, sistemas automatizados de trading y prueba de estrategias de trading

Asesores Expertos: eaBreakeven

fxsaber, 2018.01.11 08:13 pm.

#include <MT4Orders.mqh>     // https://www.mql5.com/es/code/16006
#include <Price_Compare.mqh> // https://www.mql5.com/es/code/16169

input int    Breakeven           = 15;           //Breakeven en puntos
input int    Distance            = 5;            //Distancia de equilibrio en puntos desde el precio de apertura de la posición
input int    MagicNumber         = 16112017;     //Número mágico
input bool   EnableSound         = true;         /Activar/desactivar la reproducción de sonido cuando se establece el umbral de rentabilidad
input string SoundFile           = "alert1.wav"; //Nombre del archivo de sonido

void OnTick()
{
  DoBreakeven();
}

double GetNewStopLoss()
{
  const double point = SymbolInfoDouble(OrderSymbol(), SYMBOL_POINT);  
  const double stop_level = SymbolInfoInteger(OrderSymbol(), SYMBOL_TRADE_STOPS_LEVEL) * point;
  
  const double price_open = OrderOpenPrice();
  const double latest_price = OrderClosePrice();  
  const double stoploss = OrderStopLoss();

  double new_stoploss = 0;
  
  //--- Mover el stop-loss al precio de breakven + Distancia, si el beneficio de la posición es mayor que los puntos de Breakeven 
  return(((OrderType() == OP_BUY)  && (CP(latest_price - price_open, point) >= Breakeven * point) &&
                                      (CP(new_stoploss = price_open + Distance * point, point) > stoploss) &&
                                      (CP(latest_price - new_stoploss, point) > stop_level)) ||
         ((OrderType() == OP_SELL) && (CP(price_open - latest_price, point) >= Breakeven * point) &&
                                      ((CP(new_stoploss = price_open - Distance * point, point) < stoploss) || !stoploss) &&
                                      (CP(new_stoploss - latest_price, point) > stop_level))
         ? NormalizeDouble(new_stoploss, (int)SymbolInfoInteger(OrderSymbol(), SYMBOL_DIGITS)) : 0);
}

void DoBreakeven()
{
//Si el umbral de rentabilidad es negativo, desactive la función de umbral de rentabilidad
  if (Breakeven >= 0)      
  //Bucle por posiciones
    for (int i = OrdersTotal() - 1; i >= 0; i--)
      if (OrderSelect(i, SELECT_BY_POS) && (OrderType() <= OP_SELL) && (!MagicNumber || (OrderMagicNumber() == MagicNumber)))
      {
        const double new_stoploss = GetNewStopLoss();
        
        if (new_stoploss)      
        {
          if (!OrderModify(OrderTicket(), OrderOpenPrice(), new_stoploss, OrderTakeProfit(), OrderExpiration()))
            Print(GetLastError());
          else if(EnableSound)
            PlaySound(SoundFile);
        }
      }
}
 

Foro sobre negociación, sistemas automatizados de negociación y prueba de estrategias de negociación

Cómo cambiar el volumen de una orden pendiente?

fxsaber, 2018.01.19 16:34

#include <MT4Orders.mqh> // https://www.mql5.com/es/code/16006

// Cambia el volumen de la orden pendiente. Async = true - modo asíncrono de envío de órdenes.
bool OrderChangeLots( const long Ticket, const double Lots, const bool Async = false )
{
  return(OrderSelect(Ticket, SELECT_BY_TICKET) && (Lots != OrderLots()) && (Async
         ? (OrderDeleteAsync(Ticket) &&
            OrderSendAsync(OrderSymbol(), OrderType(), Lots, OrderOpenPrice(), 0, OrderStopLoss(), OrderTakeProfit(), OrderComment(), OrderMagicNumber(), OrderExpiration()))
         : (OrderDelete(Ticket) &&
            (OrderSend(OrderSymbol(), OrderType(), Lots, OrderOpenPrice(), 0, OrderStopLoss(), OrderTakeProfit(), OrderComment(), OrderMagicNumber(), OrderExpiration()) != -1))));
}

void OnStart()
{
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderType() >= OP_BUYLIMIT))
      OrderChangeLots(OrderTicket(), OrderLots() + 1, true);
}
 
Cuanto mejor esté escrito un Asesor Experto de MT4, más fácil será convertirlo a MT5. Y el tamaño/complejidad del EA original no importa a la hora de convertirlo.

Foro sobre trading, sistemas automatizados de trading y testeo de estrategias de trading.

Asesores Expertos: Arbitraje de tres puntos

fxsaber, 2018.01.20 09:58

#define  MT4_TICKET_TYPE  // Obligar a OrderSend y OrderTicket a devolver un valor del mismo tipo que en MT4 - int.
#include <MT4Orders.mqh> // https://www.mql5.com/es/code/16006

#define MODE_MARGINREQUIRED 0

// https://www.mql5.com/ru/forum/170952/page9#comment_4134898
// La cantidad de fondos libres necesarios para abrir 1 lote para la compra
double MarketInfo( const string Symb, const int )
{
  MqlTick Tick;
  double MarginInit, MarginMain;

  return((SymbolInfoTick(Symb, Tick) && SymbolInfoMarginRate(Symb, ORDER_TYPE_BUY, MarginInit, MarginMain)) ? MarginInit * Tick.ask *
          SymbolInfoDouble(Symb, SYMBOL_TRADE_TICK_VALUE) / (SymbolInfoDouble(Symb, SYMBOL_TRADE_TICK_SIZE) * AccountInfoInteger(ACCOUNT_LEVERAGE)) : 0);
}

int DayOfWeek( void )
{
  MqlDateTime sTime = {0};

  TimeToStruct(TimeCurrent(), sTime);

  return(sTime.day_of_week);
}

int Hour( void )
{
  return((int)((TimeCurrent() % (24 * 3600)) / 3600));
}

#include "ThreePoint.mq4"
 
Si aparece la OnTradeTransaction le permite escribir un asesor no comercial (Servicio) que rastrea la presencia de un asesor "clon" comercial que se ejecuta en la cuenta.
 

cierre de posición se deduce inmediatamente del saldo.

  • Por esta razón la Equidad antes de cerrar todas las posiciones no muestra a que será igual el Balance después del cierre.
  • Esto significa que simplemente no es posible calcular el punto de equilibrio en MT5.
  • MT4Orders todavía tiene una comisión para las posiciones. Por esta razón se produce la siguiente situación

    #include <MT4Orders.mqh>
    
    #define  PRINT(A) Print(#A + " = " + (string)(A))
    
    void OnStart()
    {
      double ProfitWithoutCommission = 0;
      double ProfitWithCommission = 0;  
      
      for (int i = OrdersTotal(); i >= 0; i--)
        if (OrderSelect(i, SELECT_BY_POS))
        {
          OrderPrint();
          
          ProfitWithoutCommission += OrderProfit() + OrderSwap(); // Calcular el beneficio actual sin tener en cuenta la comisión
          
          ProfitWithCommission += OrderProfit() + OrderSwap() + OrderCommission(); // Calcular el beneficio actual teniendo en cuenta la comisión
        }
            
      PRINT(AccountInfoDouble(ACCOUNT_EQUITY) - AccountInfoDouble(ACCOUNT_BALANCE));
      
      PRINT(ProfitWithoutCommission);
      PRINT(ProfitWithCommission);  
    }


    Resultado

    #895889 2018.02.08 09:08:26 sell 1.00 EURUSD 1.22807 0.00000 0.00000 1.22877 -6.14 0.00 -70.00 0
    AccountInfoDouble(ACCOUNT_EQUITY)-AccountInfoDouble(ACCOUNT_BALANCE) = -70.0
    ProfitWithoutCommission = -70.0
    ProfitWithCommission = -76.14


    Como puede ver, la diferencia entre Equidad y Balance difiere por la cantidad de comisión. Y puede parecer que la expresión clásica de MT4

    ProfitWithCommission += OrderProfit() + OrderSwap() + OrderCommission(); // Calcular el beneficio actual teniendo en cuenta la comisión

    pierde su significado en MT5. Pero no es así. De hecho, al cerrar una posición, el Saldo cambiará por esta cantidad, no por la que mostraba antes el Capital. A grandes rasgos, el valor de Equidad en MT5 es falso, desde el punto de vista de este concepto en MT4.

    Tenga en cuenta esta peculiaridad de MT5. La librería es más precisa en este caso. Y será fácil calcular el mismo breakeven.

     

    posición abierta. Para ello basta con realizar cualquier operación sin comentario en el símbolo de la posición.

    La librería no perderá el comentario en el caso descrito - OrderComment() producirá el comentario que había cuando se abrió la posición.

     
    // Lista de cambios:
    // 13.02.2018
    // Añadir: Añadido registro de errores MT5-OrderSend.
    // Fix: Ahora sólo las órdenes MT5 de cierre (SL/TP/SO, cierre parcial/completo) son "invisibles".
    // Fix: Se ha corregido el mecanismo de determinación de SL/TP de posiciones cerradas tras OrderClose - funciona si StopLevel lo permite.
     

    Aquí se describe en detalle alguna peculiaridad del funcionamiento de MT5. La biblioteca trabajó esta situación correctamente durante mucho tiempo. Pero juraba (Alerta) que la situación no era estándar.

    Ahora no jurará

    // Lista de cambios:
    // 15.02.2018
    // Corrección: La comprobación de sincronización MT5-OrderSend ahora tiene en cuenta las posibles peculiaridades de la implementación ECN/STP.


    Como prueba, puede ejecutar este script en una cuenta demo complicada FXOpen-MT5.

    #include <Debug.mqh> // https://c.mql5.com/3/173/Debug.mqh
    #include <MT4Orders.mqh>
    
    #define Bid (SymbolInfoDouble(_Symbol, SYMBOL_BID))
    #define Ask (SymbolInfoDouble(_Symbol, SYMBOL_ASK))
    
    void OnStart()
    {
      _P(OrderCloseBy(_P(OrderSend(_Symbol, OP_BUY, 1, Ask, 0, 0, 0)), _P(OrderSend(_Symbol, OP_SELL, 1, Bid, 0, 0, 0))));
    }


    Resultado

    void OnStart(), Line = 9: OrderSend(_Symbol,OP_SELL,1,Bid,0,0,0) = 897247
    void OnStart(), Line = 9: OrderSend(_Symbol,OP_BUY,1,Ask,0,0,0) = 897248
    void OnStart(), Line = 9: OrderCloseBy(_P(OrderSend(_Symbol,OP_BUY,1,Ask,0,0,0)),_P(OrderSend(_Symbol,OP_SELL,1,Bid,0,0,0))) = true
    Archivos adjuntos:
    Debug.mqh  1 kb
     

    Foro sobre negociación, sistemas automatizados de negociación y ensayo de estrategias de negociación

    Organización del ciclo de fuerza bruta de órdenes

    fxsaber, 2018.02.16 09:40

    MT5 no va nada bien. Un ejemplo que muestra el problema

    // Ejemplo de lectura incorrecta del entorno de negociación en cada tick
    // El script emula dos ticks del TS, que debería abrir una posición si no hay ninguna.
    
    #include <Trade/Trade.mqh>
    
    // Devuelve el número de posiciones por carácter
    int GetAmountPositions( const string Symb )
    {
      int Res = 0;
      
      // Este código MQL5 tiene un error
      for (int i = PositionsTotal() - 1; i >= 0; i--)
        if (PositionGetSymbol(i) == Symb)
          Res++;
    
    /*
    // En MT4 este código se ejecuta sin error
      for (int i = OrdersTotal() - 1; i >= 0; i--)
        if (OrderSelect(i, SELECT_BY_POS) && (OrderType() <= OP_SELL) && (OrderSymbol() == Symb))
          Res++;
    */      
      return(Res);
    }
    
    // Ejemplo OnTick
    void ExampleOnTick()
    {
      static CTrade Trade;
      
      // Si no hay posición, abrir
      if (!GetAmountPositions(_Symbol))
        Trade.Buy(1);    
    }
    
    // Emulación de la llegada de dos eventos Tick
    void OnStart()
    {
      ExampleOnTick(); 
      
      Sleep(10); // Entre dos ticks ~10 ms.
      
      ExampleOnTick();
    }

    Qué te parece, si ejecutas este script en un símbolo sin posiciones, ¿qué pasará al final?

    La respuesta correcta es que se abrirán una o dos posiciones.

    Este problema se sortea si escribes en estilo MQL4 al menos parcialmente. Para asegurarse de ello, basta con hacer GetAmountPositions en estilo MQL4 (comentado en el código fuente), eliminando el estilo MQL5.

    Se especialmente vigilante con MQL5-style.