Cualquier pregunta de los recién llegados sobre MQL4 y MQL5, ayuda y discusión sobre algoritmos y códigos - página 256

 
Alexey Viktorov:

Estaba hablando de mi propio chip de memoria. :)))

Sobre no recordar tales nimiedades, que pueden ser fácilmente revisadas al escribir el código, aclaradas, hechas como sea necesario y olvidadas de nuevo.

¡Ya veo! :)
 
Artyom Trishkin:
Me he dado cuenta de que la gente suele pedir la función de arrastre o de equilibrio. He esbozado una función para dibujar el stop en el nivel Breakeven y la posición trailing stop según el valor de algún indicador, que dibuja sus líneas en el gráfico de precios (МАшашка o parabólica, por ejemplo) pasado a la función.

#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 general, si hay algo - pregunta. O correcto.

¿Puede ayudarme a perfeccionar mi EA? Tengo un EA que pone stops, pero no sabe arrastrar los stop loss. No lo entiendo en absoluto, así que espero la ayuda de algún experto.

Archivos adjuntos:
 

Se necesita una función para determinar el peso de un elemento del array. Cuanto mayor sea el número de otros elementos cercanos (y más cercanos) a un determinado elemento, mayor será su peso. Tal vez esa función ya exista. Algo así como determinar el peso de un elemento en una muestra por la concentración de elementos en la misma. Gracias.

 

Hola, no puedo entender por qué en el probador MQL4sólopasa poruna iteración y luego se detiene. ¿No se actualiza TimeCurrent()? ¿Cómo lo actualizo? Quiero que mi EA funcione no por ticks sino cada segundo, o mejor 5 veces por segundo.

  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:

Hola, no puedo entender por qué en el probador MQL4sólopasa poruna iteración y luego se detiene. ¿No se actualiza TimeCurrent()? ¿Cómo lo actualizo? Necesita un EA multidivisa que trabaje cada segundo, o mejor 5 veces por segundo, en lugar de trabajar por ticks.

¿Cómo se ejecuta este EA, es decir, desde el directorio de expertos?

La función start() (el nombre antiguo, el moderno OnTick) se ejecuta por cada tick, es decir, debería ejecutarse después del final del tick. ¿Y lo tienes en un bucle?

 
Maxim Kuznetsov:

¿lo ejecuta como asesor o qué? es decir, desde el directorio de expertos?

La función start() en los EAs (nombre antiguo, moderno OnTick) se ejecuta en cada tick, es decir, debería terminar cuando el tick haya terminado. ¿Y lo tienes en un bucle?

Aquí en el tutorial se permite y hay un ejemplo con una función "start" en bucle

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

О сложных программах - Учебник по MQL4
О сложных программах - Учебник по MQL4
  • book.mql4.com
О сложных программах - Учебник по MQL4
 
Jenya77769: Aquí en el libro de texto se permite esto y hay un ejemplo con una función de inicio en bucle

Puedes hacer un bucle, por supuesto. Pero para las próximas TIC es deseable que se suelte. De lo contrario, las TIC se perderán. ¿Lo necesitas?

 
LRA:

Hacer un bucle, por supuesto, es posible. Pero para las próximas TIC es deseable liberar. De lo contrario, las TIC se perderán. ¿Lo necesita?


¿Por qué se pierde? La información de los nuevos ticks se puede recuperar conRefreshRates(); justo en el bucle sin fin

 
Jenya77769:¿Por qué se pierde? La información sobre el nuevo tick se puede obtener utilizando la funciónRefreshRates(); justo en el bucle infinito

La función RefreshRates(); sólo comprueba. Devuelve true si los datos fueron actualizados. Puede hacer esto while(!RefreshRates(); - esperar el tick

 
LRA:

La función RefreshRates(); sólo comprueba. Devuelve true si los datos fueron actualizados. Puede hacer esto while(!RefreshRates()); - esperando un tick.

Refresca (no confundir a la gente) y devuelve la bandera si la actualización tiene éxito o falla.

Puedes prescindir de ella si obtienes los datos mediante SymbolInfoDouble(), SymbolInfoTick()