Detección de 5 dígitos

 
double pointsPerPip(){
   string suffix = StringSubstr(Symbol(), 6);
   int digits = MarketInfo("EURUSD" + suffix, MODE_DIGITS);
   if (digits == 0){
      digits = MarketInfo("EURUSD", MODE_DIGITS);
   }
   if (digits == 0){
      return(1);
   }else{
      if (digits == 5){
         return(10);
      }
   }
   return(1);
}
Actualmente estoy tratando de encontrar la forma más infalible para detectar si necesitamos 1 o 10 como multiplicador de pips. Hay brokers en los que este símbolo se llama EURUSDm o EURUSDiam u otras tonterías añadidas por los brokers sin otra razón que romper nuestro código y también hay nombres de símbolos que no tienen exactamente 6 caracteres, como GOLD o GOLDm por ejemplo y lo anterior NO puede manejar esto.

¿Alguien tiene un algoritmo más sofisticado para encontrar los dígitos correctos? Creo que todo se reduce al problema de encontrar primero cómo es exactamente el nombre del símbolo de EURUSD y luego el resto es fácil. ¿Existe, por ejemplo, una forma fácil de enumerar todos los símbolos disponibles para poder buscar un nombre que contenga o empiece por "EURUSD"?
 

Normalmente lo compruebo sólo una vez en la sección de inicio:

int mypoint;
int init()
{
if(MarketInfo(Symbol(), MODE_DIGITS)==3||MarketInfo(Symbol(), MODE_DIGITS)==5)
mypoint=10;
else mypoint=1;
}
...
 
Roger:

Normalmente lo compruebo sólo una vez en la sección de inicio:

Su código no es infalible, hay símbolos con 1 o 2 (oro) u otros números de dígitos.

He encontrado una manera mejor (todavía tengo que probarlo con algunos corredores más). Lee symbols.raw en la carpeta del historial para encontrar el nombre de eurusd y luego usa MarketInfo();

/**
* determine the pip multiplier (1 or 10) depending on how many
* digits the EURUSD symbol has. This is done by first
* finding the exact name of this symbol in the symbols.raw
* file (it could be EURUSDm or EURUSDiam or any other stupid name
* the broker comes up with only to break other people's code) 
* and then usig MarketInfo() for determining the digits.
*/
double pointsPerPip(){
   int i;
   int digits;
   double ppp = 1;
   string symbol;
   int f = FileOpenHistory("symbols.raw", FILE_BIN | FILE_READ);
   int count = FileSize(f) / 1936;
   for (i=0; i<count; i++){ 
      symbol = FileReadString(f, 12);
      if (StringFind(symbol, "EURUSD") != -1){
         digits = MarketInfo(symbol, MODE_DIGITS);
         if (digits == 4){
            ppp = 1;
         }else{
            ppp = 10;
         }
         break;
      }
      FileSeek(f, 1924, SEEK_CUR);
   }
   FileClose(f);
   return (ppp);
}
 

Era un código para una sola moneda. Si quieres usar tu EA para múltiples divisas tienes que calcularlo para cada caso por separado.

 
7bit:
He encontrado una manera mejor (todavía tengo que probarlo con algunos corredores más). Lee symbols.raw en la carpeta de la historia para encontrar el nombre de eurusd y luego usar MarketInfo();

Esto se rompería si alguna vez cambian el archivo symbols.raw (y podría no funcionar con versiones antiguas de MT4... aunque probablemente no sea un problema).

 
Yo utilizo un método igual al de Roger y todavía no me ha causado ningún problema.
Funcionará para la mayoría de las eventualidades. Si en el futuro encuentras una que no te sirva, entonces cruza ese puente cuando la encuentres.

CB
 
//++++ These are adjusted for 5 digit brokers.
double  pips2points,    // slippage  3 pips    3=points    30=points
        pips2dbl;       // Stoploss 15 pips    0.0015      0.00150
int     Digits.pips;    // DoubleToStr(dbl/pips2dbl, Digits.pips)
int init() {
    if (Digits == 5 || Digits == 3) {   // Adjust for five (5) digit brokers.
                pips2dbl    = Point*10; pips2points = 10;   Digits.pips = 1;
    } else {    pips2dbl    = Point;    pips2points =  1;   Digits.pips = 0; }
 
WHRoeder:
if (Digits == 5 || Digits == 3) {   // Adjust for five (5) digit brokers.

Usted sólo está repitiendo lo mismo que ya encontré insuficiente. El uso de la variable Digits por sí sola no ayuda al problema (el problema definido soy yo en el primer post) ya que no tiene en cuenta en qué símbolo se está ejecutando actualmente y cuántos dígitos debe tener este símbolo. Puede haber cualquier cantidad de dígitos de 0 a 5 en algunos pares exóticos, no sólo 5 o 3 contra 4 o 2. Si fuera tan sencillo no habría abierto este hilo. Por lo tanto, ahora sólo estoy usando los dígitos de eurusd, no importa en qué par se ejecuta. Encontrar el nombre real de eurusd era el mayor problema, y hasta ahora el método symbols.raw parece ser el más simple y más fiable.
 
cloudbreaker:
Si en el futuro encuentras uno que no te sirva, entonces cruza ese puente cuando lo encuentres.

Intento escribir código a prueba de errores que no se rompa. Escribir (a sabiendas) código con errores y esperar a que se rompa antes de arreglarlo no se ajusta a mi filosofía de cómo debe hacerse el desarrollo de software.
 
7bit wrote >>
Intento escribir un código infalible que no se rompa. Escribir (a sabiendas) código con errores y esperar a que se rompa antes de arreglarlo no se ajusta a mi filosofía de cómo debe hacerse el desarrollo de software.


Yo no diría que el código de arriba tiene "errores" - simplemente tiene... limitaciones, de las que los usuarios son muy conscientes
La belleza de la filosofía es que puede funcionar de forma asíncrona con la practicidad :)
-BB-
 
¿No es sólo una simple (quizás no tan simple en términos matemáticos) cuestión de calcular lo que es un punto en relación con un precio dado y luego decidir en qué dígito se encuentra en comparación con los dígitos del precio?
Una forma sencilla de conseguirlo podría ser tomar un precio, añadir un punto y compararlo con tu multiplicador + el mismo precio, si el resultado no es el mismo, aumenta tu multiplicador en un bucle hasta que coincidan.