Toute question des nouveaux arrivants sur MQL4 et MQL5, aide et discussion sur les algorithmes et les codes. - page 256

 
Alexey Viktorov:

Je parlais de ma propre puce mémoire. :)))

Le fait de ne pas se souvenir de telles vétilles, qui peuvent être facilement revérifiées lors de l'écriture du code, clarifiées, effectuées si nécessaire et oubliées à nouveau.

Je vois ! :)
 
Artyom Trishkin:
J'ai remarqué que les gens demandent souvent une fonction de chalutage ou de seuil de rentabilité. J'ai esquissé une fonction pour dessiner le stop sur le niveau Breakeven et la position du trailing stop en fonction de la valeur d'un indicateur, qui dessine ses lignes sur le graphique de prix (МАшашка ou parabolique, par exemple) passé dans la fonction.

#property strict // в самое начало кода вашей программы (если нету там ещё)


// Функцию - за пределы остальных функций программы
//+------------------------------------------------------------------+
//| Трейлинг по значению + перенос стопа на уровень безубытка        |
//+------------------------------------------------------------------+
void TrailingByLevel(string symbol_name,           // Имя символа
                     int magic_number,             // Magic ордера
                     double level_of_trail,        // Уровень, на который ставим стоп (например МА или Parabolic SAR)
                     int trailing_start,           // Профит в пунктах для старта трала
                     int trailing_step,            // Шаг трала в пунктах
                     int trailing_stop,            // Отступ стоплосс от уровня МА или SAR в пунктах
                     int profit_for_breakeven=15,  // Профит в пунктах для переноса стопа в безубыток
                     int breakeven_level=5,        // Уровень безубытка в пунктах
                     bool use_trail=true,          // Флаг использования трала
                     bool use_breakeven=false      // Флаг использования безубытка
                     )
   {
   int lv=StopLevel(symbol_name)+1;                // Получаем значение Stop Level по символу + 1 пункт (из отдельной функции)
   for(int i=OrdersTotal()-1; i>=0; i--) {
      if(OrderSelect(i,SELECT_BY_POS)) {
         if(OrderMagicNumber()!=magic_number)   continue;         //Если Магик не наш - идем к следующему ордеру
         if(OrderSymbol()!=symbol_name)         continue;         //Если Символ не наш - идем к следующему ордеру
         //--- покупки
         if(OrderType()==OP_BUY) {
            int    digits=(int)SymbolInfoInteger(symbol_name,SYMBOL_DIGITS);
            double point=(SymbolInfoDouble(symbol_name,SYMBOL_POINT));
            double pb=SymbolInfoDouble(symbol_name,SYMBOL_BID);
            double profit=pb-OrderOpenPrice();                    // Профит позиции в цене (без комиссий и свопов)
            //--- безубыток
            if(use_breakeven) {
               //--- если профит в цене больше заданного
               if(profit>=profit_for_breakeven*point) {
                  int err=ERR_NO_ERROR;
                  double sl=NormalizeDouble(OrderOpenPrice()+breakeven_level*point,digits);
                  if(pb-lv*point>sl && OrderStopLoss()<sl) {
                     // Сюда вписываем свою функцию модификации. Можно конечно и стандартной обойтись:
                     // OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),OrderExpiration(),clrModify); ...
                     // ... но в ней не предусмотрены проверки кодов возврата торгового сервера и их обработка
                     //ModifyOrder(-1,sl,-1,err);
                     }
                  if(err==ERR_MARKET_CLOSED) return;
                  }
               }
            //--- трал
            if(use_trail) {
               //--- если профит в пунктах больше заданного, или изначально задан меньше ноля
               if(profit>=trailing_start*point || trailing_start==EMPTY) {
                  int err=ERR_NO_ERROR;
                  double sl=NormalizeDouble(level_of_trail-trailing_stop*point,digits);  // вычисляем новый уровень стоплосс по значению, переданному в функцию
                  //--- Если новое значение СЛ не ближе Stop Level и если новое положение СЛ больше старого+шаг СЛ, то модифицируем стоп позиции
                  if(pb-lv*point>sl && OrderStopLoss()+trailing_step*point<sl) {
                     // Сюда вписываем свою функцию модификации. Можно конечно и стандартной обойтись:
                     // OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),OrderExpiration(),clrModify); ...
                     // ... но в ней не предусмотрены проверки кодов возврата торгового сервера и их обработка
                     //ModifyOrder(-1,sl,-1,err);
                     }
                  if(err==ERR_MARKET_CLOSED) return;
                  }
               }
            }

         //--- Продажи
         if(OrderType()==OP_SELL) {
            int    digits=(int)SymbolInfoInteger(symbol_name,SYMBOL_DIGITS);
            double point=(SymbolInfoDouble(symbol_name,SYMBOL_POINT));
            double pa=SymbolInfoDouble(symbol_name,SYMBOL_ASK);
            double profit=OrderOpenPrice()-pa;                    // Профит позиции в цене (без комиссий и свопов)
            //--- безубыток
            if(use_breakeven) {
               //--- если профит в цене больше заданного
               if(profit>=profit_for_breakeven*point) {
                  int err=ERR_NO_ERROR;
                  double sl=NormalizeDouble(OrderOpenPrice()-breakeven_level*point,digits);
                  if(pa+lv*point<sl && (OrderStopLoss()>sl || OrderStopLoss()==0)) {
                     // Сюда вписываем свою функцию модификации. Можно конечно и стандартной обойтись:
                     // OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),OrderExpiration(),clrModify); ...
                     // ... но в ней не предусмотрены проверки кодов возврата торгового сервера и их обработка
                     //ModifyOrder(-1,sl,-1,err);
                     }
                  if(err==ERR_MARKET_CLOSED) break;
                  }
               }
            //--- трал
            if(use_trail) {
               //--- если профит в пунктах больше заданного, или изначально задан меньше ноля
               if(profit>=trailing_start*point || trailing_start==EMPTY) {
                  int err=ERR_NO_ERROR;
                  double sl=NormalizeDouble(level_of_trail+trailing_stop*point,digits);  // вычисляем новый уровень стоплосс по значению, переданному в функцию
                  //--- Если новое значение СЛ не ближе Stop Level и если новое положение СЛ больше старого+шаг СЛ, то модифицируем стоп позиции
                  if(pa+lv*point<sl && (OrderStopLoss()-trailing_step*point>sl || OrderStopLoss()==0)) {
                     // Сюда вписываем свою функцию модификации. Можно конечно и стандартной обойтись:
                     // OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),OrderExpiration(),clrModify); ...
                     // ... но в ней не предусмотрены проверки кодов возврата торгового сервера и их обработка
                     //ModifyOrder(-1,sl,-1,err);
                     }
                  if(err==ERR_MARKET_CLOSED) break;
                  }
               }
            }
         }
      }
}
//+------------------------------------------------------------------+
int StopLevel(string symbol_name) {
   int sp=(int)SymbolInfoInteger(symbol_name,SYMBOL_SPREAD);
   int lv=(int)SymbolInfoInteger(symbol_name,SYMBOL_TRADE_STOPS_LEVEL);
   return((lv==0)?sp*2:lv);
   }
//+------------------------------------------------------------------+
En général, si vous avez besoin de quelque chose, demandez. Ou correct.

Pouvez-vous m'aider à affiner mon EA ? J'ai un EA qui met des stops, mais qui ne sait pas comment faire glisser les stop loss. Je n'y comprends rien, alors j'espère l'aide d'un expert.

 

Vous avez besoin d'une fonction pour déterminer le poids d'un élément du tableau. Plus le nombre d'autres éléments proches (et plus proches) d'un élément donné est important, plus son poids est élevé. Peut-être une telle fonction existe-t-elle déjà. Quelque chose comme déterminer le poids d'un élément dans un échantillon par la concentration des éléments dans l'échantillon. Merci.

 

Bonjour, je n'arrive pas à comprendre pourquoi le testeur MQL4ne fait qu'une seule itération et s'arrête ensuite ? Est-ce que TimeCurrent() n'est pas mis à jour ? Comment le mettre à jour ? Je veux que mon EA ne fonctionne pas par ticks mais chaque seconde, ou mieux 5 fois par seconde.

  int start()                                     // Спец. функция start
  {
    while(!IsStopped())
     {
      RefreshRates();
      if(RefreshRates()==true||MyTimer(1))
        {
         код советника
        }  
     }
    return(0);
  }


bool MyTimer(int Delay) //функция для работы советника по заданому интервалу времени, а не по тикам
{
  RefreshRates();
  static datetime Time1, Time2;
  bool Result = False;
  
  if(MathMod(TimeSeconds(TimeCurrent()), Delay) == 0.0)
  {
    Time1 = TimeCurrent();
    if(Time1 != Time2)
    {  
      Time2 = Time1;
      Result = True;
    }
  }
  return(Result);
}
 
Jenya77769:

Bonjour, je n'arrive pas à comprendre pourquoi le testeur MQL4ne fait qu'une seule itération et s'arrête ensuite ? Est-ce que TimeCurrent() n'est pas mis à jour ? Comment le mettre à jour ? Vous avez besoin d'un EA multi-devises qui fonctionne chaque seconde, ou mieux 5 fois par seconde, au lieu de fonctionner par ticks.

Comment exécutez-vous cet EA ? c'est-à-dire à partir du répertoire des experts ?

La fonction start() (l'ancien nom, le moderne OnTick) est exécutée pour chaque tick, c'est-à-dire qu'elle devrait être exécutée après la fin du tick. Et vous l'avez mis en boucle ?

 
Maxim Kuznetsov:

exécutez-vous ce programme en tant que conseiller ou quoi ? c'est-à-dire à partir du répertoire des experts ?

La fonction start() dans les EAs (ancien nom, moderne OnTick) s'exécute à chaque tick, c'est-à-dire qu'elle devrait se terminer lorsque le tick est terminé. Et vous l'avez mis en boucle ?

Ici, dans le tutoriel, c'est autorisé et il y a un exemple avec une fonction "start" en boucle.

https://book.mql4.com/ru/special/index

О сложных программах - Учебник по MQL4
О сложных программах - Учебник по MQL4
  • book.mql4.com
О сложных программах - Учебник по MQL4
 
Jenya77769: Dans le manuel, cela est autorisé et il y a un exemple avec une fonction de démarrage en boucle.

Vous pouvez le mettre en boucle, bien sûr. Mais au prochain TIC, il est souhaitable de lâcher prise. Sinon, le TIC sera perdu. En avez-vous besoin ?

 
LRA:

En boucle, bien sûr, c'est possible. Mais pour le prochain TIC, il est souhaitable de libérer. Sinon, le TIC sera perdu. Est-ce nécessaire ?


Les nouvelles informations sur les ticks peuvent être récupérées avecRefreshRates() ; directement dans la boucle sans fin.

 
Jenya77769: L'information sur le nouveau tick peut être obtenue en utilisant la fonctionRefreshRates() ; dans la boucle infinie.

La fonction RefreshRates() ; vérifie seulement. Il renvoie un message vrai si les données ont été mises à jour. Vous pouvez faire ceci while( !RefreshRates() ; - attendre le tick

 
LRA:

La fonction RefreshRates() ; vérifie seulement. Il renvoie un message vrai si les données ont été mises à jour. Vous pouvez faire ceci while( !RefreshRates()) ; - attendre un tick.

Rafraîchit (ne pas confondre les gens) et renvoie le drapeau si la mise à jour réussit ou échoue.

Vous pouvez vous en passer si vous recevez des données en utilisant SymbolInfoDouble(), SymbolInfoTick()

Raison: