Merkmale der Sprache mql5, Feinheiten und Techniken - Seite 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);
}

Es soll funktionieren. Aber ich würde nicht dazu raten, es so zu machen).

 
Koldun Zloy:

Das ist eigentlich optimal. Außerdem können Sie damit komplexere Sortierbedingungen festlegen.

Zum Beispiel:

Ja, und es gibt ohnehin keine anderen Lösungen.

Der Sinn des Musters ist es, universell zu sein. Wenn Sie in Ihrem Beispiel eine andere Struktur übergeben, die nicht mindestens ein Feld a,b,c enthält, wird es nicht kompiliert. Das heißt, die Funktion kann nicht mit zwei verschiedenen Datentypen gleichzeitig arbeiten.

 
Kommentare, die sich nicht auf dieses Thema beziehen, wurden nach "Fragen von Neulingen zu MQL4 und MQL5, Hilfe und Diskussion über Algorithmen und Codes" verschoben.
 

Forum zum Thema Handel, automatische Handelssysteme und Testen von Handelsstrategien

Bedienfeld für den Handel. MQL5 HILFE BENÖTIGT

Vladimir Karputov, 2020.08.18 09:04

Dieser Code würde nicht funktionieren - man kann keine Pastetchen und Quadrate vergleichen:

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

Diese Bedingung funktioniert, wenn der schwebende Auftrag teilweise ausgeführt wird und eine Position erzeugt. Dann existieren ein Auftrag und eine Position mit demselben Ticket gleichzeitig.

Aus diesem Grund ist die folgende Konstruktion in einigen Situationen sinnvoll.

::PositionSelectByTicket(::OrderGetInteger(ORDER_TICKET))
 
Wenn Sie die MMS-Daten der ausgewählten Position oder des Auftrags auf Null setzen wollen.
PositionSelectByTicket(0); // Обнуляет PositionGet*
OrderSelect(0);            // Обнуляет OrderGet*
 

Forum zum Thema Handel, automatisierte Handelssysteme und Strategietests

Bibliotheken: MT4Orders

fxsaber, 2020.08.20 15:44

Für diejenigen, die mit asynchronen Transaktionen arbeiten, ist es nützlich, die Einstellungen für die maximal mögliche Anzahl von nicht verarbeiteten asynchronen Transaktionen in Ihrem Konto zu kennen.

Es ist nicht schwer, dies herauszufinden.

Alert: 60 - Too many trade requests


Seien Sie vorsichtig, Sie können auf ein Limit stoßen.

 
fxsaber:

Renat hat schon vor langer Zeit gesagt, dass man nicht nur in einem Limit gefangen sein kann, sondern auch durch eine DC blockiert werden kann

 
fxsaber:

Diese Bedingung wird ausgelöst, wenn der schwebende Auftrag teilweise ausgeführt wird und eine Position erzeugt. Dann existieren gleichzeitig ein Auftrag und eine Position mit demselben Ticker.

Der folgende Code in einemRannForex-Server Demokonto kann diese Situation sofort reproduzieren, indem dieser EA ausgeführt wird.

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

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


Ergebnis.


Übrigens, das Skript zeigt (nicht immer zum ersten Mal) einen Fehler bei der Ausführung von synchronem OrderSend.

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

Nachdem OrderSend für einige zehn/hundert Millisekunden ausgeführt wurde, ist der Auftragspreis der alte und nicht derjenige, der durch OrderSend erfolgreich erteilt wurde.


Um auf das Thema der identischen Tickets zurückzukommen, können wir einige Schlussfolgerungen ziehen.

  1. Wenn eine Teil-Limit-Order hängt, wird auf der Registerkarte "Aufträge und Abschlüsse" der generierte Abschluss nicht angezeigt.
  2. Bei einem Hedge kann ein einziger Auftrag mehrere IN-Geschäfte mit unterschiedlichen Preisen erzeugen. Das Ergebnis ist ein Bruchteil des Eröffnungskurses der Position (bezogen auf die Pips).
  3. Sie können die erzeugte Position schließen, ohne den Partial Put zu entfernen. Wenn aber danach die Pending Order ausgelöst wird, wird ein Handel mit dem Ticket eröffnet, das dem Ticket der Position entspricht, die zuvor geschlossen wurde. Das heißt, es kann eine Situation eintreten, in der Sie eine Position mit einem bestimmten Ticket schließen. Und dann taucht eine Position mit demselben Ticker wieder auf.
  4. Die Teilausführung kann je nach Software des Brokers unterschiedlich umgesetzt werden. Die obige Darstellung ist eine Standardimplementierung von MT5.

Wenn es jemandem gelungen ist, das Problem auf einem anderen Handelsserver zu reproduzieren, teilen Sie uns bitte den Namen mit.

Suchbegriff: Oshibka 010.

 
fxsaber:


  1. Sie können die erzeugte Position schließen, ohne den Partial Put zu löschen. Wenn aber danach der Pending-Auftrag ausgelöst wird, wird er einen Handel mit einem Ticket eröffnen, das dem Ticket der zuvor geschlossenen Position entspricht. Das heißt, es kann eine Situation eintreten, in der Sie eine Position mit einem bestimmten Ticket schließen. Und dann erscheint wieder eine Stelle mit demselben Ticket.

Kein einmaliges Ticket? Wie kann das sein?

Haben sowohl Aufträge als auch Gewerke eindeutige Tickets?

 
Andrey Khatimlianskii:

Kein einmaliges Ticket? Wie kann das sein?

Die Erklärung dafür ist, dass, solange es einen Eröffnungsauftrag gibt, immer eine Position vorhanden ist. Sie ist nur nicht immer sichtbar - es gibt keine Lautstärke. Und diese Stelle hat eine einzigartige Eintrittskarte. Nun, bei einer Absicherung aus diesem Grund ist es durchaus möglich, dass es nach den entsprechenden In- und Out-Trades In-Trigger auf derselben Position geben wird.

Gibt es für die Bestellungen und Angebote überhaupt einmalige Tickets?

Sie sind einzigartig. Aber natürlich kann ORDER_TICKET gleich DEAL_TICKET sein.