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

 
STARIJ:

Internet vuelve a funcionar. ¿Puedo escribir a la oficina de correos?


Sí, estoy en contacto. Envíame un mensaje.

 

Ayuda para afinar el asesor Soy un programador novato, descripción:

El asesor trabaja en dos pares de divisas EURUSD y USDCHF, sólo abre dos operaciones de compra cuando hay una divergencia de 10pp (esencialmente un árbitro estándar).

Esta es la condición: si ((ind2>ind1+impulso*Punto && ind3<ind4-impulso*Punto) || (ind2<ind1-impulso*Punto && ind3>ind4+impulso*Punto))

Y se cierra cuando la ganancia/pérdida total alcanza un determinado valor: si ((AccountProfit()>=10)||(AccountProfit()<=-20))


EL PROBLEMA: No siempre abre 2 operaciones, a veces abre 3. O abre dos operaciones de la misma moneda. Necesita: siempre abre 2 transacciones en diferentes divisas (una - en EURUSD; otra - en USDCHF).



Aquí está el código en sí:


extern double impulse = 10; // Variables globales

extern double Lots = 1;


int inicio()

{

double ind2=iClose("EURUSD",PERIOD_M1,0);

double ind1=iOpen("EURUSD",PERIOD_M1,0);


double ind3=iClose("USDCHF",PERIOD_M1,0);

double ind4=iOpen("USDCHF",PERIOD_M1,0);


doble oper1=ind2-ind1;

double EUR=(int)DoubleToStr(oper1*100000,0);


doble oper2=ind3-ind4;

double CHF=(int)DoubleToStr(oper2*100000,0);


Comment(StringFormat("Datos de salida\nEUR = %G\nCHF =%G",EUR,CHF));

si ((AccountProfit()>=10)||(AccountProfit()<=-20)) // Condición de cierre

Alerta3();

if ((ind2>ind1+impulso*Punto && ind3<ind4-impulso*Punto) || (ind2<ind1-impulso*Punto && ind3>ind4+impulso*Punto)) //condición abierta

if (OrdersTotal() == 0)

Alerta1();

if (OrdersTotal() == 1)

Alerta2();

return(0);

}


int Alerta1()

{

if (OrdersTotal() == 0)

int send1=OrderSend("EURUSD",OP_BUY,Lots,Ask,3,0,0);

return(0);

}


int Alerta2()

{

if(PedidosTotal() == 1)

int send2=OrderSend("USDCHF",OP_BUY,Lots,Ask,3,0,0);

return(0);

}


int Alerta3()

{

while (OrdersTotal()>0)

if (OrderSelect(0, SELECT_BY_POS, MODE_TRADES)) /Cerrar

int cl1=Cierre del pedido (OrderTicket(),OrderLots(),Bid,3);

int cl1=Cierre del pedido (OrderTicket(),OrderLots(),Ask,3);

return(0);

}

 

Alexey Belyakov:  CУТЬ ПРОБЛЕММЫ: Не всегда открывает 2 сделки, а бывает открывает 3. Или открывает две сделки по одной валюте. Нужно чтобы: открывал всегда 2 сделки по разным валютам ( одна - по EURUSD; другая- по USDCHF)

Se ordena al servidor que abra el euro. Para cuando llega al servidor, para cuando el servidor ... De momento, no hay pedidos. En el siguiente tick se vuelve a cumplir la condición y de nuevo la orden de abrir el euro. El servidor ha abierto el primer pedido. Como hay 1 pedido, se envía la orden de abrir un segundo (¡y ya es el tercero!) pedido.

He anulado todas las funciones y he eliminado la devolución. Aquí está esta parte del programa (pulsamos el botón SRC para insertarlo)

  if((ind2>ind1+impulse*Point && ind3<ind4-impulse*Point) ||
     (ind2<ind1-impulse*Point && ind3>ind4+impulse*Point))   // Условие открытия
     if(OrdersTotal() == 0) Alert1();
     if(OrdersTotal() == 1) Alert2();
}

void Alert1()
{
  if (OrdersTotal() == 0)  // Перед вызовом этой функции уже проверялось количество ордеров
  int send1=OrderSend("EURUSD",OP_BUY,Lots,Ask,3,0,0);
}

void Alert2()
{
  if(OrdersTotal() == 1)  // Перед вызовом этой функции уже проверялось количество ордеров
  int send2=OrderSend("USDCHF",OP_BUY,Lots,Ask,3,0,0);
}

y lo he sustituido (un poco tosco, pero en mi opinión es mejor que el original) por

  if((ind2>ind1+impulse*Point && ind3<ind4-impulse*Point) ||
     (ind2<ind1-impulse*Point && ind3>ind4+impulse*Point))   // Условие открытия
     if(OrdersTotal() == 0)
  {
    int send1=OrderSend("EURUSD",OP_BUY,Lots,Ask,3,0,0); 
    int send2=OrderSend("USDCHF",OP_BUY,Lots,Ask,3,0,0);
    Sleep(60); // Дождаться следующего бара, а то еще пооткрывает
  }
}

Hay una línea extra en la función Alert3

  int cl1=OrderClose (OrderTicket(),OrderLots(),Ask,3);
En lugar de double CHF=(int)DoubleToStr(oper2*100000,0); try int CHF=oper2/_Point;
 
STARIJ:

sustituido (burdo, pero en mi opinión mejor que el original) por

No es grosero, pero funcionará con errores. Aunque sólo sea porque ambas órdenes pasan por pedir el mismo carácter.
 
Alexey Kozitsyn:   No es grosero, pero funcionará con errores. Aunque sólo sea porque ambas órdenes van por Ask del mismo símbolo.

Por supuesto, tienes toda la razón. Además, este error estaba en el código fuente, pero se disimuló utilizando funciones tanto del autor como de ti, como de mí, que soy un pecador. Después de haber eliminado las funciones, el error se hizo evidente. Creo que las posiciones se abrirán sólo por el símbolo en cuyo gráfico se encuentra el EA. ¿Verdad?

 
STARIJ:

Por supuesto, tienes toda la razón. Y este error estaba contenido en el código fuente, pero fue enmascarado por el uso de funciones del autor, de ti y de mi pecador. Después de haber eliminado las funciones, el error se hizo evidente. Creo que las posiciones se abrirán sólo por el símbolo en cuyo gráfico se encuentra el EA. ¿Verdad?

Sí, por supuesto, si se cumplen las condiciones para la apertura. El Ask para el segundo símbolo debe obtenerse por separado.
 
Hola a todos. La pregunta es ingenua, se refiere a la función OrdersTotal(). Está claro que devuelve el número de pedidos, y los pedidos están numerados de 0 a N. Pero si las barras se numeran a partir de la recién abierta en el historial, es decir, la barra "fresca" se numera como 0 y la "antigua" como N. Y en la función OrdersTotal(), entiendo que todo sucede al revés - la orden abierta más antigua se numera como 0 y la "fresca" como N. ¿Lo he hecho bien?
 
Youri Lazurenko:
Hola a todos. La pregunta es ingenua, se refiere a la función OrdersTotal(). Está claro que devuelve el número de pedidos y la numeración de los mismos es de 0 a N. Pero si las barras se numeran a partir de la recién abierta en el historial, es decir, una barra "fresca" se numera como 0 y una antigua - N. Y en la función OrdersTotal(), entiendo que todo sucede al revés - la orden abierta más antigua se numera como 0 y la "fresca" como N. ¿Lo he hecho bien?

Sí, pero hay matices.

Hubo un tiempo en que la clasificación dependía de la clasificación en la terminal. Ningún usuario puede decir con seguridad si ese tiempo volverá "de repente" cuando la ordenación dependa de nuevo de la ordenación del terminal. Por eso es más fiable recoger las órdenes en un array y ordenarlas por su hora de apertura/cierre - entonces sabrá con seguridad que su ordenación depende del tiempo y no "de repente" de la ordenación en el terminal.

 
Artyom Trishkin:

Sí, pero hay matices.

Hubo un tiempo en que la clasificación dependía de la clasificación en la terminal. Ningún usuario puede decir con seguridad si ese tiempo volverá "de repente" cuando la ordenación dependa de nuevo de la ordenación del terminal. Por eso es mejor recoger las órdenes en un array y ordenarlas por hora de apertura/cierre - entonces sabrá con seguridad que su ordenación depende del tiempo y no "de repente" de la ordenación en el terminal.


Hola. Gracias por su respuesta. En primer lugar, quiero volver a su respuesta anterior a mi pregunta, sobre el ciclo inverso. Ayer, antes de irme a trabajar, escribí una respuesta, y hoy, no he podido encontrar mis (y tus) mensajes en absoluto. Por lo que entendí, lo pregunté en una rama equivocada. El ciclo inverso es...

"Por eso es más fiable recoger las órdenes en un array y ordenarlas por tiempo de apertura/cierre" - esto es muy interesante, y creo que es más fiable y correcto (y me parece que, al definir la última orden, no siempre se consigue lo que se necesita). Si no es difícil, ¿cómo lo hago (crear una matriz por tiempo de apertura)?

Y una cosa más. Todavía no lo he probado. Tenemos una orden rentable y otra perdedora (de bloqueo). Las órdenes de beneficios se cierran con el trailing stop. Me gustaría tener una nota de que las órdenes se han cerrado para comparar su beneficio total con el de las órdenes perdedoras y cerrar las perdedoras, si el saldo es positivo. Me interesa saber exactamente qué pedidos se han cerrado.

 
STARIJ:

Supongo que las posiciones sólo se abrirán en el símbolo en cuyo gráfico se encuentra el EA. ¿Verdad?

Si su Asesor Experto está trabajando en el EURUSD, pero usted quiere colocar una orden de COMPRA en el USDCHF

entonces debe utilizar MarketInfo("USDCHF",MODE_ASK); en lugar de Ask (será para EURUSD) en OrderSend