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

 
hoz:

S'il est 7h43 et que je ne me suis pas couché... Donc je suppose que ça s'écrit graal !

Nan, pas besoin de jurer comme ça :)) Yusuf m'a donné le Graal. Je suis assis dans mes valises, attendant la manne du ciel, pour aller aux Maldives :))

 
artmedia70:
Alors montre-moi ce que tu as fait... Pas de télépathes ici - ils sont en vacances.

extern string time1 = "n";// 
extern string time2="m";
extern double lot=0.2;// объявили лот
extern int slippage=2;// объявили макс отклонение от цены





int start()
{
double max;// максимальная цена 6-ти свечей
double min;// минимальная цена 6-ти свечей
int hour1 = TimeHour(StrToTime(time1)); // время часы
int minute1 = TimeMinute(StrToTime(time1));// время минуты


if (hour1 == TimeHour(TimeCurrent()) && minute1 == TimeMinute(TimeCurrent()))// если время подошло то
{
min=Low[iLowest(Symbol(),0,MODE_LOW,6,1)]; // вычисляем минимальную цену последних 6 свечей
max=High[iHighest(Symbol(),0,MODE_HIGH,6,1)]; // вычисляем максимальную цену последних 6 свечей
double volum=max-min;// общий объем локалки последних 6 свечей М5
 int ticket1=-1;
 int ticket2=-1;
if ((volum<=0.0018)==true)// если объем свечей меньше или равно z пунктов 

if (ticket1<0)
{ 
OrderSend ( Symbol (), OP_BUYSTOP, lot,max+Point,3,min-Point,max+0.0022, NULL,0,time2, Red);
Alert(GetLastError());
}
if(ticket2<0)
{
OrderSend( Symbol (), OP_SELLSTOP, lot,min-Point,3,max+Point,min-0.0022, NULL,0,time2, Yellow);
Alert(GetLastError());
}


return;


if (OrderSelect(1,SELECT_BY_POS,MODE_HISTORY)) ///если первый открытый ордер закрылся с профитом 
if(OrderProfit()>0)
{
OrderDelete(OrderTicket());// удаляем второй отложенный
}

}



bool closeorder;//определим переменную закрытия ордеров
closeorder=true;

if (closeorder==true)// вечернее закрытие всех отложенных ордеров, и рыночных позиций
{
int hour2 = TimeHour(StrToTime(time2));// вычисляем время закрытия ордеров
int minute2 = TimeMinute(StrToTime(time2));

if (hour2 == TimeHour(TimeCurrent()) && minute2 == TimeMinute(TimeCurrent()))// если время ***
{// определяем количество открытых позиций, и отложенных ордеров
for(int i=OrdersTotal()-1; i>=0; i--)
 if (OrderSelect(1,SELECT_BY_POS,MODE_TRADES))break; //определяем место где будем искать ( рабочие позиции)
if (OrderType()==OP_BUY ) OrderClose (OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),slippage);// Закрытие ордера бай если такой есть
if (OrderType()==OP_SELL) OrderClose (OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),slippage);//Закрытие ордера селл если такой есть
if (OrderType()==OP_BUYSTOP)
{ 
OrderDelete(OrderTicket()); //удаляем отложенный байстоп
}                    
if(OrderType()==OP_SELLSTOP)
{ 
OrderDelete(OrderTicket()); //удаляем отложенный sellstop
}                    

J'ai téléchargé le code général de l'Expert Advisor, afin de rendre plus clair ce qu'il devrait faire... Je sais que c'est un peu le bazar, mais je n'ai pas encore appris autre chose =)))
Je vais vous dire une fois de plus où c'est stupide.
ouvrir des ordres en suspens : ouvre soit un ordre en suspens sans l'opposé, soit un ensemble d'ordres en suspens dans une direction.
Il supprime les commandes : parfois ok le soir à une heure bien précise, et parfois en une journée, ou ne ferme pas du tout....

Eh bien, la condition est :
Si le premier ordre en attente ouvert se ferme avec un profit, le second est supprimé immédiatement - je doute d'avoir écrit correctement, mais je ne peux pas le vérifier en action car je ne veux pas ouvrir deux positions opposées=(((((.
 
artmedia70:
Lors de la recherche du dernier ordre clôturé, nous devrions d'abord trouver le plus récemment clôturé mais la vérification de la clôture à la prise devrait être retirée de la boucle, sinon elle vérifiera la clôture à la prise pour chaque ordre clôturé et, si c'est le cas, elle se souviendra de l'heure du premier ordre clôturé à la prise dans la boucle et non du dernier.


C'est de l'optimisation de code. Le résultat ne changera pas, comme je le vois. Il faut juste plus de temps pour le calculer. J'ai corrigé le code, mais c'est toujours la même chose.

//+-------------------------------------------------------------------------------------+
//| Получаем состояние последней позиции (Открыта или закрыта)                          |
//+-------------------------------------------------------------------------------------+
datetime GetLastOrderState()
{
   datetime lastOrderCloseTime = -1,               // Время закрытия последнего открытого ордера
            lastOOTMarket = -1,          // Время открытия последнего открытого ордера рыночного
            lastOOTHist = -1;            // Время открытия последнего открытого ордера из истории
   
   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();   // ..последней закрытой позиции в истории
      Comment("Время закрытия последнего ордера в истории lastOrderCloseTime = ", lastOrderCloseTime);
   }

   if (MathAbs(OrderTakeProfit() - OrderOpenPrice()) < i_tp * pt) return(0);
      Comment("OrderTakeProfit() - OrderOpenPrice() < i_tp * pt = ", MathAbs(OrderTakeProfit() - OrderOpenPrice()) < i_tp * pt);
   lastOOTHist = OrderOpenTime();   // Тогда время открытия последней закрытой позиции из истории
      Comment("Время закрытия последнего ордера в истории lastOOTHist = ", lastOOTHist);
   
      Comment("Время открытия последнего открытого ордера = ", lastOOTHist);
  
   for (int h=OrdersTotal()-1; i>=0; i--)
   {   
      if (!OrderSelect(h, SELECT_BY_POS, MODE_TRADES)) continue;
      if (OrderMagicNumber() != i_magic) continue;
      if (OrderSymbol() != Symbol()) continue;
      {
         if (lastOOTMarket < OrderOpenTime())
             lastOOTMarket = OrderOpenTime();
  
         if (lastOOTMarket < lastOOTHist)      // Если время открытия последнего открытого ордера (рыночного) ниже последнего открытого ордера из истории..
             lastOrderCloseTime = OrderCloseTime(); // Значит это искомый ордер
      }
   }

   Comment("Время закрытия последнего открытого ордера = ", lastOrderCloseTime);
   return (lastOrderCloseTime);
}

Pourtant, il y a quelque chose qui cloche.

 
ex1m:

J'ai essayé de vous montrer le code d'une EA, je sais que c'est un fouillis, mais je n'ai jamais appris à le faire d'une autre manière).
Je vais vous dire encore une fois où c'est stupide
Ouvrir des ordres en suspens : il ouvre soit un ordre en suspens sans l'opposé, soit tout un tas d'ordres en suspens dans une direction.
Suppression des commandes : les supprime à chaque fois, parfois ok le soir à une heure bien précise, et parfois en une journée, ou ne ferme pas du tout...

Eh bien, la condition :
Si le premier ordre en attente ouvert ferme avec un profit, le second sera supprimé immédiatement - Je doute également que je l'ai écrit correctement, mais je ne peux pas vérifier au travail, parce que je ne veux pas ouvrir deux positions opposées=(((((



Pour répondre à une question par une question. Qu'est-ce que c'est que ça ?

if ((volum<=0.0018)==true)// если объем свечей меньше или равно z пунктов 

Déchiffrez-le pour moi, je ne comprends pas :)

Les contrôles pour ouvrir une position doivent être effectués après la tentative d'ouverture d'une position. I.e.

if (ticket1<0)

Vous le placez après avoir envoyé une commande.

Le prix doit être supérieur ou inférieur à l'Asc ou à l'Bid pour ouvrir la position. C'est comme ça que ça se passe pour le Buy :

 if (OOP > Ask)
 
hoz:


C'est de l'optimisation de code. Le résultat ne changera pas, comme je le vois. Il faut juste plus de temps pour le calculer. J'ai corrigé le code, mais c'est toujours la même chose.

Il y a toujours quelque chose qui cloche.

Non, ce n'est pas de l'optimisation de code. C'est juste qu'il cherche exactement le dernier. Une fois que nous avons terminé la recherche de tous les ordres fermés et que nous avons trouvé le dernier ordre fermé d'entre eux, alors seulement nous devons vérifier la fermeture par la prise et, si elle est fermée par la prise, alors seulement il est logique de continuer à chercher le reste.

Si nous vérifions qu'il y a un proche à l'intérieur de la boucle, qu'obtiendrons-nous ? Nous obtiendrons une erreur de logique :
Supposons que nous ayons sélectionné un ordre qui a été fermé il y a un an. Son temps sera de toute façon supérieur à -1, donc nous le vérifions pour le fermer à la prise (il est vérifié à l'intérieur de la boucle). Oui, ça a fermé sur la prise... Que fait votre fonction ensuite ? C'est vrai - il continue à fonctionner avec cet ordre fermé à la marque il y a un an. Laissez-moi voir ce qui ne va pas. Je viens de rentrer chez moi...

 

Il était écrit : 2. Si la dernière position ouverte se ferme à la prise, alors fermez tout !

Donc, ça se passe comme ça :

//-----------------------------------------------------------------------------------------------+
bool isCloseByTakeLastOpenPos (string sy, int mn, int delta) {
   datetime t=0;
   int   i, k, j=-1;
   
// Сначала определим, что последняя закрытая позиция была закрыта по тейку (в пределах дельты)
   k=OrdersHistoryTotal()-1;
   for(i=k; i>=0; i--) {
      if (OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) {
         if (OrderMagicNumber()!=mn)   continue;
         if (OrderSymbol()!=sy)        continue;
         if (OrderType()>1)            continue;            // Сначала забыл вписать, подправил
         if (t<OrderCloseTime()) {t=OrderCloseTime(); j=i;}
         }
      }  
   // Нашли последнюю. Проверим её закрытие по тейку
   if (OrderSelect(j,SELECT_BY_POS,MODE_HISTORY)) {                      
      if (OrderProfit()+OrderSwap()+OrderCommission()<=0)   return(false);          // Закрыта с убытком или в ноль
      if (MathAbs(OrderTakeProfit()-OrderClosePrice())>delta*Point) return(false);  // закрыта в профите, но не в пределах дельты
      else t=OrderOpenTime();    // Если последняя закрытая была закрыта по тейку (в пределах дельты), запомним время её открытия
      }
   else {Print("FUNC isCloseByTakeLastOpenPos : не удалось выбрать ордер в истории");return(false);}
// Здесь мы имеем последнюю закрытую позицию в профите и закрытую по тейку (в пределах дельты), ищем дальше
   k=OrdersTotal()-1;
   for(i=k; i>=0; i--) {
      if (OrderSelect(i,SELECT_BY_POS)) {
         if (OrderMagicNumber()!=mn)   continue;
         if (OrderSymbol()!=sy)        continue;
         if (OrderType()>1)            continue;
         if (t<OrderOpenTime()) return(false);  // Выбранная рыночная позиция открыта позже закрытой по тейку
         }
      else {Print("FUNC isCloseByTakeLastOpenPos : не удалось выбрать рыночный ордер");return(false);}
      }
   return(true);  // Найденная закрытая по тейку позиция была открыта позже всех, возвращаем её время открытия
}
//-----------------------------------------------------------------------------------------------+

Nous passons à la fonction le symbole que nous voulons vérifier, le numéro magique et le delta (distance en pips == différence entre le prix de l'ordre et le prix de clôture), comme ceci :

   if (isCloseByTakeLastOpenPos (Symbol(), Magic, 5)) { // Если последняя открытая была закрыта по тейку ...
      // ... тут обрабатываем эту ситуёвину
      }
   else {   // Иначе ...
      // тут обрабатываем, если последняя закрытая была открыта не последней или ...
      // ... последняя закрытая была закрыта с убытком или в профите, но за пределами дельты
      }

Je n'ai pas vérifié cette fonction, je l'ai écrite de ma propre main. Je vous laisse donc le soin de rechercher les erreurs.

Vous pouvez le rendre int et utiliser des codes de retour. Par exemple, si la position recherchée n'existe pas ou existe, mais est fermée avec une perte, retournez -1 ;
si elle existe et est fermée avec un profit, mais pas dans le delta, retournez 0 ;
si elle existe et est fermée avec un profit et au Take (dans le delta), retournez 1...

Les possibilités d'imagination sont énormes...

 
artmedia70:

Si, d'autre part, nous vérifions la fermeture de la prise, qu'obtenons-nous ? Nous obtiendrons une erreur de logique :

Supposons que nous ayons sélectionné une commande qui a été clôturée il y a un an. Son temps sera de toute façon supérieur à -1, donc nous le vérifions pour le fermer à la prise (cette vérification à l'intérieur de la boucle est incluse dans le code). Oui, ça a fermé sur la prise...


Ainsi, si nous bouclons sur toutes les commandes, la boucle passera de toute façon par toutes les commandes. L'heure de clôture de chaque commande sera comparée à celle de la commande sélectionnée précédemment. Mais c'est là que nous sommes confrontés à un problème de performance. Le TakeProfit sera constamment vérifié dans la boucle, avec chaque position fermée, au lieu de seulement la dernière. N'est-ce pas ! ?
 
PapaYozh:

Bien.

Mais il existe Open[], avec un prix d'ouverture.


Je l'ai eu, merci :)
 
hoz:

Donc, si vous faites un cycle de toutes les commandes, le cycle fera de toute façon un cycle de toutes les commandes. L'heure de clôture de chaque commande sera comparée à celle de la commande précédente. Mais c'est là que nous sommes confrontés à un problème de performance. Le TakeProfit sera constamment vérifié dans la boucle, avec chaque position fermée, au lieu de seulement la dernière. N'est-ce pas ?
J'ai déjà écrit un exemple de la fonction.
 
hoz:

Donc si nous bouclons sur toutes les commandes, la boucle bouclera de toute façon sur toutes les commandes. L'heure de clôture de chaque commande sera comparée à celle de la commande précédente. Mais ici, nous avons un problème de performance. Le TakeProfit sera constamment vérifié dans la boucle, avec chaque position fermée, au lieu de seulement la dernière. N'est-ce pas ! ?

C'est un problème :

   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();   // ..последней закрытой позиции в истории
      
      if (MathAbs(OrderTakeProfit() - OrderOpenPrice()) < i_tp * pt) return(0); // ЗДЕСЬ ВЫХОДИМ ПРИ ПЕРВОМ ВСТРЕЧНОМ
      
      lastOOTHist = OrderOpenTime();   // Тогда время открытия последней закрытой позиции из истории
   }