Toute question des nouveaux arrivants sur MQL4 et MQL5, aide et discussion sur les algorithmes et les codes. - page 106

 
-Aleks-:

Veuillez me conseiller sur une solution au problème d'arrondi !

J'ai besoin de me débarrasser du point décimal sans reste - l'arrondi et l'exponentiation ne résolvent pas tout le problème - que dois-je faire ?

Par exemple, il était de 1.44430 et j'ai besoin de 144430.

Une partie du code - tel quel

NormalizeDouble(Low[1],Digits)*MathPow(10,(Digits+1)*1-1)

Il suffit de diviser par _Point.
 
Alexey Viktorov:
Il suffit de diviser par _Point.

Le résultat imprimé est incorrect, l'original est 161188 (1.61188) Votre méthode 161187 print donne 1.6119 (pourquoi l'arrondi est fait quand print Low[1] si cinq décimales ?), ma version est 161188.

Mais si on complique le problème.


long Calc=
NormalizeDouble(Close[1],Digits)*MathPow(10,(Digits+1)*3-1)+
NormalizeDouble(High[1],Digits)*MathPow(10,(Digits+1)*2-1)+
NormalizeDouble(Low[1],Digits)*MathPow(10,(Digits+1)*1-1);

C'est-à-dire la dernière partie du nombre 161184 - soit une divergence de 4 unités.

Votre Variante de cette expression produit la même valeur

long CalcX=
NormalizeDouble(Close[1],Digits)*MathPow(10,(Digits+1)*3-1)+
NormalizeDouble(High[1],Digits)*MathPow(10,(Digits+1)*2-1)+
Low[1]/Point;

Une idée de ce qu'est l'erreur et comment la réparer ?

 
-Aleks-:

Le résultat imprimé est erroné, l'original est 161188 (1.61188) votre méthode 161187 print donne 1.6119 (pourquoi arrondir vers le haut quand print Low[1] si cinq décimales ?), ma version est 161188.

Mais si on complique le problème.


long Calc=
NormalizeDouble(Close[1],Digits)*MathPow(10,(Digits+1)*3-1)+
NormalizeDouble(High[1],Digits)*MathPow(10,(Digits+1)*2-1)+
NormalizeDouble(Low[1],Digits)*MathPow(10,(Digits+1)*1-1);

C'est-à-dire la dernière partie du nombre 161184 - soit une divergence de 4 unités.

Votre variante dans cette expression donne la même valeur

long CalcX=
NormalizeDouble(Close[1],Digits)*MathPow(10,(Digits+1)*3-1)+
NormalizeDouble(High[1],Digits)*MathPow(10,(Digits+1)*2-1)+
Low[1]/Point;

Une idée de ce qu'est l'erreur et comment la réparer ?

Exécutez-le comme ceci.

/********************Script program start function*******************/
void OnStart()
{
   string i = DoubleToString(SymbolInfoDouble(_Symbol, SYMBOL_BID)/_Point, 0);
   Print(i);
   Print(SymbolInfoDouble(_Symbol, SYMBOL_BID)/_Point);
}/*******************************************************************/
 
Alexey Viktorov:
Exécutez-le comme ceci.

/********************Script program start function*******************/
void OnStart()
{
   string i = DoubleToString(SymbolInfoDouble(_Symbol, SYMBOL_BID)/_Point, 0);
   Print(i);
   Print(SymbolInfoDouble(_Symbol, SYMBOL_BID)/_Point);
}/*******************************************************************/

Oui, la variable chaîne obtient le bon numéro (de façon préliminaire), mais les zéros 161188.00000000 sont ajoutés, comment puis-je m'en débarrasser ?

 
-Aleks-:

Oui, la variable chaîne obtient le bon numéro (de façon préliminaire), mais les zéros 161188.00000000 sont ajoutés, comment puis-je m'en débarrasser ?

Il n'y a pas de zéros dans mon code. Regardez la façon dont c'est écrit.
 
Alexey Viktorov:
Il n'y a pas de zéros dans mon code. Regardez comment c'est écrit.

Merci - j'ai oublié un zéro.

C'est la construction.

string CalcX=
DoubleToString(Close[1]/_Point,0)+
DoubleToString(High[1]/_Point,0)+
DoubleToString(Low[1]/_Point,0);
Print("CalcX=",CalcX);

Maintenant, je dois décomposer ces chiffres en leurs composants.

Lorsque j'essaie de convertir la chaîne en un nombre, j'obtiens à nouveau le mauvais nombre 161184 au lieu de 161188.

long testX = StringToDouble(CalcX);
Print("testX=",testX);

Je devrais probablement couper la ficelle, mais comment le faire de manière optimale ?


 
-Aleks-:

Oui, la variable chaîne obtient le bon numéro (de manière préliminaire), mais les zéros 161188.00000000 sont ajoutés, comment puis-je m'en débarrasser?

Analyser la chaîne en utilisant le délimiteur ".".
 
Artyom Trishkin:
Alors... Montre-moi le modèle. Comment savez-vous ce qu'il y a là-dedans ?
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
  
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
  
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
Pouvez-vous me dire comment implémenter un indicateur pour que le temps de la deuxième coordonnée de la ligne de tendance soit fixé par le temps de percée ou son toucher. C'est-à-dire que la ligne de tendance a son départ à un certain endroit, et le moment de la deuxième coordonnée est fixé à discrétion, mais la ligne doit se terminer là où elle croise une bougie. Comme par exemple dans l'indicateur montré dans l'image
 
-Aleks-:

Merci - le zéro m'a échappé.

Il en est ressorti cette construction

string CalcX=
DoubleToString(Close[1]/_Point,0)+
DoubleToString(High[1]/_Point,0)+
DoubleToString(Low[1]/_Point,0);
Print("CalcX=",CalcX);

Maintenant, je dois décomposer ces chiffres en leurs composants.

Lorsque j'essaie de convertir la chaîne de caractères en un nombre, j'obtiens à nouveau le mauvais nombre 161184 au lieu de 161188.

long testX = StringToDouble(CalcX);
Print("testX=",testX);

Je devrais probablement couper la ficelle, mais comment le faire de manière optimale ?


Il n'y a pas besoin de couper quoi que ce soit. La conversion en chaîne est juste pour voir le bon numéro. Vous n'avez rien à faire pour les calculs.

Eh bien, si vous avez une envie irrésistible de faire du désordre, reconvertissez la chaîne en un nombre StringToDouble() et multipliez par _Point avec normalisation au nombre de chiffres souhaité, probablement _Digits
Raison: