Features of the mql5 language, subtleties and tricks - page 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);
}

It's supposed to work. But I wouldn't advise doing it that way.)

 
Koldun Zloy:

This is actually optimal. And it allows you to set more complex sorting conditions.

For example:

Yes and there are no other solutions anyway.

The point of the pattern is to be universal. If you pass another structure in your example that does not contain at least one field a,b,c, it will not compile. That is, the function cannot work with two different data types at the same time.

 
 

Forum on trading, automated trading systems and trading strategy testing

Control panel for trading. MQL5 HELP NEEDED

Vladimir Karputov, 2020.08.18 09:04

This code would not work - you can't compare patties and squares:

   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);
              }
           }
        }
     }

This condition will work if the pending order is partially executed and generates a position. Then an order and a position with the same ticket will exist at the same time.

For this reason the following construction makes sense in some situations.

::PositionSelectByTicket(::OrderGetInteger(ORDER_TICKET))
 
If you want to zero the MQL data of the selected position or order.
PositionSelectByTicket(0); // Обнуляет PositionGet*
OrderSelect(0);            // Обнуляет OrderGet*
 

Forum on trading, automated trading systems and strategy testing

Libraries: MT4Orders

fxsaber, 2020.08.20 15:44

For those working with asynchronous transactions, it will be useful to know the settings for the maximum possible number of unprocessed asynchronous transactions in your account.

This is not difficult to find out.

Alert: 60 - Too many trade requests


Be careful, you can run into a limit.

 
fxsaber:

Renat said a long time ago that not only can you get caught up in a limit, you can also get blocked by a DC

 
fxsaber:

This condition will be triggered if the pending order is partially executed and generates a position. Then an order and a position with the same ticker will exist at the same time.

The following code in aRannForex-Server demo account can immediately reproduce this situation by running this 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();
  }     
}


Result.


By the way, the script shows (not always the first time) a bug in the execution of synchronous OrderSend.

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

After OrderSend is executed for a few tens/hundreds of milliseconds, the order price is the old one, and not the one that was successfully placed by OrderSend.


Coming back to the topic of identical tickets, we can draw some conclusions.

  1. If a partial limit order is hanging, the tab "Orders and trades" will not show the generated trade.
  2. On a hedge, a single order can generate multiple IN trades with different prices. The result will be a fractional (relative to pips) opening price of the position.
  3. You can close the generated position without removing the Partial Put. But if after that the pending order is triggered, then a trade will be opened with the ticket, equal to the ticket of the position, which was closed before. That is, there may be a situation where you close a position with a certain ticket. And then a position reappears with the same ticker.
  4. Partial execution may be implemented differently, depending on the broker's software. The above is a standard MT5 implementation.

If someone has managed to reproduce it on another trading server, please share the name.

Search string: Oshibka 010.

 
fxsaber:


  1. You can close the generated position without deleting the Partial Put. But if after that the pending order is triggered, it will open a trade with a ticket equal to the ticket of the previously closed position. That is, there may be a situation where you close a position with a certain ticket. And then a position appears again with the same ticket.

Not a unique ticket? How can this be?

Are both orders and trades have unique tickets?

 
Andrey Khatimlianskii:

Not a unique ticket? How can that be?

The explanation that can be found is that as long as there is an opening order, there is always a position. It is just not always visible - there is zero volume. And this position has a unique ticket. Well, on a hedge for this reason it is quite possible that there will be in-triggers on the same position after the corresponding in and out trades.

Are the orders and deals even have unique tickets?

They are unique. But of course ORDER_TICKET can be equal to DEAL_TICKET.