NormalizeDouble funktioniert nicht.

 

 Hallo, derzeit bin ich am schreiben meines Money und Risikomanagement, dabei ist mir im Journal folgende Meldung aufgetaucht:

2021.03.22 00:07:31.753    2021.02.16 15:59:59   failed market sell 0.01213333 GBPUSD sl: 1.38845 [Invalid volume]

Der dafür entsprechende Code ist in die OnTick Funktion eingebunden.

 double FreiesKapital=0;
 double AccountBalance=NormalizeDouble(AccountInfoDouble(ACCOUNT_BALANCE),2);

 string Kontowaehrung = AccountInfoString(ACCOUNT_CURRENCY);

   if(AktAccountBalance)
     {
      FreiesKapital=NormalizeDouble(AccountInfoDouble(ACCOUNT_MARGIN_FREE),2);
     }
   else
     {
      FreiesKapital = AccountBalance;
     }

   double PipValue = SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE)*point/(SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_SIZE));
   double lot=GetLot();
   double lots = InpRisiko * FreiesKapital / (PipValue * StopLoss);
   CalcLot=lots;
// Truncate lot quantity to 2 decimal digits without rounding it
   lots = floor(lots * 100) / 100;
   Comment("\n CalcLot: ",lots," Lot nach Moneymanagement bei verlust: ",lot," Verlust in Folge: ",ViF,
           "\n CalcTagesziel: ",CTagesziel," CMonat: ",CMonat,"PipVal: ",PipValue,
           "\n Gesetztes Risiko: ",DoubleToString(InpRisiko * 100, 0),"%"," = ",DoubleToString(InpRisiko * FreiesKapital, 2)," "+Kontowaehrung
          );

diese Änderungen Brachten kein Erfolg:

double lots = NormalizeDouble(InpRisiko * FreiesKapital / (PipValue * StopLoss),2);

oder

double lots = MathRound(InpRisiko * FreiesKapital / (PipValue * StopLoss),2);

Nun bin ich mit meinem Latein am Ende, wie kann ich das beheben?

 
Double Werte werden dargestellt in der Form x = sm2^e dargestellt. Das ändert sich sich auch nicht durch NormalizeDouble(). Intern kann man mit NormalizeDouble() den nächsten gültigen Wert ermitteln ähnlich dem Runden. Für die textliche Ausgabe, auch in csv-Dateien, muss man allerdings PrintFormat() oder StringFormat() oder DoubleToString() verwenden.
 
Carl Schreiber:
Double Werte werden dargestellt in der Form x = sm2^e dargestellt. Das ändert sich sich auch nicht durch NormalizeDouble(). Intern kann man mit NormalizeDouble() den nächsten gültigen Wert ermitteln ähnlich dem Runden. Für die textliche Ausgabe, auch in csv-Dateien, muss man allerdings PrintFormat() oder StringFormat() oder DoubleToString() verwenden.

Das hab ich auch schon gelesen im englischen Forum, mir geht es aber nicht um eine Textausgabe sondern um das Ergebnis meiner Volumen, der EA verweigert den Handel mit dieser Fehlermeldung. 

failed market sell 0.01213333 GBPUSD sl: 1.38845 [Invalid volume]

Sprich wenn ich bei nachfolgenden Code lots einsetze einen Fehler bekomme,da er offensichtlich mit den Ergebnis nix anfangen kann.

  MqlTradeRequest myrequest;
      MqlTradeResult myresult;
      ZeroMemory(myrequest);
      myrequest.action = TRADE_ACTION_DEAL;
      myrequest.type = ORDER_TYPE_BUY;
      myrequest.symbol = _Symbol;
      myrequest.volume = lots; // Wert verursacht Fehermeldung
      myrequest.type_filling = ORDER_FILLING_FOK;
      myrequest.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
      myrequest.tp = Ask + (TakeProfit * _Point) ;
      myrequest.sl = Ask - (StopLoss * _Point);
      myrequest.deviation =5;
      myrequest.comment =Kommentar;
      myrequest.magic=Magic;
      OrderSend (myrequest,myresult);
 
Und wenn es nicht am Volumen liegt, sondern an SL oder TP? Schreib ins Log: Richtung, Ask, Bid, SL und TP und schau nach, ob alles richtig ist.
 
Carl Schreiber:
Und wenn es nicht am Volumen liegt, sondern an SL oder TP? Schreib ins Log: Richtung, Ask, Bid, SL und TP und schau nach, ob alles richtig ist.

Ich würde mal vermuten es liegt an den lots, du musst die zuerst 2 stellig machen

 
amando:

Ich würde mal vermuten es liegt an den lots, du musst die zuerst 2 stellig machen

Nein, ein Doublewert hat nur in wenig Sonderfällen genau zwei Nachkommastellen.

 
Carl Schreiber:

Nein, ein Doublewert hat nur in wenig Sonderfällen genau zwei Nachkommastellen.

Ich weis, aber es gibt genug broker, die damit nicht umgehen können, weis der himmel warum. Dachte bei der umstellung auf mt5 ist das problem gelöst, gelöst ist es bis heute nicht.

bisher hat bei mir immer normalize double gereicht

 
amando:

Ich weis, aber es gibt genug broker, die damit nicht umgehen können, weis der himmel warum. Dachte bei der umstellung auf mt5 ist das problem gelöst, gelöst ist es bis heute nicht.

bisher hat bei mir immer normalize double gereicht


Jap, es liegt auch an "lots", hab die formel mal neu geschrieben mit Zahlen aus dem Buch,da klappt es... demnach kann es also nur an den Wert liegen bzw dem Ergebnis.

Aber lots mit NormalizeDouble und 2 digits funzt nicht genauso mit MathRound.


So noch mal alles in ruhe angeschaut, diese Änderung funtioniert schon mal

  double lots= NormalizeDouble(((FreiesKapital  * InpRisiko ) / StopLoss ) / ((100000 /  141.20 ) * 0.01),2);

// ((100000 /  141.20 ) * 0.01),2) ändern...


dabei handelt es sich um: Kontowährung / Kurswährung des gehandelten Paares = EUR/JPY Wechselkurs = 141,20  umrechnung ist für JPY 0.01

 0,0001 wäre für nicht JPY Paare

Die Frage ist jetzt wie kann ich "Kontowährung / Kurswährung " berechnen? wäre dann meine Vermutung mit den Code richtig?

// Für alle Symbole, FOREX,CRYPTO, usw
 double lots= NormalizeDouble(((FreiesKapital  * InpRisiko ) / StopLoss ) / ((SymbolInfoDouble("EUR",SYMBOL_TRADE_CONTRACT_SIZE) /  SymbolInfoDouble(_Symbol,SYMBOL_BID) * SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE))),2);
 

Ich habe mir mal meine eigene Normierung der LotSize geschrieben, die sich an LotStep des Symbols orientiert:

double NormDoub( double v, double stp){ return(stp*MathFloor(v /stp)); }   //Beispiel:   lots = NormDoub(lots,SymbolInfoDouble((Symbol(), SYMBOL_VOLUME_STEP )) // Lotsize

(Stammt allerdings noch vom MQ$ und ich hab das versucht  'on the fly' anzupassen, kann sein, das es einen Fehler hat.)

Dokumentation zu MQL5: Marktinformation erhalten / SymbolInfoDouble
Dokumentation zu MQL5: Marktinformation erhalten / SymbolInfoDouble
  • www.mql5.com
SymbolInfoDouble - Marktinformation erhalten - Nachschlagewerk MQL5 - Nachschlagewerk über die Sprache des algothitmischen/automatischen Handels für MetaTrader 5
 
Carl Schreiber:

Ich habe mir mal meine eigene Normierung der LotSize geschrieben, die sich an LotStep des Symbols orientiert:

double NormDoub( double v, double stp){ return(stp*MathFloor(v /stp)); }   //Beispiel:   lots = NormDoub(lots,SymbolInfoDouble((Symbol(), SYMBOL_VOLUME_STEP )) // Lotsize

(Stammt allerdings noch vom MQ$ und ich hab das versucht  'on the fly' anzupassen, kann sein, das es einen Fehler hat.)

Täuscht das oder gibts wirklich so unterschiedliche arten das zu berechnen?

ich nutze diese Formel:

https://www.scalp-trading.com/pips-lots-und-positionsgroessen/

is die Selbe wie im Buch, hab aber schon andere gesehen die auf LotStep orientieren.

Was ist jetzt also nun korrekt?

 
Das ist kein Gegensatz. Meine Formel benötigt v, das Volumen, das vorab berechnet werden muss, zB. auf Basis von Kapital, Risiko etc. Meine Formel ersetzt nur das NormalizeDouble(..),  das zu Fehlern führen würde, wenn die Schrittweite der Losgröße nicht 0,01 wäre sondern zB. 0,5.