Fehler, Irrtümer, Fragen - Seite 1931

 

Morgens ist es immer besser... :)

 
Aleksey Vyazmikin:

Im Helpdesk

MT4:

Für Objekte mit fester Größe: OBJ_BUTTON, OBJ_RECTANGLE_LABEL und OBJ_EDIT Eigenschaften OBJPROP_XDISTANCE und OBJPROP_YDISTANCE legen die Position des oberen linken Objektpunktes relativ zur Diagrammecke (OBJPROP_CORNER) fest, von der aus die X- und Y-Koordinaten in Pixel gezählt werden.


MT5:

Für Objekte mit fester Größe: OBJ_BUTTON, OBJ_RECTANGLE_LABEL, OBJ_EDIT und OBJ_CHART, legen die Eigenschaften OBJPROP_XDISTANCE und OBJPROP_YDISTANCE die Position des oberen linken Punktes des Objekts relativ zur Diagrammecke (OBJPROP_CORNER) fest, von der aus die X- und Y-Koordinaten in Pixel gemessen werden.

Das Problem ist, dass die alte Version von MT4, die ObjectSet verwendet , die Platzierung von Objekten relativ zu ihren Kanten (Ecken) erlaubt - für Objekte im linken Teil wird die Berechnung der Pixel vom ersten Symbol aus durchgeführt, für Objekte im rechten Teil - vom letzten Symbol aus, während die neue Version die Berechnung immer vom ersten Symbol aus durchführt, was die Positionierung von Etiketten mit Text schwierig macht, weil man nicht immer weiß, wie viele Textsymbole es geben wird. Ich fordere die Entwickler auf, eine Auswahl an Textausrichtungsmethoden hinzuzufügen!


Wenn jemand weiß, wie man sich in MT5 links und rechts ausrichten kann, bitte die entsprechende Funktion mitteilen!

Und ärgern Sie sich nicht, sondern lesen Sie die Hilfe aufmerksam:

Für die Objekte OBJ_LABEL, OBJ_BITMAP_LABEL und OBJ_RECTANGLE_LABEL können Sie den Kartenwinkel einstellen, relativ zu dem der Objektankerpunkt positioniert wird. Dieser Winkel wird über die Objekteigenschaft OBJPROP_CORNER festgelegt, die einen der vier Werte der Aufzählung ENUM_BASE_CORNER annehmen kann:

Kennung

Beschreibung

ECKE_LINKS_OBEN

Koordinaten des Ankerpunkts in Bezug auf die linke obere Ecke des Diagramms

ECKE_LINKS_UNTEN

Die Koordinaten der Ankerpunkte werden relativ zur linken unteren Ecke der Karte angegeben.

ECKE_RECHTS_UNTEN

Ankerpunktkoordinaten werden relativ zur unteren rechten Ecke des Diagramms festgelegt

ECKE_RECHTS_OBEN

Die Koordinaten des Ankerpunkts werden relativ zur oberen rechten Ecke des Diagramms festgelegt

Die Position des Ankerpunkts des Objekts wird durch die Eigenschaft OBJPROP_ANCHOR angegeben und kann einer der 9 Werte der Aufzählung ENUM_ANCHOR_POINT sein:

Kennung

Beschreibung

ANKER_LINKS_OBEN

Verankerungspunkt in der oberen linken Ecke

ANCHOR_LEFT

Verankerungspunkt links in der Mitte

ANKER_LINKS_UNTEN

Verankerungspunkt in der linken unteren Ecke

ANCHOR_LOWER

Verankerungspunkt unter der Mitte

ANKER_RECHTS_UNTEN

Verankerungspunkt in der rechten unteren Ecke

ANCHOR_RIGHT

Verankerungspunkt rechts in der Mitte

ANKER_RECHTS_OBEN

Verankerungspunkt in der oberen rechten Ecke

ANCHOR_UPPER

Verankerungspunkt in der oberen Mitte

ANCHOR_CENTER

Verankerungspunkt genau in der Mitte des Objekts

 
Artyom Trishkin:

Soll ich den Listeneintrag, den Sie mit der Zahl 4 zu kennzeichnen versuchen, die es nicht gibt, nach oben verschieben? Es wird Null - und alles ist an seinem Platz.

Natürlich habe ich alles verschoben - vielleicht bin ich dumm...



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:

Und ärgern Sie sich nicht, sondern lesen Sie die Hilfe aufmerksam:

Für die Objekte OBJ_LABEL, OBJ_BITMAP_LABEL und OBJ_RECTANGLE_LABEL können Sie den Kartenwinkel einstellen, relativ zu dem der Objektankerpunkt positioniert wird. Dieser Winkel wird über die Objekteigenschaft OBJPROP_CORNER festgelegt, die einen der vier Werte der Aufzählung ENUM_BASE_CORNER annehmen kann:

Kennung

Beschreibung

ECKE_LINKS_OBEN

Koordinaten des Ankerpunkts in Bezug auf die linke obere Ecke des Diagramms

ECKE_LINKS_UNTEN

Die Koordinaten der Ankerpunkte werden relativ zur linken unteren Ecke der Karte angegeben.

ECKE_RECHTS_UNTEN

Ankerpunktkoordinaten werden relativ zur unteren rechten Ecke des Diagramms festgelegt

ECKE_RECHTS_OBEN

Die Koordinaten des Ankerpunkts werden relativ zur oberen rechten Ecke des Diagramms festgelegt

Die Position des Ankerpunkts des Objekts wird durch die Eigenschaft OBJPROP_ANCHOR angegeben und kann einer der 9 Werte der Aufzählung ENUM_ANCHOR_POINT sein:

Kennung

Beschreibung

ANKER_LINKS_OBEN

Verankerungspunkt in der oberen linken Ecke

ANCHOR_LEFT

Verankerungspunkt links in der Mitte

ANKER_LINKS_UNTEN

Verankerungspunkt in der linken unteren Ecke

ANCHOR_LOWER

Verankerungspunkt unter der Mitte

ANKER_RECHTS_UNTEN

Verankerungspunkt in der rechten unteren Ecke

ANCHOR_RIGHT

Verankerungspunkt rechts in der Mitte

ANKER_RECHTS_OBEN

Verankerungspunkt in der oberen rechten Ecke

ANCHOR_UPPER

Verankerungspunkt in der oberen Mitte

ANCHOR_CENTER

Verankerungspunkt direkt in der Mitte des Objekts

Danke, ich werde versuchen, mir morgen etwas einfallen zu lassen...

 
prostotrader:

Morgens ist es immer besser... :)

Das ist es meistens :)
 
Der SD sagt, dass es in diesem Fall das Richtige ist

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Wanzen, Wanzen, Fragen

fxsaber, 2017.07.18 09:51

Eine fast kindliche Frage: Warum ist das so?
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
}

Aus irgendeinem Grund war ich sicher, dass DoubleToString nach der Normalisierung bedeutungslos ist. Aber nein, wie das Drehbuch zeigt. Warum ist dies der Fall?

Es scheint, dass die Konvertierung Double -> String nicht richtig funktioniert.


Dieses Beispiel ist ziemlich kompliziert zu verstehen, deshalb habe ich ein anderes gewählt.

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

Ich meine Folgendes.

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

D.h. ich habe die Zeichenkette "8.905" genommen, sie in double und sofort in string umgewandelt und so 8.904999999999999 erhalten. Aber die erste Zeile von OnStart zeigt, dass (double) "8.905" == 8.905. Das heißt, 8,905 sollte gedruckt werden.

Natürlich sollte die offensichtliche Null-Situation nicht funktionieren:

Wenn die Bedingung(double) "8.9050" == 8.9050erfüllt ist, dann sollte auch die Bedingung(string)(double) "8.9050" == "8.9050"erfüllt sein.

Nachdem ich das Problem ein wenig untersucht habe, bin ich zu folgender Situation gekommen

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

Erläutern Sie bitte, warum die Umwandlung double -> string immer noch als korrekt gilt. Das letzte Beispiel hat mich völlig aus den Socken gehauen.

 
fxsaber:

Erläutern Sie bitte, warum die Konvertierung Double -> String immer noch als korrekt angesehen wird. Das letzte Beispiel ist wirklich umwerfend.

Kommentar zum letzten Beispiel

Reelle Zahlen können als identisch betrachtet werden, wenn sie die gleichen Umwandlungen durchlaufen haben. Selbst scheinbar identische Umrechnungen - num*0,5 und num/2,0 - führen zu unterschiedlichen Ergebnissen. Das Gleiche gilt für Spiegeloperationen. num*=num2, num/=num2. Die resultierende Zahl ist nicht gleich der ursprünglichen Zahl. Willkommen in der Welt der reellen Zahlen.

Während des Normalisierungsprozesses wurden in dieser Stichprobe 3 Operationen mit einer reellen Zahl durchgeführt - num*=1000, num+=0,5, num/=1000.

Sie können die Schritte im Debugger überprüfen

 
fxsaber:
SD sagt, dass es in diesem Fall richtig ist.

Warum ist das verwirrend?

Die große Mehrheit der reellen Dezimalzahlen lässt sich nicht als binärer Bruch ohne Rest darstellen. Wenn man dann noch ein doppeltes Speicherformat hinzufügt, erhält man solch hässliches Zeug.

Eigentlich wäre der Dezimaltyp schön, er ist praktisch.

 
Slava:

Kommentar zum letzten Beispiel

Reelle Zahlen können als identisch angesehen werden, wenn die gleichen Umrechnungen an ihnen vorgenommen werden. Selbst scheinbar identische Umrechnungen - num*0,5 und num/2,0 - führen zu unterschiedlichen Ergebnissen. Das Gleiche gilt für Spiegeloperationen. num*=num2, num/=num2. Die resultierende Zahl ist nicht gleich der ursprünglichen Zahl. Willkommen in der Welt der reellen Zahlen.

In diesem Beispiel wurden während der Normalisierung 3 Operationen - num*=1000, num+=0,5, num/=1000 - an einer reellen Zahl durchgeführt.

Sie können die Schritte im Debugger überprüfen


Sehr konstruktive Erklärung, danke!


Aber dieses Gegenbeispiel macht mich sprachlos.

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 - а после нормализации полный облом!
}

Soll die Normalisierung so funktionieren?

 
Комбинатор:

Warum ist das verwirrend?

Nach der Erklärung von Slava ist es nicht verwirrend, aber dann gibt es ein Beispiel, das uns die Korrektheit von NormalizeDouble selbst in Frage stellt.

Grund der Beschwerde: