Errori, bug, domande - pagina 1931

 

È sempre meglio al mattino... :)

 
Aleksey Vyazmikin:

Nell'helpdesk

MT4:

Per gli oggetti con dimensioni fisse: OBJ_BUTTON, OBJ_RECTANGLE_LABEL e OBJ_EDIT le proprietà OBJPROP_XDISTANCE e OBJPROP_YDISTANCE impostano la posizione del punto superiore sinistro dell'oggetto rispetto all'angolo del grafico (OBJPROP_CORNER), da cui saranno contate le coordinate X e Y in pixel.


MT5:

Per gli oggetti con dimensioni fisse: OBJ_BUTTON, OBJ_RECTANGLE_LABEL, OBJ_EDIT e OBJ_CHART, le proprietà OBJPROP_XDISTANCE e OBJPROP_YDISTANCE impostano la posizione del punto superiore sinistro dell'oggetto rispetto all'angolo del grafico (OBJPROP_CORNER), dal quale saranno misurate le coordinate X e Y in pixel.

La questione è che la vecchia versione di MT4 usando ObjectSet permette di posizionare gli oggetti relativamente ai loro bordi (angoli) - per gli oggetti nella parte sinistra il calcolo dei pixel viene eseguito dal primo simbolo, per gli oggetti nella parte destra - dall'ultimo simbolo, mentre la nuova versione esegue sempre il calcolo dal primo simbolo, il che rende difficile il posizionamento delle etichette con testo, perché non si sa sempre quanti saranno i simboli di testo. Chiedo agli sviluppatori di aggiungere una scelta del metodo di allineamento del testo!


Se qualcuno sa come ottenere l'allineamento a sinistra e a destra in MT5, per favore condivida la funzione corrispondente!

E non arrabbiatevi, ma leggete attentamente la guida:

Per gli oggetti OBJ_LABEL, OBJ_BITMAP_LABEL e OBJ_RECTANGLE_LABEL potete impostare l'angolo del grafico, relativo al quale è posizionato il punto di ancoraggio dell'oggetto. Questo angolo è impostato tramite la proprietà dell'oggetto OBJPROP_CORNER, che può avere uno dei quattro valori dell'enumerazione ENUM_BASE_CORNER:

Identificatore

Descrizione

ANGOLO_SINISTRA_SUPERIORE

Coordinate del punto di ancoraggio relative all'angolo superiore sinistro del grafico

ANGOLO_SINISTRA_INFERIORE

Le coordinate del punto di ancoraggio sono date rispetto all'angolo inferiore sinistro del grafico

ANGOLO_DESTRA_INFERIORE

Le coordinate del punto di ancoraggio sono impostate rispetto all'angolo inferiore destro del grafico

ANGOLO_DESTRA_SUPERIORE

Le coordinate del punto di ancoraggio sono impostate rispetto all'angolo superiore destro del grafico

La posizione del punto di ancoraggio dell'oggetto è specificata dalla proprietà OBJPROP_ANCHOR e può essere uno dei 9 valori dell'enumerazione ENUM_ANCHOR_POINT:

Identificatore

Descrizione

ANCORA A SINISTRA IN ALTO

Punto di ancoraggio in alto a sinistra

ANCHOR_LEFT

Punto di ancoraggio a sinistra nel centro

ANCORA A SINISTRA IN BASSO

Punto di ancoraggio in basso a sinistra

ANCHOR_LOWER

Punto di ancoraggio sotto il centro

ANCORA_DESTRA_INFERIORE

Punto di ancoraggio in basso a destra

ANCORA DESTRA

Punto di ancoraggio a destra nel centro

ANCORA_DESTRA_SUPERIORE

Punto di ancoraggio in alto a destra

ANCHOR_UPPER

Punto di ancoraggio al centro superiore

CENTRO ANCORA

Punto di ancoraggio esattamente al centro dell'oggetto

 
Artyom Trishkin:

Devo spostare in alto la voce della lista che stai cercando di etichettare con il numero 4, che non c'è? Diventa zero - e tutto è a posto.

Naturalmente ho spostato tutto - forse sono stupido...



void OnStart()
  {
      Label("0",//Название
            0,       //Окно
            10,      //X
            32,      //Y
            "0 - Центр координат в левом верхнем углу графика",
            10,//Размер шрифта
            Yellow,//Цвет шрифта
            0        //Выбор угла: 3 - нижний правый, 1 - верхний правый. 2 - нижний левый, 4 - верхний левый                   
            );     
      Label("1",//Название
            0,       //Окно
            10,      //X
            32,      //Y
            "1 - Центр координат в левом нижнем углу графика",
            10,//Размер шрифта
            Yellow,//Цвет шрифта
            1        //Выбор угла: 3 - нижний правый, 1 - верхний правый. 2 - нижний левый, 4 - верхний левый                   
            );     
      Label("2",//Название
            0,       //Окно
            10,      //X
            32,      //Y
            "2 - Центр координат в правом нижнем углу графика",
            10,//Размер шрифта
            Yellow,//Цвет шрифта
            2        //Выбор угла: 3 - нижний правый, 1 - верхний правый. 2 - нижний левый, 4 - верхний левый                   
            );
      Label("3",//Название
            0,       //Окно
            10,     //X
            32,      //Y
            "3 - Центр координат в правом верхнем углу графика",
            10,//Размер шрифта
            Yellow,//Цвет шрифта
            3      //Выбор угла: 3 - нижний правый, 1 - верхний правый. 2 - нижний левый, 4 - верхний левый                   
            ); 

  }

//+------------------------------------------------------------------+
//|Функция вывода информации на экран -- Старый вариант              |
//+------------------------------------------------------------------+
void Label(string _name,int _window,int _x,int _y,string _text,int _font,color _color,int corner)
  {
   ObjectDelete(_name);
   ObjectCreate(_name,OBJ_LABEL,_window,0,0);
   ObjectSet(_name,OBJPROP_CORNER,corner);
   ObjectSet(_name,OBJPROP_XDISTANCE,_x);
   ObjectSet(_name,OBJPROP_YDISTANCE,_y);
   ObjectSetText(_name,_text,_font,"Arial",_color);
  }
/*
//+------------------------------------------------------------------+
//|Функция вывода информации на экран -- Новый вариант               |
//+------------------------------------------------------------------+
void Label(string _name,int _window,int _x,int _y,string _text,int _font,color _color,int corner)
  {
   //corner=4;
   ObjectDelete(0,_name);
   ObjectCreate(0,_name,OBJ_LABEL,_window,0,0);
   ObjectSetInteger(0,_name,OBJPROP_CORNER,corner);
   ObjectSetInteger(0,_name,OBJPROP_XDISTANCE,_x);
   ObjectSetInteger(0,_name,OBJPROP_YDISTANCE,_y);
   ObjectSetText(_name,_text,_font,"Arial",_color);
  }
*/   
 
Artyom Trishkin:

E non arrabbiatevi, leggete attentamente la guida:

Per gli oggetti OBJ_LABEL, OBJ_BITMAP_LABEL e OBJ_RECTANGLE_LABEL potete impostare l'angolo del grafico, relativo al quale è posizionato il punto di ancoraggio dell'oggetto. Questo angolo è impostato tramite la proprietà dell'oggetto OBJPROP_CORNER, che può avere uno dei quattro valori dell'enumerazione ENUM_BASE_CORNER:

Identificatore

Descrizione

ANGOLO_SINISTRA_SUPERIORE

Coordinate del punto di ancoraggio relative all'angolo superiore sinistro del grafico

ANGOLO_SINISTRA_INFERIORE

Le coordinate del punto di ancoraggio sono date rispetto all'angolo inferiore sinistro del grafico

ANGOLO_DESTRA_INFERIORE

Le coordinate del punto di ancoraggio sono impostate rispetto all'angolo inferiore destro del grafico

ANGOLO_DESTRA_SUPERIORE

Le coordinate del punto di ancoraggio sono impostate rispetto all'angolo superiore destro del grafico

La posizione del punto di ancoraggio dell'oggetto è specificata dalla proprietà OBJPROP_ANCHOR e può essere uno dei 9 valori dell'enumerazione ENUM_ANCHOR_POINT:

Identificatore

Descrizione

ANCORA A SINISTRA IN ALTO

Punto di ancoraggio in alto a sinistra

ANCHOR_LEFT

Punto di ancoraggio a sinistra nel centro

ANCORA A SINISTRA IN BASSO

Punto di ancoraggio in basso a sinistra

ANCHOR_LOWER

Punto di ancoraggio sotto il centro

ANCORA_DESTRA_INFERIORE

Punto di ancoraggio in basso a destra

ANCORA DESTRA

Punto di ancoraggio a destra nel centro

ANCORA_DESTRA_SUPERIORE

Punto di ancoraggio in alto a destra

ANCHOR_UPPER

Punto di ancoraggio al centro superiore

CENTRO ANCORA

Punto di ancoraggio direttamente al centro dell'oggetto

Grazie, cercherò di pensare a qualcosa domani...

 
prostotrader:

È sempre meglio al mattino... :)

Di solito lo è :)
 
La SD dice che è la cosa giusta da fare in questo caso

Forum sul trading, sistemi di trading automatico e test di strategie di trading

Bug, bug, domande

fxsaber, 2017.07.18 09:51

Quasi una domanda infantile: perché è così?
void OnStart()
{
  const double Norm = NormalizeDouble(8905 / 1000.0, 3);
  Print(Norm); // 8.904999999999999
  Print(DoubleToString(Norm, 3)); // 8.905
  
  const double Norm2 = (double)DoubleToString(Norm, 3);
  Print(Norm2); // 8.904999999999999
  Print(Norm == Norm2); // true
}

Per qualche ragione ero sicuro che DoubleToString non avesse senso dopo la normalizzazione. Ma no, come mostra la sceneggiatura. Perché questo è il caso?

Sembra che la conversione doppio -> stringa non funzioni correttamente.


Questo esempio è piuttosto complicato da capire, quindi ve ne ho dato un altro.

void OnStart()
{
  Print((double)"8.905" == 8.905); // true
  Print(((string)(double)"8.905")); // 8.904999999999999
}

Ecco cosa intendo.

Строковая в double переводится без проблем. Обратно - получаем другой результат.

Cioè ha preso la stringa "8.905", l'ha convertita in doppio e immediatamente in stringa, ottenendo 8.9049999999999999999. Ma la prima linea di OnStart mostra che (doppio) "8.905" == 8.905. Cioè, dovrebbe essere stampato 8,905.

Naturalmente, l'ovvia situazione a zero non dovrebbe funzionare:

Se la condizione(doppia) "8.9050" == 8.9050èsoddisfatta, allora anche la condizione(stringa)(doppia) "8.9050" == "8.9050"dovrebbe essere soddisfatta.

Avendo investigato un po' il problema, sono arrivato alla seguente situazione

void OnStart()
{
  const double Num = 8.274;
  const double Norm = NormalizeDouble(Num, 3);
  
  Print(Num);  // 8.273999999999999
  Print(Norm); // 8.274000000000001
}

Si prega di spiegare perché la conversione doppio -> stringa è ancora considerata corretta. L'ultimo esempio mi fa impazzire.

 
fxsaber:

Per favore, spiega perché la conversione doppio -> stringa è ancora considerata corretta. L'ultimo esempio è così completamente strabiliante.

Commento sull'ultimo esempio

I numeri reali possono essere considerati identici se hanno subito le stesse conversioni. Anche conversioni apparentemente identiche - num*0.5 e num/2.0 portano a risultati diversi. Lo stesso si può dire delle operazioni a specchio. num*=num2, num/=num2. Il numero risultante non sarà uguale al numero originale. Benvenuti nel mondo dei numeri reali.

Durante il processo di normalizzazione, 3 operazioni sono state eseguite in questo campione con un numero reale - num*=1000, num+=0,5, num/=1000.

Puoi controllare i passi nel debugger

 
fxsaber:
SD dice che in questo caso è corretto.

Perché è confuso?

La grande maggioranza dei numeri reali decimali non è rappresentabile come una frazione binaria senza resto. Metteteci sopra un doppio formato di memorizzazione e otterrete una roba così brutta.

In realtà, il tipo decimale sarebbe bello, è comodo.

 
Slava:

Commento sull'ultimo esempio

I numeri reali possono essere considerati identici se su di essi vengono eseguite le stesse conversioni. Anche conversioni apparentemente identiche - num*0.5 e num/2.0 portano a risultati diversi. Lo stesso si può dire delle operazioni a specchio. num*=num2, num/=num2. Il numero risultante non sarà uguale al numero originale. Benvenuti nel mondo dei numeri reali.

In questo esempio, 3 operazioni - num*=1000, num+=0,5, num/=1000 - sono state eseguite su un numero reale durante la normalizzazione.

Puoi controllare i passi nel debugger


Spiegazione molto costruttiva, grazie!


Ma questo controesempio mi fa impazzire.

void OnStart()
{
  const double Num = 8.274;
  const double Norm = NormalizeDouble(Num, 3);
   
  Print(Num);  // 8.273999999999999
  Print(Norm); // 8.274000000000001
  
  Print((double)DoubleToString(Num, 3) == Num);     // true - без нормализации все замечательно
  Print((double)DoubleToString(Norm, 3) == Norm);   // false - а после нормализации полный облом!
}

È così che dovrebbe funzionare la normalizzazione?

 
Комбинатор:

Perché è confuso?

Dopo la spiegazione di Slava non è confuso, ma poi c'è un esempio che ci fa dubitare della correttezza di NormalizeDouble stesso.