Mi EA hace una doble entrada - página 4

 
doshur:

¿Puedo preguntar si PositionSelect() comprueba el lado del cliente o el lado del servidor?

Tengo la fuerte sensación de que el problema es causado por el retraso en el que el servidor (lado del corredor) está procesando la solicitud y no se actualiza el lado del cliente es por eso que PositionSelect() se ejecuta de nuevo

Siento fuertemente que no hay diferencia cuando usamos cTrade vs MqlTradeRequest manera y la función Sleep debe ayudar a retrasar todo para conseguir nuestro lado del cliente se "actualiza" antes de PositionSelect() se ejecuta de nuevo causando una doble entrada. Comprobando desde mi ficha de diario, >2013.12.20 08:35:00 Trades '800****': exchange buy 0.01 EURUSD at market placed for execution in 313 ms <

poner el sueño más de 400 debe ser seguro???

¿Qué piensa usted?


"Tengo una fuerte sensación de que el problema es causado por el retraso en el que el servidor (lado del corredor) está procesando la solicitud y no se actualiza el lado del cliente es por eso que PositionSelect() se ejecuta de nuevo"

También creo que esta es la causa de la doble entrada. En mi código es teóricamente imposible enviar una nueva orden si el tamaño de la posición actual es igual o mayor que el tamaño máximo de posición permitido, por lo que cuando el PositionSelect() no recibe a tiempo el estado de la posición actual, mi EA vuelve a enviar una nueva orden.


"¿poner la posición más de 400 debería ser seguro?"

Cuanto mayor sea el intervalo de tiempo mejor, pero hay un problema. Si usted gira su posición, en dos pasos (LARGO a CORTO o CORTO a LARGO), este retraso de tiempo extra puede ser la causa de un mal precio de ejecución, especialmente durante el evento económico macro.

 
snelle_moda:


"Tengo la fuerte sensación de que el problema es causado por el retraso en el que el servidor (lado del corredor) está procesando la solicitud y no se actualiza el lado del cliente por eso PositionSelect() se ejecuta de nuevo"

También creo que esta es la causa de la doble entrada. En mi código es teóricamente imposible enviar una nueva orden si el tamaño de la posición actual es igual o mayor que el tamaño máximo de posición permitido, por lo que cuando el PositionSelect() no recibe a tiempo el estado de la posición actual, mi EA vuelve a enviar una nueva orden.


"Poner el sueño más de 400 debería ser seguro???"

Cuanto mayor sea el intervalo de tiempo mejor, pero hay un problema. Si usted gira su posición, en dos pasos (LARGO a CORTO o CORTO a LARGO), este retraso de tiempo extra puede ser la causa de un mal precio de ejecución, especialmente durante el evento económico macro.

Creo que no debería ser un problema. Mi EA no invierte inmediatamente cuando acabo de enviar una solicitud de compra/venta. Estoy poniendo mi sueño a 800ms para que mi EA tiene tiempo suficiente para esperar a las actualizaciones del corredor. Esperemos que el sueño puede resolver este problema aquí.
 
doshur:
No sé si el broker juega aparte aquí pero parece que nuestro broker es el mismo. Alpari.

Por favor, elimine el nombre del corredor si es necesario.
Sí, el corredor es el mismo.
 
snelle_moda:


He tenido 1 doble entrada más desde el 03-10-2013. Utilizo ambos métodos para enviar mi pedido. Ver mi post anterior.

ah huh... tal como lo esperaba...
 

esto es lo que acabo de implementar. espero que pueda resolver el problema

if(m_Trade.PositionOpen(Symbol(), ORDER_TYPE_BUY, LotSize, Price, 0, 0))
            {
               Sleep(800);

               if(m_Trade.ResultRetcode() == 10009)
               {
                  Print("Position opened in ", Symbol());

                  return;
               }
               else
               {
                  Print("Error opening position in ", Symbol(), " - ", m_Trade.ResultComment(), "\n", "Return Code Desc - ", m_Trade.ResultRetcodeDescription());
               }
            }
            else
            {
               Print("Error with PositionOpen in ", Symbol(), " - ", m_Trade.ResultComment(), "\n", "Return Code Desc - ", m_Trade.ResultRetcodeDescription());
            }
 
doshur:

esto es lo que acabo de implementar. espero que pueda resolver el problema

Por lo que sé, un código de resultado = 10008 también indica que una operación está bien colocada.
 

Creo que es muy importante encontrar la razón detrás de este problema, por supuesto también es importante tener una solución (Sleep ?) hasta que podamos entender completamente lo que está sucediendo. Así que trato de resumir la situación :

  • Cuando se utiliza el método PositionOpen de la clase CTrade, al menos 3 usuarios obtuvieron en algún momento, 2 ofertas en la misma dirección en lugar de 1, lo que resulta en una posición con un volumen doble en relación con lo que se espera.
  • El código publicado inicialmente por doshur, puede explicar por qué puede ver en su registro "Posición abierta en..." mientras que no se ha abierto ninguna operación. Esto se debe a que, aunque PositionOpen() devuelva true no significa que se haya colocado una operación. Vea la documentación. Pero no puede explicar por qué un comercio "doble" fue colocado.
  • Sólo puedo ver 2 explicaciones para esta operación "doble":
  1. PositionSelect() no siempre devuelve la situación real de la posición. Se abre una posición pero PositionSelect devuelve false. Error en PositionSelect entonces.
  2. Se coloca una operación pero, cuando se llama a PositionSelect() en el siguiente tick, la posición aún no existe. Para entender si es posible tenemos que conocer el flujo de operación cuando se coloca una operación.
  • Este problema parece ocurrir en el mismo broker, con un símbolo donde la Profundidad de Mercado está activada (los interesados pueden confirmarlo por favor).
  • Este problema ocurre con la orden sincrónica, no se utilizó la orden asincrónica (por favor, confirme).
  • El problema se produce de forma aleatoria.
  • Klammeraffe informa que ya no tiene el problema, pero no veo cómo el código que publicó puede explicar eso. ¿Este código se ejecuta en cada tick? ¿Se ejecuta este código después de usar PositionSelect()? Así que tal vez eliminó la causa del error o es simplemente al azar.
  • Después de revisar el código, no veo ninguna diferencia entre usar la clase CTrade o MqlTradeRequest con OrderSend directamente.

Estoy de acuerdo con snella_moda en que la mejor explicación es:

I think the problem is the (to slow) execution of the PositionSelect(Symbol()) function. Maybe, the new ticks come in so fast, the EA sends in a new order before it receives a response of the PositionSelect(Symbol()). So the current position size is not calculated properly. In my code, its theoretically impossible to send in a new/double order if the current position size is equal or greater than the max allowed position size, see code. 

Pero es difícil de comprobar.

Creo que lo mejor es pedir consejo a Metaquotes. Lo intentaré.

 
angevoyageur:
  • Klammeraffe informa que ya no tiene el problema, pero no puedo ver cómo el código que publicó puede explicar eso. ¿Se ejecuta este código en cada tick? ¿Se ejecuta este código después del uso de PositionSelect()? Así que tal vez eliminó la causa del error o es simplemente al azar.

La línea relativa a "cada tick" podría ser la razón por la que ya no ocurre.

La función sólo se ejecuta, cuando aparece una nueva barra. Así que, lo más probable es que sólo el primer tick de una barra pueda ejecutar una operación. Después de la primera barra, el código obtiene un "retorno" hasta que aparezca una nueva barra. Tal vez esto lo solucionó para mí.

Creo que este pedazo de código es de los artículos:

//-------------------------------------------------- Check for new bar     
         static datetime OldTime;
         datetime NewTime[1];
         bool newBar=false;
         
         int copied=CopyTime(Symbol(),Period(),0,1,NewTime);
         if (copied>0)
           {
             if (OldTime != NewTime[0])
               {  
                 newBar=true;
                 OldTime=NewTime[0];
               }
           }
         else
           {
            Print("Error in copying historical times data, error =",GetLastError());
            ResetLastError();
            return;
           }  
         if(newBar==false) return;      
//-------------------------------------------------- Check for new bar
 
Klammeraffe:

La línea relativa a "cada tick" puede ser la razón por la que ya no sucede.

La función sólo se ejecuta cuando aparece una nueva barra. Por lo tanto, lo más probable es que sólo el primer tick de una barra pueda ejecutar una operación. Después de la primera barra, el código obtiene un "retorno" hasta que aparezca una nueva barra. Tal vez esto lo solucionó para mí.

Creo que este trozo de código es de los artículos:

Sí, creo que sí. Gracias.
 
  • El código publicado inicialmente por doshur, puede explicar por qué puede ver en su registro "Posición abierta en..." mientras que no se ha abierto ninguna operación. Esto se debe a que, aunque PositionOpen() devuelva true, no significa que se haya colocado una operación,véase la documentación. Pero no puede explicar por qué un comercio "doble" fue colocado.

Corrección. Hay un doble "Posición abierta en..." y se han abierto 2 operaciones.

  • Este problema parece ocurrir en el mismo broker, con un símbolo donde la Profundidad de Mercado está activada (pueden los interesados confirmar esto por favor).
No estoy seguro de los demás, pero el mío tiene DOM

  • Este problema ocurre con la orden sincrónica, no se utilizó la orden asincrónica (por favor, confirme).
Estoy usando la configuración por defecto de cTrade.

  • El problema ocurre aleatoriamente.
sí, aleatoriamente