Toute question de débutant, afin de ne pas encombrer le forum. Professionnels, ne passez pas à côté. Nulle part sans toi - 6. - page 123

 
nick_travel:

Bonne journée !

Veuillez nous aider et nous expliquer pourquoi le conseiller expert ne fonctionne pas ou n'effectue pas de transactions ?

Peut-être qu'il veut manger ? Ou attendre un chèque de paie...
 
hoz:


Oui, d'ailleurs, cet arrangement est plus intelligent dans sa mise en œuvre. La fonction associée au début prend maintenant plus de place. Ça s'est passé comme ça :

Il n'y a rien à optimiser, n'est-ce pas ?

Je veux dire que c'est beaucoup plus pratique, quand il n'y a pas grand-chose au départ. Et tout est appelé purement par des fonctions. Et la dernière fois, il s'est avéré que le départ a toutes sortes de surcroîts de fonctions principales et de surcroîts de fonctions supplémentaires...

Et pourquoi passer un tableau par référence, si vous utilisez un nom de tableau déclaré globalement dans une fonction ? Peut-être que tu devrais le faire de cette façon :

void FindOrders(int &massive[])
{
   int oType;
   ArrayInitialize(massive, 0);
   for (int i=OrdersTotal() - 1; i>=0; i--)
   {
      if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
      if (OrderSymbol() != Symbol()) continue;
      if (OrderMagicNumber() != i_magic) continue;
      
      oType = OrderType();
      massive[oType] = massive[oType] + 1;
   }
}

Et tu peux le réduire un peu :

void FindOrders(int &massive[])
{
   ArrayInitialize(massive, 0);
   for (int i=OrdersTotal() - 1; i>=0; i--)
   {
      if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
      if (OrderSymbol() != Symbol()) continue;
      if (OrderMagicNumber() != i_magic) continue;
      
      massive[OrderType()] = massive[OrderType()] + 1;
   }
}

Et qu'en est-il des appels depuis le début et de l'affichage des messages. Il me semble qu'ils ont fait une erreur. Nous ne pouvons pas voir la fonction pr(), donc nous n'avons rien à suggérer.

J'ai vérifié le nombre d'ordres dans le testeur en utilisant un algorithme rapide :

   FindOrders(mn0, OrdersMassive);

   Comment ("\n"+"Всего ордеров = "+OrdersTotal()+
            "\n"+"Количество "+GetNameOP(0)+" = "+OrdersMassive[0]+
            "\n"+"Количество "+GetNameOP(1)+" = "+OrdersMassive[1]+
            "\n"+"Количество "+GetNameOP(2)+" = "+OrdersMassive[2]+
            "\n"+"Количество "+GetNameOP(3)+" = "+OrdersMassive[3]+
            "\n"+"Количество "+GetNameOP(4)+" = "+OrdersMassive[4]+
            "\n"+"Количество "+GetNameOP(5)+" = "+OrdersMassive[5]
            );

Vous pouvez envelopper l'ensemble de la sortie dans une fonction qui lira les données du tableau et affichera les informations de manière humaine.

 
nick_travel:

Bonne journée !

Veuillez nous aider et nous expliquer pourquoi l'EA ne fonctionne pas ou n'effectue pas de transactions ?


Parce qu'ici. pas tous télépathes et pas tous et les visionnaires !
 

Je vois !

Je veux dire, y a-t-il un paramètre ou quelque chose d'autre dont vous avez besoin ?

 
artmedia70:

Pourquoi passer un tableau par référence si vous utilisez un nom de tableau déclaré globalement dans la fonction ? Peut-être que ça devrait être comme ça :

void FindOrders(int &massive[])
{
   int oType;
   ArrayInitialize(massive, 0);
   for (int i=OrdersTotal() - 1; i>=0; i--)
   {
      if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
      if (OrderSymbol() != Symbol()) continue;
      if (OrderMagicNumber() != i_magic) continue;
      
      oType = OrderType();
      massive[oType] = massive[oType] + 1;
   }
}

En fait, oui, c'est logique. Mais vous le passez par référence ici aussi :)) Je l'ai eu après la dernière fois, lorsque les paramètres n'étaient pas déclarés globalement.

Et à propos de la fonction pr. C'est ici :

//+-------------------------------------------------------------------------------------+
//| Распринтовка на экран                                                               |
//+-------------------------------------------------------------------------------------+
void pr (string txt)
{
   string info [];
   ArrayResize(info, 20);
   string h, m, s, cm; int i;
   
   h = DoubleToStr(Hour(), 0);    if (StringLen(h) < 2) h = "0" + h;
   m = DoubleToStr(Minute(), 0);  if (StringLen(m) < 2) m = "0" + m;
   s = DoubleToStr(Seconds(), 0); if (StringLen(s) < 2) s = "0" + s;
   txt = h + ":" + m + ":" + s + " - " + txt;
   
   for (i=20-1; i>=1; i--)
   info[i] = info[i-1];
   info[0] = txt;
   
   for (i=20-1; i>=0; i--)
   if (info[i] != "")
   {
      cm = info[i];
      ObjectCreate ("txtw"+i, OBJ_LABEL, 0, 0, 0);
      ObjectSet    ("txtw"+i, OBJPROP_CORNER, 1);
      ObjectSet    ("txtw"+i, OBJPROP_XDISTANCE, 10);
      ObjectSet    ("txtw"+i, OBJPROP_YDISTANCE, 30+15*i);
      ObjectSetText("txtw"+i, cm, 10, "Times New Roman", Green);
   }
}
 
nick_travel:

Je vois !

Je veux dire, y a-t-il un paramètre ou quelque chose d'autre dont vous avez besoin ?


Je veux dire, je ne pense pas qu'il y ait de télépathes ici, et même s'il y en a, essayez de les intéresser à un tel exploit... Devinez et aidez...

 
hoz:


Je veux dire, il n'y a presque pas de télépathes par ici, et même s'il y en a, vous feriez mieux d'essayer de les intéresser à de tels exploits... Devinez et aidez...

Et peut-être un très bon système qui ne permet pas une mauvaise entrée sur le marché ! J'aimerais en avoir un !
 

J'ai un arrêt continu dans la fermeture des positions requises. L'essentiel est là :

1. la fermeture des postes fait l'objet d'un suivi.

2. Dès que la dernière position a été fermée sur la prise... ...toutes les positions ouvertes et en attente doivent être fermées immédiatement. Tout est fermé et trié par lots, c'est-à-dire les grands lots d'un coup, puis les plus petits. Il s'agit uniquement d'acquérir de l'expérience en matière de commandes.

La mise en œuvre est la suivante :

Dans start() à chaque tick :

 for (int ord=OrdersTotal()-1; ord>=0; ord--)
   {
      if (!OrderSelect(ord,SELECT_BY_POS)) continue;
      if (OrderMagicNumber() != i_magic) continue;
      if (OrderSymbol() != Symbol()) continue;
      if (OrderType() == 6) continue;
        
      g_ticket = OrderTicket();
      g_type = OrderType();
              
      // Блок модификации ордеров       
      if (i_sl != 0 || i_tp != 0)
      {
         if (OrderStopLoss() == 0 && OrderTakeProfit() == 0)
         {
            OrdersModifyer(g_ticket);
         }
      }
      // Закрытие всех ордеров, если последний ордер закрыт
      if (isCloseByTakeLastOpenPos(2))
      {
         // if (g_type < 2)
          {
              ClosePosBySortLots();
          }
          //else
          if (g_type > 1)
          {
              DeletePendingOrders(g_ticket);
          }
      }
   }

Nous sommes intéressés par la clôture des ordres de marché puisque l'ordre en attente est supprimé au besoin. Voici ce que nous avons :

//+-------------------------------------------------------------------------------------+
//| Получаем состояние последней позиции (Открыта или закрыта)                          |
//+-------------------------------------------------------------------------------------+
bool isCloseByTakeLastOpenPos(int delta)
{
   datetime lastOrderCloseTime = -1,               // Время закрытия последнего открытого ордера
            lastOOTHist = -1;                     // Время открытия последнего открытого ордера из истории
   int j = -1;
   pr ("Запустилась функция isCloseByTakeLastOpenPos");
   
   for (int i=OrdersHistoryTotal()-1; i>=0; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;
      if (OrderMagicNumber() != i_magic) continue;
      if (OrderSymbol() != Symbol()) continue;
      if (OrderType() > 1) continue;               // Все удалённые отложки нас не интересуют..
  
      if (lastOrderCloseTime < OrderCloseTime())   // Находим время закрытия..
      {
         lastOrderCloseTime = OrderCloseTime();   // ..последней закрытой позиции в истории
         j = i;
         pr ("j = " + j + "   " + TimeToStr(TimeCurrent()));
      }
   }
  if (OrderSelect(j, SELECT_BY_POS, MODE_HISTORY))
   {
      if (OrderProfit() + OrderCommission() + OrderSwap() <= 0) return (false);
//      pr ("OTP() = " + OrderTakeProfit() + "; OCP() " + OrderClosePrice() + "   " + TimeToStr(TimeCurrent()));
  //    pr ("OOP() = " + OrderOpenPrice() + "; OCP() " + OrderClosePrice() + "   " + TimeToStr(TimeCurrent()));
      if (MathAbs(OrderTakeProfit() - OrderClosePrice()) > delta * pt) return (false);
      else
      {
         lastOOTHist = OrderOpenTime();
         Comment("\n", "FUNC isCloseByTakeLastOpenPos: ",
                 "\n", "j = ", j,
                 "\n", "lastOOTHist = ", TimeToStr(lastOOTHist, TIME_SECONDS));
      }
   }
   else
   {
      Comment("\n", "FUNC isCloseByTakeLastOpenPos: ",
              "\n", "j = ", j,
              "\n", "не удалось выбрать ордер в истории");
      return(false);
   }
  
   for(int h=OrdersTotal()-1; h>=0; h--)
   {
      if (OrderSelect(h, SELECT_BY_POS, MODE_TRADES))
      {
         if (OrderMagicNumber() != i_magic)   continue;
         if (OrderSymbol() != Symbol())       continue;
         if (OrderType() > 1)                 continue;
         if (lastOOTHist < OrderOpenTime()) return(false);  // Выбранная рыночная позиция открыта позже закрытой по тейку
      }
      else {Print("FUNC isCloseByTakeLastOpenPos : не удалось выбрать рыночный ордер");return(false);}
   }
   
   return (true);
}

//+-------------------------------------------------------------------------------------+
//| Закрытие ордеров, отсортированных по размеру лотов                                  |
//+-------------------------------------------------------------------------------------+
void ClosePosBySortLots()
{
   double a[][2];
   int p = 0;
   
   for (int i=OrdersTotal()-1; i>=0; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
      if (OrderMagicNumber() != i_magic) continue;
      if (OrderSymbol() != Symbol()) continue;
      if (OrderType() < 2)
      {
         p++;
         ArrayResize(a, p);
         a[p-1][0] = OrderLots();
         a[p-1][1] = OrderTicket();
      }
   }
   pr ("ClosePosBySortLots(): " + "p = " + p);
   if (p > 0)
   {
      ArraySort(a, WHOLE_ARRAY, 0, MODE_DESCEND);
      for(i=0; i<p; i++)
      {
         if (OrderSelect(a[i][1], SELECT_BY_TICKET, MODE_TRADES))
         {
             if (OrderCloseTime() == 0) ClosePosBySelect();
         }
      }
   }
}
//+-------------------------------------------------------------------------------------+
//| Закрытие одного, предварительно выбранного ордера                                   |
//+-------------------------------------------------------------------------------------+
void ClosePosBySelect()
{
   bool   fc;
   color  clClose, clCloseBuy = Blue, clCloseSell = Red;
   double ll, pa, pb, pp;
   int    err, it, NumberOfTry = 3;

   if (OrderType() == OP_BUY || OrderType() == OP_SELL)
   {
       for (it=1; it<=NumberOfTry; it++)
       {
           while (!IsTradeAllowed()) Sleep(5000);
           RefreshRates();
           pa = MarketInfo(OrderSymbol(), MODE_ASK);
           pb = MarketInfo(OrderSymbol(), MODE_BID);
           if (OrderType() == OP_BUY)
           {
               pp = pb; clClose = clCloseBuy;
           }
           else
           {
               pp = pa; clClose = clCloseSell;
           }
           ll = OrderLots();
           fc = OrderClose(OrderTicket(), ll, pp, 30, clClose);
           if (fc)
           {
              break;
           }
           else
           {
               err = GetLastError();
           }
       }
   }
   else Print("Некорректная торговая операция. Close ");
}

Pour une raison quelconque, certaines des commandes ne sont pas fermées. J'imprime certains segments quand je les vois, je ne comprends rien. Voici un exemple :

Le commentaire indique que lastOOTHist = 01:30:00, bien que cela ne soit pas correct. Si nous vérifions lastOOTHist dans la fenêtre des résultats, nous verrons que

leurs heures de fermeture sont différentes...

Qu'est-ce qui ne va pas ici ?

 
hoz:

En fait, oui, c'est logique. Vous avez également un lien ici... :)) Il me restait ceci de la dernière fois, lorsque les paramètres n'étaient pas globaux.

J'ai fait valoir que le tableau doit être transmis par référence ici. Sinon, la fonction est condamnée à fonctionner avec un seul tableau, codé en dur. Même si vous l'avez défini de manière globale.
 

Désolé d'être nécessaire à la fin de la semaine, mais je vais demander.

Quelqu'un a-t-il une expérience de la lecture d'un message sur une boîte aux lettres d'un expéditeur connu ?