Merkmale der Sprache mql4, Feinheiten und Techniken - Seite 34

 
Mir ist folgendes Problem aufgefallen: Wenn Sie ein Skript ausführen und es abstürzt (die Plattform schließt), dann speichert die Protokolldatei keine Datensätze, während das Skript läuft, was es ziemlich schwierig macht, einen Fehler im Code zu erkennen. Dieses Problem ist mir bisher nicht aufgefallen. War das schon immer so (keine gespeicherten Datensätze)?
 

Es scheint keine Möglichkeit zu geben, in MT4 zu wissen (ohne eine neue Verbindung herzustellen), ob sich die Hebelwirkung auf dem Konto geändert hat.

 
fxsaber #:

Es scheint keine Möglichkeit zu geben, in MT4 zu wissen (ohne eine neue Verbindung herzustellen), ob sich die Hebelwirkung des Kontos geändert hat.

Ich habe es vor etwa fünf Jahren getan. Die Hebelwirkung eines Kunden wurde zu bestimmten Stunden reduziert, ohne dass sich die Variable AccountInfoInteger(ACCOUNT_LEVERAGE) in irgendeiner Weise geändert hätte. Und er musste davon erfahren.

Ich weiß nicht, wie es wissenschaftlich aussieht, aber ich bin zu dem Schluss gekommen, dass es einen Kontoleverage gibt, der sich selten ändert, und einen Symbol-Leverage, der sich mehrmals am Tag ändern kann.
Ich habe es auf diese Weise überprüft:

//+------------------------------------------------------------------------------------------------------------------+
//| Проверяет изменение плеча и сообщает если это было
//+------------------------------------------------------------------------------------------------------------------+
void leverageCheck()
{
  if(MarketInfo(Symbol(), MODE_MARGINREQUIRED) == 0) return;

   // --- получаем текущее плечо из маржинальных требований, стоимости пункта, тек.котировки
  double leverageSymb = MarketInfo(Symbol(),MODE_TICKVALUE) * Bid / MarketInfo(Symbol(),MODE_MARGINREQUIRED) / Point;
  leverageSymb = int(MathRound(leverageSymb));
  
   // --- если плечо по символу стало меньше на 10% плеча по счету отметим это
  if(leverageSymb < percVar(AccountInfoInteger(ACCOUNT_LEVERAGE), -10))
  {
    string txt = TimeToString(TimeCurrent()) + " Leverage is reduced 1:" + (string)leverageSymb;
    Print(txt, " but account leverage = " + (string)AccountInfoInteger(ACCOUNT_LEVERAGE));

    // --- вывод информации на график
  }
}

//+-------------------------------------------------------------------------------------------------------------------+
//| Получает переменную, увеличивает или уменьшает его на переданный процент и возвращает новое значение
//| Чтобы уменьшить, нужно передать percent с минусом
//+-------------------------------------------------------------------------------------------------------------------+
double percVar(double var, double percent)
{
  return var*(1 + percent/100);
}


Manchmal kann der aktuell berechnete Hebel durch das Symbol leverageSymb 199, 198 statt 200 ergeben (wenn der Hebel 1:200 ist). Deshalb musste ich einen bestimmten Prozentsatz von der Standardhebelwirkung abziehen und mit diesem Wert vergleichen. Die obige Lösung war seinerzeit hilfreich, sie könnte sich als nützlich erweisen.

 
Vasiliy Pushkaryov #:

Ich habe dies vor etwa fünf Jahren getan. Bei einem Kunden wurde die Hebelwirkung zu bestimmten Stunden reduziert, ohne dass sich die Variable AccountInfoInteger(ACCOUNT_LEVERAGE) in irgendeiner Weise geändert hätte. Und er musste davon erfahren.

Ich weiß nicht, wie es wissenschaftlich aussieht, aber ich bin zu dem Schluss gekommen, dass es einen Kontoleverage gibt, der sich selten ändert, und einen Symbol-Leverage, der sich mehrmals am Tag ändern kann.
Ich habe es auf diese Weise überprüft:


Manchmal kann der aktuell berechnete Hebel durch das Symbol leverageSymb 199, 198 statt 200 ergeben (wenn der Hebel 1:200 ist). Deshalb musste ich einen bestimmten Prozentsatz von der Standardhebelwirkung abziehen und mit diesem Wert vergleichen. Die oben beschriebene Lösung könnte sich dann als nützlich erweisen.

Ja, es gibt kein Problem mit der Überwachung der Einschussanforderungen des Symbols. ACCOUNT_LEVERAGE - nur die Verbindung wiederherstellen.

 

Es ist gängige Praxis, den Handelsverlauf zu filtern, indem man sich die gewünschten Aufträge in einer Ticketliste merkt. Und dann SELECT_BY_TICKET auf dieser Liste.

Ich habe noch nie eine Variante gesehen, bei der nicht ein Ticket, sondern eine Position gespeichert wird. Nachfolgend finden Sie einen Vergleich der Leistungen.

#include <MT4Orders.mqh> // https://www.mql5.com/ru/code/16006
#include <fxsaber\Benchmark\Benchmark.mqh> // https://www.mql5.com/ru/code/31279

int Filter( TICKET_TYPE &Tickets[], int &Pos[] )
{
  const int Total = OrdersHistoryTotal();            

  ArrayResize(Tickets, Total);
  ArrayResize(Pos, Total);
  
  int Amount = 0;

  for (int i = 0; i < Total; i++)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && (OrderProfit() > 0))
    {
      Tickets[Amount] = OrderTicket();
      Pos[Amount] = i;
      
      Amount++;
    }
    
  ArrayResize(Tickets, Amount);
  ArrayResize(Pos, Amount);
  
  return(Amount);
}

template <typename T>
double Func1( int TypeSelect, const T &Array[] )
{
  double Res = 0;
  const int Total = ArraySize(Array);
  
  for (int i = 0; i < Total; i++)
    if (OrderSelect(Array[i], TypeSelect, MODE_HISTORY))
      Res += OrderProfit();
      
  return(Res);
}

void OnStart()
{   
  TICKET_TYPE Tickets[];
  int Pos[];

  Print(Filter(Tickets, Pos));
  
  const double Res1 = _B(Func1(SELECT_BY_TICKET, Tickets), 1); // Так делают почти все.
  const double Res2 = _B(Func1(SELECT_BY_POS, Pos), 1);        // Не встречал.
  
  Print(Res1);
  Print(Res2);
}


2021.10.11 01:37:08.254 Test19 EURUSD.rann,M1: 561002.61
2021.10.11 01:37:08.254 Test19 EURUSD.rann,M1: 561002.61
2021.10.11 01:37:08.254 Test19 EURUSD.rann,M1: Alert: Bench_Stack = 0, 1 <= Time[Test19.mq4 49 in OnStart: Func1(SELECT_BY_POS,Pos)] = 2827 mcs.
2021.10.11 01:37:08.251 Test19 EURUSD.rann,M1: Alert: Bench_Stack = 0, 1 <= Time[Test19.mq4 48 in OnStart: Func1(SELECT_BY_TICKET,Tickets)] = 7460 mcs.
2021.10.11 01:37:08.244 Test19 EURUSD.rann,M1: 35936

Wir sehen, dass die Ticketvariante fast dreimal so viel Leistung verliert.

 
fxsaber #:

Es ist zu erkennen, dass die Ticketvariante fast dreimal so viel Leistung verliert.

Wenn eine Position geschlossen/geöffnet ist, wird die Logik mit dem Ticket nicht unterbrochen, die Logik mit der Position jedoch schon.

 
TheXpert #:

Wenn eine Position geschlossen/geöffnet ist, wird die Logik mit dem Ticket nicht unterbrochen, die Logik mit der Position jedoch schon.

Es geht nur um den MODE_HISTORY-Modus.

 

Ist es theoretisch möglich, dass dieser Code eine Reihenfolge vermisst, die VOR und NACH dem Aufruf der Funktion bestand? Oder wird sie doppelt gezählt.

double GetLots()
{
  double Lots = 0;
  
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS))
      Lots += OrderLots();
      
  return(Lots);
}

D.h. was passiert mit der Indizierung, wenn ein Auftrag gelöscht wird oder während der Aufzählung erscheint?

 
fxsaber #:

Oder es wird doppelt gezählt.

Wenn wir von einer Standardsortierung nach Zeit oder Ticket ausgehen, erscheinen neue Aufträge am Ende der Liste, und logischerweise werden alle verschoben, wenn die ältesten gelöscht werden.

Es stellt sich heraus, dass beim Löschen einer Bestellung vom Anfang der Liste eine der Listen zweimal berücksichtigt werden kann. Das scheint leicht zu umgehen zu sein - man muss sich nur an das Ticket vom vorherigen Durchgang erinnern und vergleichen (aber immer noch keine Garantie).

Wie man einen Pass für den Rückpass bekommt - nicht herausgefunden

 
Andrei Trukhanovich #:

Wenn wir von einer Standardsortierung nach Zeit oder Ticket ausgehen, erscheinen neue Aufträge am Ende der Liste, und logischerweise werden alle verschoben, wenn die ältesten gelöscht werden.

Es stellt sich heraus, dass beim Löschen einer Bestellung vom Anfang der Liste eine der Listen zweimal berücksichtigt werden kann. Das scheint leicht zu umgehen zu sein - man muss sich nur an das Ticket vom vorherigen Durchgang erinnern und vergleichen (aber immer noch keine Garantie).

Wie man einen Pass für den Rückpass bekommt - ich habe es nicht herausgefunden

Vielen Dank für die ausführliche Antwort! Jetzt frage ich mich, wie ich ALLE Bestellungen auf einmal durchgehen kann.

Grund der Beschwerde: