Error de validación al lanzar el robot de trading al mercado. - página 5

 
Gracias por el consejo, pero probablemente no sea mi caso. Mi validador no ve las funciones de comercio en absoluto, no hay manera de llegar al número máximo de órdenes )))
 

Oh, shaitan... Ha pasado la validación y ahora

no hay operaciones comerciales

ya no es un error.

P.D. Fue una toma al azar. La siguiente prueba vuelve a ser lo mismo


 
Andrey Kaunov:

Aquí no hay ningún error, no entiendo en absoluto lo que está pasando. Puse una muleta (división por cero) antes de la función de comercio:

Funciona:

Si lo saco, me da lo mismo

No hay operaciones comerciales.

No entiendo qué es lo que impide al validador de OrderSend(). Al fin y al cabo, si le llega, debe haber errores de facturación (aunque los he arreglado todos) 130, 131, 134, ..., pero no"no hay operaciones comerciales". Sólo tengo que poner una orden pendiente en algún lugar lejano en OnInit() para evitar que se dispare.

¿Y qué sentido tiene esa muletilla si la condición bajo la cual debe ejecutarse una posición no entra en el código?

 
¿Por qué no entra? Mira cuidadosamente, Alexey. Justo antes de OrderSend hay una muleta.
 
Andrey Kaunov:
¿Por qué no hay entrada? Mira cuidadosamente Alexey. Hay una muleta justo antes de OrderSend.

Sí. Si OrderSend no se ejecuta, significa que la ejecución del código no llega a él por alguna razón. Y no importa lo que pongas antes en el bloque de condición, no hay entrada ni ejecución, ni siquiera división por cero.

 

Espera, no entiendo. Si se ejecuta el operador 1 (división por cero), el siguiente es el operador if. Y eso significa comprobar su estado. Para comprobar la condición, la función OrderSend debe ser ejecutada, lo que significa que es la siguiente en la línea después de la división por cero.

Pero no importa. He cambiado el código en aras de la pureza del experimento:


El resultado es el mismo. El resultado con la muleta es un error de división por cero. Sin la muleta, el resultado es el que se muestra arriba: ninguna operación.

 
Andrey Kaunov:

Espera, no entiendo. Si se ejecuta el operador 1 (división por cero), el siguiente es el operador if. Y eso significa comprobar su estado. Para comprobar la condición, la función OrderSend debe ser ejecutada, lo que significa que es la siguiente en la línea después de la división por cero.

Pero no importa. He cambiado el código en aras de la pureza del experimento:


El resultado es el mismo. El resultado con la muletilla es un error de división por cero. El resultado se muestra arriba sin ella: no hay operaciones.

No deberías haber utilizado una imagen para pegar el código. Es imposible leerlo en absoluto. Y el problema no está en este fragmento de código. El problema es que alguna condición no se cumple en algunos parámetros de entrada y no hay notificación.

 
Andrey Kaunov:
¿Por qué no entra?

¿Por qué intentas escribir peor para el mercado que para ti?

Es sencillo: antes de enviar un pedido, comprueba "si es ejecutable".

comprueba los límites (lo has dicho), comprueba los fondos y el margen (no lo tienes), mira si hay un enlace y si la operación está permitida.

(opción) si hubiera cálculos pesados, no es un pecado refrescar las tarifas antes de leer la oferta y la demanda.

Por tu propio bien harás todas estas comprobaciones. ¿Por qué no ahora?

 

Crees que no lo compruebo. El tamaño del lote se comprueba en una función independiente

//+------------------------------------------------------------------+
//| Функция нормализации лота                                        |
//+------------------------------------------------------------------+
double NormalizeLots(string symbol, double lot, bool is_margin=true) {
   if(lot<=0) return(0.0);
   RefreshRates();
   double min=SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN);
   double max=SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX);
   double step=SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP); 
   double free = AccountFreeMargin();
   double margin = MarketInfo(symbol,MODE_MARGINREQUIRED);
   double _lot=lot<min?min:(lot>max?max:lot);
          _lot=MathRound(_lot/step)*step;
   if(is_margin && _lot*margin>free)  _lot=0.0; //MathFloor(free/margin/step)*step;
   return(_lot);
}

Los límites no son necesarios aquí, porque el Stop Loss y el Take Profit son iguales a cero en la apertura de la operación.RefreshRates() actualiza los datos en el cálculo del lote. Por supuesto, no se comprueba la conexión, etc. antes de cada entrada, pero eso no es lo importante. Si OrderSend enviara una solicitud, habría un error específico: 130, 131, etc. Pero lo que tengo es.

No se trata de enviar una orden de apertura en absoluto. Incluso en la última prueba, cuando establezco una posición de control en la función OnInit().

int OnInit() {
  
   int stops_level=(int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
   iTrailStart=inpTrailStart;
   iTrailStart2=inpTrailStart2;
   iTrailStartL=inpTrailStartL;
   //---
   if(stops_level>0) {
      if(inpTrailStart<stops_level+3) iTrailStart=stops_level+3;
      if(inpTrailStart2<stops_level+3) iTrailStart2=stops_level+3;
      if(inpTrailStartL<stops_level+3) iTrailStartL=stops_level+3;
   }
   
   Comment("");
   EventSetMillisecondTimer(300);
   ButtonCreate("V_5",5,25,50,20,"FLAT",9,clrBlack,C'236,233,235', clrNONE,false);
   ButtonCreate("V_7",60,25,50,20,"TREND",9,clrBlack,C'236,233,235', clrNONE,false);
   ButtonCreate("Auto",115,25,50,20,"Auto",9,clrBlack,C'236,233,235',clrNONE,false);
   ObjectCreate(0,"Lot",OBJ_EDIT,0,0,0);
   ObjectSetInteger(0,"Lot",OBJPROP_CORNER,CORNER_LEFT_LOWER);
   ObjectSetInteger(0,"Lot",OBJPROP_XDISTANCE,115);
   ObjectSetInteger(0,"Lot",OBJPROP_YDISTANCE,50);
   ObjectSetString(0,"Lot",OBJPROP_TEXT,"");
   ObjectSetInteger(0,"Lot",OBJPROP_ALIGN,ALIGN_RIGHT);
   ObjectSetInteger(0,"Lot",OBJPROP_FONTSIZE,9);
   ObjectSetInteger(0,"Lot",OBJPROP_COLOR,clrBlack);
   ObjectSetInteger(0,"Lot",OBJPROP_YSIZE,20);
   ButtonCreate("V_5_buy",5,50,50,20,"BUY",9,clrBlack,C'236,233,235', clrNONE,false);
   ButtonCreate("V_5_sell",60,50,50,20,"SELL",9,clrBlack,C'236,233,235', clrNONE,false); 
     
   test_ticket=OrderSend(_Symbol,OP_BUYLIMIT,SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN),_Point,30,0.0,0.0,"NZT-48_test",iMagicNumber,0,clrNONE);
   
   return(INIT_SUCCEEDED);
}//-------------------------------------- End OnInit ---------------------------------------- 

Alexey Viktorov:

No deberías haber pegado el código en una imagen. Es imposible leerlo. El problema no está en este fragmento de código. El problema es que alguna condición no se cumple en algunos parámetros de entrada y no hay notificación de este hecho.

Puede ser. Pero ya he comprobado todo dos veces. No sé dónde cavar después.

 
Andrey Kaunov:

Crees que no lo compruebo. El tamaño del lote se comprueba en una función separada

Los límites no son necesarios aquí, porque el Stop Loss y el Take Profit son iguales a cero en la apertura de la operación.RefreshRates() actualiza los datos en el cálculo del lote. Por supuesto, no se comprueba la conexión, etc. antes de cada entrada, pero eso no es lo importante. Si OrderSend enviara una solicitud, habría un error específico: 130, 131, etc. Pero lo que tengo es.

No se trata de enviar una orden de apertura en absoluto. Incluso en la última prueba, cuando establezco una posición de control en la función OnInit().


Es posible. Pero ya he comprobado todo dos veces. No sé dónde ir ahora.

Mira cómo se han implementado otras órdenes en la EA. No creo que el Asesor Experto sólo abra

en el ticket de apertura<0 se ha establecido - mira la otra lógica, cómo reacciona a esto en realidad