Fragen von Neueinsteigern zu MQL4 und MQL5, Hilfe und Diskussion über Algorithmen und Codes - Seite 256

 
Alexey Viktorov:

Ich habe von meinem eigenen Speicherchip gesprochen. :)))

Es geht darum, sich nicht an solche Kleinigkeiten zu erinnern, die beim Schreiben des Codes leicht nachgeprüft, geklärt, nach Bedarf erledigt und wieder vergessen werden können.

Verstehe! :)
 
Artyom Trishkin:
Ich habe festgestellt, dass die Leute oft nach einer Schleppnetz- oder Break-even-Funktion fragen. Ich habe eine Funktion zum Zeichnen des Stopps auf dem Breakeven-Niveau und der Trailing-Stop-Position nach dem Wert eines Indikators entworfen, der seine Linien auf dem Preisdiagramm zeichnet (МАшашка oder parabolisch, zum Beispiel), die in die Funktion übergeben werden.

#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);
   }
//+------------------------------------------------------------------+
Generell gilt: Fragen Sie, wenn Sie etwas brauchen. Oder richtig.

Können Sie mir helfen, meinen EA zu verfeinern? Ich habe einen EA, der Stops setzt, aber nicht weiß, wie man Stop Losses zieht. Ich verstehe das überhaupt nicht, deshalb hoffe ich auf die Hilfe eines Experten.

 

Sie benötigen eine Funktion, um das Gewicht eines Elements in einem Array zu bestimmen. Je größer die Anzahl der anderen Elemente ist, die einem bestimmten Element nahe (und näher) stehen, desto größer ist sein Gewicht. Vielleicht existiert eine solche Funktion bereits. So etwas wie die Bestimmung des Gewichts eines Elements in einer Probe anhand der Konzentration der Elemente in der Probe. Danke.

 

Hallo! Ich kann nicht herausfinden, warum der MQL4-Testernur eine Iterationdurchläuftund dann anhält? Wird TimeCurrent() nicht aktualisiert? Wie kann ich sie aktualisieren? Ich möchte, dass mein EA nicht durch Ticks, sondern jede Sekunde, oder besser 5 mal pro Sekunde arbeiten.

  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:

Hallo! Ich kann nicht herausfinden, warum der MQL4-Testernur eine Iterationdurchläuftund dann anhält? Wird TimeCurrent() nicht aktualisiert? Wie kann ich sie aktualisieren? Sie brauchen einen Multi-Währungs-EA, der jede Sekunde oder besser 5 Mal pro Sekunde arbeitet, anstatt mit Ticks zu arbeiten.

Wie führen Sie diesen EA aus, z. B. aus dem Expertenverzeichnis?

Die Funktion start() (der alte Name, der moderne OnTick) wird für jeden Tick ausgeführt, d.h. sie sollte nach dem Ende des Ticks ausgeführt werden. Und Sie haben es in einer Schleife?

 
Maxim Kuznetsov:

Führen Sie dies als Berater aus, d.h. vom Expertenverzeichnis aus?

Die start()-Funktion in EAs (alter Name, modern OnTick) läuft bei jedem Tick, d.h. sie sollte enden, wenn der Tick beendet ist. Und Sie haben es in einer Schleife?

Hier im Tutorial ist es erlaubt und es gibt ein Beispiel mit einer geschleiften "Start"-Funktion

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

О сложных программах - Учебник по MQL4
О сложных программах - Учебник по MQL4
  • book.mql4.com
О сложных программах - Учебник по MQL4
 
Jenya77769: Hier im Lehrbuch ist dies erlaubt und es gibt ein Beispiel mit einer geschleiften Startfunktion

Sie können es natürlich in eine Schleife legen. Aber bei der nächsten TIC ist es wünschenswert, loszulassen. Andernfalls geht die TIC verloren. Brauchen Sie es?

 
LRA:

Natürlich ist es möglich, eine Schleife zu legen. Aber bis zur nächsten TIC ist es wünschenswert, sie freizugeben. Andernfalls geht die TIC verloren. Braucht es das?


Die neuen Tick-Informationen können mitRefreshRates(); direkt in der Endlosschleife abgerufen werden

 
Jenya77769: Die Informationen über den neuen Tick können mit der FunktionRefreshRates(); direkt in der Endlosschleife abgerufen werden

Die Funktion RefreshRates(); prüft nur. Sie gibt true zurück, wenn die Daten aktualisiert wurden. Sie können dies tun while(!RefreshRates(); - Warten auf den Tick

 
LRA:

Die Funktion RefreshRates(); prüft nur. Sie gibt true zurück, wenn die Daten aktualisiert wurden. Sie können dies tun while(!RefreshRates()); - Warten auf einen Tick.

Aktualisiert (nicht verwirren lassen) und gibt das Flag zurück, wenn die Aktualisierung erfolgreich war oder fehlgeschlagen ist.

Sie können darauf verzichten, wenn Sie die Daten mit SymbolInfoDouble(), SymbolInfoTick()