asesor experto - preguntas varias - página 3

 
double LotCalculator(double lots)
  {
   double minlot  = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN),
          maxlot  = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX),
          lotstep = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
   lots = MathFloor(lots/lotstep)*lotstep;
   lots = MathMax(lots,minlot);
   lots = MathMin(lots,maxlot);
   return(NormalizeDouble(lots,2));
  }
 
honest_knave:
double LotCalculator(double lots){}

Te lo agradezco mucho.

Sólo quiero empezar a escribir ese código :)

Me has salvado más veces.

¡Muchas gracias!

 
Tengo el mismo mensaje para el tamaño del lote.
Llamo 'LotCalculator()' en 'OnChartEvent()' así que no es correcto?
 

Estoy buscando un buen foro para el cálculo de'MarketInfo & LotSize'.
¿Quién sabe que el tipo de buen foro por favor, comparta conmigo.

Gracias.

 
¿Por casualidad usaste mi fragmento de código antes de que editara la última línea (NormalizeDouble)? Veo que sólo pasaron 3 minutos desde mi post hasta el tuyo, y lo edité casi inmediatamente.
 
Max Enrik: Estoy usando NormalizeDouble para mi EA. Pero me preocupa el mensaje'Normal izeDouble', pero veo el tamaño del lote en el gráfico así: 0.07

Así que necesito un buen consejo, por favor.

02:00:00.069 - custom expert EURUSD,H1: | _lotSize - NormalizeDouble: 0.07000000000000001
02:00:00.069 - custom expert EURUSD,H1: | _lotSize - DoubleToString : 0.07
  1. NormalizeDouble devuelve un doble. El punto flotante tiene un número infinito de decimales, es que no entiendes el punto flotante y que algunos números no pueden ser representados exactamente. (como 1/10.) Formato de punto flotante de doble precisión - Wikipedia, la enciclopedia libre Ver también El operando ==. - Foro MQL4
  2. NO use NormalizeDouble, NUNCA. Por ninguna razón. Es una chapuza, no la use. Su uso es siempre incorrecto
 
whroeder1:
  1. NO useNormalizeDouble, NUNCA. Por ninguna razón. Es una chapuza, no la uses. Suuso es siempre erróneo

Creo que todavía necesitas NormalizeDouble().

Aquí hay un ejemplo, usando su fragmento de código (lo mismo se aplica a mi ejemplo usando MathFloor):

double NormalizeLots(double lots, string pair=""){
    if (pair == "") pair = Symbol();
    double  lotStep     = MarketInfo(pair, MODE_LOTSTEP),
            minLot      = MarketInfo(pair, MODE_MINLOT);
    lots                = MathRound(lots/lotStep) * lotStep;
    if (lots < minLot) lots = 0;    // or minLot
    return(lots);
}

Llamada:

Print(NormalizeLots(2/3.0));

Resultado:

0.7000000000000001

Ahora código ajustado:

double NormalizeLots(double lots, string pair=""){
    if (pair == "") pair = Symbol();
    double  lotStep     = MarketInfo(pair, MODE_LOTSTEP),
            minLot      = MarketInfo(pair, MODE_MINLOT);
    lots            = MathRound(lots/lotStep) * lotStep;
    if (lots < minLot) lots = 0;    // or minLot
    return(NormalizeDouble(lots,2));
}

Resultado:

0.7


 

 Result: 0.7000000000000001

¿Qué parte de "no entiendes el punto flotante y que algunos números no pueden ser representados exactamente. (como 1/10.) Formato de punto flotante de doble precisión - Wikipedia, la enciclopedia libre" no estaba claro?

NormalizeDouble(0.7, 2) producirá el mismo resultado exacto (o posiblemente 0.6999999999999.)

 
whroeder1:

¿Qué parte de "no entiendes el punto flotante y que algunos números no pueden ser representados exactamente. (como 1/10.) Formato de punto flotante de doble precisión - Wikipedia, la enciclopedia libre" no quedó claro?

NormalizeDouble(0.7, 2) producirá el mismo resultado exacto (o posiblemente 0.6999999999999.)

No estoy diciendo que NormalizeDouble() sea necesario para un OrderSend válido. Por eso mi primer fragmento de código lo excluía. Tampoco soy poco claro sobre la forma en que se representan los números de punto flotante.

He editado el fragmento de código para incluirlo porque me pareció que respondía mejor a mi comprensión del problema de la OP (esencialmente un problema de visualización, que puede resolverse utilizando NormalizeDouble() en el código del "normalizador de lotes", o utilizando printf o DoubleToStr cuando el valor debe mostrarse).

Tal vez he entendido mal el OP.

02:00:00.069 - custom expert EURUSD,H1: | _lotSize - NormalizeDouble: 0.07000000000000001
02:00:00.069 - custom expert EURUSD,H1: | _lotSize - DoubleToString : 0.07

(editado para eliminar la innecesaria extensión)

 
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- get minimum stop level
   double minstoplevel=MarketInfo(Symbol(),MODE_STOPLEVEL);
   Print("Minimum Stop Level=",minstoplevel," points");
   double price=Ask;
//--- calculated SL and TP prices must be normalized
   double stoploss=NormalizeDouble(Bid-minstoplevel*Point,Digits);
   double takeprofit=NormalizeDouble(Bid+minstoplevel*Point,Digits);
//--- place market order to buy 1 lot
   int ticket=OrderSend(Symbol(),OP_BUY,1,price,3,stoploss,takeprofit,"My order",16384,0,clrGreen);
   if(ticket<0)
     {
      Print("OrderSend failed with error #",GetLastError());
     }
   else
      Print("OrderSend placed successfully");
//---
  }

Esto puede ser confuso para la gente porque la documentación de MQL4 utiliza la función NormalizeDouble() en la mayoría de los ejemplos.

Incluso llega a advertir que no se puede aplicar el precio no normalizado:

Nota

En la apertura de una orden de mercado (OP_SELL u OP_BUY), sólo se pueden utilizar como precio de apertura los últimos precios de Bid (para vender) o Ask (para comprar). Si la operación se realiza con un valor diferente al actual, se debe utilizar la función MarketInfo() con el parámetro MODE_BID o MODE_ASK para obtener las últimas cotizaciones de este valor.

No se pueden aplicar precios calculados o no normalizados. Si no ha habido el precio abierto solicitado en el hilo de precios o no se ha normalizado según la cantidad de dígitos después del punto decimal, se generará el error 129 (ERR_INVALID_PRICE). Si el precio abierto solicitado está totalmente desfasado, se generará el error 138 (ERR_REQUOTE) independientemente del parámetro de deslizamiento. Si el precio solicitado está desfasado, pero presente en el hilo, la orden se abrirá al precio actual y sólo si el precio actual se encuentra dentro del rango de precio+deslizamiento.

E incluso en algunos de los mejores libros sobre MQL lo utilizan bastante.

Puede ser que depende de su aplicación un problema de visualización es menos dramático que los fallos de orden o modificación.

Personalmente siempre upconvert a valores enteros por lo que rara vez se ocupan de ella.