como cerrar una orden en MQL4?

Portada Foros Metatrader como cerrar una orden en MQL4?

Este debate contiene 16 respuestas, tiene 3 mensajes y lo actualizó  IndicatoriNosu hace 7 años, 6 meses.

Viendo 15 publicaciones - del 1 al 15 (de un total de 17)
  • Autor
    Artículos
  • #17181

    jdcabezas
    Participante

    Hola, si estoy largo o corto, cómo puedo cerrar una orden en un EA, pensaba que sería con la función
    bool OrderClose( int ticket, double lots, double price, int slippage, color Color=CLR_NONE)
    Pero necesito el número de ticket, no? y este lo asigna el bróker cuando lanza la orden al mercado, por tanto que ticke tengo que meterle a la función si no se el número que me asignará el broker?

    #19954

    IndicatoriNosu
    Participante

    Buenos días, jdcabezas!!

    Antes de ejectutar la función OrderClose() tienes que seleccionar la orden que quieres con la OrderSelect() y así puedes acceder al número de ticket con la función OrderTicket().

    Un ejemplo lo tienes en la plantilla para Expert Advisor que comentaba en otro tema, en la función CheckForClose(). Espero que te sirva, si no dime y te posteo un ejemplo comentado cuándo tenga un poco más de tiempo, que ahora esoy muy liado.

    #19956

    jdcabezas
    Participante

    Hola, una prueba rápida para abrir una orden y cerrar la misma (ya se que no tiene utilidad), es para ver si order ticket me captura automaticamente el número de orden, sería así?

    Code:
    int start()
    {
    OrderSend(Symbol(),OP_BUY,0.1,Ask,3,Bid-15*Point,Bid+15*Point);
    OrderClose(OrderTicket(),0.1,Ask,3,Red);
    return; // Exit start()
    }
    #19955

    jdcabezas
    Participante

    Hola, gracias por tomarte tantas molestias.

    No entiendo el ejemplo de tu plantilla, podrías comentarme como hacerlo para un código tan simple como este, pretendo que lance una orden de compra, muestre el número de ticket, la cierre y haga lo mismo con una orden de venta:

    Code:
    int numerodeorden;
    int start() // Special function start()
    { // Opening BUY
    OrderSend(Symbol(),OP_BUY,0.1,Ask,3,Bid-15*Point,Bid+15*Point);
    numerodeorden=OrderTicket();
    Alert(«el numero de orden es «, numerodeorden);
    OrderClose(OrderTicket(),0.1,Ask,3,Red);

    OrderSend(Symbol(),OP_SELL,0.1,Ask,3,Bid-15*Point,Bid+15*Point);
    numerodeorden=OrderTicket();
    Alert(«el numero de orden de venta es «, numerodeorden);
    OrderClose(OrderTicket(),0.1,Ask,3,Red);

    return; // Exit start()
    }

    #19957

    IndicatoriNosu
    Participante

    Como te dije, antes:

    Quote:
    Antes de ejectutar la función OrderClose() tienes que seleccionar la orden que quieres con la OrderSelect() y así puedes acceder al número de ticket con la función OrderTicket().

    Es decir, primero seleccionas una orden con OrderSelect() y luego accedes a su número de ticket de la orden seleccionada con OrderTicket() para recibir el número de ticket y poder ejecutar OrderClose(). La selección de una orden puede ser algo complicado si no se sabe el número de ticket, como es el caso. Primero hay que hacer un recorrido por todas las órdenes que tengas activas en tu cuenta, incluyendo todas las posiciones (órdenes abiertas o ejecutadas) y todas las órdenes pendientes (órdenes stop y limit). Cada una de estas órdenes tiene un número de índice, cómo si fuese un array. Imagenemos que tienes las siguientes 4 órdenes:

    • Orden 1: posición cero en el índice. Orden de compra en el par EUR/USD abierta manualmente
    • Orden 2: posición 1 en el índice. Orden de compra en el par EUR/USD abierta por tu EA, esta será nuetro objetivo en el ejemplo.
    • Orden 3: posición 2 en el índice. Orden de venta en USD/CHF.
    • Orden 4: posición 3 en el índice. Orden de compra STOP en EUR/USD abierta también por el EA y que aún no ha sido abierta.

    Tenemos nuestro Expert Advisor andando en el par EUR/USD y queremos cerrar una operación de compra que el EA abrió anteriormente en el par EUR/USD y que ya esté como operación abierta, no pendiente. Si miramos las 4 órdenes que tienes, sería la orden 2, la que está en la posición 1 del índice.

    Primero hacemos un recorrido por todo el índice, desde cero hasta 3. Para que el programa sepa siempre hasta dónde llegar hacemos el recorrido desde cero hasta el total de órdenes menos 1:

    Code:
    for (int i = 0; i < OrdersTotal(); i++){ //aquí ejecutamos el OrderSelect() para ir seleccionado cada una de las ordenes del indice //cuando la orden seleccionada cumpla las condiciones de la orden que queremos cerrar //ejecutamos OrderTicket() y ya podemos ejecutar OrderClose() }

    ¿Qué condiciones ha de cumplir la orden que queremos cerrar?: Hemos dicho que sea una operación en EUR/USD, cómo el EA hemos dicho que está ejecutándose en EUR/USD se puede utilizar Symbol(), que devuelve el símbolo del gráfico en el que está el EA. También queremos cerrar sólo la operación que abrió el EA, no la que se abiró manualmente o la que abrió otro EA (se puede hacer de muchas formas, a mi me gusta hacerlo con el MagicNumber ya que así se permite que se puedan utilizar múltiples instancias del mismo EA incluso en el mismo par de divisas y mismo timeframe de forma totalmente independiente). Cómo tercera condición queremos cerrar la operación de compra abierta, no la pendiente:

    Code:
    for (int i = 0; i < OrdersTotal(); i++){ //Ejecutadmos la funcion OrderSelect if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { //si OrderSelect ha seleccionado alguna orden, comprobamos las condiones que buscamos if(Symbol() == OrderSymbol()) { //si el simbolo del grafico actual es igual al simbolo de la orden seleccionada, //pasamos a la siguiente comprobacion if(OrderMagicNumber() == EL_MAGIC_NUMBER_DE_TU_EA) { //si el MagicNumber de la orden seleccionada es igual al MagicNumber que utilizamos //pasamos a la suiente comprobacion if(OrderType() == OP_BUY){ //si la orden seleccionada es del tipo OP_BUY //se han dado las tres condiciones que hace que la orden seleccionada sea //la orden que queremos cerrar, asi que la cerramos OrderClose(OrderTicket(),DEMAS_PARAMETROS.....); } } } } } }

    El ejemplo que te decía de la plantilla es similar pero hace más comprobaciones para evitar, en la medida de los posible, algunos fallos que pueden darse en la vida real, como puede ser la repetición del proceso un determinado número de veces en caso de que, por alguna razón, falle el ciere en un primer intento. Estudialo, creo que está bastante completo.

    Espero que te sirva de ayuda y no te lie más.

#19958

jdcabezas
Participante

Hola, me queda claro como tengo que hacerlo según tu explicación, pero cuando lo aplico a mi código no me cierra las órdenes, sinceramente me está volviendo loco este lenguaje de programación, en C es muy sencillo pero no me aclaro con las ordenes de apertura y cierre de posiciones, te paso el código que tengo para probar el cierre y apertura de operaciones que a mi no me funciona.

Code:
#include

extern int MagicNumber = 852745961;
extern int MagicNumber = 852745962;
int numerodeorden;
int testcompra=0;
int testventa=0;

void start()
{
while (testcompra==0)
{
Alert(«enviar orden de compra»);
OrderSend(Symbol(),OP_BUY,0.1,Ask,3,Ask-15*Point,Ask+25*Point,»My order #1″,MagicNumber1,0,Green);
testcompra=1;
}

while (testventa==0)
{
Alert(«enviar orden de venta»);
OrderSend(Symbol(),OP_SELL,0.1,Ask,3,Ask-15*Point,Ask+25*Point,»My order #2″,MagicNumber2,0,Green);
testventa=1;
}

for (int i = 0; i < OrdersTotal(); i++) { //aquí ejecutamos el OrderSelect() para ir seleccionado cada una de las ordenes del índice //cuando la orden seleccionada cumpla las condiciones de la orden que queremos cerrar //ejecutamos OrderTicket() y ya podemos ejecutar OrderClose() OrderSelect(i,SELECT_BY_POS,MODE_TRADES); //Ejecutamos la funcion OrderSelect if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { //si OrderSelect ha seleccionado alguna orden, comprobamos las condiones que buscamos if(Symbol() == OrderSymbol()) { //si el simbolo del grafico actual es igual al simbolo de la orden seleccionada, //pasamos a la siguiente comprobacion if(OrderMagicNumber() == MagicNumber) { if(OrderType() == OP_BUY) { //se han dado las tres condiciones que hace que la orden seleccionada sea //la orden que queremos cerrar, asi que la cerramos OrderClose(OrderTicket(),0.1,Ask,3,Red); } } } } } return; // Exit start() }

tan sólo pretendo abrir una orden de compra y una orden de venta, y que después me cierre las operaciones, pues no hay forma, qué estoy haciendo mal, por que he puesto el código tal cual me has indicado, qué modificaciones tendría que hacer en este código y una vez que controle bien como abrir y cerrar posiciones poder aplicarlo a mi código?
Gracias y te debo una.

#19960

IndicatoriNosu
Participante

Jejejeje, creo que lo tienes hecho, sólo tienees errores tontos típicos de cuándo llevas horas dándole vueltas a un problema, tienes la solución delante y no la ves.

Bromas a parte, te comento, inicializabas dos veces la variable MagicNumber, pero es que además luego ponías en una orden MagicNumber1 y en la otra MagicNumber2 y ninguna de estas variables existen en tu código. Luego haces la comprobación if(OrderMagicNumber() == MagicNumber), pero lo que has asociado a las órdenes era MagicNumber1 y MagicNumber2, por lo que no se cumple la condición para ejecutar OrderClose().

Code:
#include

extern int MagicNumber = 852745961;
int numerodeorden;
int testcompra=0;
int testventa=0;

void start()
{
while (testcompra==0)
{
Alert(«enviar orden de compra»);
OrderSend(Symbol(),OP_BUY,0.1,Ask,3,Ask-15*Point,Ask+25*Point,»My order #1″,MagicNumber,0,Green);
testcompra=1;
}

while (testventa==0)
{
Alert(«enviar orden de venta»);
OrderSend(Symbol(),OP_SELL,0.1,Ask,3,Ask-15*Point,Ask+25*Point,»My order #2″,MagicNumber,0,Green);
testventa=1;
}

for (int i = 0; i < OrdersTotal(); i++) { //Ejecutamos la funcion OrderSelect if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { //si OrderSelect ha seleccionado alguna orden, comprobamos las condiones que buscamos if(Symbol() == OrderSymbol()) { //si el simbolo del grafico actual es igual al simbolo de la orden seleccionada, //pasamos a la siguiente comprobacion if(OrderMagicNumber() == MagicNumber) { if(OrderType() == OP_BUY) { //se han dado las tres condiciones que hace que la orden seleccionada sea //la orden que queremos cerrar, asi que la cerramos OrderClose(OrderTicket(),0.1,Bid,3,Red); } if(OrderType() == OP_SELL) { //se han dado las tres condiciones que hace que la orden seleccionada sea //la orden que queremos cerrar, asi que la cerramos OrderClose(OrderTicket(),0.1,Ask,3,Red); } } } } } return; }

También hay que tener en cuenta que en OrderClose se pone el precio Ask para cerrar un operación de venta y el precio Bid para cerrar una operación de compra, es simplemente porque es la forma en que funciona el mercado: si cierras una operación de venta, lo que haces en realidad es comprar y las compras se realizan al precio Ask, y viceversa. Si no se pone así es muy fácil que obtengas errores al intentar cerrar una determinada orden.

#19961

jdcabezas
Participante

Gracias, te debo una paella, ya está el código funcionando, otra cosa es que sea rentable o no, un saludo.
Mi mail es [email protected], por si necesitas algo, gracias de nuevo.

#19964

IndicatoriNosu
Participante

Me alegro!!! Y si este no te es rentable no pares de echarle imaginación e ir probando diferentes estrategias.

#19966

jdcabezas
Participante

Hola, este sistema como te decia no es rentable por que cuando entra en tendencia sólo me hace una compra o una venta, y si el mercado se gira pierdo lo ganado, por tanto al ponerle el take profit y stop loss, recojo ganancias pero no se como hacer que si sigue en tendencia me vuelva a hacer otra compra de nuevo, te pongo el código para que lo veas.

Code:
#property copyright «jose damian cabezas pozo»
#property link «http://www.metaquotes.net»

//————————————————————-
//—————-cuerpo del programa principal—————
//————————————————————-
#include

extern int MagicNumber = 852745962;
extern int Periodocalctrend = 5; //variable externa que almacena el periodo para calcular la tendencia
extern int PeriodoMA = 5; //periodo de la media alta
extern int PeriodoMM = 5; //periodo de la media de medios
extern int PeriodoMB = 5; //periodo de la media baja
extern double TakeProfit =15;
extern double StopLoss =15;

int testcompra=0;
int testventa=0;
int numordersend, numorderbuy;
int numerodeorden;
int ticket = 0;

int start()
{

//int testcompra=0;
//int testventa=0;
double trend; //variable que almacena la tendencia
double MA_alta_1, MA_baja_1, MA_media_1; //variables que me almacenan el valor de la media alta, media baja y media de medios

//————————————————————-
//while(Close[1]!=0)
//{
MA_alta_1 = iMA(NULL, 0, PeriodoMA, 0, MODE_EMA, PRICE_HIGH, 1); //valor de media alta para el ultimo tick de la vela anterior

MA_baja_1 = iMA(NULL, 0, PeriodoMB, 0, MODE_EMA, PRICE_LOW, 1);//valor de media baja para el ultimo tick de la vela anterior

MA_media_1 = iMA(NULL, 0, PeriodoMM, 0, MODE_EMA, PRICE_MEDIAN, 1);//valor de media de medios para el ultimo tick de la vela anterior

trend=calctrend(); //saltamos a la funcion que calcula la tendencia
//————————————————————-
if(trend==0) //si tendencia es 0 no tenemos tendencia
{
Alert(«no tenemos tendencia»);
}
//————————————————————-

if(trend!=0)
{
//————————————————————–
if (trend>0)
{
Alert («la tendencia es alcista, y su valor es de», trend);
while (Close[1]>MA_alta_1&&testcompra==0)
{
cierraoperacion();
Alert(«enviar orden de compra»);
ticket=OrderSend(Symbol(),OP_BUY,0.1,Ask,3,Ask – StopLoss * Point,Ask + TakeProfit * Point,»My order #1″,MagicNumber,0,Green);
testcompra=1;
testventa=0;
Alert(«el valor de la variable ticket una vez ha vendido es», ticket);
}
}
//————————————————————-
else
{
if(trend<0)
{
Alert("la tendencia es bajista, y su valor es de", trend);
while (Close[1]

La idea es que una vez estamos en tendencia por ejemplo alcista, funcione como lo hace pero que por ejemplo a 15 ticks recoja beneficios y realice otra compra, cómo puedo conseguirlo, pensaba que utilizando la variable ticket, que tomara un valor y utilizar este valor cuando se vendiera para volver a comprar, pero me da un valor raro, se te ocurre algo. Me he fijado en tus funciones pero no saco nada en claro.
Se te ocurre alguna variación para no perder lo ganado una vez el mercado se gire?
Gracias.
alcista

#19968

IndicatoriNosu
Participante

Como te dije, tu idea para decidir en algún momento si hay tendencia o no, no me parece muy buena, pero yo pienso desde un punto de vista a medio-largo plazo y creo que tú intentas hacer algo a corto plazo, puede incluso que scalping, ¿no? Entonces puede que valga. De todas formas, ideas de sistemas de trading hay miles, yo no tengo una infalible, de lo contrario ya sería millonario.

Si me pongo muy repelente dime, no quiero que parezca que yo lo se todo, porque no lo sé ni de lejos.

Archivos adjuntos:
#19970

jdcabezas
Participante

No por favor, no te preocupes cualquier idea o sugerencia será bien recibida. Mi idea para determinar la tendencia es comparar dos valores sucesivos de la EMA, el de la vela recién finalizada y el de la vela anterior, para suavizar la EMA se pueden ir probando valores a ver cual va mejor y de esta forma que determine la tendencia sin esos altibajos.
No se me ocurre otra forma de determinar la tendencia (pero yo soy muy pollo programando sistemas automáticos).
El funcionamiento del sistema que estoy programando es el siguiente:

– 1º determina tendencia.
– 2º Si no tenemos tendencia no hace nada.
– 3º si la tendencia es alcista y la vela que finaliza está por encima de la EMA de altos (será una vela verde) entramos largos y lanza una orden de compra. Si estamos vendidos cierra la orden de venta.
– 4º Si la tendencia es bajista y la vela que finaliza está por debajo de la EMA inferior (será una vela roja) entramos cortos y lanza una orden de venta. Si estamos comprados cierra la orden de compra.

El problema es que los ticks que consigues cuando estás en tendencia, los pierdes cuando la tendencia se gira, para esto necesito:
– Cada 5, 10, 15, etc (esto se irá probando), salir y si seguimos en tendencia volver a entrar, es decir si estamos en tendencia alcista y estamos comprados cuando tenga por ejemplo 15 ticks, vender y volver a comprar hasta que tenga de nuevo 15 ticks y así hasta que la tendencia se gira-
– Si la tendencia es bajista el mismo proceso pero yendo vendido.

La pregunta es:
– Cómo puedo hacer esto, existe algún boolean que puede darme un true o un false cuando se haya vendido para así usarlo para entrar de nuevo, o cómo puedo hacerlo?
-Conoces algún indicador que vaya bien para anticiparme al cambio de tendencia y entonces salir de la operació?
– Se admiten sugerencias.

Gracias y perdona por la extensión del comentario, un saludo.

#19971

Derec
Participante
jdcabezas wrote:
– Conoces algún indicador que vaya bien para anticiparme al cambio de tendencia y entonces salir de la operació?

Yo también lo quiero saber!!! (junto a unos cuántos miles de personas) :woohoo:

#19972

IndicatoriNosu
Participante

Como dice Derec, you también quiero un indicador que me diga cuándo va a cambiar la tendencia!! Jeje.

Fuera bromas, indicadores hay muchos. Desde mi punto de vista todos tienen su utilidad, todos son buenos y todos son malos. La clave es la forma de uso y la experiencia del trader. Por eso siempre hay que aprender y entrenarse. Y si vas a programar hay que conocer muy bien que es lo que hace el indicador, su fórmula de cálculo, qué datos tiene en cuenta y que significa su resultado. No es tan simple como se ha planteado aquí, al menos desde mi opinión.

#19973

jdcabezas
Participante

Hola, tengo un problema con el código, es el siguiente, quiero lanzan 4 ordenes de compra o de venta cuando se cumplen ciertas condiciones, y cada una de ellas debe tener un take profit diferente, de la siguiente forma:

Code:
OrderSend(Symbol(),OP_BUY,0.1,Ask,3,0,Ask + 30 * Point,»My order #1″,MagicNumber,0,Green);
OrderSend(Symbol(),OP_BUY,0.1,Ask,3,0,Ask + 60 * Point,»My order #1″,MagicNumber,0,Green);
OrderSend(Symbol(),OP_BUY,0.1,Ask,3,0,Ask + 90 * Point,»My order #1″,MagicNumber,0,Green);
OrderSend(Symbol(),OP_BUY,0.1,Ask,3,0,0,»My order #1″,MagicNumber,0,Green);

Una de las condiciones que tiene que cumplirse es la siguiente:

Code:
vela1=Close[1]-Open[1]; //Si la vela actual y la anterior es >=0 la vela es verde, si es <0, la vela es roja

vela2=Close[2]-Open[2];

if (comprados==1&&vela1<0&&vela2>=0&&Close[1]=0&&vela2<0&&Close[1]>MA_media_1) //si la vela actual es verde y la vela anterior es roja, si estamos vendidos y si el cierra de la vela actual
{ //está por encima de la media de medios, tenemos que cerrar la mitad de las posiciones, o sea 2.
cierraoperacion();
}

Cuando se cumple esto salta a la función:

Code:
double cierraoperacion()

{

for (int i = 0; i < OrdersTotal(); i++) { //Ejecutamos la funcion OrderSelect if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { //si OrderSelect ha seleccionado alguna orden, comprobamos las condiones que buscamos if(Symbol() == OrderSymbol()) { //si el simbolo del grafico actual es igual al simbolo de la orden seleccionada, //pasamos a la siguiente comprobacion if(OrderMagicNumber() == MagicNumber) { if(OrderType() == OP_BUY) { //se han dado las tres condiciones que hace que la orden seleccionada sea //la orden que queremos cerrar, asi que la cerramos OrderClose(OrderTicket(),0.1,Bid,3,Blue); testcompra=1; comprados=0; } if(OrderType() == OP_SELL) { //se han dado las tres condiciones que hace que la orden seleccionada sea //la orden que queremos cerrar, asi que la cerramos OrderClose(OrderTicket(),0.1,Ask,3,Blue); testventa=1; vendidos=0; } } } } } }

Cuando salta a esta función y tiene por ejemplo 4 órdenes abiertas, debería cerrarlas todas a la vez, sin embargo no lo hace. Cierra 2 o 3, no siempre las mismas. Esto puede deberse a que no le da tiempo a cerrarlas todas cuando salta a la función y se espera al siguiente ciclo para cerrar las que sigue teniendo abiertas?
De qué forma podría cerrarlas todas a la vez?
Es posible abrir sólo una orden e ir cerrándola por lotes, es decir abro una orden y cuando se cumplen 30 ticks cierro el 30 % de la operación, cuando se cumplen otros 30 ticks cierro el otro 30 %, al cumplirse otros 30 ticks cierro otro 30 % y el resto de la operación abierta, que será del 10% seguirá abierta?

Otra pregunta, como puedo programar las órdenes para que el take profit esté condicionado al trailing stop, es decir abrir 4 posiciones y tal y como he puesto en el código anterior y la que el take profit de cada orden sea de 20 pips para la primera, 40 pips para la segunda y 60 pips para la tercera por ejemplo?

Gracias.

Viendo 15 publicaciones - del 1 al 15 (de un total de 17)

Debes estar registrado para responder a este debate.

La inversión es especulativa. Al invertir su capital está en riesgo. Este sitio no está destinado para su uso en jurisdicciones en las que las operaciones o inversiones descritas están prohibidas y solo deben ser utilizadas por dichas personas y en las formas legalmente permitidas. Es posible que su inversión no califique para la protección de los inversores en su país o estado de residencia, por lo que debe realizar su propia diligencia debida. Este sitio web es gratuito para su uso, pero es posible que recibamos una comisión de las compañías que presentamos en este sitio. Haga clic aquí para mas información.