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

 
Бахром Балтабаев una notificación a mi teléfono cuando el precio alcance un determinado nivel, que yo especifique.

Hace poco escribí una alerta:. Pero se puede mejorar añadiendo SendNotification:

// использовать алерт
input bool alert = true;
// использовать push-уведомления
input bool notification = true;
// уровень срабатывания
input double trigLv = 0.0;
// отклонение от trigLv в пунктах
input int deviation = 30; 


// функция взята из https://www.mql5.com/ru/docs/basis/types/double
bool EqualDoubles(double d1,double d2,double epsilon)
  {
   if(epsilon<0) 
      epsilon=-epsilon;
//---
   if(d1-d2>epsilon) 
      return false;
   if(d1-d2<-epsilon) 
      return false;
//---
   return true;
  }

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit() {
  return(INIT_SUCCEEDED);
}

int OnCalculate(const int rates_total,
                 const int prev_calculated,
                 const datetime &time[],
                 const double &open[],
                 const double &high[],
                 const double &low[],
                 const double &close[],
                 const long &tick_volume[],
                 const long &volume[],
                 const int &spread[]
) {
  static bool triggered = false;
  static datetime time_ = 0;
  if (!alert && !notification)
    return rates_total;
  if (EqualDoubles(trigLv, close[rates_total - 1], deviation * SymbolInfoDouble(NULL, SYMBOL_POINT))) { // сравнение цены Close с trigLv
    if (time_ != time[rates_total - 1])
      time_ = time[rates_total - 1];
    else
      return rates_total;
    if (!triggered) {
      if (alert)
        Alert("Level ", NormalizeDouble(trigLv, (int)SymbolInfoInteger(NULL, SYMBOL_DIGITS)), " triggered!");
      if (notification)
        SendNotification("Level " + (string)NormalizeDouble(trigLv, (int)SymbolInfoInteger(NULL, SYMBOL_DIGITS)) + " triggered!");
    }
    triggered = true;
  }
  else
    triggered = false;
  
  return rates_total;
}

Añade las líneas que he resaltado al código fuente, colócalo en la carpeta Indicadores y compílalo. Este indicador puede añadirse al gráfico tantas veces como se quiera y recibir señales cuando se crucen diferentes niveles. El código se ha finalizado en línea. El resultado no se verifica.

Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам
Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам
  • www.mql5.com
В этой ветке я хочу начать свою помощь тем, кто действительно хочет разобраться и научиться программированию на новом MQL4 и желает легко перейти н...
 

Foro sobre comercio, sistemas de comercio automatizados y pruebas de estrategias

Cualquier pregunta de los novatos en MQL4 y MQL5, ayuda y discusión sobre algoritmos y códigos

GlaVredFX, 2022.01.17 18:59

Estoy buscando el código para cerrar órdenes y si no veo ninguna, abriré una nueva orden.

Pero por alguna razón, sólo cierra 1 orden y se detiene antes de la siguiente señal.

2022.01.17 16:22:08.38 92022.01.04 08:00:00 e:Señal1.1322 < clos 1.1304 ExistPosSell 0
2022.01.17 16:22:08.389 2022.01.04 08:00:00 e: Señal 1.1322 >clos1.1304ExistPosBuy1
2022.01.17 16:22:08.366 2022.01.04 08:00:00 e: Señal 1.1325 < clos 1.1306 ExistPosSell 0
2022.01.17 16:22:08.366 2022.01.04 04:00:00 e: Señal 1.1325 > clos 1.1306 ExistPosBuy 1
2022.01.17 16:22:08.327 2022.01.04 2022.01.04 00:00:00 e: Señal 1.1326 < clos 1.1296ExistPosSell0
2022.01.17 16:22:08.327 2022.01.04 00:00:00 e: Señal 1.1326 > clos 1.1296 ExistPosBuy 1
2022.
01.17 16:22:08.298 2022.01.03 20:00:00 e:Señal 1.1328 <cierre 1.1283 ExistPosSell 0
2022.01.17 16:22:08.298 2022.01.03 20:00:00 e: cierre #1 compra 0.01 EURUSD a 1.13598 al precio 1.12831

2022.01.17 16:22:08.298 2022.01.03 20:00:00 e: Señal 1.1328> cierre 1.
ExistPosBuy 1
2022.01.17 16:22:08.190 2022.01.03 16:00:00 e: open #4 bu y0.01 EURUSD at 1.13512 ok 2022.01.17 16:22:08.190 2022.01.03 16:00:00 e:Señal 1.134 <cierre 1.135ExistPosSell0
2022.01.17 16:22:08.190 2022.01.03 16:00:00 e: Señal 1.134 > cierre 1.135 ExistPosBuy 1

if(isNewBar()==true) {  
if(Signal > clos ) {  //--------------------- МА выше цены закрытия предыдущего бара.
     if(ExistPositions( NULL, OP_BUY, Magic) == true) //---------------- Если есть позиция BUY то
ClosePosWithMaxProfitInCurrency(); //--------  закрытие одной позиции с максимальным профитом в валюте депозита.
         if(ExistPositions( NULL, OP_BUY, Magic) == False) //----------- если позиции BUY отсутствуют то
   ticket=OpenPosition(NULL,OP_SELL, NDLot(Lot),0,0, Magic, Com);} //------------ открываем позицию SELL

if(Signal < clos ) { //--------------------- МА ниже цены закрытия предыдущего бара.
    if(ExistPositions( NULL, OP_SELL, Magic) == true) //---------------- Если есть позиция SELL то
 ClosePosWithMaxProfitInCurrency(); //---------------------закрытие одной позиции с максимальным профитом в валюте депозита.
        if(ExistPositions( NULL, OP_SELL, Magic) == False)  //----------- если позиции SELL отсутствуют то
  ticket=OpenPosition(NULL,OP_BUY, NDLot(Lot),0,0, Magic, Com);} //------------ открываем позицию BUY

} return; 
Si prestas un poco más de atención a tu pregunta y a tu código, verás por ti mismo cuál es el problema.
 
Mihail Matkovskij #:

Si prestas un poco más de atención a tu pregunta y a tu código, lo verás por ti mismo.

La cuestión es que la 1 orden más rentable debe cerrarse en 1 barra, luego esperar a una nueva barra y cerrar de nuevo 1 orden rentable. No debemos cerrarlas todas a la vez.

Esto significa que cerramos en la primera barra, pero no pasa nada en la siguiente.

 
GlaVredFX #:

El problema ahí es que la 1 orden más rentable debería cerrarse en 1 barra, luego esperar a una nueva barra y volver a cerrar 1 orden rentable. No hay que cerrarlos todos a la vez.

Luego hay que formular las preguntas correctamente. Sólo tienes una señal. Sólo recibirá una señal en la apertura de una nueva barra. Si sólo hay una señal, ¿cuántas órdenes se cerrarán? Y sólo si la señal aparece en una nueva barra. Y, si no hay señal, las órdenes se cerrarán en las siguientes barras. De nuevo, si hay una señal.

 
Mihail Matkovskij #:

Luego hay que formular las preguntas correctamente. Sólo tienes una señal. Y es en la apertura de un nuevo bar. Y si sólo hay una señal, ¿cuántas órdenes se cerrarán? Y sólo si la señal aparece en una nueva barra. Y, si no hay señal, las órdenes se cerrarán en las siguientes barras. Y de nuevo, si hay una señal.

En estos casos, un diagrama de flujo suele ser de ayuda. O tenemos que describir el algoritmo en detalle punto por punto en un papel o en un archivo de texto. Y sólo entonces entenderás cómo escribir tu código.

 

Necesito la función de cerrar 1 orden abierta en primer lugar entre todas las órdenes disponibles. que puede compartir.

 
GlaVredFX #:

Así que si te has dado cuenta, el algoritmo está escrito en el código.

1) Aparece una nueva barra

2) Si la MA es mayor que el precio de cierre de la barra anterior, vaya al paso 3 si la MA está por debajo del precio de cierre, vaya al paso 4.

3)Si tenemos una posición de COMPRA, cerramos una posición con el máximo beneficio en el par de divisas.

3.1)Si no hay órdenes de COMPRA abiertas, abra una posición de VENTA.

4) Si tenemos una posición de COMPRA, cerramos una posición con un beneficio máximo en el par de divisas.

4.1)Si no hay una orden de VENTA abierta, abrimos una posición de COMPRA.


Ahora de nuevo tengo una pregunta, ¿qué es lo que está mal en este código del algoritmo descrito anteriormente:

Este código contiene un conjunto de comandos. El terminal no sabe lo que necesitas, ¡sólo sabe lo que está escrito en el código!

...

if(isNewBar()) {  
  if(Signal > clos ) {  //--------------------- МА выше цены закрытия предыдущего бара.
    if(ExistPositions( NULL, OP_BUY, Magic)) //---------------- Если есть позиция BUY то
      ClosePosWithMaxProfitInCurrency(); //--------  закрытие одной позиции с максимальным профитом в валюте депозита.
    if(!ExistPositions( NULL, OP_BUY, Magic)) //----------- если позиции BUY отсутствуют то
      sellSignal = true;
  } 

 // и аналогично для п.4.

} 
return; 

...

void OnTimer() {
  if (sellSignal) {
    ticket=OpenPosition(NULL,OP_SELL, NDLot(Lot),0,0, Magic, Com); //------------ открываем позицию SELL
    sellSignal = false;
  }
  // и аналогично для buy
}
Escribe las variables buySignal ysellSignal de forma global.
 
Mihail Matkovskij #:

Un conjunto de comandos está escrito en el código. El terminal no sabe lo que necesitas, ¡sólo sabe lo que está escrito en el código!

He borrado este mensaje porque el problema es que las órdenes no deberían cerrarse por beneficios sino por tiempo.

Esto se debe a que tenemos beneficios no siempre y no siempre donde deberían estar.

Por lo tanto, necesitamos la función"Cerrar una posición abierta al principio de todas las posiciones disponibles".

 
GlaVredFX #:

He borrado este mensaje, porque el problema es que las órdenes deberían cerrarse en función del tiempo y no del beneficio.

Porque el beneficio no siempre está ahí y no siempre está donde debería estar.

Por lo tanto, necesitamos la función"Cerrar una posición abierta al principio de todas las posiciones disponibles".

He añadido un ejemplo de apertura de posición en el temporizador en el post anterior. Así se garantiza la apertura de la posición. Puede sustituir su propia función allí.

 
Mihail Matkovskij #:

Añadido un ejemplo de apertura de posición de temporizador en el post anterior. Así se garantiza la apertura del puesto. Puede sustituir su propia función allí.

Pero no así. Es necesario controlar el resultado de

ClosePosWithMaxProfitInCurrency

o una nueva función suya en OnTradeTransaction. Y si no hay posiciones, entrará. O escribir la señal en buySignal osellSignal y procesarla en OnTimer como he mostrado en el ejemplo.

Razón de la queja: