Características del lenguaje mql5, sutilezas y técnicas - página 184

 
enum EAct{PUSH,POP};

template<typename T>
void TempCondition(T &value,EAct act){
   static T temp=T();
   switch(act){
      case PUSH: temp=value; break;
      case POP: value=temp;
   }
}

#define  sortArray(_lArray,_lField) do {                     \
   for(int i = 0; i < ArraySize(_lArray); i++) {            \
      TempCondition(_lArray[i],PUSH);                       \
      for(int a = 1; a <= i; a++) {                         \
         if(_lArray[i]._lField < _lArray[a - 1]._lField){   \
            for(int b = i; b >= a; b--) {                   \
               _lArray[b] = _lArray[b - 1];                 \
               }                                            \
               TempCondition(_lArray[a - 1],POP);           \
               break;}}}} while(false)


struct STest{
   double a;
   int b;
};

void OnStart()
{
    STest test[700];
    sortArray(test,a);
}

Se supone que funciona. Pero no aconsejo hacerlo así).

 
Koldun Zloy:

Esto es realmente óptimo. Además, permite establecer condiciones de clasificación más complejas.

Por ejemplo:

Sí, y de todos modos no hay otras soluciones.

El objetivo del patrón es ser universal. Si pasas otra estructura en tu ejemplo que no contenga al menos un campo a,b,c, no compilará. Es decir, la función no puede trabajar con dos tipos de datos diferentes al mismo tiempo.

 
Los comentarios no relacionados con este tema han sido trasladados a "Cualquier pregunta de los novatos en MQL4 y MQL5, ayuda y discusión sobre algoritmos y códigos".
 

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

Panel de control para el comercio. SE NECESITA AYUDA PARA MQL5

Vladimir Karputov, 2020.08.18 09:04

Este código no funcionaría: no se pueden comparar hamburguesas y cuadrados:

   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      ulong OrderTicket=OrderGetTicket(i);
      if(OrderTicket>0 && PositionSelectByTicket(OrderTicket))
        {
         // Stop long позиции------------------------------------------
         if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
           {
            int cur_tr; //трейлинг
            double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
            double newSl = ask - cur_tr*_Point;
            double positionSl = PositionGetDouble(POSITION_SL);
            double positionTP = PositionGetDouble(POSITION_TP);
            if(newSl > positionSl || positionSl == 0)
              {
               CTrade trade;
               trade.PositionModify(OrderTicket,newSl,positionTP);
              }
           }
        }
     }

Esta condición funcionará si la orden pendiente se ejecuta parcialmente y genera una posición. Entonces una orden y una posición con el mismo ticket existirán al mismo tiempo.

Por esta razón, la siguiente construcción tiene sentido en algunas situaciones.

::PositionSelectByTicket(::OrderGetInteger(ORDER_TICKET))
 
Si quiere poner a cero los datos MQL de la posición o del pedido seleccionado.
PositionSelectByTicket(0); // Обнуляет PositionGet*
OrderSelect(0);            // Обнуляет OrderGet*
 

Foro sobre comercio, sistemas de comercio automatizados y pruebas de estrategias

Bibliotecas: MT4Orders

fxsaber, 2020.08.20 15:44

Para los que trabajan con transacciones asíncronas, será útil conocer la configuración del número máximo posible de transacciones asíncronas no procesadas en su cuenta.

Esto no es difícil de averiguar.

Alert: 60 - Too many trade requests


Ten cuidado, puedes encontrarte con un límite.

 
fxsaber:

Renat dijo hace tiempo que no sólo puedes quedar atrapado en un límite, sino que también puedes quedar bloqueado por un DC

 
fxsaber:

Esta condición se activará si la orden pendiente se ejecuta parcialmente y genera una posición. Entonces una orden y una posición con el mismo ticker existirán al mismo tiempo.

El siguiente código en una cuenta demode RannForex-Server puede reproducir inmediatamente esta situación ejecutando este EA.

// Воспроизведение ситуации наличия позиции и отложенного ордера с одинаковыми тикетами.

#define  Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

MqlTradeResult Result = {0};
MqlTradeRequest Request = {0};

int OnInit()
{

        Request.action = TRADE_ACTION_PENDING;
        Request.symbol = _Symbol;
        Request.volume = 100;
        Request.price = Ask;
        Request.type = ORDER_TYPE_BUY_LIMIT;
        
        return(!OrderSend(Request, Result)); // Выставили лимитник по текущей цене.
}

#define  TOSTRING(A) #A + " = " + DoubleToString(A, _Digits)

void OnTradeTransaction( const MqlTradeTransaction&, const MqlTradeRequest&, const MqlTradeResult& )
{
  if (OrderSelect(Result.order) && (OrderGetInteger(ORDER_STATE) == ORDER_STATE_PARTIAL)) // Если наш лимитник исполнился частично
  {
    if (Ask - OrderGetDouble(ORDER_PRICE_OPEN) < 100 * _Point)                            // и находится близко от текущей цены
    {
        Request.action = TRADE_ACTION_MODIFY;
        Request.order = Result.order;
        Request.price = Ask - 1000 * _Point;

      // тогда передвигаем его подальше.
      if (OrderSend(Request, Result)) // Если синхронный OrderSend выполнился успешно, то торговое окружение должно соответствовать.
      {
        // Проверка соответствия торгового окружения.
        if (OrderSelect(Request.order) &&                                                                // Если получилось взять данные нашего ордера
            NormalizeDouble(OrderGetDouble(ORDER_PRICE_OPEN) - Request.price, _Digits))                  // и цена ордера не равна цене успешного OrderSend
          Alert("Bug:" + TOSTRING(OrderGetDouble(ORDER_PRICE_OPEN)) + " != " + TOSTRING(Request.price)); // сообщаем о баге MT5.
      }
    }
    else
      ExpertRemove();
  }     
}


Resultado.


Por cierto, el script muestra (no siempre la primera vez) un error en la ejecución del OrderSend sincrónico.

Alert: Bug:OrderGetDouble(ORDER_PRICE_OPEN) = 0.89837 != Request.price = 0.88837

Después de que OrderSend se ejecute durante unas decenas/centenares de milisegundos, el precio de la orden es el antiguo, y no el que fue colocado con éxito por OrderSend.


Volviendo al tema de los billetes idénticos, podemos sacar algunas conclusiones.

  1. Si se cuelga una orden limitada parcial, la pestaña "Órdenes y operaciones" no mostrará la operación generada.
  2. En una cobertura, una sola orden puede generar múltiples operaciones IN con diferentes precios. El resultado será un precio de apertura fraccionado (en relación con los pips) de la posición.
  3. Puede cerrar la posición generada sin eliminar la venta parcial. Pero si después se activa la orden pendiente, entonces se abrirá una operación con el ticket, igual al ticket de la posición, que se cerró antes. Es decir, puede darse una situación en la que se cierre una posición con una determinada entrada. Y luego vuelve a aparecer una posición con el mismo ticker.
  4. La ejecución parcial puede implementarse de forma diferente, dependiendo del software del corredor. Lo anterior es una implementación estándar de MT5.

Si alguien ha conseguido reproducirlo en otro servidor de comercio, por favor comparta el nombre.

Cadena de búsqueda: Oshibka 010.

 
fxsaber:


  1. Puede cerrar la posición generada sin borrar la venta parcial. Pero si después se activa la orden pendiente, abrirá una operación con un ticket igual al de la posición cerrada anteriormente. Es decir, puede darse una situación en la que se cierre una posición con una determinada entrada. Y luego vuelve a aparecer un puesto con el mismo billete.

¿No es un billete único? ¿Cómo puede ser esto?

¿Tanto los pedidos como los intercambios tienen entradas únicas?

 
Andrey Khatimlianskii:

¿No es un billete único? ¿Cómo puede ser eso?

La explicación es que mientras haya una orden de apertura, siempre hay una posición. Sólo que no siempre es visible: hay un volumen cero. Y este puesto tiene una entrada única. Pues bien, en una cobertura por este motivo es muy posible que haya in-triggers en la misma posición después de las correspondientes operaciones de entrada y salida.

¿Los pedidos y las ofertas tienen incluso billetes únicos?

Son únicos. Pero, por supuesto, ORDER_TICKET puede ser igual a DEAL_TICKET.

Razón de la queja: