Necesito ayuda con el error #130 stoploss inválido - página 2

 

La mejor manera de conseguir el stoploss correcto es pensar adecuadamente en el spread. El spread es la distancia entre el Ask y el Bid. Así que cuando usted añade un stoploss a una orden de compra usando Bid - SL automáticamente incluye el spread y usted no necesitará codificar para ello y podrá efectivamente ignorar totalmente el spread. Para una operación de venta usando Ask + SL tiene el mismo efecto. Sin embargo, CUIDADO --- en momentos de bajo volumen de negociación el spread se hace más grande y puedes terminar con un SL muy lejos del lugar que esperas que esté --- por lo tanto puedes querer añadir algún código para prevenir la adición del SL por encima de un tamaño de Spread establecido.

Ahora que la cuestión del Spread está fuera del camino, la siguiente causa principal de los errores 130 es que los precios han cambiado mientras su EA se está ejecutando. Esto puede ser causado por un EA que tarda mucho tiempo en ejecutarse o el servidor está muy ocupado atendiendo operaciones que retrasan la ejecución de su EA. El resultado es que un tick ha hecho que su EA comience a ejecutarse pero otro tick ha llegado antes de que la ejecución haya terminado y los precios son ahora inválidos.

En cualquiera de los casos es necesario refrescar los precios usando RefreshRates: while (RefrshRates() == 1) Sleep(5); ------ o lo que quiera como tiempo de espera.

 
BigAl:


En cualquiera de los dos casos hay que refrescar los precios usando RefreshRates: while (RefrshRates() == 1) Sleep(5); ------ o lo que quiera como tiempo de espera.

Eso sólo es correcto si el código utiliza variables predefinidas https://docs.mql4.com/predefined/variables si el código utiliza MarketInfo para la Oferta y la Demanda entonces RefreshRates no tendrá ninguna relación....
 
qjol:
AFAIK RefreshRates() no tiene nada que ver con el error 130

Entiendo RaptorUK y estoy de acuerdo en que el uso de MODE_ASK etc eliminaría la necesidad de RefreshRates() pero asumí que como en el ejemplo de código de shinobi ....

Yo envío una orden con, por ejemplo:

int ticket = OrderSend(Symbol(), OP_BUY, position_size, Ask, SLIPPAGE, initial_stop, TAKEPROFIT, NULL, EXPERT_ID, 0, Green);

se está utilizando la variable predefinida ASK y por lo tanto el valor del ask/bid así como el spread pueden haber cambiado dando el error 130. En tal caso se podría utilizar RefreshRates() inmediatamente antes del OrderSend

 
BigAl:

Punto tomado RaptorUK y estoy de acuerdo en que el uso de MODE_ASK etc eliminaría la necesidad de RefreshRates() pero asumí que como en el ejemplo de código de shinobi ....

Envío una orden con, por ejemplo:

int ticket = OrderSend(Symbol(), OP_BUY, position_size, Ask, SLIPPAGE, initial_stop, TAKEPROFIT, NULL, EXPERT_ID, 0, Green);

se está utilizando la variable predefinida ASK y por lo tanto el valor del ask/bid así como el spread pueden haber cambiado dando el error 130. En tal caso se podría utilizar RefreshRates() inmediatamente antes del OrderSend

Gracias a todos por vuestros magníficos consejos.
Estoy un poco ocupado en este momento, pero una vez que tuve la oportunidad, voy a tratar todas sus sugerencias y luego escribir un post de resumen para cualquier persona que pueda tropezar con este hilo con el mismo problema.

¡Gracias, y cuídate!

shinobi
 
BigAl: Envío una orden con, por ejemplo:

int ticket = OrderSend(Symbol(), OP_BUY, position_size, Ask, SLIPPAGE, initial_stop, TAKEPROFIT, NULL, EXPERT_ID, 0, Green);

no dice todo. ¿Cómo estás calculando el initial_stop - usando el Bid?

¿Cómo estás computando SLIPPAGE - ajustando para corredores de 4/5 dígitos?

 
¡Hola chicos!

He tenido que tomarme un descanso por un tiempo (mudanza a una nueva ciudad, nuevo trabajo).
Pero ahora me gustaría retomar este hilo, y por fin encontrar una solución para este maldito error de stoploss #130.

Agradezco todos vuestros consejos y he intentado incorporarlos todos:

1: Spread.
para eliminar el spread como posible causa del error, establecí el stoploss como
Bid-stoploss (Largo)
Ask+stoploss (Corto)

2: Cambio de
tasas de
mercado
para eliminar la posible causa de que las tasas de mercado cambien antes de que se envíe la orden,
cambié mi código y reemplacé todas las ocurrencias de Ask y Bid con
MarketInfo(Symbol(), MODE_ASK) y MarketInfo(Symbol(), MODE_BID)

3: 4-5 Dígitos-Broker
para eliminar la posible causa de un número inválido de dígitos, redondeé el stoploss de acuerdo al código de WHRoeders:
int     pips2points;    // slippage  3 pips    3=points    30=points
double  pips2dbl;       // Stoploss 15 pips    0.0015      0.00150
int     Digits.pips;    // DoubleToStr(dbl/pips2dbl, Digits.pips)

//init digit adjustment
if (Digits % 2 == 1) {      // DE30=1/JPY=3/EURUSD=5 forum.mql4.com/43064#515262
    pips2dbl    = Point*10; pips2points = 10;   Digits.pips = 1;
} else {
    pips2dbl    = Point;    pips2points =  1;   Digits.pips = 0; 
}

OrderSend(Symbol(), OP_BUY, position_size, MarketInfo(Symbol(), MODE_ASK), SLIPPAGE, (MarketInfo(Symbol(), MODE_BID) - stoploss) * pips2dbl, TAKEPROFIT, NULL, EXPERT_ID, 0, Green);
Como se mencionó anteriormente, las variables SLIPPAGE y TAKEPROFIT en mi caso son siempre 0. Así que no deberían causar un problema también.


Así que incorporé todas las sugerencias, pero el error aún persiste. Por lo que puedo decir, ocurre con la misma frecuencia que antes, así que tiene que haber otra causa para ello.
Aquí está un registro reciente:

tickvalue: 12.50000000
pos size: 37.00000000
Ask/Bid 1262.00000000/1261.75000000
stoploss:12.59610000
position_size: 37
Spread 0.25000000

Error could not take long position. El error es: #130 stops inválidos

La línea de código OrderSend anterior se utilizó con los valores registrados para tratar de tomar una posición larga.
¿Tienes alguna idea más, cuál podría ser la causa?

Gracias!
shinobi
 

¿Es un broker ECN?

WHRoeder 2011.09.15 20:36

En los corredores ECN debe abrir y luego establecer paradas.

 
shinobi:
para eliminar la posible causa del número inválido de dígitos, redondeé el stoploss según el código de WHRoeders:
  1. No había redondeo en el código que publiqué
  2. En los brokers ECN hay que abrir y LUEGO poner los stops.
  3. En los metales (donde TICKSIZE != Punto) el precio de apertura para las órdenes pendientes debe ser redondeado
    double TS=MarketInfo(pair, MODE_TICKSIZE);
    OOP = MathRound(OOP/TS)*TS;
    No sé acerca de las paradas.

  4. Deja de decirnos cuales son los valores y lo que crees que has hecho. Publica el código.
 

Simplemente haga

extern double StopLoss = 50

extern double TakeProfit = 50;

entonces para las compras

double SL=Oferta - StopLoss*Punto;

double TP=Bid + TakeProfit*Punto;

int Ticket=OrderSend(Symbol(),0,1,Ask,2,SL,TP,",12345);

if( Ticket<0) print("error="GetLastError());

para las ventas:

doubleSL=Ask + StopLoss*Punto;

doubleTP=Ask - TakeProfit*Punto;

int Ticket=OrderSend(Symbol(),1,1,Bid,2,SL,TP,",12345);

if( Ticket<0) print("error="GetLastError());

entonces publique el archivo de registro si no funciona.

 
Gracias Raptor, WHRoeder y SDC por sus respuestas.

SDC:
He probado tu código así:
   int result_ticket = -1;
   double stoploss            = 50;
   double takeprofit          = 50;
   double SL = 0.0;
   double TP = 0.0;
   if(long) {   //take long position
      SL = MarketInfo(Symbol(), MODE_BID) - stoploss * MarketInfo(Symbol(), MODE_POINT));
      TP = MarketInfo(Symbol(), MODE_BID) + takeprofit * MarketInfo(Symbol(), MODE_POINT));
      result_ticket = OrderSend(Symbol(), 0, 1, MarketInfo(Symbol(), MODE_ASK), 2, SL, TP, "", 12345);
   } else {     //take short position
      SL = MarketInfo(Symbol(), MODE_ASK) + stoploss * MarketInfo(Symbol(), MODE_POINT));
      TP = MarketInfo(Symbol(), MODE_ASK) - takeprofit * MarketInfo(Symbol(), MODE_POINT));
      result_ticket = OrderSend(Symbol(), 1, 1, MarketInfo(Symbol(), MODE_BID), 2, SL, TP, "", 12345);
   }

   //check for errors
   if(result_ticket == -1) {
      Log("error="+GetLastError());
      return(-1);
   }
La única diferencia es que reemplacé Punto, Demanda y Oferta con MarketInfo para evitar el problema de RefreshRates mencionado por Raptor y BigAI.
El problema persiste con este simple ejemplo. Todavía obtengo

#ESZ1,M5: Posición de apertura
#ESZ1,M5: tickvalue: 12.50000000
#ESZ1,M5: pos size: 1.00000000
#ESZ1,M5: Oferta 1244.50000000/1244.25000000
#ESZ1,M5: Spread 0.25000000
#ESZ1,M5: SL: 1244.00000000
#ESZ1,M5: TP: 1245.00000000
#ESZ1,M5: error=130

Raptor:
Actualmente utilizo UWC-Trader con una cuenta demo para hacer pruebas.
Como se mencionó anteriormente estoy negociando Futuros. Por ejemplo, ESZ1 y FDXZ1.

WHRoeder:
Lo siento, yo tampoco redondeo. Sustituye "redondear" por "ajustar para brokers de 4/5 dígitos". Es decir, acabo de aplicar tu código.
También he puesto el OrderSend tal y como lo uso en mi respuesta anterior. Y los valores de todas las variables involucradas. No sé qué otra parte del código sería interesante.
Como el mini-ejemplo, sugerido por SDC, mostró, el error puede ser descompuesto en este simple código. Así que debe ser más fundamental.

No estoy operando con metales, así que el redondeo no debería ser importante.

Voy a probar a continuación:
abrir (sin stoploss) y luego modificar (establecer stoploss) más tarde.

Gracias de nuevo por tus opiniones,

shinobi