Merkmale der Sprache mql5, Feinheiten und Techniken - Seite 147

 
Igor Makanu:

IsInf() und IsNaN() funktionieren,

IsEqual() und IsZerro() sind fragwürdig, von einigen Quellen als "Trick für Double" gegoogelt.

IsNan() funktioniert, aber IsInf() nicht

IsInf( DBL_MIN_DENORM) == true

Seit wann sind denormalisierte Zahlen unendlich?

Und all diese Vergleiche mit epsilon - epsilon sollte proportional zu den Operanden erhöht werden. Im Allgemeinen gibt es kein allgemeingültiges Rezept, ich verwende Point als Epsilon (mit gerundeten Operanden) und ich möchte (und muss) die Differenz nicht mit DBL_EPSILON vergleichen.

 
Vict:

Und all diese Vergleiche mit epsilon - epsilon sollte proportional zu den Operanden erhöht werden. Im Allgemeinen gibt es kein allgemeingültiges Rezept, ich verwende Point als Epsilon (mit gerundeten Operanden), ich möchte die Differenz nicht mit DBL_EPSILON vergleichen (und ich brauche es auch nicht).

Ich habe einen Artikel von TVhttps://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ gefunden, den ich gestern gelesen habe.

Ja, Sie müssen ein anderes Beispiel verwenden, bei dem Sie die Vergleichsgenauigkeit angeben müssen

Sieg:

IsNan() funktioniert, aber IsInf() nicht

Seit wann sind denormalisierte Zahlen unendlich?

MQL scheint auf die 8. Stelle zu normalisieren, d.h. wenn NormalizeDouble() zu IsInf() hinzugefügt wird, ist das Ergebnis immer noch nicht besser.

 
Igor Makanu:

die Normalisierung in MQL scheint bis zur 8. Stelle zu gehen, d. h. wenn NormalizeDouble() zu IsInf() hinzugefügt wird, ist das Ergebnis immer noch nicht besser

Normalisierung in MQL ist überhaupt nicht dasselbe, ich weiß nicht, warum sie die Funktion so benannt haben. https://ru.wikipedia.org/wiki/%D0%94%D0%B5%D0%BD%D0%BE%D1%80%D0%BC%D0%B0%D0%BB%D0%B8%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D1%8B%D0%B5_%D1%87%D0%B8%D1%81%D0%BB%D0%B0

 
Ich habe zufällig in ME entdeckt, dass man mit STRG+1, STRG+2, ..... Lesezeichen erstellen kann. Und wechseln Sie zwischen ihnen mit ALT+1, ALT+2, ...
 
// Количество успешных OrderSend.
int GetOrderSendSucceeded()
{
  MqlTradeRequest Request = {0};
  MqlTradeResult Result;

  return(OrderSend(Request, Result) ? 0 : (int)Result.request_id + 1);
}

Zeigt an, wie viele erfolgreiche synchrone Handelsaufträge (OrderSend) und asynchrone Aufträge im Terminal insgesamt generiert wurden (seit Start).

Ich verwende es im Tester (am Ende), um zu sehen, wie oft die Aufträge geändert wurden.

 
Es gibt nur wenige Menschen, die nicht wissen, wie man z.B. TC-Klassen mit eigenen On-Events erstellt.

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

OnTick() funktioniert nicht in einer Klasseninstanz?

fxsaber, 2019.10.31 23:45

class BASE
{  
private:
  static BASE* Objects[];
  
public:
  BASE()
  {
    BASE::Objects[::ArrayResize(BASE::Objects, ::ArraySize(BASE::Objects) + 1) - 1] = &this;
  }
  
  ~BASE()
  {
    const int Size = ::ArraySize(BASE::Objects);
    
    for (int i = Size - 1; i >= 0; i--)
      if (BASE::Objects[i] == &this)
      {
        for (int j = i; j < Size - 1; j++)
          BASE::Objects[j] = BASE::Objects[j + 1];
          
        ::ArrayResize(BASE::Objects, Size - 1);
        
        break;
      }
  } 
    
  virtual void OnTick() = 0;
  
  static void AllTick()
  {
    for (int i = ::ArraySize(BASE::Objects) - 1; i >= 0; i--)
      BASE::Objects[i].OnTick();
  }
};

static BASE* BASE::Objects[];


class A : BASE
{
  virtual void OnTick()
  {
    Print(__FUNCSIG__);
  }
};

class B : BASE
{
  virtual void OnTick()
  {
    Print(__FUNCSIG__);
  }
};

A a;
B b;

void OnTick()
{
  BASE::AllTick();
}


Von BASE erben, dann werden die OnTick-Methoden in den Klassen automatisch aufgerufen.

 

Ein Beispiel für die Verwendung von X-Makro (achten Sie nicht auf die obskuren Typen, ich habe sie aus dem Arbeitscode herausgerissen. Vector ist ein dynamisches Array):

Zum Beispiel:

   vector_fund<upindex_t> seg2; vector_ref<vector_fund<upindex_t>> seg2_sub;
   vector_fund<upindex_t> seg3; vector_ref<vector_fund<upindex_t>> seg3_sub;
   vector_fund<upindex_t> seg4; vector_ref<vector_fund<upindex_t>> seg4_sub;
   for (uint i = 0;  i < 5114;  ++ i) {
      restore_image(seg2, "seg2"); restore_subimages(seg2_sub, "seg2");
      restore_image(seg3, "seg3"); restore_subimages(seg3_sub, "seg3");
      restore_image(seg4, "seg4"); restore_subimages(seg4_sub, "seg4");
      
      if (true) {} // тест №1, использует seg2 и seg2_sub
      if (true) {} // тест №2, использует seg3 и seg3_sub
      if (true) {} // тест №3, использует seg4 и seg4_sub
   }

1. Wir wollen Vektoren hinter einer Schleife definieren, um konstante Zuweisungen zu verhindern.

2. Jeder der Tests kann ausgeschaltet werden (es gibt sogar mehrere).

3. restore_image() und restore_subimages(), eine schwere und sehr zeitaufwändige Funktion (Lesen von Graph-Objekten aus dem Graph).

4. Wenn keiner der Tests z.B. seg2 verwendet, würde ich gerne sowohl die Definition als auch die entsprechende restore...() in einer Aktion entfernen, um zu verhindern, dass der Vektor zwar definiert, aber aufgrund der kommentierten restore...() leer ist, was zu fehlerhaften Ergebnissen führen würde.

Was ist zu tun?

#define  DEFSEG_LIST    \
   DEFSEG_HELPER(seg2) \
   DEFSEG_HELPER(seg3) \
   DEFSEG_HELPER(seg4)
   
#define  DEFSEG_HELPER(SEG) vector_fund<upindex_t> SEG; vector_ref<vector_fund<upindex_t>> SEG##_sub;
    DEFSEG_LIST;
#undef  DEFSEG_HELPER
   
   for (uint i = 0;  i < 5114;  ++ i) {
#define  DEFSEG_HELPER(SEG) restore_image(SEG, #SEG);  restore_subimages(SEG##_sub, #SEG);
    DEFSEG_LIST;
#undef  DEFSEG_HELPER
      ...
   }

Kommentieren Sie einfach die unnötigen Segx in DEFSEG_LIST aus. Dies führt zu den gleichen Ergebnissen wie im ersten Code. Eigentlich ist es schade, dass der Compiler nicht in der Lage ist, die Ausgabe des Prozessors anzuzeigen (der gcc -E analog).

 

Bei der genetischen Optimierung reichen manchmal schon die ersten paar tausend Durchläufe aus, um das Ergebnis mehr oder weniger zu verstehen.

Wenn Sie automatisch viele Optimierungen durchführen, möchten Sie, dass alles schneller läuft. Deshalb brauchen wir einen Mechanismus zur Unterbrechung der Optimierung.

#include <fxsaber\MultiTester\MTTester.mqh>  // https://www.mql5.com/ru/code/26132

// Выключает Оптимизацию ( и одиночный проход)
bool OptimizationStop( void )
{
  return(!MTTESTER::IsReady() && MTTESTER::ClickStart(false));
}


Verwendung.

// Демонстрация прерывания Оптимизации.

sinput int inAmountPasses = 20; // Через сколько проходов закончить
input int Range = 0; // 0..10000

double OnTester()
{
  int Data[];
  
  return(FrameAdd(NULL, 0, 0, Data)); // Сгенерировали TesterPass
}

void OnTesterPass()
{
  static int Amount = 0;
  
  ulong Pass;
  string Name;
  long ID;
  double Value;
  int Data[];

  while (FrameNext(Pass, Name, ID, Value, Data))
    if (++Amount > inAmountPasses)
    {
      OptimizationStop(); // Как достигли нужного количества проходов, выключили оптимизатор.
      
      break;
    }
}
 

Anweisungen zum Öffnen eines Diagramms mit einem Nullzeichen.


  1. Löschen Sie alle Charts aus Market Watch.
  2. Start Optimierung eines Rahmens EA (z.B. dieser) im mathematischen Modus.
  3. Beenden Sie die Optimierung und entfernen Sie den Frame EA aus dem Null-Symbol-Chart.
Eine solche Tabelle kann wahrscheinlich nützlich sein, um Ressourcen zu sparen.
 
Ich bin auf diese Besonderheit gestoßen.
class A
{
  static int i;
} a; // unresolved static variable 'A::i'

static int A::i = 0;

A b; // Надо прописывать после static


Wenn bei der Definition einer Klasse sofort eine Klasse mit statischen Feldern erstellt wird, kommt es zu einem Kompilierfehler.