Problema de los pedidos múltiples - página 2

 

Hola Raptor;

Mientras que en Tester todas las órdenes se cierran cuando se cierra el TrailingStop, en Demo sólo se cierra la orden cerrada por medio del TrailingStop, cualquier orden que esté abierta sigue abierta.

Usando el siguiente código sobre el de su consejo la lógica es;

"Encuentra la condición de la última orden, si fue un cierre entonces ejecuta el código para empezar a cerrar todas las órdenes abiertas restantes".

¿Alguna idea de por qué ocurre esto?

Saludos

Luis

int OrdType, GLError;
   double OrderClosed;
   RefreshRates();
   
    for(int Closed = OrdersTotal()-1;Closed >= 0; Closed--) 
      if(OrderSelect(Closed,SELECT_BY_POS,MODE_HISTORY)
        && OrderMagicNumber()== MagicNumber
        && OrderSymbol()== Symbol())
        {//29
        OrderClosed = OrderCloseTime();
        if(OrderClosed!=0)
           {//30                                  
   for(int OrderPos = OrdersTotal()-1; OrderPos >= 0; OrderPos--)       
      if(OrderSelect(OrderPos, SELECT_BY_POS, MODE_TRADES)
         && OrderMagicNumber()== MagicNumber 
         && OrderSymbol()== Symbol())                                       
         {//31
         OrdType = OrderType();
         if(OrdType == OP_BUY || OrdType==OP_SELL)
           {//32
           if(!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(),RealSlippage, Yellow))
               GLError = GetLastError();
           }//32                                         
          }//31
       }//30
     }//29 
    
  if(GLError > 0) Print("Error Closing/Deleting Order, error # ", GLError, " for ticket: ", OrderTicket());           
  return(0);
  }//0 
 
luisneves:

Hola Raptor;

Mientras que en Tester todas las órdenes se cierran cuando se cierra el TrailingStop, en Demo sólo se cierra la orden cerrada por medio del TrailingStop, cualquier orden que esté abierta sigue abierta.

Usando el siguiente código sobre el de su consejo la lógica es;

"Encuentra la condición de la última orden, si fue un cierre entonces realiza el código para empezar a cerrar todas las órdenes abiertas restantes".

¿Alguna idea de por qué ocurre esto?

No se puede hacer esto. . .

    for(int Closed = OrdersTotal()-1;Closed >= 0; Closed--)    // OrdersTotal is the total of open orders
      if(OrderSelect(Closed,SELECT_BY_POS,MODE_HISTORY)        //  this is looping through the closed orders

... no tiene sentido utilizar el número de órdenes abiertas como condición de inicio del bucle para recorrer las órdenes cerradas.¿Quizás se refiere a utilizarOrderssHistoryTotal()? pero el OrderCloseTime() de una orden cerrada nunca será == 0

 
luisneves:

.....

Estoy usando BuyTicket y SellTicket en el código para evitar la apertura de múltiples órdenes pero parece que no es el método correcto...

.....

El problema viene cuando viene una condición para abrir una tercera orden y así sucesivamente. Aquí, sin embargo, las condiciones para abrir están ahí y el código ha tratado bien con la segunda apertura, ¿por qué el código no funciona aquí?

Entiendo que has cambiado ligeramente el tema inicial y tal vez la primera cuestión se discute hasta su final (está bien para mí)
Si aún así quieres seguir con el tema inicial, tienes que explicarlo un poco más, porque no entiendo muy bien lo que buscas.

El primer fragmento que he ajustado evita que el código abra varios pedidos. Parecías no estar contento con él, por eso lo has quitado (o simplemente no lo has añadido), pero haciendo lo mismo con BuyTicket y SellTicket.
Entonces usted está hablando de una tercera orden... ¿Buscas algo así?

Compra->Venta->Compra->Venta->Compra
pero evitar
Comprar->Comprar->Vender->Comprar

En otras palabras, si la última orden abierta es de compra, la siguiente debe ser de venta y viceversa?

¿O cuál es la cantidad máxima de órdenes que debe abrir tu EA? ¿Son 2, una de venta y si se cumple la condición de una orden contraria, una de compra, pero ya no una de venta si rebota de nuevo desde el disparo de compra?
Si esto es cierto, ¿cuál fue el problema con el contador OpenOpposite que añadí a su código inicial?

editar:

La tercera opción que puedo imaginar es que quieres abrir otra orden opuesta si la primera orden opuesta ha sido detenida?
Así que como esto:

Comprar->Vender->si la venta ha sido detenida->Vender->si la venta ha sido detenida->Vender

 
kronin:

Entiendo que has cambiado un poco el tema inicial y tal vez el primer tema se discute hasta su final (para mí está bien)
Si todavía quieres seguir con el tema inicial, tienes que explicarlo un poco más, porque no entiendo muy bien lo que buscas.

El primer fragmento que he ajustado evita que el código abra varios pedidos. Parecías no estar contento con él, por eso lo has quitado (o simplemente no lo has añadido), pero haciendo lo mismo con BuyTicket y SellTicket.
Entonces usted está hablando de una tercera orden... ¿Buscas algo así?

Comprar->Vender->Comprar->Vender->Comprar
pero evitar
Comprar->Comprar->Vender->Comprar

En otras palabras, si la última orden abierta es de compra, la siguiente debe ser de venta y viceversa?

¿O cuál es la cantidad máxima de órdenes que debe abrir tu EA? ¿Son 2, una de venta y si se cumple la condición de una orden contraria, una de compra, pero ya no una de venta si rebota de nuevo desde el disparo de compra?
Si esto es cierto, ¿cuál fue el problema con el contador OpenOpposite que añadí a su código inicial?

editar:

La tercera opción que puedo imaginar es que quieres abrir otra orden opuesta si la primera orden opuesta ha sido detenida?
Así que como esto:

Comprar->Vender->si la venta ha sido parada->Vender->si la venta ha sido parada->Vender


Hola Kronin,

Gracias de antemano por su tiempo para apoyarme en esta cuestión.

La estrategia observa esta lógica;

Digamos que la primera orden en abrirse es una compra y luego busca cerrarse por medio del TrailingStop, pero si el Bid rebota algunos pips por debajo delOrderOpenPrice(ReturnDistance), se abrirá una Venta y busca cerrarse por medio del TrailingStop y de nuevo si el Ask rebota algunos pips por encima del OrderOpenPrice entonces se abrirá una compra. Este proceso de ping pong terminará cuando la última orden en abrirse cierre por medio del TrailingStop o alcance la configuración de órdenes máximas que es 7 (uno podría ajustar esto por medio de un externo).

El problema de las aperturas múltiples se produce cuando el precio sube y baja cruzando el OrderOpenPrice, por lo que si tenemos una orden de compra la siguiente puede ser de venta y así sucesivamente.

Respecto a tu ayuda anterior quizás no he explicado bien cual era mi problema. Cualquier ayuda que se me brinde tiene para mi el mayor valor.

Un saludo

Luis

 

Luis, he dedicado bastante tiempo a tu código, pero sinceramente no estoy muy seguro de que haga lo que quieres.

Mira el adjunto. Termínalo/cámbialo, pruébalo, entiéndelo.... y dime al menos que funciona cerca, parecido o completo a lo que buscas. Todavía no estoy muy seguro de la estrategia.
Por favor, no añadas una nueva función todavía (no vuelvas a añadir la martingala). El código es lo suficientemente grande y usted tiene todavía un montón de trabajo en frente de usted, para obtener un funcionamiento fiable.
Tengo que decir que el código no está mucho más claro. No quise cambiar sus partes en funcionamiento (incluso necesita un mejor manejo de errores). He comentado partes y movido partes, pero todo sigue ahí...


Que te diviertas...

Archivos adjuntos:
 
kronin:

Luis, pasé bastante tiempo en su código, pero honestamente no estoy realmente seguro de que hace lo que quiere.

Mira el archivo adjunto, finalízalo/cambia, pruébalo, entiéndelo.... y dime al menos que funciona cerca, parecido o completo a lo que buscas. Todavía no estoy muy seguro de la estrategia.
Por favor, no añadas una nueva función todavía (no vuelvas a añadir la martingala). El código es lo suficientemente grande y usted tiene todavía un montón de trabajo en frente de usted, para obtener un funcionamiento fiable.
Tengo que decir que el código no está mucho más claro. No quise cambiar sus partes en funcionamiento (incluso necesita un mejor manejo de errores). He comentado partes y movido partes, pero todo sigue ahí...


Que te diviertas...


Hola Kronin,

Antes de todo mi más gracias por el tiempo dedicado a apoyar a mis problemas.

Si bien creo que usted ha hecho su mejor esfuerzo para entender la estrategia de algunas cosas no son del todo responder (debido, por supuesto, de mi falta de comprensión en esta materia).

He hecho algunas modificaciones comprar su consejo, pero no estoy seguro de si se hace correctamente.

Dos cuestiones;

1 - La idea es que una vez que el comercio se han cerrado por medio de TrailingStop todas las órdenes abiertas restantes deben cerrar. Las órdenes no deben ser cerradas en el TakeProfit (que el TakeProfit es sólo allí porque quiero estar seguro de que se pone de Freeze Zone). Así que pensé en hacer eso usando el cierre de la última orden para ejecutar la función CloseAll (algunas cosas estúpidas surgen al intentar hacerlo...). Estas usando la última orden cerrada para ejecutar el cierre de las órdenes abiertas, pero no entiendo si eso sucede cuando la operación se cierra por medio del TrailingStop...

2 - El "ping pong" no funciona, al menos en Tester.

Adjunto el archivo donde se han hecho las modificaciones según he entendido.

Gracias de antemano por la paciencia y el tiempo dedicado. (más en mensaje privado)

Saludos cordiales

Luis

Archivos adjuntos:
 

Ok, he cambiado el algoritmo para cerrar todas las órdenes en SL en lugar de TP. (El cambio fue '<' reemplazado por '>' - usted debe encontrar donde)

El ping pong sí me funciona y sólo lo he dejado correr en el tester en modo visual. Pero he ajustado sus parámetros de entrada para que no se abran todas las órdenes casi al mismo tiempo. Tal vez tengas que verificar los params por defecto.

Comienza con la orden inicial (he cambiado la sentencia print()) y luego hace órdenes opuestas.

EURUSD,M1: open #1 comprar 0.01 EURUSD a 1.43310 ok
EURUSD,M1: orden inicial de compra # 1
EURUSD,M1: modificar #1 comprar 0.01 EURUSD a 1.43310 sl: 1.42810 tp: 1.43510 ok
EURUSD,M1: abrir #2 vender 0.01 EURUSD a 1.43200 ok
EURUSD,M1: Orden de venta opuesta colocada # 2
EURUSD,M1: modificar #2 vender 0.01 EURUSD a 1.43200 sl: 1.43700 tp: 1.43000 ok
EURUSD,M1: abrir #3 comprar 0.01 EURUSD a 1.43300 ok
EURUSD,M1: Orden de compra opuesta colocada # 3
EURUSD,M1: modificar #3 comprar 0.01 EURUSD a 1.43300 sl: 1.42800 tp: 1.43500 ok

He añadido el retorno a la OpenOppositeOrder() cuando he abierto una orden. Junto con los ajustes fue posible abrir una orden de compra y en el mismo tick una orden de venta. Esta pista en MaxOrder no es fiable.
Tal vez un mejor enfoque es, para dividir en 2 funciones o dar la función de un parámetro para ejecutar sólo para las órdenes de venta o de compra.

Por cierto, el código que has subido no ha operado, todas las operaciones han fallado debido a un "tamaño de lote no válido" ....

Archivos adjuntos:
 

Hola Kronin,

Gracias por el tiempo dedicado a apoyarme.

En cuanto a la cuestión "el código que has subido no ha operado, todas las operaciones han fallado debido a un "tamaño de lote no válido" .... ", eso sucedió después de mover el código MM al final del archivo. He hecho la llamada de la función usando MM(); al principio del código, parece que este tipo de acción no funciona, pero el último código que enviaste está trabajando y la función MM() sigue en el mismo lugar y está trabajando, así que aquí estoy perdido....

Sobre la apertura de la orden en el mismo tick;

Cuando el EA se mete en el gráfico debe ir hasta que el precio sea mayor (o menor) que el precio en ese momento, es decir, cuando el precio sube (o baja) la OpenDistance una orden de compra (o venta) tiene lugar. A partir de aquí, la siguiente apertura sólo puede ocurrir cuando el precio rebote hacia abajo (si la última orden es de compra) desde el OrderOpenPrice menos el ReturnDistance.La misma lógica en caso de que la última orden sea de venta. Tal vez un límite tiene que estar en su lugar para evitar cualquier apertura de la orden fuera de esta lógica.

Saludos cordiales

Luis

 
//mine
LotSize = (RiskAmount / StopLoss) / TickValue;              //Phil: LotSize is defined in global scope

//yours
double LotSize = (RiskAmount / StopLoss) / TickValue;


Has definido LotSize en el ámbito global y lo has inicializado con 0. En la función void MM() calculas un LotSize sólo válido en esa función. Sólo he quitado la inicialización, por lo que la variable en ámbito global se actualiza.

¿Podrías comentar para cada uno de estos valores, el valor en Pips, por favor?

extern double StopLoss       =  50;
extern double TakeProfit     =  20;
extern double TrailingStop   =   2;
extern int    MinimumProfit  =   3;
extern int    Slippage       =   3;
extern double OpenDistance   =   2;
extern double ReturnDist     =   1;
extern double MinStop        =   1;

¿Cuál es el spread para el Símbolo que quieres ejecutar el EA?

Pero he ajustado tus params de entrada para que no se abran todas las órdenes casi al mismo tiempo.Tal vez usted tiene que verificar los params por defecto.

Intenta hacer lo mismo y déjalo correr en el tester en modo visual.

 
kronin:


Has definido LotSize en el ámbito global y lo has inicializado con 0. En la función void MM() calculas un LotSize sólo válido en esa función. Sólo he quitado la inicialización, por lo que la variable en ámbito global se actualiza.

¿Podrías comentar para cada uno de estos valores, el valor en Pips, por favor?

¿Cuál es el spread para el Símbolo que quieres ejecutar el EA?

Pero he ajustado tus params de entrada para que no se abran todas las órdenes casi al mismo tiempo.Tal vez usted tiene que verificar los params por defecto.

Intenta hacer lo mismo y déjalo correr en el tester en modo visual.


Hola Kronin,

Sí, tengo mucho que aprender....Ahora entiendo que cuando hay una necesidad de un valor para obtener acceso desde el exterior de una función que debe estar en Global.

Los valores que están en externo se multiplican por 10 porque el EA también debe correr en corredores de 5 dígitos. Estoy usando este bloque de código para conseguirlo automáticamente, pero recibo un consejo de WHRoeder que no es compatible con los metales.

int init ()// Adjust for 4 or 5 digits.
   {
   if (Digits == 2 || Digits == 4) <------- not compatible with metals
      {
      pt = Point;
      RealSlippage = Slippage;
      }    
   if (Digits == 3 || Digits == 5) 
      {
      pt = Point * 10;
      RealSlippage = Slippage * 10;
      }

El spread del par puede ser variable. Es por eso que estoy usando el código para salir del nivel de parada.

Con respecto a este tema "Pero he ajustado sus parámetros de entrada para que no todas las órdenes se abran casi al mismo tiempo. Tal vez tengas que verificar los params por defecto".

Por lo que veo (perdón si no es así...), OpenDistance se mantiene como 2 pips y ReturnDistance está ahora con 2 también. Lo que veo ahora mismo es que la orden se abre pero no con 2 pips de diferencia. Esto se está ejecutando con un tester desde una plataforma de un broker ECN (IC Markets). ¿Podría tener esto alguna importancia?

De hecho las ordenes no se abren al mismo tiempo pero parece que la distancia de apertura y la distancia de retorno no se tienen en cuenta para obtener la distancia correcta para abrir las ordenes.

Usted tiene en el código que;

OTLastTick=OTCurrentTick;                      //shift OrderTotal
  OTCurrentTick=OrdersTotal();                   //reinit OrderTotal
  if(OTCurrentTick>0)Trail();                    //Trail
  if(OTLastTick>=2                               //if OrderTotal has changed
     &&OTCurrentTick<OTLastTick
     &&OTCurrentTick>0){CloseAllOnSL();return;}  //Check order closed on SL level
  if(OTCurrentTick>=MaxOrders)return;            //Dont open more orders. Trail and return.
                                                 //Actually we have nothing more to do.
                                                 //Only call opposite if the initial order of the serie is open
  if(OTCurrentTick>0)OpenOppositeOrder(); //<--------------------- include this line to call function (not sure if this the right method to do it...)
  MM();                //<--------------------- include this line to call function (not sure if this the right method to do it...)
                        
  if(OTCurrentTick==0){//init serie
     BuyAllowed=true;
     SellAllowed=true; 

He incluido la línea en negrita para llamar a la función OpenOppositeOrder y aquí no estoy seguro de si esto es correcto. Por otro lado no veo donde está la comparación del tick actual con el último tick que ocurrió 2 pips antes (OpenDistance).

Lo siento si empiezo a aburrirte con mis problemas.

Saludos cordiales

Luis