Bibliotheken: OnTickMulti

 

OnTickMulti:

Multisymbol OnTick.

OnTickMulti

Author: fxsaber

 
Мультисимвольное виртуальное окружение.
Мультисимвольное виртуальное окружение.
  • www.mql5.com
Данный пост посвящен дополнительному функционалу библиотеки виртуального окружения Virtual : Мультисимвольность. Теперь можно торговать в VIrtual не по одному символу, а по любым в одном виртуальном
 
   if (prev_calculated)
    EventChartCustom(Chart, 0, Index, 0, NULL);
Es kann vorkommen, dass Ticks übersprungen werden, wenn das Ereignis nicht in die Warteschlange gestellt wird. Das kommt vor (vor allem auf einem VPS oder einem langsamen Computer).
 
Alain Verleyen auf VPS oder langsamen Computern).

Leider lassen selbst einfache Expert Advisors, die nur über die Funktion „OnTick“ verfügen, Ticks aus. Bei handelsaktiven Expert Advisors werden CopyTicks-Funktionen und andere Kniffe eingesetzt, um sicherzustellen, dass keine Ticks ausgelassen werden.

Diese Bibliothek lässt garantiert keine Ticks aus – allerdings nur im Tester. Alles läuft genau wie bei OnTick.

 
Im Folgenden finden Sie den Code eines einfachen Expert Advisors von jemand anderem, anhand dessen ich die Anwendung von OnTickMulti veranschaulichen möchte.
/*
// https://www.mql5.com/ru/blogs/post/755348
#define VIRTUAL_TESTER_MULTI // Start in der virtuellen Handelsumgebung OnTickMulti
#define VIRTUAL_LIMITS_TP_SLIPPAGE // Limit-Orders und TP werden zum ersten akzeptierten Preis ausgeführt – positives Slippage
#define VIRTUAL_CLOSEALL_BYEND // Schließt alle Orders am Ende des Tests zwangsweise
// #define VIRTUAL_ALTERNATIVE // Alternative Abrechnungsgeschwindigkeit
*/

#include <MT4Orders.mqh> // https://www.mql5.com/de/code/16006
#include <fxsaber\OnTickMulti\OnTickMulti.mqh> // https://www.mql5.com/de/code/47647

/*
#define REPORT_TESTER             // Im Tester werden Berichte automatisch gespeichert
#define REPORT_BROWSER            // Bericht erstellen und Browser starten – erfordert DLL-Berechtigung.
#include <Report.mqh> // https://www.mql5.com/de/code/18801
*/

input group "Trading"
input double             LotSize=0.01;
input double             TPdist=0.1;                        // TP (%)
input double             SLdist=0.2;                        // SL (%)
input long               MyMagic=123;

input group "Benchmark: https://www.mql5.com/ru/forum/282062/page49#comment_50801337"
input int inRange = 0;

// OnTick mit mehreren Zeichen.
void OnTickMulti( const string &Symb, const int &Index )
{
  TradeStep(Symb, Index);
}

double OnTester()
{
   return AccountInfoDouble(ACCOUNT_BALANCE);
}

int GetHour( const datetime time )
{
  return((int)(time / 3600) % 24);
}

void TradeStep( const string &symbol, const int &Index )
{
   if(GetHour(TimeTradeServer()) < 2)
      return;

   DoTrade(symbol, Index);
}

bool IsMySymbol( const string &Symb, const int &Index )
{
  return(OnTickMulti.IsOnlySymbolBase ||
         (
        #ifdef __VIRTUAL__
          VIRTUAL::GetHandle() ? (OrderSymbolID() == Index) : // https://www.mql5.com/ru/forum/282062/page52#comment_51051261
        #endif // #ifdef __VIRTUAL__
          (OrderSymbol() == Symb)));
}

void DoTrade(const string &symbol, const int &Index )
{
   int total=OrdersTotal();
   bool haveBuy=false;
   bool haveSell=false;
   for(int i=0; i<total; i++)
   {
      if(OrderSelect(i, SELECT_BY_POS) &&
         OrderMagicNumber()==MyMagic &&
         IsMySymbol(symbol, Index))
      {
         int type=OrderType();
         if(type==OP_BUY)
            haveBuy=true;
         if(type==OP_SELL)
            haveSell=true;
      }
   }
   
   if(!haveBuy)
   {
      double price=SymbolInfoDouble(symbol,SYMBOL_ASK);
      int digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
      double tp=NormalizeDouble(price*(1.0+TPdist/100.0), digits);
      double sl=NormalizeDouble(price*(1.0-SLdist/100.0), digits);
      OrderSend(
         symbol,
         OP_BUY,
         LotSize,
         price,
         0,
         sl,
         tp,
         NULL,
         MyMagic);
   }

   if(!haveSell)
   {
      double price=SymbolInfoDouble(symbol,SYMBOL_BID);
      int digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
      double tp=NormalizeDouble(price*(1.0-TPdist/100.0), digits);
      double sl=NormalizeDouble(price*(1.0+SLdist/100.0), digits);
      OrderSend(
         symbol,
         OP_SELL,
         LotSize,
         price,
         0,
         sl,
         tp,
         NULL,
         MyMagic);
   }
}


Einstellungen des Testers.



Beschleunigung.

Man kann den Code beschleunigen, indem man am Anfang einige Zeilen auskommentiert.


Messungen.

Konfiguration Ergebnis
Ohne Virtual.mqh. kürzester Durchlauf 0:00:13,184, längster Durchlauf 0:00:15,031, durchschnittlicher Durchlauf 0:00:13,633
Mit Virtual.mqh, inVirtualTester = false. kürzester Durchlauf 0:00:14,735, längster Durchlauf 0:00:16,384, durchschnittlicher Durchlauf 0:00:15,081
Mit Virtual.mqh, inVirtualTester = true. kürzester Durchlauf 0:00:05,872, längster Durchlauf 0:00:05,964, durchschnittlicher Durchlauf 0:00:05,919
Mit Virtual.mqh, inVirtualTester = true + VIRTUAL_ALTERNATIVE. kürzester Durchlauf 0:00:06,172, längster Durchlauf 0:00:07,791, durchschnittlicher Durchlauf 0:00:06,524

Der Expert Advisor ist äußerst einfach aufgebaut (0–2 offene Positionen pro Wertpapier mit festen SL/TP, ohne Pending Orders), weshalb in dieser Variante lediglich eine 2,5-fache Beschleunigung erreicht werden kann.


TickValue+Swap+Commission.

Die oben genannten Tests wurden im Pip-Modus durchgeführt (siehe Screenshot der Einstellungen), um den TickValue nicht bei jedem Tick neu berechnen zu müssen und dafür andere Symbole einzubinden. In diesem Modus sind die Ergebnisse identisch.

Wenn eine maximale Beschleunigung mit vollem Umfang erforderlich ist, sollte diese Lösung verwendet werden.

OnTickMulti - с добавленными пересчетом прибыли в валюту депозита, свопами, комисссией в % за лот.
OnTickMulti - с добавленными пересчетом прибыли в валюту депозита, свопами, комисссией в % за лот.
  • 2023.12.25
  • www.mql5.com
Текущий вариант OnTickMulti https://www.mql5.com/ru/code/47647 считает прибыль в валюте каждого символа или можно получить в пипсах. Но на общий баланс они влияют в другой пропорции, согласно текущему
 

Forum zu Trading, automatisierten Handelssystemen und dem Testen von Handelsstrategien

Bibliotheken: OnTickMulti

fxsaber, 18.03.2024, 18:36

void DoTrade(const string &symbol, const int &Index )
{
   int total=OrdersTotal();
   bool haveBuy=false;
   bool haveSell=false;
   for(int i=0; i<total; i++)
   {
      if(OrderSelect(i, SELECT_BY_POS) &&
         (OrderMagicNumber()==Index))
      {
         int type=OrderType();
         if(type==OP_BUY)
            haveBuy=true;
         if(type==OP_SELL)
            haveSell=true;
      }
   }
   
   if(!haveBuy)
   {
      double price=SymbolInfoDouble(symbol,SYMBOL_ASK);
      int digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
      double tp=NormalizeDouble(price*(1.0+TPdist/100.0), digits);
      double sl=NormalizeDouble(price*(1.0-SLdist/100.0), digits);
      OrderSend(
         symbol,
         OP_BUY,
         LotSize,
         price,
         0,
         sl,
         tp,
         NULL,
         Index);
   }

   if(!haveSell)
   {
      double price=SymbolInfoDouble(symbol,SYMBOL_BID);
      int digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
      double tp=NormalizeDouble(price*(1.0-TPdist/100.0), digits);
      double sl=NormalizeDouble(price*(1.0+SLdist/100.0), digits);
      OrderSend(
         symbol,
         OP_SELL,
         LotSize,
         price,
         0,
         sl,
         tp,
         NULL,
         Index);
   }
}

Konfiguration Ergebnis
Ohne Virtual.mqh. kürzester Durchlauf 0:00:13,184, längster Durchlauf 0:00:15,031, durchschnittlicher Durchlauf 0:00:13,633

Oben habe ich im Code eine einfache Methode zur Beschleunigung eines Multi-Währungs-Expert-Advisors ohne jegliche Virtual-Bibliotheken hervorgehoben.

Konfiguration Ergebnis
Ohne Virtual.mqh +MagicNumberOrderSymbol kürzester Durchlauf 0:00:08,608, längster Durchlauf 0:00:10,236, durchschnittlicher Durchlauf 0:00:08,942

Eine kostenlose Beschleunigung um das 1,5-Fache!

 

Ich habe die Verlangsamung des Testers beim Wechsel vom Ein-Zeichen-Modus zum Mehrzeichen-Modus überprüft. Das war nicht ganz perfekt – der Berater ist nur ein Platzhalter.


Einziffern-Expert Advisor.

#property tester_no_cache

input group "Benchmark: https://www.mql5.com/ru/forum/282062/page49#comment_50801337"
input int inRange = 0;

const ulong StartTime = GetMicrosecondCount();
int AmountTicks = 0;

double OnTester()
{
  return((double)(GetMicrosecondCount() - StartTime));
//  return(AmountTicks);
//  return((double)AmountTicks / (GetMicrosecondCount() - StartTime));
}

void OnTick()
{
  AmountTicks++;
}
Konfiguration (OnTick) TimeLength (mcs) Anzahl der Ticks Leistung (Ticks/mcs)
EURUSD 1079331 9927153 9,19
GBPUSD 1.229.032 11.309.740 9,20
USDJPY 1.307.322 11986756 9,16
USDCHF 1.121.541 10359511 9,23
AUDUSD 1.175.578 10758136 9,15

Es ist deutlich zu erkennen, dass die Leistung des Testers, gemessen an der Anzahl der Ticks pro Zeiteinheit, nicht vom Symbol abhängt (Pips-Modus).


Multi-Symbol-Expert Advisor.

#property tester_no_cache

input group "Benchmark: https://www.mql5.com/ru/forum/282062/page49#comment_50801337"
input int inRange = 0;

#include <fxsaber\OnTickMulti\OnTickMulti.mqh> // https://www.mql5.com/de/code/47647

const ulong StartTime = GetMicrosecondCount();
int AmountTicks = 0;

double OnTester()
{
  return((double)(GetMicrosecondCount() - StartTime));
//  return(AmountTicks);
//  return((double)AmountTicks / (GetMicrosecondCount() - StartTime));
}

// OnTick mit mehreren Zeichen.
void OnTickMulti( const string &Symb, const int &Index )
{
  AmountTicks++;
}
Konfiguration (OnTickMulti) TimeLength (OnTickMulti) TimeLength (OnTick) Anzahl der Ticks Performance (OnTickMulti) Performance (OnTick)
EURUSD
3455901 1.079.331 9.927.153 2,87 9,19
EUR/USD, GBP/USD
6617085 2.308.363
21.236.893 3,20 9,19
EURUSD, GBPUSD, USDJPY
9188781 3615685 33.223.649 3,61 9,18
EURUSD, GBPUSD, USDJPY, USDCHF
11517804 4737226 43.583.160 3,78 9,20
EURUSD, GBPUSD, USDJPY, USDCHF, AUDUSD
16058223 5912804 54.341.296 3,38 9,19

Die Leistung hängt nur geringfügig von der Anzahl der Zeichen ab, ist jedoch dreimal niedriger.


Fazit:

Wenn Ihr Multi-Währungs-Expert Advisor aus einer Mischung unabhängiger Single-Währungs-Sub-TS besteht, ist es (mindestens) dreimal schneller, jeden der Sub-TS einzeln zu optimieren (und anschließend über Validate in einem Durchgang zusammenzufassen), als alle gemeinsam in einem Multiwährungs-Expert Advisor zu optimieren.

 
Der „Apart“-Modus wurde hinzugefügt.
Мультивалютный Apart-режим.
Мультивалютный Apart-режим.
  • www.mql5.com
Большинство мультивалютных советников представляют из себя портфель независимых (по логике торговых сигналов) друг от друга ТС, где если связь и есть, то за счет ММ - все ТС оказывают влияние на общие
 
Die Signatur von OnTickMulti hat sich leicht geändert.
// OnTick mit mehreren Zeichen.
void OnTickMulti( const string &Symb, const u int &Index )
 

Hallo,

Es sieht so aus, als würde der Code bei den neuesten Builds (5200+) nicht mehr kompiliert werden:

#include <fxsaber\OnTickMulti\OnTickMulti.mqh> // OnTick mit mehreren Zeichen.

int TicksCounter[]; // Zähler für die Anzahl der eingegangenen Ticks jedes angegebenen Zeichens.

void OnInit()
{
  // Wir initialisieren den Zähler für die eingegangenen Ticks.
  ArrayResize(TicksCounter, ArraySize(OnTickMulti.Symbols));
  ArrayInitialize(TicksCounter, 0);
}

double OnTester()
{
  // Wir geben die Anzahl der eingegangenen Ticks für jedes angegebene Symbol aus.
  for (uint i = ArraySize(TicksCounter); (bool)i--;)
    Print(OnTickMulti.Symbols[i] + " - " + (string)TicksCounter[i] + " ticks.");

  ArrayPrint(OnTickMulti.Symbols); // Liste der OnTickMulti-Zeichen.

  return(0);
}

// OnTick mit mehreren Zeichen.
void OnTickMulti( const string &Symb, const uint &Index )
{
  TicksCounter[Index]++; // Der Zähler für die eingegangenen Ticks für das angegebene Symbol wurde erhöht.
}
 
Marat Sultanov #:

Es sieht so aus, als würde der Code bei den neuesten Builds (5200+) nicht mehr kompiliert werden

DieBibliothek wurde an die Änderungen inMQL5_b5200+angepasst.

Новая версия платформы MetaTrader 5 build 5200: расширение OpenBLAS и усиление контроля в MQL5 - Версия MetaTrader 5 расширила поддержку библиотеки линейной алгебры OpenBLAS.
Новая версия платформы MetaTrader 5 build 5200: расширение OpenBLAS и усиление контроля в MQL5 - Версия MetaTrader 5 расширила поддержку библиотеки линейной алгебры OpenBLAS.
  • 2025.07.31
  • www.mql5.com
SylvesterEquationTriangular решает уравнение Сильвестра для вещественных квазитреугольных или комплексных треугольных матриц верхнетреугольные. SylvesterEquationTriangularBlocked решает уравнение Сильвестра для вещественных квазитреугольных или комплексных треугольных матриц верхнетреугольные матрицы