consulente esperto - domande varie - pagina 3

 
double LotCalculator(double lots)
  {
   double minlot  = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN),
          maxlot  = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX),
          lotstep = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
   lots = MathFloor(lots/lotstep)*lotstep;
   lots = MathMax(lots,minlot);
   lots = MathMin(lots,maxlot);
   return(NormalizeDouble(lots,2));
  }
 
honest_knave:
double LotCalculator(double lots){}

Molto apprezzato.

Voglio solo iniziare a scrivere quel codice :)

Hai salvato il mio più volte.

Grande grazie!

 
Ho ricevuto lo stesso messaggio per la dimensione del lotto.
Chiamo 'LotCalculator()' in 'OnChartEvent()' quindi non è giusto?
 

Sto cercando un buon forum per il calcolo di'MarketInfo & LotSize'.
Chi sa che tipo di buon forum per favore condivida con me.

Grazie.

 
Hai per caso usato il mio snippet di codice prima che io modificassi l'ultima linea (NormalizeDouble)? Vedo che ci sono stati solo 3 minuti dal mio post al tuo, e l'ho modificato quasi immediatamente.
 
Max Enrik: Sto usando NormalizeDouble per i miei EA. Ma mi preoccupo del messaggio'NormalizeDouble', ma vedo la dimensione del lotto sul grafico in questo modo: 0.07

Quindi, ho bisogno di un buon consiglio, per favore.

02:00:00.069 - custom expert EURUSD,H1: | _lotSize - NormalizeDouble: 0.07000000000000001
02:00:00.069 - custom expert EURUSD,H1: | _lotSize - DoubleToString : 0.07
  1. NormalizeDouble restituisce un doppio. La virgola mobile ha un numero infinito di decimali, è il tuo non capire la virgola mobile e che alcuni numeri non possono essere rappresentati esattamente. (come 1/10.) Formato in virgola mobile a doppia precisione - Wikipedia, l'enciclopedia libera Vedi anche L'operando ==. - MQL4 forum
  2. NON usare NormalizeDouble, MAI. Per nessuna ragione. È un trucco, non usarlo. Il suo uso è sempre sbagliato
 
whroeder1:
  1. NON usareNormalizeDouble, MAI. Per nessuna ragione. È un trucco, non usarlo. Ilsuo uso è sempre sbagliato

Credo che tu abbia ancora bisogno di NormalizeDouble().

Ecco un esempio, usando il tuo frammento di codice (lo stesso vale per il mio esempio usando MathFloor):

double NormalizeLots(double lots, string pair=""){
    if (pair == "") pair = Symbol();
    double  lotStep     = MarketInfo(pair, MODE_LOTSTEP),
            minLot      = MarketInfo(pair, MODE_MINLOT);
    lots                = MathRound(lots/lotStep) * lotStep;
    if (lots < minLot) lots = 0;    // or minLot
    return(lots);
}

Chiamato:

Print(NormalizeLots(2/3.0));

Risultato:

0.7000000000000001

Ora codice aggiustato:

double NormalizeLots(double lots, string pair=""){
    if (pair == "") pair = Symbol();
    double  lotStep     = MarketInfo(pair, MODE_LOTSTEP),
            minLot      = MarketInfo(pair, MODE_MINLOT);
    lots            = MathRound(lots/lotStep) * lotStep;
    if (lots < minLot) lots = 0;    // or minLot
    return(NormalizeDouble(lots,2));
}

Risultato:

0.7


 

 Result: 0.7000000000000001

Quale parte di "il tuo non capire la virgola mobile e che alcuni numeri non possono essere rappresentati esattamente. (come 1/10.) Formato in virgola mobile a doppia precisione - Wikipedia, l'enciclopedia libera" non era chiara?

NormalizeDouble(0.7, 2) produrrà lo stesso esatto risultato (o forse 0.69999999999999999.)

 
whroeder1:

Quale parte di "il tuo non capire la virgola mobile e che alcuni numeri non possono essere rappresentati esattamente. (come 1/10.) Formato in virgola mobile a doppia precisione - Wikipedia, l'enciclopedia libera" non era chiara?

NormalizeDouble(0.7, 2) produrrà lo stesso identico risultato (o forse 0.69999999999999999.)

Non sto dicendo che NormalizeDouble() è necessario per un OrderSend valido. Ecco perché il mio primo frammento di codice lo escludeva. Né sono poco chiaro sul modo in cui sono rappresentati i numeri in virgola mobile.

Ho modificato lo snippet per includerlo perché sentivo che indirizzava meglio la mia comprensione del problema dell'OP (essenzialmente un problema di visualizzazione, che può essere risolto sia usando NormalizeDouble() nel codice del "normalizzatore del lotto", sia usando printf o DoubleToStr quando il valore deve essere visualizzato).

Forse ho frainteso l'OP.

02:00:00.069 - custom expert EURUSD,H1: | _lotSize - NormalizeDouble: 0.07000000000000001
02:00:00.069 - custom expert EURUSD,H1: | _lotSize - DoubleToString : 0.07

(editato per rimuovere inutili tersità)

 
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- get minimum stop level
   double minstoplevel=MarketInfo(Symbol(),MODE_STOPLEVEL);
   Print("Minimum Stop Level=",minstoplevel," points");
   double price=Ask;
//--- calculated SL and TP prices must be normalized
   double stoploss=NormalizeDouble(Bid-minstoplevel*Point,Digits);
   double takeprofit=NormalizeDouble(Bid+minstoplevel*Point,Digits);
//--- place market order to buy 1 lot
   int ticket=OrderSend(Symbol(),OP_BUY,1,price,3,stoploss,takeprofit,"My order",16384,0,clrGreen);
   if(ticket<0)
     {
      Print("OrderSend failed with error #",GetLastError());
     }
   else
      Print("OrderSend placed successfully");
//---
  }

Questo potrebbe confondere le persone perché la documentazione di MQL4 usa la funzione NormalizeDouble() nella maggior parte degli esempi.

Arriva persino ad avvertire che il prezzo non normalizzato non può essere applicato:

Nota

All'apertura di un ordine di mercato (OP_SELL o OP_BUY), solo gli ultimi prezzi di Bid (per la vendita) o Ask (per l'acquisto) possono essere usati come prezzo aperto. Se l'operazione viene eseguita con un titolo diverso da quello corrente, bisogna utilizzare la funzione MarketInfo() con il parametro MODE_BID o MODE_ASK per ottenere le ultime quotazioni di questo titolo.

Il prezzo calcolato o non normalizzato non può essere applicato. Se non c'è stato il prezzo aperto richiesto nel thread del prezzo o non è stato normalizzato secondo la quantità di cifre dopo la virgola, si genera l'errore 129 (ERR_INVALID_PRICE). Se il prezzo aperto richiesto è completamente scaduto, verrà generato l'errore 138 (ERR_REQUOTE) indipendentemente dal parametro slippage. Se il prezzo richiesto non è aggiornato, ma presente nel thread, l'ordine verrà aperto al prezzo corrente e solo se il prezzo corrente si trova all'interno dell'intervallo prezzo+-slippage.

E anche in alcuni dei migliori libri sul MQL lo usano abbastanza pesantemente.

Potrebbe dipendere dalla sua applicazione, un problema di visualizzazione è meno drammatico dei fallimenti di ordini o modifiche.

Personalmente ho sempre convertito a valori interi interi, quindi raramente ho a che fare con questo problema.