Bibliothèque: SingleTesterCache

 

SingleTesterCache:

Données d'un seul passage du testeur.

SingleTesterCache

Author: fxsaber

 

Toutes les statistiques figurant dans le rapport d'exécution unique sont disponibles. Auparavant, la plupart de ces statistiques étaient impossibles à obtenir, même si vous disposiez de la source de l'Expert Advisor.

  double            ghpr;                    // moyenne géométrique transaction 
  double            ghprpercent;             // moyenne géométrique de la transaction en pourcentage 
  double            ahpr;                    // moyenne arithmétique de la transaction 
  double            ahprpercent;             // Moyenne arithmétique des transactions en pourcentage 
  double            zscore;                  // test en série 
  double            zscorepercent;           // test en série en pourcentage 
  double            lrcorr;                  // coefficient de corrélation de la régression linéaire 
  double            lrstderror;              // Erreur standard de l'écart d'équilibre de la régression linéaire 
  double            corr_prf_mfe;            // corrélation entre la mfe et le bénéfice 
  double            corr_prf_mae;            // corrélation entre mae et profit 
  double            corr_mfe_mae;            // corrélation entre mae et mfe 
  double            mfe_a;                   // corrélation entre mfe et profit, coefficient de la ligne de régression linéaire 
  double            mfe_b;                   // corrélation entre mfe et profit, coefficient de la ligne de régression linéaire 
  double            mae_a;                   // corrélation entre mae et profit, coefficient de la droite de régression linéaire 
  double            mae_b;                   // corrélation entre mae et profit, coefficient de la droite de régression linéaire 
  UINT              in_per_hours[24];        // répartition des intrants par heures 
  UINT              in_per_week_days[7];     // répartition des intrants par jour de la semaine 
  UINT              in_per_months[12];       // répartition des intrants par mois 
  double            out_per_hours[24][2];    // répartition des intrants par heures 
  double            out_per_week_days[7][2]; // répartition des intrants par jour de la semaine 
  double            out_per_months[12][2];   // répartition des intrants par mois 
  INT64             holding_time_min;        // temps de maintien de la position minimale 
  INT64             holding_time_max;        // durée maximale de maintien de la position 
  INT64             holding_time_avr;        // temps moyen de maintien de la position
 

La version actuelle du format tst ne contient pas les données suivantes

  • Temps en millisecondes.
  • PositionID.
  • Nombre magique.
Ceci impose des limitations dans les scénarios d'utilisation.
 

Reproduction de plusieurs bogues. Exécutez l'Expert Advisor dans le Tester sur un compte de couverture.

#include <MT4Orders.mqh> // https://www.mql5.com/fr/code/16006

#define  Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

#define  PAUSE 100000

void OnTick()
{
  static bool FirstRun = true;
  
  if (FirstRun)
  {
    OrderSend(_Symbol, OP_BUY, 1, Ask, 0, 0, 0);
    Sleep(PAUSE);
    
    OrderSend(_Symbol, OP_BUY, 2, Ask, 0, 0, 0);
    Sleep(PAUSE);

    if (OrderSelect(0, SELECT_BY_POS))
      OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0);
    Sleep(PAUSE * 2);
    
    if (OrderSelect(0, SELECT_BY_POS))
      OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0);
    Sleep(PAUSE * 2);

    TesterWithdrawal(100);    
    
    FirstRun = false;
  }
}

void OnDeinit( const int )
{
  const int Total = OrdersHistoryTotal();
  
  for (int i = 0; i < Total; i++)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
    {
      OrderPrint();
      
      Print(OrderTicketID()); // MT5-PositionID
    }
}


Nous obtenons ceci

2020.01.08 23:59:58   #1 2020.01.01 00:00:00 balance 0.00 0.00000 0.00000 0.00000 2020.01.01 00:00:00 0.00000 0.00 0.00 100000.00 0
2020.01.08 23:59:58   0
2020.01.08 23:59:58   #4 2020.01.02 06:00:00 buy 1.00 EURUSD 1.12137 0.00000 0.00000 2020.01.02 06:03:20 1.12132 -3.56 0.00 -4.46 0
2020.01.08 23:59:58   2
2020.01.08 23:59:58   #5 2020.01.02 06:01:40 buy 2.00 EURUSD 1.12137 0.00000 0.00000 2020.01.02 06:06:40 1.12129 -7.14 0.00 -14.27 0
2020.01.08 23:59:58   3
2020.01.08 23:59:58   #6 2020.01.02 06:10:00 balance 0.00 0.00000 0.00000 0.00000 2020.01.02 06:10:00 0.00000 0.00 0.00 -100.00 withdrawal 0
2020.01.08 23:59:58   0


Ensuite, nous lisons le fichier tst correspondant avec le script.

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

void OnStart()
{  
  uchar Bytes2[];
  
  if (MTTESTER::GetLastTstCache(Bytes2) != -1) // S'il était possible de lire le dernier enregistrement de cache d'une seule exécution
  {
    const SINGLETESTERCACHE SingleTesterCache(Bytes2); // L'introduire dans l'objet approprié.

    for (int i = 0; i < ArraySize(SingleTesterCache.Positions); i++)
      Print(SingleTesterCache.Positions[i].ToString());
  }
}


Il affichera des données sur les positions

id = 0
mfe = 0.0
mae = -8.029999999999999
profit = -4.46
lifetime = 00:03:20

id = 0
mfe = 0.0
mae = -21.4
profit = -14.27
lifetime = 00:05:00

id = 0
mfe = 0.0
mae = 0.0
profit = 0.0
lifetime = 00:00:00


Si nous comparons tout ce qui a été dit dans ce post, les bugs suivants sont formulés.

  • Des identifiants nuls au lieu des identifiants corrects.
  • La commission et le swap ne sont pas pris en compte dans le calcul du profit.
  • La transaction de retrait est incluse par erreur dans le nombre de positions de trading fermées.
 

Au lieu de fichiers set, j'utilise maintenant des fichiers tst. On peut passer de l'un à l'autre très rapidement, en ayant non seulement les paramètres d'entrée, mais aussi des backtests complets.

Il est dommage qu'il soit impossible de combiner différents TS dans un portefeuille en raison du manque de données millisecondes dans tst.


J'espère que les développeurs commenceront à utiliser pleinement les champs existants.

INT64             TradeDeal::time_create;             // heure de création de l'enregistrement

INT64             TradeOrder::time_setup;             // heure de réception de l'ordre du client par le système
INT64             TradeOrder::time_done;              // moment de l'annulation de la commande

Je pense qu'il est possible d'utiliser les champs existants en écrivant la valeur du temps en millisecondes plutôt qu'en secondes.


En général, dans la pratique, pour démontrer toute la coolitude de l'utilisation de tst, il ne faut pas donner de très petits défauts de tst. Il convient de les corriger.

 
Il est souvent nécessaire d'examiner plus en détail le graphique d'équilibre en un seul passage.
// Graphique d'équilibre interactif à passage unique.

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

#include <..\Files\Graph.mqh> // https://www.mql5.com/fr/code/18801

#import "shell32.dll"
  int ShellExecuteW( int, string, string, string, string, int );
#import

#define  BASEPATH (::TerminalInfoString(TERMINAL_DATA_PATH) + "\\MQL5\\Files\\")

bool CreateBalanceData( const SINGLETESTERCACHE &SingleTesterCache, const string FileName = "exdat.txt" )
{
  const int handle = FileOpen(FileName, FILE_WRITE | FILE_TXT | FILE_ANSI);
  const bool Res = (handle != INVALID_HANDLE);

  if (Res)
  {
    FileWriteString(handle, "var dat1=[\n");
    
    for (uint i = 0; i < SingleTesterCache.Header.equities_total; i++)
      FileWriteString(handle, "[" + (string)((long)SingleTesterCache.TradeState[i].time * 1000) + "," + ::DoubleToString(SingleTesterCache.TradeState[i].balance, 2) + "],\n");

    FileWriteString(handle, "];\n");
    FileWriteString(handle, "var T1=dat1[0][0];\n");
    FileWriteString(handle, "var T2=dat1[dat1.length-1][0];\n");
    FileWriteString(handle, "var nTrades=dat1.length;\n");
    FileWriteString(handle, "var Balance=" + ::DoubleToString(SingleTesterCache.TradeState[SingleTesterCache.Header.equities_total - 1].balance, 2) + ";\n");
    FileWriteString(handle, "var Currency=\"" + (SingleTesterCache.Header.trade_pips ? "Pips" : SingleTesterCache.Header.trade_currency[]) + "\";\n");

    FileClose(handle);
  }

  return(Res);
}

void OnStart()
{  
  uchar Bytes2[];
  
  if (MTTESTER::GetLastTstCache(Bytes2) != -1) // S'il était possible de lire le dernier enregistrement de cache d'une seule exécution
  {
    const SINGLETESTERCACHE SingleTesterCache(Bytes2); // L'introduire dans l'objet correspondant.
    
    const string FileName = "Report.htm";
    uchar Array[];    
    
    if ((StringToCharArray(StrMQH, Array) > 0) && FileSave(FileName, Array) && CreateBalanceData(SingleTesterCache))
      ShellExecuteW(0, "Open", BASEPATH + FileName, NULL, NULL, 3);      
  }
}


Si nous remplaçons

TradeState[i].balance -> TradeState[i].equity

il s'agit d'un graphique d'équité.

 

Dans tst, le volume des transactions/ordres est écrit de manière incorrecte. Il est toujours calculé comme si SYMBOL_TRADE_CONTRACT_SIZE = 100 000.

Si une valeur différente est définie, elle n'a aucun effet sur la valeur du volume dans tst.

 
fxsaber:

dans la pratique pour démontrer tout le bien-fondé de l'utilisation de tst dans la pratique n'est pas du tout donné par les petits défauts de tst. Il convient de les corriger.

Lapremière gorgée.

TesterPortfolio - портфель ТС
TesterPortfolio - портфель ТС
  • www.mql5.com
Возьмем третий пункт. Допустим, взяли несколько приглянувшихся советников из Маркета. Настроили их для каждого символа. TesterPortfolio запустит все варианты одновременно, показав общую торговую статистику (просадка эквити на реальных тиках и т.д.). Чаще всего использую для оценки диверсификации различных настроек своих ТС. Использование. На...
 
TesterPortfolio - портфель ТС
TesterPortfolio - портфель ТС
  • 2020.01.16
  • www.mql5.com
В приложении советник/робот, который объединяет несколько независимых одиночных проходов MT5-Тестера в один. Сценарии использования. Чужой советник с закрытым исходным кодом не запускается в MT5-Визуализаторе. TesterPortfolio сможет немного помочь. Сбор статистики прямо во время торговли советников с закрытым исходным кодом. Например...
 
 

Je ne sais pas comment cela se passe sur les blogs, l'apparition d'un nouveau commentaire (s'il ne s'agit pas d'une réponse) est-elle signalée d'une manière ou d'une autre ? Ou est-il préférable de poster dans l'un des fils de discussion du forum où les nouveaux commentaires sont visibles ?

Pourquoi ne l'ont-ils pas publié dans le KB ? Ce serait plus pratique.

Où poster pour obtenir une réponse rapide ?