Bibliotheken: CDouble & CDoubleVector - Seite 2

 
Alain Verleyen:
Ein guter Fang. Vom Standpunkt des Handels aus gesehen brauchen Sie jedoch entweder 1,70060 oder 1,70061, beide sind korrekt. Vielleicht sollten Sie also die beste Lösung für Ihre Handelsoperationen wählen, anstatt sich auf ein mathematisches Rundungsschema zu verlassen.

In diesem Szenario, wenn Ihre Schrittweite == 0,00001 ist, sollten Sie nur 1,70061 als Ergebnis erhalten, und ein Wert von 1,70060 ist nahe dran, aber falsch.

 
nicholishen:

In diesem Szenario, wenn Ihre Schrittweite == 0,00001 ist, sollten Sie nur 1,70061 als Ergebnis erhalten, und ein Wert von 1,70060 ist nahe dran, aber falsch.

Sorry, aber ich verstehe Ihre Argumentation nicht. Was ist "Schrittweite"?

 
Alain Verleyen:

Entschuldigung, aber ich verstehe Ihre Argumentation nicht. Was ist "Schrittweite"?

Schrittweite ist der Wert des Schritts, auf den Sie runden. z.B. lot_step = 0.01 (2 Ziffern), oder tick_size = 0.00005...


In diesem Beispiel arbeiten wir mit einem 5-stelligen Symbol mit einer Tick-Size == 0,00001

 
nicholishen:

Schrittgröße ist der Wert des Schritts, auf den gerundet wird. z.B. lot_step = 0.01 (2 Ziffern), oder tick_size = 0.00005...


In diesem Beispiel arbeiten wir mit einem 5-stelligen Symbol mit einer Tick-Größe == 0,00001

Ok, also ist die Schrittgröße die Tick-Größe. Das sagt mir aber immer noch nicht, warum ein berechneter Preis wie 1,700605 nicht auf 1,70060 "gerundet" werden kann (wie auch immer das mathematisch/kodierungstechnisch aussieht)?
 
Alain Verleyen: Ok, die Schrittgröße ist also die Tick-Größe. Das sagt mir aber immer noch nicht, warum ein berechneter Preis wie 1,700605 aus Handelssicht nicht auf 1,70060 "gerundet" werden kann (wie auch immer das mathematisch/kodiert sein mag).

Bitte verstehen Sie, dass ein "Handelsstandpunkt" hier nicht relevant ist. Dies ist ein rein mathematisches Problem, für das @amrali eine Lösung gefunden hat.

Es gibt keinen Grund, hier über den "Handelsstandpunkt" zu diskutieren, da dies nicht zum Thema dieses Threads passt und letztendlich zu einer weiteren hitzigen Debatte führen wird, die damit endet, dass wieder jemand gesperrt wird. Versuchen Sie also bitte, das zu vermeiden!

 
Fernando Carreiro:

Bitte haben Sie Verständnis dafür, dass ein "Handelsstandpunkt" hier nicht relevant ist. Dies ist ein rein mathematisches Problem, für das @amrali eine Lösung gefunden hat.

Es gibt keinen Grund, hier über den "Handelsstandpunkt" zu diskutieren, da dies nicht zum Thema dieses Threads gehört und letztlich zu einer weiteren hitzigen Debatte führen wird, die damit endet, dass wieder jemand gesperrt wird. Versuchen Sie also bitte, das zu vermeiden!

Ich versuche nur zu verstehen, was @nicholishen gesagt hat. Es gibt keinen Grund für eine hitzige Debatte oder ähnliches. Dies ist ein Forum über den Handel, nicht wahr?

Bitte erklären Sie mir, warum aus einem errechneten Kurs von 1,700605 ein realer Kurs von 1,70060 "falsch" ist ? Wenn ich etwas übersehe, würde ich es gerne verstehen.

 
Alain Verleyen:

Ich versuche nur zu verstehen, was @nicholishen gesagt hat. Es gibt keinen Grund für eine hitzige Debatte oder ähnliches. Dies ist ein Forum über den Handel, nicht wahr?

Bitte erklären Sie mir, warum aus einem berechneten Kurs von 1,700605 ein realer Kurs von 1,70060 "falsch" ist ? Wenn ich etwas übersehe, würde ich es gerne verstehen.

Wie Fernando sagte, "ist dies ein rein mathematisches Problem", und im mathematischen Sinne ist das erwartete Ergebnis, dass die 5 auf die nächste Ziffer auf- statt abgerundet wird. Die MathRound-Funktion liefert inkonsistente Ergebnisse, und wenn Sie Inkonsistenzen vermeiden wollen, würde ich empfehlen, stattdessen ND zu verwenden, wie von @amrali klugerweise vorgeschlagen. Um wieder zum Thema zurückzukommen: Die CDouble-Bibliothek verwendet die MathRound-Funktion nicht mehr, um konsistentere Ergebnisse zu erzielen.

 
Alain Verleyen:

Ich versuche nur zu verstehen, was @nicholishen gesagt hat. Es gibt keinen Grund für eine hitzige Debatte oder ähnliches. Dies ist ein Forum über den Handel, nicht wahr?

Bitte erklären Sie mir, warum aus einem berechneten Kurs von 1,700605 ein realer Kurs von 1,70060 "falsch" ist ? Wenn ich etwas übersehe, würde ich es gerne verstehen.

Hallo Alain Verleyen, Sie haben Recht mit Ihrem Punkt. Bei einer einzelnen Berechnung macht das vielleicht keinen großen Unterschied. Wenn Sie jedoch mehrere Berechnungen durchführen, bei denen in jedem Schritt gerundet werden muss, wird der endgültige Fehler vergrößert. Nehmen wir eine Martingale-Strategie, bei der jede berechnete Losgröße von der vorherigen abgeleitet wird (die als gerundeter Wert an den Handelsserver gesendet wurde). Das Problem, das wir hier betrachten, heißt "Fehlerfortpflanzung". Daher halte ich es für sicherer, NormalizeDouble() zu verwenden, um die Zwischenfehler so gering wie möglich zu halten.

Zweitens gibt es hier auch einen eher technischen Punkt. Wenn Sie die Funktion MathRound(Zahl * Potenz) / Potenz mit Randzahlenverwenden, erhalten Sie manchmal den oberen gerundeten Wert und manchmal den unteren gerundeten Wert, je nach Eingabe. Wie Sie in Ihrem Kommentar erwähnt haben, ist diese Inkonsistenz bei der Rundung aus Handelssicht möglicherweise nicht von Bedeutung, solange Sie einen endgültigen gerundeten Wert erhalten (entweder nach oben oder nach unten), so dass sich der Handelsserver nicht beschweren wird. Wie Mark Watkin jedoch feststellte , kann eine solche Inkonsistenz bei der Rundung zu schwer zu erkennenden Fehlern im Client-Code führen, der die "CDouble"-Bibliothek verwendet.

Übrigens, wenn Sie eine andere Variante der obigen Funktion wie MathRound(number / point) * point mit Randzahlenverwenden , erhalten Sie eine gerundete Zahl (entweder auf- oder abgerundet), oder interessanterweise erhalten Sie keine exakte gerundete Zahl! (das Ergebnis weicht um 1 Epsilon vom erwarteten Wert ab, aber für Handelsfunktionen ist das in Ordnung)

Das folgende Skript hilft, diese Probleme zu verdeutlichen:

#property strict

#define  PRINT(A) Print(#A + " = ", (A))

//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
// inkonsistente Ergebnisse von MathRound() mit Kantenzahlen

void OnStart()
{
    // Preise auf die Hälfte der nächsten 5 Dezimalstellen aufrunden

    PRINT(MathRound(1.248825 * 100000) / 100000 == 1.24883);    // true, dieser Preis wird aufgerundet (wie erwartet)
    PRINT(MathRound(1.248835 * 100000) / 100000 == 1.24883);    // wahr, der Preis wird dieses Mal abgerundet
    PRINT(MathRound(1.248845 * 100000) / 100000 == 1.24885);    // wahr, dieser Preis wird wieder aufgerundet

    // die zweite Variante von MathRound()

    PRINT(MathRound(1.248825 / 0.00001) * 0.00001 == 1.24883);   // wahr, dieser Preis wird aufgerundet (wie erwartet)
    PRINT(MathRound(1.248835 / 0.00001) * 0.00001 == 1.24883);   // wahr, der Preis wird dieses Mal abgerundet
    PRINT(MathRound(1.248845 / 0.00001) * 0.00001 == 1.24885);   // false, dieser Preis wird nicht genau aufgerundet!!
    PRINT(MathRound(1.248845 / 0.00001) * 0.00001 == 1.24884);   // false, der gleiche Preis wird nicht exakt abgerundet!!
    PRINT(MathRound(1.248845 / 0.00001) * 0.00001 == 1.2488400000000001);   // wahr, aber es ist OK für Handelsfunktionen. 
}

Daher wäre es besser, MathRound(number) durch NormalizeDouble(number, 0) zu ersetzen , um inkonsistente Ergebnisse zu vermeiden, wenn eine arithmetische (Mittelwert-)Rundung angezeigt wird.

Die andere gute Alternative für das Runden in der Mitte: MathRound() verwenden + Halb-Epsilon-Korrektur anwenden.

(Dies wurde in der FunktionMathRoundCorrect() implementiert , wie bereits erwähnt).

double MathRoundCorrect(double num, int precision) {
        double c = 0.5 * DBL_EPSILON * num;
// double p = MathPow(10, Genauigkeit); //slow
        double p = 1; while (precision--> 0) p *= 10;
        if (num < 0)
                p *= -1;
        return MathRound((num + c) * p) / p;
}

Laut diesem Wikipedia-Artikel gibt es viele andere Rundungsmodi, die unterschiedlichen Zwecken dienen. Es steht Ihnen frei, den für Ihre Anforderungen geeigneten Modus zu wählen. Mit freundlichen Grüßen.

https://en.wikipedia.org/wiki/Rounding

Rounding - Wikipedia
Rounding - Wikipedia
  • en.wikipedia.org
Graphs of the result, y, of rounding x using different methods. For clarity, the graphs are shown displaced from integer y values. In the SVG file, hover over a method to highlight it and, in SMIL-enabled browsers, click to select or deselect it. Rounding a numerical value means replacing it by another value that is approximately equal but has...