Erreurs, bugs, questions - page 1861

 
kaus_bonus:

Alpari

fxopen

Ils n'ont pas de nageoires.
 
fxsaber:
Ils n'ont pas de drapeaux.


c'est clair, mais alors qu'est-ce qu'on ajoute pour obtenirCOPY_TICKS_ALL ?

parce qu'ils ontCOPY_TICKS_TRADE=0

et les ticks dans l'histoire avec les drapeaux manquants sont lesCOPY_TICKS_TRADE inconnus?

 
kaus_bonus:


c'est clair, mais alors qu'est-ce qu'on ajoute pour obtenirCOPY_TICKS_ALL ?

parce qu'ils ontCOPY_TICKS_TRADE=0

et les ticks dans l'historique avec les drapeaux manquants sont inconnusCOPY_TICKS_TRADE ?

Je pense que ce sont les mains tordues des courtiers.
 

Les fonctions HistoryDealGet* et HistoryOrderGet* sont écrites de manière très étrange, en termes de performances.

Lorsque je fais HistorySelect, par exemple, pour 100K enregistrements individuels. La fonction HistoryDealGet doit avoir comme premier argument non pas le nombre d'enregistrements dans la table de l'historique, mais un ticket. Et le tableau est trié par heure, et non par ticket. Par conséquent, la première chose que fait la fonction HistoryDealGet, à chaque fois qu'elle s'exécute, est de parcourir la table et de rechercher un ticket correspondant.


Pourquoi un tel gaspillage de ressources ! Il s'avère que le tout premier ticket et le plus récent seront exécutés à des vitesses différentes. Et pour obtenir toutes les caractéristiques de la dernière transaction, les fonctions HistoryDealGet parcourront à chaque fois l'ensemble de la table.


Pourquoi ne pas le rendre normal ?

long HistoryDealGetInteger( const int index, const ENUM_ORDER_PROPERTY_INTEGER  property_id ); // номер сделки, а не тикет


Et comment pouvons-nous tester le robot HFT, si pour obtenir le montant de la commission de la position actuelle, nous devons entrer dans l'historique lent par HistorySelect à chaque fois, et en aucun cas par HistorySelectByPosition? Le slippage de l'ordre en attente se transforme en une perte de performance !

 

ACCOUNT_PROFIT dans le testeur montre un non-sens.

Exécutez le conseiller expert qui ouvre et ferme la position immédiatement.

#include <MT4Orders.mqh>

#define  PRINT(A) Print(#A + " = " + (string)(A));

void OnTick()
{  
  static bool FirstRun = true;

  if (FirstRun && OrderSelect(OrderSend(_Symbol, OP_BUY, 1, 0, 0, 0, 0), SELECT_BY_TICKET))
  {
    PRINT(AccountInfoDouble(ACCOUNT_PROFIT))
    
    if (OrderClose(OrderTicket(), OrderLots(), 0, 0) && OrderSelect(OrdersHistoryTotal() - 1, SELECT_BY_POS, MODE_HISTORY))
      OrderPrint();
    
    FirstRun = false;          
  }
}

Le résultat est

2017.04.19 23:24:50.317 RTS-6.17,M1 (MetaQuotes-Demo): generating based on real ticks
2017.04.19 23:24:50.317 RTS-6.17,M1: testing of Experts\fxsaber\Test2.ex5 from 2017.04.06 00:00 to 2017.04.08 00:00 started
2017.04.19 23:24:50.419 RTS-6.17 : real ticks begin from 2017.04.06 00:00:00
2017.04.19 23:24:50.419 2017.04.06 09:45:01   deal #2  buy 1.00 RTS-6.17 at 114250 done (based on order #2)
2017.04.19 23:24:50.419 2017.04.06 09:45:01   deal performed [#2  buy 1.00 RTS-6.17 at 114250]
2017.04.19 23:24:50.419 2017.04.06 09:45:01   order performed buy 1.00 at 114250 [#2  buy 1.00 RTS-6.17 at 114250]
2017.04.19 23:24:50.421 2017.04.06 09:45:01   AccountInfoDouble(ACCOUNT_PROFIT) = 0.0
2017.04.19 23:24:50.421 2017.04.06 09:45:01   exchange sell 1.00 RTS-6.17 at 114200, close #2 (114200 / 114250)
2017.04.19 23:24:50.421 2017.04.06 09:45:01   deal #3  sell 1.00 RTS-6.17 at 114200 done (based on order #3)
2017.04.19 23:24:50.421 2017.04.06 09:45:01   deal performed [#3  sell 1.00 RTS-6.17 at 114200]
2017.04.19 23:24:50.421 2017.04.06 09:45:01   order performed sell 1.00 at 114200 [#3  sell 1.00 RTS-6.17 at 114200]
2017.04.19 23:24:50.421 2017.04.06 09:45:01   #3 2017.04.06 09:45:01 buy 1.00 RTS-6.17 114250 0 0 2017.04.06 09:45:01 114200 0.00 0.00 -56.44 0
2017.04.19 23:24:50.629 RTS-6.17,M1: 582089 ticks, 1573 bars generated. Environment synchronized in 0:00:00.063. Test passed in 0:00:00.421 (including ticks preprocessing 0:00:00.078).

ACCOUNT_PROFIT affiche zéro, mais en fait il est de -56.44. Par conséquent, l'équité, le drawdown, etc. sont estimés de manière incorrecte.

PositionGetDouble(POSITION_PROFIT) - même chose.

 
fxsaber:

Et comment tester un robot HFT, si pour connaître la taille de la commission de la position actuelle, vous devez entrer dans l'historique par HistorySelect et non par HistorySelectByPosition à chaque fois ? Voir le glissement d'un ordre en attente se transforme en un déchet de performance !

Est-ce que HistorySelect fonctionne par une recherche binaire de l'intervalle de temps demandé ou non ? C'est-à-dire O(N) ou O(log(N)) ?
 
fxsaber:
Est-ce que HistorySelect fonctionne par une recherche binaire de l'intervalle de temps demandé ou non ? C'est-à-dire O(N) ou O(log(N)) ?
Non. La recherche binaire n'est pas applicable dans ce cas.
 
Slawa:
Non. La recherche binaire n'est pas applicable dans ce cas.
Ainsi, en interne, les deux histoires (commandes et transactions) sont triées par ordre chronologique. Nous parlons de HistorySelect, et non de HistorySelectByPosition, qui n'est pas du tout optimisé.
 
fxsaber:
Ainsi, en interne, les deux histoires (commandes et transactions) sont triées par ordre chronologique.

Je suis désolé, je me suis un peu emporté.

Oui, ils sont triés par heure. L'enregistrement initial est recherché par une recherche binaire.

 
Slawa:

Oui, trié par heure. L'entrée initiale est recherchée par recherche binaire.

N'est-il pas logique de rechercher le dernier enregistrement de la même manière ?

C'est très stressant d'organiser l'histoire. Le HFT dans le testeur est presque irréaliste. J'ai écrit plusieurs messages sur le forum à ce sujet et fait une demande à la SD.


Et autre chose, si le terminal dispose déjà de l'historique, pourquoi exigez-vous d' utiliser HistorySelect au lieu de SELECT_BY_POS selon le principe de MT4 ? Et ce n'est pas clair du tout, pourquoi HistoryDealGet* est implémenté par le billet avec O(N) approprié, alors qu'il est raisonnable d'utiliser SELECT_BY_POS à nouveau ?


Des dossiers très intéressants

HistoryDealGetInteger(DealTicket, DEAL_TICKET);
HistoryOrderGetInteger(OrderTicket, ORDER_TICKET);