Fonctions utiles de KimIV - page 2

 
Que pensez-vous de ceci :
if (err==146)
{
while (IsTradeContextBusy())
{
if (IsTradeAllowed()) break ;
else
Sleep(1000*1,1) ;
}}
Je pense que c'est une solution plus rapide. Veuillez partager vos commentaires.
Merci.
 
Red.Line писал (а): Merci pour ce sujet utile, bien que je sois sur les tartes brûlées, mais quand même, peut-être que quelqu'un a été confronté au problème du stockage et de l'échantillonnage de grands ensembles de données en µl. µl et des bases de données ? Quelqu'un a-t-il pensé dans cette direction ?
Une solution certes simple, mais quelque chose. https://forum.mql4.com/ru/9377
 
zhuki:
Que diriez-vous de cette variante :
if (err==146)
{
  while (IsTradeContextBusy())
  {
    if (IsTradeAllowed()) break;
    else 
    Sleep(1000*1,1);
  }
}
Cela me semble être une solution plus rapide. Je travaille de cette façon. Commentaire.
Merci.

Je m'en accommoderai. Avec compréhension. La pause est moindre, ça marche plus vite... Mais il y a une certaine redondance injustifiée dans votre version.

La fonction IsTradeContextBusy renvoie l'indicateur d'occupation du fil commercial. Cette fonction n'existait pas du tout avant la construction du 195e. Nous avons donc utilisé la fonction IsTradeAllowed qui renvoie un signe indiquant que l'EA est autorisé à négocier et que le flux de négociation est libre.

Nous autorisons l'EA à trader en cochant la case "Allow EA to trade" dans la boîte de dialogue des propriétés de l'EA (touche F7).

L'erreur 146 (Trade Stream is busy) n'a rien à voir avec le fait d'autoriser le conseiller expert à effectuer des transactions. Par conséquent, passons en revue les propriétés de la fonction IsTradeAllowed dans la mesure où elles concernent uniquement le fil de négociation.

Ainsi, le fil de négociation est libre et la fonction IsTradeAllowed renvoie True. Le fil de négociation est occupé, la fonction IsTradeAllowed renvoie False. Examinons maintenant les valeurs renvoyées par la fonction IsTradeContextBusy. Le fil commercial est libre, la fonction IsTradeContextBusy renvoie False. Le fil commercial est occupé, la fonction IsTradeContextBusy renvoie True. Nous pouvons constater que pour les mêmes états de flux commerciaux, les valeurs des fonctions IsTradeAllowed et IsTradeContextBusy sont opposées. En outre, ces fonctions font double emploi plutôt que de se compléter en ce qui concerne les états des flux commerciaux. Par conséquent, l'un d'entre eux peut être exclu. Laquelle ? La fonction IsTradeAllowed, comme je l'ai déjà mentionné ci-dessus, outre l'indicateur d'état du flux commercial, renvoie également l'indicateur permettant à l'EA de négocier, ce qui, dans cette situation, c'est-à-dire lors du traitement de l'erreur 146 (Trade Flow is busy), ne nous est pas nécessaire. Par conséquent, il sera nécessaire et suffisant d'utiliser une seule fonction IsTradeContextBusy. Si vous effectuez les abréviations ci-dessus, votre code sera réduit au mien :

if (err==146) while (IsTradeContextBusy()) Sleep(1000*1,1);
la seule différence étant la taille de la pause. Mais c'est une question de goût, de préférence personnelle, de style de négociation, etc. Vous pourriez mettre une pause de 0,1 seconde. Ce n'est pas une question de principe... Je préfère simplement 11 secondes.
 
Mais pour plus de précision, je préfère encore faire une pause entre tous les types d'opérations de trading de 5 secondes à la sortie du fil. Merci.
 

Deux erreurs ont été trouvées dans la fonction SetOrder:

  1. Utilisation incorrecte de la fonction MarketInfo. Elle aurait dû être appelée APRÈS la vérification du paramètre sy, et non AVANT.
  2. Correction des niveaux de réglage des commandes fonctionnant de manière incorrecte. En outre, les niveaux de prix des arrêts et des reprises n'ont pas été corrigés. Maintenant, il est réparé et fonctionne parfaitement. J'ai testé cette chose pendant longtemps en utilisant le script de test que je montrerai un peu plus tard.

Attention ! Le poste avec la fonction SetOrder pour le commerce en ligne a été corrigé. La fonction est un peu plus longue. Il ne rentrait pas dans le poste entier, il a donc fallu le déplacer dans la remorque.

 

Dans ce billet, j'ai décidé de donner les principaux points expliquant le fonctionnement de la fonction SetOrder. Je ne travaille pas moi-même avec des commandes, c'est-à-dire que je suis ici sur le territoire de quelqu'un d'autre. Peut-être que quelqu'un qui connaît le fonctionnement de la fonction SetOrder pourra suggérer des améliorations ou trouver des erreurs.

1. Dans les premières lignes de code, les variables locales sont déclarées et certaines d'entre elles sont initialisées. Par exemple, dans lsComm, le nom de l'EA et le nom de l'horizon temporel renvoyé par la fonction GetNameTF sont écrits. À propos, je ne vais pas m'attarder sur les fonctions telles que GetNameOP, GetNameTF, Message, etc., uniquement si quelqu'un a des questions à leur sujet.

string   lsComm=WindowExpertName()+" "+GetNameTF(Period());

2. Vérification des paramètres reçus. Si sy est vide, il est initialisé avec le nom de l'outil actuel. La variable de la couleur de l'icône sur le graphique est initialisée par le type de l'opération. Si le délai d'expiration non nul de l'ordre est inférieur au délai actuel, il est remis à zéro.

if (sy=="" || sy=="0") sy=Symbol();
msl=MarketInfo(sy, MODE_STOPLEVEL);
if (op==OP_BUYLIMIT || op==OP_BUYSTOP) clOpen=clOpenBuy; else clOpen=clOpenSell;
if (ex>0 && ex<TimeCurrent()) ex=0;

3. le corps du cycle des tentatives de négociation, dont le nombre est limité par la valeur de la variable globale NumberOfTry. Les opérations effectuées à l'intérieur de la boucle principale de la fonction SetOrder vont plus loin.

for (it=1; it<=NumberOfTry; it++)

4. Si la fonction SetOrder n'est pas exécutée dans le testeur, celui-ci a la possibilité de mettre fin à son fonctionnement. L'attente du cycle de libération du flux commercial est effectuée ici. Les variables d'environnement du marché sont mises à jour et l'heure actuelle est enregistrée.

if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) {
  Print("SetOrder(): Остановка работы функции");
  break;
}
while (!IsTradeAllowed()) Sleep(5000);
RefreshRates();
ot=TimeCurrent();

5. Envoi d'une demande à un serveur commercial. Si le ticket est positif, la fonction SetOrder est terminée.

ticket=OrderSend(sy, op, ll, pp, Slippage, sl, tp, lsComm, mn, ex, clOpen);
if (ticket>0) {
  if (UseSound) PlaySound(NameFileSound); break;
 

6. Si le ticket est négatif, le traitement des erreurs d' exécution est effectué.
7. Dans le cas des erreurs 128 (le temps d'attente a expiré pour l'exécution de la transaction), 142 (l'ordre a été mis en file d'attente) et 143 (l'ordre a été accepté par le concessionnaire pour exécution), nous marquons une pause de 66 secondes. Après la pause, à l'aide de la fonction ExistOrders (que nous décrirons plus tard), nous vérifions si l'ordre a déjà été passé pendant la période de temps entre la demande du serveur et le moment présent. Si l'ordre a été défini, quittez la fonction.

err=GetLastError();
if (err==128 || err==142 || err==143) {
  Sleep(1000*66);
  if (ExistOrders(sy, op, mn, ot)) {
    if (UseSound) PlaySound(NameFileSound); break;
  }
  Print("Error(",err,") set order: ",ErrorDescription(err),", try ",it);
  continue;
}

8. La taille de l'article et les prix d'achat et de vente sont stockés dans les variables locales.

mp=MarketInfo(sy, MODE_POINT);
pa=MarketInfo(sy, MODE_ASK);
pb=MarketInfo(sy, MODE_BID);

9. En cas d'erreur 130 (arrêts incorrects), les niveaux de prix de l'ordre, du stop et du take out sont corrigés si possible.

// Неправильные стопы
if (err==130) {
  switch (op) {
    case OP_BUYLIMIT:
      if (pp>pa-msl*mp) pp=pa-msl*mp;
      if (sl>pp-(msl+1)*mp) sl=pp-(msl+1)*mp;
      if (tp>0 && tp<pp+(msl+1)*mp) tp=pp+(msl+1)*mp;
      break;
    case OP_BUYSTOP:
      if (pp<pa+(msl+1)*mp) pp=pa+(msl+1)*mp;
      if (sl>pp-(msl+1)*mp) sl=pp-(msl+1)*mp;
      if (tp>0 && tp<pp+(msl+1)*mp) tp=pp+(msl+1)*mp;
      break;
    case OP_SELLLIMIT:
      if (pp<pb+msl*mp) pp=pb+msl*mp;
      if (sl>0 && sl<pp+(msl+1)*mp) sl=pp+(msl+1)*mp;
      if (tp>pp-(msl+1)*mp) tp=pp-(msl+1)*mp;
      break;
    case OP_SELLSTOP:
      if (pp>pb-msl*mp) pp=pb-msl*mp;
      if (sl>0 && sl<pp+(msl+1)*mp) sl=pp+(msl+1)*mp;
      if (tp>pp-(msl+1)*mp) tp=pp-(msl+1)*mp;
      break;
  }
  Print("SetOrder(): Скорректированы ценовые уровни");
}

10. Les informations, qui peuvent aider à résoudre le problème ou à trouver l'erreur ultérieurement, sont affichées dans le rapport.

Print("Error(",err,") set order: ",ErrorDescription(err),", try ",it);
Print("Ask=",pa,"  Bid=",pb,"  sy=",sy,"  ll=",ll,"  op=",GetNameOP(op),
      "  pp=",pp,"  sl=",sl,"  tp=",tp,"  mn=",mn);
if (pa==0 && pb==0) Message("SetOrder(): Проверьте в обзоре рынка наличие символа "+sy);

A la fin, nous traitons d'autres erreurs. Certains affichent une longue pause (5 minutes), d'autres bloquent le conseiller expert, d'autres encore autorisent de nouvelles tentatives de transaction, etc.

C'est ça ! Fin de la description !

 

La fonction ExistOrders().

Renvoie un indicateur de l'existence d'une commande. Répond à la question de savoir si l'ordre est fixé ou non. Vous pouvez utiliser cette fonction pour demander n'importe quelle commande, ainsi que des commandes plus spécifiques. Le filtre de demande est configuré à l'aide des paramètres de la fonction :

  • sy - Impose une restriction sur le nom de l'instrument. Le paramètre par défaut est "" - aucune restriction, c'est-à-dire n'importe quel instrument. Si vous passez NULL, la sélection des ordres sera limitée par le symbole actuel.
  • op - impose une restriction sur le type de commande. Aucune contrainte par défaut, c'est-à-dire que tout type d'ordre est vérifié. Les valeurs valides du paramètre sont -1, OP_BUYLIMIT, OP_BUYSTOP, OP_SELLLIMIT et OP_SELLSTOP.
  • mn - place une limite sur le numéro d'identification ("magique") de l'ordre. Aucune contrainte par défaut, c'est-à-dire que l'ordre avec n'importe quel numéro magique est vérifié.
  • ot - place une limite sur le temps de fixation de l'ordre. Il est vérifié que l'ordre a été fixé après la valeur de ce paramètre. Par défaut, il n'y a pas de limite, c'est-à-dire qu'un ordre avec n'importe quel temps de réglage est vérifié.
//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 12.03.2008                                                     |
//|  Описание : Возвращает флаг существования ордеров.                         |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (""   - любой символ,                   |
//|                                     NULL - текущий символ)                 |
//|    op - операция                   (-1   - любой ордер)                    |
//|    mn - MagicNumber                (-1   - любой магик)                    |
//|    ot - время открытия             ( 0   - любое время установки)          |
//+----------------------------------------------------------------------------+
bool ExistOrders(string sy="", int op=-1, int mn=-1, datetime ot=0) {
  int i, k=OrdersTotal(), ty;
 
  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      ty=OrderType();
      if (ty>1 && ty<6) {
        if ((OrderSymbol()==sy || sy=="") && (op<0 || ty==op)) {
          if (mn<0 || OrderMagicNumber()==mn) {
            if (ot<=OrderOpenTime()) return(True);
          }
        }
      }
    }
  }
  return(False);
}
 

Exemples d'utilisation de la fonction ExistOrders().

1. Vérifier la disponibilité de toute commande

ExistOrders();

2. Vérifier la disponibilité de tout ordre sur tout instrument sur le graphique actuel

ExistOrders(NULL);

3. Vérifier la présence d'un ordre BuyLimit sur un instrument quelconque.

ExistOrders("", OP_BUYLIMIT);

4. Vérifier s'il y a un ordre SellStop avec le numéro magique 123456 sur EURUSD

ExistOrders("EURUSD", OP_SELLSTOP, 123456);

5. Vérifiez la disponibilité de toute commande dont le délai de préparation est inférieur ou égal à 2 heures.

ExistOrders("", -1, -1, TimeCurrent()-2*60*60);
Dans le trailer, il y a un script pour tester la fonction ExistOrders. Les 4 premiers exemples du script sont commentés.

Dossiers :
 

Attention ! Dans le post du 12.03.2008 07:24 j'ai remplacé la pièce jointe SetOrder.mq4