Bibliothèque: MT4Orders QuickReport - page 4

 
Forester #:

Il s'est avéré que le testeur MQ transfère les ordres limités supprimés vers l'archive avec un certain retard :

Veuillez fournir des données pour la reproduction.
 
Forester #:

J'ai changé pour highchart. Il s'est avéré meilleur : google.charts s'est bloqué à 700 000 transactions, tandis que highchart les a affichées sans freins particuliers et a permis de zoomer sur des transactions individuelles.

Est-il exact que dans l'implémentation actuelle, Highcharts nécessite d'être en ligne ?
 
fxsaber #:
Veuillez fournir des données pour la reproduction.
 // différence par rapport à - connecter le testeur virtuel via SelectByIndex() au lieu de #define VIRTUAL_TESTER
 
 #include <MT4Orders.mqh>

#define  REPORT_TESTER             // Le testeur enregistrera automatiquement les rapports
//#define  REPORT_BROWSER            // Création d'un rapport au démarrage du navigateur - nécessite l'autorisation de la DLL.
#include <MT4Orders_QuickReport.mqh>//

input int inAmount = 10;
input int inOffset = 5;
input int inRange = 0;

bool OrdersBuy[];
bool OrdersSell[];
bool OrdersBuyStop[];
bool OrdersSellStop[];

void OnInit()
{
  ArrayResize(OrdersBuy, inAmount + 1);
  ArrayResize(OrdersSell, inAmount + 1);
  ArrayResize(OrdersBuyStop, inAmount + 1);
  ArrayResize(OrdersSellStop, inAmount + 1);
}

void OnTick()
{

   strategy ();

}

double OnTester() { 
QuickReport("report_0", true, 0);
   return(AccountInfoDouble(ACCOUNT_BALANCE)); 
}

void OnDeinit(const int  reason ){
   Print("OnDeinit main");

}


int TimeHour     ( datetime time ){return((int)((time / 3600) % 24));}/heure actuelle du jour. 3600 sec dans l'heure

void strategy (){
  string Symb = _Symbol;
  MqlTick Tick;
  
  if (SymbolInfoTick(Symb, Tick))
  {    
    double sl, tp, point = SymbolInfoDouble(Symb, SYMBOL_POINT);
    const double Offset = inOffset * point;

    ArrayInitialize(OrdersBuy, false);
    ArrayInitialize(OrdersSell, false);
    ArrayInitialize(OrdersBuyStop, false);
    ArrayInitialize(OrdersSellStop, false);

    for (uint i = OrdersTotal(); (bool)i--;)
      if (OrderSelect(i, SELECT_BY_POS))         
      {
        ulong Magic = OrderMagicNumber();
        if(Magic > 0 && Magic < 100 ){
           switch (OrderType())
           {
             case OP_BUY:
               OrderModify(OrderTicket(), OrderOpenPrice(), 0, Tick.bid + Magic * Offset, 0);
               OrdersBuy[Magic] = true;
               
               break;
             case OP_SELL:
               OrderModify(OrderTicket(), OrderOpenPrice(), 0, Tick.ask - Magic * Offset, 0);
               OrdersSell[Magic] = true;
               
               break;
             case OP_BUYLIMIT:
               OrderModify(OrderTicket(), Tick.ask - Magic * Offset, 0, 0, 0);
               OrdersBuy[Magic] = true;
               
               break;
             case OP_SELLLIMIT:          
               OrderModify(OrderTicket(), Tick.bid + Magic * Offset, 0, 0, 0);
               OrdersSell[Magic] = true;
               
               break;
           }
         }
         
        if(Magic > 100 && Magic < 200 ){
           Magic = Magic - 100;
           switch (OrderType())
           { 
             case OP_BUY:
               OrderModify(OrderTicket(), OrderOpenPrice(), 0, Tick.bid + Magic * Offset, 0);
               OrdersBuyStop[Magic] = true;
               
               break;
             case OP_SELL:
               OrderModify(OrderTicket(), OrderOpenPrice(), 0, Tick.ask - Magic * Offset, 0);
               OrdersSellStop[Magic] = true;
               
               break;
             case OP_BUYSTOP:
               OrderModify(OrderTicket(), Tick.ask + Magic * Offset, 0, 0, 0);
               OrdersBuyStop[Magic] = true;
               
               break;
             case OP_SELLSTOP:          
               OrderModify(OrderTicket(), Tick.bid - Magic * Offset, 0, 0, 0);
               OrdersSellStop[Magic] = true;
               
               break;
           }
           
         }
         if(Magic == 1001 ){//vérifier la fermeture complète
           OrderClose(OrderTicket(), OrderLots(), (OrderType()==OP_BUY ? Tick.bid : Tick.ask), 0 ) ;//vérifier la fermeture complète - cela fonctionne
         }
         
         //vérifier la fermeture partielle sur différents ticks
         if(Magic == 1002 ){
           double Lots = OrderLots();
           if(Lots==10){//lot primaire - fermer 25%
               double LotsDel1=NormalizeDouble(Lots/4, 2);// fermer 25% du lot d'origine
               OrderClose(OrderTicket(), LotsDel1, (OrderType()==OP_BUY ? Tick.bid : Tick.ask), 0 ) ;//vérifier la fermeture partielle
           }else{ // clôture du solde au prochain tick
              OrderClose(OrderTicket(), Lots, (OrderType()==OP_BUY ? Tick.bid : Tick.ask), 0 ) ;//vérifier la fermeture complète
           }
         }
            
         //vérifier la fermeture partielle de OrderClose() sur le même tick. Cela ne fonctionne pas dans le testeur virtuel - il passe de nombreux ordres avec 1/2 lot. 
         //Parce qu'après le premier OrderSend, un nouveau ticket sera créé et que l'ancien ticket ne sera pas retrouvé lors du deuxième OrderSend, le troisième ticket sera créé.
         if(Magic == 1003 ){
           double Lots = OrderLots();
           double LotsDel1=NormalizeDouble(Lots/3, 2);// fermer 33% du lot original
           OrderClose(OrderTicket(), LotsDel1,                         (OrderType()==OP_BUY ? Tick.bid : Tick.ask), 0 ) ;//vérifier la fermeture partielle
           OrderClose(OrderTicket(), NormalizeDouble(Lots-LotsDel1,2), (OrderType()==OP_BUY ? Tick.bid : Tick.ask), 0 ) ;//vérifier la clôture complète du solde sur le même tick - il y a un échec ici
         }
         
         if(Magic == 1004 ){
           //OrderCloseBy() ; //vérifiez-le
         }
         if(Magic == 1005 ){
            OrderDelete(OrderTicket());
         }

      }
     
    if(TimeHour(TimeCurrent())<23 && TimeHour(TimeCurrent())>0 ){return;} // effectuer des opérations de 0 à 1 et de 23 à 0
 
    for (int i = 1; i <= inAmount; i++)
    {
      if (!OrdersBuy[i])
        OrderSend(Symb, OP_BUYLIMIT, 10, Tick.ask - i * Offset, 0, 0, 0, NULL, i);

      if (!OrdersSell[i])
        OrderSend(Symb, OP_SELLLIMIT, 10, Tick.bid + i * Offset, 0, 0, 0, NULL, i);
      // 
      if (!OrdersBuyStop[i])
        OrderSend(Symb, OP_BUYSTOP, 10, Tick.ask + i * Offset, 0, 0, 0, NULL, i+100);

      if (!OrdersSellStop[i])
        OrderSend(Symb, OP_SELLSTOP, 10, Tick.bid - i * Offset, 0, 0, 0, NULL, i+100);
      
    }  
//vérifier les ordres à cours limité avec TP=SL=prix d'ouverture.
    OrderSend(Symb, OP_BUYLIMIT, 11,  Tick.ask -  Offset, 0,Tick.ask -  Offset, Tick.ask -  Offset, NULL, 1100);
    OrderSend(Symb, OP_SELLLIMIT, 11, Tick.bid +  Offset, 0,Tick.bid +  Offset, Tick.bid +  Offset, NULL, 1100);

//vérifie la clôture des ordres à cours limité OrderDelete()
    OrderSend(Symb, OP_BUYLIMIT, 12,  Tick.ask -  Offset, 0,Tick.ask -  Offset, Tick.ask -  Offset, NULL, 1005);
    OrderSend(Symb, OP_SELLLIMIT, 12, Tick.bid +  Offset, 0,Tick.bid +  Offset, Tick.bid +  Offset, NULL, 1005);
      

/ordres communs avec TP/SL = Offset Ne sera pas modifié, déclenché par TP/SL
    sl=Tick.bid-Offset; tp=Tick.ask+Offset;
    OrderSend(Symb, OP_BUY,  0.01, Tick.ask, 0, sl, tp,  NULL, 1000);//
    sl=Tick.ask+Offset; tp=Tick.bid-Offset;
    OrderSend(Symb, OP_SELL, 0.1, Tick.bid, 0, sl, tp,  NULL, 1000);//

//проверка ТП/СЛ на границе спреда. В виртуальном тестере - ок. У тестера MQ бывают сбои на 1-х сделках теста https://www.mql5.com/ru/forum/455977/page36#comment_51246904&nbsp;&nbsp; и   https://www.mql5.com/ru/forum/455977/page36#comment_51248196
    OrderSend(Symb, OP_BUY,  10, Tick.ask, 0, Tick.bid, Tick.bid,  NULL, 1000);//TP/SL à la limite de la propagation 
    OrderSend(Symb, OP_SELL, 10, Tick.bid, 0, Tick.ask, Tick.ask,  NULL, 1000);//TP/SL à la limite de la propagation 
  
//vérifier si OrderClose() est complètement fermé
    OrderSend(Symb, OP_BUY,  10, Tick.ask, 0, 0, 0,  NULL, 1001);
    OrderSend(Symb, OP_SELL, 10, Tick.bid, 0, 0, 0,  NULL, 1001);


    //vérifier la fermeture partielle OrderClose() 
    sl=Tick.bid-Offset; tp=Tick.ask+Offset;
    OrderSend(Symb, OP_BUY,  10, Tick.ask, 0, 0, 0,  NULL, 1002);
    sl=Tick.ask+Offset; tp=Tick.bid-Offset;
    OrderSend(Symb, OP_SELL, 10, Tick.bid, 0, 0, 0,  NULL, 1002);// 

  }
}

Serveur : MetaQuotes-Demo Hedge

Traiter le ticket 99 sur la deuxième page.

 

Этот отчет показал Firefox. Chrome зависает, ему нужны файлы поменьше.

Plus de 5,4 millions de lignes peuvent être téléchargées dans un fichier, mais le navigateur Firefox ne peut en traiter davantage.

Lors du chargement de ce rapport, le navigateur a utilisé environ 6 Go de mémoire (traitement d'environ 1 minute), puis l'a libérée, après quoi le rapport s'affiche sur la page : (Le rapport utilise 5 à 6 Go pour 80 à 100 000 lignes).

Je me demande ce qu'il en est avec d'autres navigateurs.

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégies de trading

Bugs, bugs, questions

fxsaber, 2023.10.18 15:00

Classement des navigateurs les plus rapides pour l'ouverture de grands tableaux html - steutments. Résultat sommaire pour un tableau de 35K lignes.

Navigateur LongueurTemps (sec)
MyPal 24
Basilic 35
Lune pâle 50
K-Meleon 52
Thorium 55

Mon choix sans équivoque se porte sur MyPal.

 
fxsaber #:
Ai-je bien compris que la mise en œuvre actuelle exige que vous soyez en ligne pour que Highcharts fonctionne ?

Oui, ou si les fichiers JS sont téléchargés plus tôt, ils sont extraits du cache.
Stocké pendant 1 mois : téléchargé le 8 janvier, supprimé le 8 février.


Je voulais ajouter rapidement leur code au fichier, mais il y a des milliers de guillemets, automatiquement changés en """. Mais une erreur apparaît. Cela n'a pas fonctionné rapidement.
 
Forester #:

Je voulais ajouter rapidement leur code au fichier, mais il y a des milliers de guillemets, je l'ai automatiquement changé en \"". Mais une erreur apparaît. Je n'ai pas pu le faire rapidement.

Version rapide.

Scripts: Balance Graph HTML - How to generate various variants of the Balance Graph.
Scripts: Balance Graph HTML - How to generate various variants of the Balance Graph.
  • 2019.04.09
  • www.mql5.com
But has no possibility of further modification. For example, if you need to get graphs of profits, commissions, turnover, etc. Where can i generate various variants of the graph. I pasted your html code into my library
 

QuickReport est en haut, Report est en bas. Le second ne met en évidence les couleurs que pour les niveaux déclenchés. Cela permet de comprendre que le SL ou le TP a été déclenché. Je l'ajouterais à QuickReport.

 
fxsaber #:

QuickReport est en haut, Report est en bas. Le second ne met en évidence les couleurs que pour les niveaux déclenchés. Cela permet de comprendre que le SL ou le TP a été déclenché. Je l'ajouterais à QuickReport.

Le TP et le SL seraient tous deux mis en évidence, puisqu'ils sont tous deux fixés au même prix. Le cas est rare (seulement pour un test d'état extrême), mais par souci de précision, j'ai ajouté du code pour le détecter et le mettre en évidence.

Forester #:
Je voulais ajouter rapidement leur code au fichier, mais il y a des milliers de guillemets, je l'ai automatiquement changé en \"". Mais une erreur apparaît. Cela n'a pas fonctionné rapidement.

J'ai changé d'avis sur l'ajout du code au fichier parce qu'il nécessite une licence. Plus d'informations ici https://shop.highcharts.com/
J'ai mis google.charts par défaut, si quelqu'un a besoin de Highcharts et a le droit de l'utiliser, il peut l'inclure par ce biais :

// Par défaut, MT4Orders_QuickReport utilise le logiciel gratuit google.charts, mais vous pouvez utiliser highcharts si vous en avez les droits.
// #define USE_highcharts // Vous pouvez télécharger et tester gratuitement tous les produits Highcharts. Une fois que votre projet/produit est prêt à être lancé, achetez une licence commerciale. https://shop.highcharts.com/
 
Forester #:

Le TP et le SL ont été mis en évidence, puisqu'ils sont tous deux fixés au même prix. Le cas est rare (uniquement pour le test des états extrêmes), mais pour plus de précision, j'ai ajouté du code pour la détection et la mise en évidence même dans ce cas.

Un cas intéressant qui a révélé une autre différence avec le MQ Tester.


Voici Virtual.


Et voici MQ-Tester.

Virtual a fermé les deux positions sur SL, MQ a fermé les deux positions sur SL, MQ a fermé les deux positions sur SL, MQ a fermé les deux positions sur SL. Virtual avait la priorité pour la fermeture de SL spécialement prescrite. MQ - inconnu.

 
fxsaber #:

Un cas intéressant qui a mis en évidence une autre différence par rapport au testeur MQ.

Il s'agit de Virtual.

Et voici MQ-Tester.

Virtual a clôturé les deux positions par SL, MQ - d'une manière différente. La priorité pour la fermeture SL a été spécialement prescrite pour Virtual. MQ - inconnue.

Oui, j'ai remarqué cela aussi. Peut-être que MQ dépend de la direction de l'achat ou de la vente, ce qui fonctionnera en premier.