Caractéristiques du langage mql5, subtilités et techniques - 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);
}

C'est censé fonctionner. Mais je ne conseillerais pas de le faire de cette façon).

 
Koldun Zloy:

C'est en fait optimal. Et il vous permet de définir des conditions de tri plus complexes.

Par exemple :

Oui et il n'y a pas d'autres solutions de toute façon.

Le but de ce modèle est d'être universel. Si vous passez une autre structure dans votre exemple qui ne contient pas au moins un champ a,b,c, il ne compilera pas. Autrement dit, la fonction ne peut pas travailler avec deux types de données différents en même temps.

 
 

Forum sur le trading, les systèmes de trading automatisé et les tests de stratégies de trading

Panneau de contrôle pour le trading. MQL5 AIDE NÉCESSAIRE

Vladimir Karputov, 2020.08.18 09:04

Ce code ne fonctionnerait pas - on ne peut pas comparer des galettes et des carrés:

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

Cette condition fonctionnera si l'ordre en attente est partiellement exécuté et génère une position. Alors un ordre et une position avec le même ticket existeront en même temps.

C'est pourquoi la construction suivante a du sens dans certaines situations.

::PositionSelectByTicket(::OrderGetInteger(ORDER_TICKET))
 
Si vous voulez mettre à zéro les données MQL de la position ou de la commande sélectionnée.
PositionSelectByTicket(0); // Обнуляет PositionGet*
OrderSelect(0);            // Обнуляет OrderGet*
 

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégie

Bibliothèques : MT4Orders

fxsaber, 2020.08.20 15:44

Pour ceux qui travaillent avec des transactions asynchrones, il sera utile de connaître les paramètres du nombre maximal possible de transactions asynchrones non traitées dans votre compte.

Il n'est pas difficile de le savoir.

Alert: 60 - Too many trade requests


Faites attention, vous pouvez vous heurter à une limite.

 
fxsaber:

Renat a dit il y a longtemps que l'on peut non seulement être pris dans une limite, mais aussi être bloqué par une DC.

 
fxsaber:

Cette condition sera déclenchée si l'ordre en attente est partiellement exécuté et génère une position. Alors un ordre et une position avec le même ticker existeront en même temps.

Le code suivant dans un compte de démonstrationRannForex-Server permet de reproduire immédiatement cette situation en exécutant cet 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();
  }     
}


Résultat.


A propos, le script montre (pas toujours la première fois) un bug dans l'exécution de l'OrderSend synchrone.

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

Après l'exécution d'OrderSend pendant quelques dizaines ou centaines de millisecondes, le prix de l'ordre est l'ancien, et non celui qui a été placé avec succès par OrderSend.


Pour en revenir au sujet des billets identiques, nous pouvons tirer quelques conclusions.

  1. Si un ordre à cours limité partiel est suspendu, l'onglet "Ordres et transactions" n'affichera pas la transaction générée.
  2. Sur une couverture, un seul ordre peut engendrer plusieurs transactions IN avec des prix différents. Le résultat sera un prix d'ouverture fractionné (par rapport aux pips) de la position.
  3. Vous pouvez fermer la position générée sans supprimer le Put partiel. Mais si après cela l'ordre en attente est déclenché, alors une transaction sera ouverte avec le ticket, égal au ticket de la position, qui a été fermée avant. Autrement dit, il peut arriver que vous fermiez une position avec un certain ticket. Et puis une position réapparaît avec le même ticker.
  4. L'exécution partielle peut être mise en œuvre différemment, selon le logiciel du courtier. Ce qui précède est une mise en œuvre standard de MT5.

Si quelqu'un a réussi à le reproduire sur un autre serveur de négociation, veuillez en partager le nom.

Nom de recherche: Oshibka 010.

 
fxsaber:


  1. Vous pouvez fermer la position générée sans supprimer le Put partiel. Mais si après cela l'ordre en attente est déclenché, il ouvrira une transaction avec un ticket égal au ticket de la position précédemment fermée. Autrement dit, il peut arriver que vous fermiez une position avec un certain ticket. Et puis une position apparaît à nouveau avec le même billet.

Pas un billet unique ? Comment est-ce possible ?

Les commandes et les transactions ont-elles des tickets uniques ?

 
Andrey Khatimlianskii:

Pas un billet unique ? Comment est-ce possible ?

L'explication que l'on peut trouver est que tant qu'il y a un ordre d'ouverture, il y a toujours une position. C'est juste qu'il n'est pas toujours visible - il n'y a pas de volume. Et ce poste a un ticket unique. Dans le cas d'un hedge, il est tout à fait possible qu'il y ait des in-triggers sur la même position après les transactions d'entrée et de sortie correspondantes.

Les commandes et les offres ont-elles même des billets uniques ?

Ils sont uniques. Mais bien sûr, ORDER_TICKET peut être égal à DEAL_TICKET.