Fehler, Irrtümer, Fragen - Seite 107

 
Yedelkin:
Simpleton, ich folgte der gleichen Weise, aber verwendet explizite Umwandlung in int Typ. Ich bin davon ausgegangen, dass die maximal mögliche Losgröße entweder durch den Broker/Händler oder durch die Höhe meines Eigenkapitals begrenzt wird. Die Verwendung von int sollte also ausreichen. Gibt es Ihrer Meinung nach irgendwelche Fallstricke bei diesem Ansatz (Aufrunden von unten nach oben mit int)?

Für den realen Handel ist int/uint wahrscheinlich ausreichend.

Aber wenn man es in einem Testgerät laufen lässt, kann es für einige Experimente nicht ausreichen.

Bei der Verwendung von int gibt es keine Fallstricke, abgesehen von möglichen nächsten Pannen in der MQL5-Implementierung, wenn wir garantieren können, dass die Ganzzahl N aus der Formel in den Bereich 0...INT_MAX fällt und wir somit keinen Überlauf haben werden. Das heißt, Check ersetzen

tmp < ULONG_MAX * stepvol

zu

tmp < INT_MAX * stepvol

Der Typ int ist vorzeichenbehaftet und die Hälfte seiner möglichen Werte liegt im Bereich der negativen Zahlen, während sie hier immer nicht-negativ sind. Es ist irrational, int zu verwenden, wenn es eine vorzeichenlose uint gibt, die die gleiche Größe, aber den doppelten Bereich im nicht-negativen Bereich hat. Wenn wir also int/uint verwenden wollen, ist es besser, uint zu verwenden und die Prüfung durch uint zu ersetzen:

tmp < UINT_MAX * stepvol
 

gumgum:

#property script_show_inputs

Danke für den Hinweis.
 
simpleton:

Für den realen Handel ist int/uint höchstwahrscheinlich ausreichend.

...Eigentlich ist der Typ int vorzeichenbehaftet, die Hälfte seiner möglichen Werte liegt im Bereich der negativen Zahlen, und hier wird er immer nicht-negativ sein. Es ist irrational, int zu verwenden, wenn es eine vorzeichenlose uint gibt, die die gleiche Größe, aber den doppelten Bereich im nicht-negativen Bereich hat. Wenn wir also int/uint verwenden wollen, ist es besser, uint zu verwenden und die Prüfung durch uint zu ersetzen:

Ja, ich habe es verstanden, danke!
 

Es handelt sich nicht um einen Fehler, sondern um eine interessante Beobachtung über Typen

Was denkst du, was 2 mal 2 ist, d.h. 2*2?

du denkst 4 vielleicht hast du recht!

OK, wie wäre es damit
zweihunderttausend mal zweihunderttausend

200000 * 200000

Jeder Schuljunge kann Zweier und Vierer multiplizieren und Nullen addieren und erhält...

40000000000.

Nun wollen wir einen einfachen Code in der Sprache der Maschine schreiben.

lange Lose = 200000*200000;

beachten Sie, dass der Host-Typ der Variablen lang ist, d. h.
Der Mindestwert ist -9 223 372 036 854 775 808; der Höchstwert ist 9 223 372 036 854 775 807.

Drucken Sie die Summe aus und Sie erhalten

Partien = 1345294336
Das ist weit entfernt von zwei mal zwei und du bekommst zwei.

Ich habe den Hilfeabschnitt über Typen und Typkonvertierungen noch einmal gelesen.
Ich habe keine Informationen darüber gefunden, dass reguläre Zahlen explizit in den richtigen Typ umgewandelt werden müssen

So sollte es also sein

long lots = (long) 200000 * (long) 200000;

alternativ können Sie zusätzliche Hilfsvariablen verwenden.

Документация по MQL5: Основы языка / Типы данных / Приведение типов
Документация по MQL5: Основы языка / Типы данных / Приведение типов
  • www.mql5.com
Основы языка / Типы данных / Приведение типов - Документация по MQL5
 

Es gibt noch mehr.

Wenn Sie einige Eigenschaften abrufen und mit großen Zahlen multiplizieren möchten....

Hier ist der Code

long A = AccountInfoInteger(ACCOUNT_LOGIN);  // 661701
long B = A;
long C = 661701;
Print(" A=",A,"  B=",B,"  C=",C);
long X =10000;

long L1 = A*X;
long L2 = B*X;
long L3 = C*X;

Print(" L1=",L1,"   L2=",L2,"   L3=",L3);

Und hier ist das Ergebnis

L1=2322042704   L2=2322042704   L3=6617010000
A =661701        B =661701      C =661701
die Eingaben sind die gleichen, aber das Ergebnis ist anders
Dateien:
servis.mq5  2 kb
 

SHOOTER777:

Und nun ein einfacher Code in Maschinensprache

lange Lose = 200000*200000;

Beachten Sie, dass der empfangende Typ der Long-Variablen long ist, d. h.
Der Mindestwert ist -9 223 372 036 854 775 808, der Höchstwert ist 9 223 372 036 854 775 807.

Drucken Sie die Summe und erhalten Sie

Partien = 1345294336
Das ist weit entfernt von zwei mal zwei und du bekommst zwei.

Ich habe den Hilfeabschnitt über Typen und Typkonvertierungen noch einmal gelesen.
Ich habe keine Informationen darüber gefunden, dass man reguläre Zahlen explizit in einen bestimmten Typ umwandeln muss.

So sollte es also sein

long lots = (long) 200000 * (long) 200000;

Alternativ dazu können Sie auch Hilfsvariablen verwenden.

"Gewöhnliche Zahlen" sind konstante Ausdrücke, die auch einen Typ haben. In diesem Fall handelt es sich um den Typ int.

Der Ausdruck, der aus der Multiplikation zweier Unterausdrücke besteht, die jeweils vom Typ int sind, ist ebenfalls vom Typ int. An dieser Stelle kommt es zum Überlauf.

Und nur dann erfolgt die implizite Umwandlung vom Typ des int-Ausdrucks in den Typ long, wenn eine Variable vom Typ long initialisiert wird.

Hier ist alles klar. Übrigens muss in diesem Fall nicht jeder der Operanden in den Typ long gecastet werden. Es reicht aus, eine zu wählen, und die zweite wird implizit gewählt.

 
SHOOTER777:

Es gibt noch mehr.

Wenn Sie einige Eigenschaften abrufen und mit großen Zahlen multiplizieren möchten....

Hier ist der Code

Und hier ist das Ergebnis.

Die Ausgangsdaten sind dieselben, aber das Ergebnis ist ein anderes.

Es sieht so aus, als ob das Protokoll und der Code durcheinander geraten sind. Der obige Code funktioniert "sauber". Und um ein solches Protokoll zu erhalten, musste ich die Variablen A und B vom Typ int oder uint und die Variable X vom Typ uint machen:

void OnStart()
{
int A = 661701;
int B = A;
long C = 661701;
Print(" A=",A,"  B=",B,"  C=",C);
uint X =10000;

long L1 = A*X;
long L2 = B*X;
long L3 = C*X;

Print(" L1=",L1,"   L2=",L2,"   L3=",L3);
}

/* Вывод в лог (хронология - сверху вниз):
KO      0       1 (EURUSD,M15)  00:46:28         A=661701  B=661701  C=661701
OE      0       1 (EURUSD,M15)  00:46:28         L1=2322042704   L2=2322042704   L3=6617010000
*/

Und so funktioniert der ursprüngliche Code:

void OnStart()
{
long A = 661701;
long B = A;
long C = 661701;
Print(" A=",A,"  B=",B,"  C=",C);
long X =10000;

long L1 = A*X;
long L2 = B*X;
long L3 = C*X;

Print(" L1=",L1,"   L2=",L2,"   L3=",L3);
}

/* Вывод в лог (хронология сверху вниз):
DL      0       1 (EURUSD,M15)  00:49:13         A=661701  B=661701  C=661701
HG      0       1 (EURUSD,M15)  00:49:13         L1=6617010000   L2=6617010000   L3=6617010000
*/

Build 314 (20. August 2010).

Документация по MQL5: Основы языка / Типы данных / Целые типы / Типы char, short, int и long
Документация по MQL5: Основы языка / Типы данных / Целые типы / Типы char, short, int и long
  • www.mql5.com
Основы языка / Типы данных / Целые типы / Типы char, short, int и long - Документация по MQL5
 

Können Sie mir zum Beispiel sagen, ob ich den Wert eines Indikators abfragen möchte? Früher habe ich sie mit der eingebauten Funktion genau und garantiert erhalten. Jetzt muss ich es selbst schreiben, mit einem Haufen Code, Puffern, Handles usw. Aber das ist nicht der Punkt. Die Hauptsache für mich ist, dass der Code buchstäblich in jeder Zeile glitchy wird, weil ich diese jede Zeile des Codes überprüfen muss, um sicherzustellen, dass kein Fehler aufgetreten ist... Im Allgemeinen dachte ich, dass all diese Komplexitäten, Klassen und Dinge, die elementar waren, aber umständlich und unbequem wurden, gemacht wurden, um die Geschwindigkeit, Zuverlässigkeit usw. zu erhöhen. Ich habe einen Artikel über 20 Signale gelesen... heißt es:

"Sie können nicht direkt nach der Erstellung auf die Indikatordaten zugreifen, da die Berechnung der Indikatorwerte einige Zeit in Anspruch nimmt. Daher ist es besser, die Indikator-Handles in OnInit() zu erstellen.

Dann gibt es Prüfungen für jede Zeile

"Überprüfen wir sie: Wenn es weniger Daten gibt, als wir brauchen, bedeutet dies, dass ein Kopierfehler aufgetreten ist und ein weiterer Zugriff auf das Array, in dem die Daten gespeichert werden sollten, zu einem Fehler führen wird. Um dies auszuschließen, werden wir die Funktion beenden.

Anstatt schneller zu werden, muss ich also eine Schleife (wie oft?) durch diese Funktion laufen lassen, um am Ende ein Ergebnis zu erhalten... Und wenn ich in regelmäßigen Abständen einzelne Werte von verschiedenen Zeilen verschiedener Indikatoren benötige... Dies ist eine separate Funktion für jeden Wert... Das sind eine Menge zusätzlicher Variablen und Code...

Kurz gesagt, bitte erklären Sie es mir, geben Sie mir einen Link, ich möchte die Bedeutung von all dem verstehen, warum es so und nicht so zuverlässig ist...

Und es wäre gut, wenn die Antworten auf solche Fragen im Bereich der Migration von µl4 zu µl5 Hilfe platziert werden könnten, oder um einen entsprechenden Bereich auf dem Forum zu schaffen, ohne jede Diskussion, speziell eine Frage und Antwort, mit einer Erklärung, warum dies so ist... Zum Beispiel wird der Zeitraum hier sehr verständlich erklärt, und wir möchten auch Antworten auf elementare Fragen haben

 
Dmitriy2:

Können Sie mir zum Beispiel sagen, ob ich den Wert eines Indikators abfragen möchte? Früher habe ich es genau und sicher mit der eingebauten Funktion bekommen. Jetzt muss ich es selbst schreiben, mit einem Haufen Code, Puffern, Handles usw. Aber das ist nicht der Punkt. Die Hauptsache für mich ist, dass der Code buchstäblich in jeder Zeile glitchy wird, weil ich diese jede Zeile des Codes überprüfen muss, um sicherzustellen, dass kein Fehler aufgetreten ist... Im Allgemeinen dachte ich, dass all diese Komplexitäten, Klassen und Dinge, die elementar waren, aber umständlich und unbequem wurden, gemacht wurden, um die Geschwindigkeit, Zuverlässigkeit usw. zu erhöhen. Ich habe einen Artikel über 20 Signale gelesen... heißt es:

"Sie können nicht direkt nach der Erstellung auf die Indikatordaten zugreifen, da die Berechnung der Indikatorwerte einige Zeit in Anspruch nimmt. Daher ist es besser, die Indikator-Handles in OnInit() zu erstellen.

Dann gibt es Prüfungen für jede Zeile

"Überprüfen wir sie: Wenn es weniger Daten gibt, als wir brauchen, bedeutet dies, dass ein Kopierfehler aufgetreten ist und ein weiterer Zugriff auf das Array, in dem die Daten gespeichert werden sollten, zu einem Fehler führen wird. Um dies auszuschließen, werden wir die Funktion beenden.

Anstatt schneller zu werden, muss ich also eine Schleife (wie oft?) durch diese Funktion laufen lassen, um am Ende ein Ergebnis zu erhalten... Und wenn ich in regelmäßigen Abständen einzelne Werte von verschiedenen Zeilen verschiedener Indikatoren benötige... Dies ist eine separate Funktion für jeden Wert... Das sind eine Menge zusätzlicher Variablen und Code...

Kurz gesagt, bitte erklären Sie es mir, geben Sie mir einen Link, ich möchte die Bedeutung von all dem verstehen, warum es so und nicht so zuverlässig ist...

Und es wäre gut, wenn die Antworten auf solche Fragen im Bereich der Migration von µl4 zu µl5 Hilfe platziert werden könnten, oder um einen entsprechenden Bereich auf dem Forum zu schaffen, ohne jede Diskussion, speziell eine Frage und Antwort, mit einer Erklärung, warum dies so ist... Zum Beispiel wird der Zeitraum hier auf sehr verständliche Weise erklärt, so dass es gut wäre, Antworten auf elementare Fragen auf dieselbe Weise zu erhalten.

Ist sie zuverlässiger? Warum ist es unzuverlässig, bei der Initialisierung Handles zu erhalten? Warum ist es nicht zuverlässig, die Verfügbarkeit der benötigten Daten zu prüfen? Und warum ist es nicht verlässlich, Kontrollen durchzuführen?

Für Anfänger ist es vielleicht nicht so einfach, aber mit der Zeit wird es klar...

 
Interesting:

Zuverlässiger? Warum ist das Abrufen von Handles bei der Initialisierung nicht zuverlässig? Warum ist es unzuverlässig, nach notwendigen Daten zu suchen? Und vor allem, warum sind die Kontrollen nicht zuverlässig?

Für Neulinge ist es vielleicht nicht so einfach, aber mit der Zeit wird es klar...

Die Überprüfung der Daten beeinträchtigt die Geschwindigkeit des Programms insgesamt nicht, vielleicht nur um 0,01%, ich habe diese Überprüfung nicht durchgeführt, und die Tatsache, dass die Daten vor ihrer Verwendung überprüft werden sollten, dient nur der Stabilität des gesamten Systems, da es sonst zu unvorhersehbaren Folgen kommen kann, bis hin zum Absturz des Terminals insgesamt.