Detecção 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);
}
Atualmente estou tentando encontrar a maneira mais infalível de detectar se precisamos de 1 ou 10 como multiplicador de tubulações. O acima foi minha primeira idéia, simplesmente olhando quantos dígitos o EURUSD tem. há corretores onde este símbolo é chamado de EURUSDm ou EURUSDiam ou outros disparates engraçados adicionados por corretores sem outra razão que não seja quebrar nosso código e também há nomes de símbolos que não têm exatamente 6 caracteres, como GOLD ou GOLDm por exemplo e os acima NÃO podem lidar com isso.

Alguém tem um algoritmo ainda mais sofisticado para encontrar os dígitos corretos? Eu acho que tudo se resume ao problema de primeiro descobrir como é exatamente o nome do símbolo EURUSD e depois o resto é fácil. Existe, por exemplo, uma maneira fácil de enumerar todos os símbolos disponíveis para que eu possa procurar por um nome que contenha ou comece com "EURUSD"?
 

Normalmente, eu o verifico apenas uma vez na seção init:

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

Normalmente, eu o verifico apenas uma vez na seção init:

Seu código não é infalível, existem Símbolos com 1 ou 2 (ouro) ou outros números de dígitos.

Eu encontrei uma maneira melhor (ainda preciso testá-lo com mais alguns corretores). Ele lê symbols.raw na pasta history para encontrar o nome de eurusd e depois usar 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 um código para apenas uma moeda. Se você quiser usar sua EA para várias moedas, você tem que calculá-la para cada caso separadamente.

 
7bit:
Eu encontrei uma maneira melhor (ainda preciso testá-lo com mais alguns corretores). Ele lê symbols.raw na pasta history para encontrar o nome de eurusd e depois usar MarketInfo();

Isto quebraria se eles mudassem o arquivo simbólico.raw (e poderia não funcionar com versões antigas do MT4... embora isso provavelmente não seja um problema).

 
Uso um método igual ao do Roger e ainda não me causou nenhum problema.
Funcionará para a maioria das eventualidades. Se você encontrar um que não se encaixe no futuro, então basta cruzar essa ponte quando você o encontrar.

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.

Você está apenas repetindo a mesma coisa que eu já achei insuficiente. Usar apenas a variável Dígitos não ajuda no problema (o problema definido sou eu no primeiro lançamento), pois não leva em conta em que símbolo ele está rodando atualmente e quantos dígitos este símbolo deve ter. Pode haver qualquer quantidade de dígitos de 0 a 5 em alguns pares exóticos, não apenas 5 ou 3 contra 4 ou 2. Se fosse tão simples, eu não teria aberto esta linha. Portanto, agora estou usando apenas os dígitos do eurusd, não importa em que par ele rode. Encontrar o nome real de eurusd era o maior problema, e até agora o método dos símbolos.raw parece ser o mais simples e mais confiável.
 
cloudbreaker:
Se você encontrar uma que não se encaixe no futuro, então basta cruzar essa ponte quando você a encontrar.

Estou tentando escrever um código infalível que não se quebre. Escrever (conscientemente) código buggy e esperar que ele quebre antes de consertá-lo não se encaixa na minha filosofia de como o desenvolvimento de software deve ser feito.
 
7bit wrote >>
Estou tentando escrever um código infalível que não se quebre. Escrever (conscientemente) código buggy e esperar que ele quebre antes de consertá-lo não se encaixa na minha filosofia de como o desenvolvimento de software deve ser feito.


Eu não diria que o código acima foi 'buggy' - ele tem apenas... limitações, das quais os usuários estão bem cientes
A beleza da filosofia é que ela pode funcionar de forma assíncrona com praticidade :)
-BB-
 
Não é apenas uma questão simples (talvez não tão simples em termos matemáticos) de se saber qual é um ponto relativo a um determinado preço e depois decidir qual é o dígito em comparação com os dígitos do preço?
Uma maneira simples de conseguir isso poderia ser pegar um preço adicionar um ponto e compará-lo com seu multiplicador + o mesmo preço se seu resultado não for o mesmo aumentar seu mutiplicador em um laço até que eles coincidam.