Tutte le domande dei nuovi arrivati su MQL4 e MQL5, aiuto e discussione su algoritmi e codici - pagina 256

 
Alexey Viktorov:

Stavo parlando del mio chip di memoria. :)))

Di non ricordarsi di queste sciocchezze, che possono essere facilmente ricontrollate quando si scrive il codice, chiarite, fatte come necessario e dimenticate di nuovo.

Capisco! :)
 
Artyom Trishkin:
Ho notato che la gente chiede spesso la funzione trawl o breakeven. Ho abbozzato una funzione per disegnare lo stop sul livello di Breakeven e la posizione di trailing stop secondo il valore di qualche indicatore, che disegna le sue linee sul grafico del prezzo (МАшашка o parabolico, per esempio) passato nella funzione.

#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);
   }
//+------------------------------------------------------------------+
In generale, se c'è qualcosa da chiedere. O corretto.

Potete aiutarmi a perfezionare il mio EA? Ho un EA che mette degli stop, ma non sa come trascinare gli stop loss. Non ci capisco niente, quindi spero nell'aiuto di un esperto.

 

Avete bisogno di una funzione per determinare il peso di un elemento dell'array. Maggiore è il numero di altri elementi vicini (e più vicini) a un dato elemento, maggiore è il suo peso. Forse una tale funzione esiste già. Qualcosa come determinare il peso di un elemento in un campione in base alla concentrazione di elementi nel campione. Grazie.

 

Ciao, non riesco a capire perché nel tester MQL4 passasolo una iterazione e poi si ferma? TimeCurrent() non viene aggiornato? Come faccio ad aggiornarlo? Voglio che il mio EA lavori non in tick ma ogni secondo, o meglio 5 volte al secondo.

  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:

Ciao, non riesco a capire perché nel tester MQL4 passasolo una iterazione e poi si ferma? TimeCurrent() non viene aggiornato? Come faccio ad aggiornarlo? Hai bisogno di un EA multivaluta che lavori ogni secondo, o meglio 5 volte al secondo, invece di lavorare in tick.

Come si esegue questo EA? Cioè dalla directory degli esperti?

La funzione start() (il vecchio nome, il moderno OnTick) viene eseguita per ogni tick, cioè dovrebbe essere eseguita dopo la fine del tick. E l'avete in un ciclo?

 
Maxim Kuznetsov:

Lo stai eseguendo come consulente o cosa? cioè dalla directory degli esperti?

La funzione start() negli EA (vecchio nome, il moderno OnTick) gira su ogni tick, cioè dovrebbe finire quando il tick è finito. E l'avete in un ciclo?

Qui nel tutorial è permesso e c'è un esempio con una funzione "start" in loop

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

О сложных программах - Учебник по MQL4
О сложных программах - Учебник по MQL4
  • book.mql4.com
О сложных программах - Учебник по MQL4
 
Jenya77769: Qui nel libro di testo questo è permesso e c'è un esempio con una funzione di avvio in loop

Si può fare il loop, naturalmente. Ma al prossimo TIC è auspicabile lasciar andare. Altrimenti il TIC sarà perso. Ne hai bisogno?

 
LRA:

Al loop, naturalmente, è possibile. Ma dal prossimo TIC è auspicabile il rilascio. Altrimenti il TIC sarà perso. È necessario?


Le nuove informazioni sui tick possono essere recuperate conRefreshRates(); proprio nel ciclo infinito

 
Jenya77769: L'informazione sul nuovo tick può essere ottenuta usando la funzioneRefreshRates(); proprio nel ciclo infinito

La funzione RefreshRates(); controlla solo. Restituisce true se i dati sono stati aggiornati. Potete fare questo while(!RefreshRates(); - aspettando il tick

 
LRA:

La funzione RefreshRates(); controlla solo. Restituisce true se i dati sono stati aggiornati. Potete fare questo while(!RefreshRates()); - aspettando un tick.

Aggiorna (non confondere le persone) e restituisce il flag se l'aggiornamento ha successo o fallisce.

Potete farne a meno se ottenete dati usando SymbolInfoDouble(), SymbolInfoTick()

Motivazione: