Errori, bug, domande - pagina 442

 
voix_kas:

Qualcuno ha del codice pronto per calcolare il numero di cifre significative per un volume?
Qualcosa come SymbolInfoInteger(_Symbol, SYMBOL_DIGITS), ma solo per il volume.
Per esempio, per il caso SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_STEP) = "1.0" - la risposta sarebbe "0", per "0.1" - "1", per "0.01" - "2" ecc.

Permettetemi di chiarire una sfumatura. Per un passo di volume come "0.1", "0.01", "0.001" ho.

Il codice dovrebbe funzionare per i seguenti casi: "0.2", "0.11", 0.023" ecc.

Non esiste un codice specificoper il volume. C'è per qualsiasi cosa.

int CountSignedDigits(double x)
{  
  for(int i=0; i<1000; i++,x*=10) if(x-MathFloor(x)<DBL_MIN*2) return i;
  return -1;
}
La sceneggiatura è da controllare nel rimorchio.
File:
_UniTest.mq5  2 kb
 
MetaDriver:
Uno script da controllare nel trailer.
Vuoi dire che..., ho pensato di controllare il lotto accettabile prima di fare un ordine.
 
sergeev:
Vuoi dire che..., e ho pensato che avrei dovuto controllare il lotto ammissibile prima di fare un ordine.

;)

Non so davvero cosa voglia. Vedremo cosa dice, sto solo esercitando la mia telepatia. ;)

 
voix_kas:

Qualcuno ha del codice pronto per calcolare il numero di cifre significative per un volume?
Qualcosa come SymbolInfoInteger(_Symbol, SYMBOL_DIGITS), ma solo per il volume.
Per esempio, per il caso SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_STEP) = "1.0" - la risposta sarebbe "0", per "0.1" - "1", per "0.01" - "2" ecc.

Permettetemi di chiarire una sfumatura. Per un passo di volume come "0.1", "0.01", "0.001" ho.
Il codice dovrebbe funzionare per i seguenti casi: "0.2", "0.11", 0.023" ecc.

Specificamente per i volumi può essere semplice:

      int N=0;
      double step=SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP);
      if(step-1.0<0)  N++;
      if(step-0.1<0)  N++;
      if(step-0.01<0) N++;
[Eliminato]  

sergeev
MetaDriver
Valmars

Una domanda ben formulata è metà della risposta. :) Scusa, sono già andato a letto, non sono riuscito a descrivere accuratamente il compito. Proverò di nuovo.

Sto parlando di passare un volume normalizzato a un ordine commerciale.
È quello che facciamo con il prezzo:

MqlTradeRequest TradeRequest;
...
TradeRequest.volume = NormalizeDouble(Volume, GetVolumeDigits(_Symbol));
TradeRequest.price  = NormalizeDouble(Price, SymbolInfoInteger(_Symbol, SYMBOL_DIGITS));
...

Normalizzazione dei prezzi - penso che sia chiaro a tutti.

Ai miei tempi (da MT4), ho letto da qualche parte negli articoli di MT che sarebbe auspicabile normalizzare anche il volume.
In realtà, ho scritto la funzioneGetVolumeDigits(string Symbol) per trovare il più piccolo valore possibile di volume secondo le condizioni del broker. Ci sono almeno due implementazioni (il risultato è lo stesso):
Attuazione #1.

int GetVolumeDigits(string Symbol) {
  int VolumeDigits = 0;
  double VolumeStep = SymbolInfoDouble(Symbol, SYMBOL_VOLUME_STEP);
  while (VolumeStep < 1) {
    VolumeStep *= 10;
    VolumeDigits++;
  }
  return VolumeDigits;
}
Attuazione №2.

int GetVolumeDigits(string Symbol) {
  return (int)MathLog10(1.0 / SymbolInfoDouble(Symbol, SYMBOL_VOLUME_STEP));
}

Entrambi funzionano perfettamente per le varianti con passo min = 1,0, 0,1, 0,01, 0,001, ecc. Cioè, se il passo minimo è 1,0, la funzione restituirà 0; se il passo è 0,1, la funzione restituirà 1, ecc.
E se il passo minimo è 1,1, o 0,11, o 0,011, per esempio? Questo algoritmo mostrerà erroneamente la cifra meno significativa.
Naturalmente, si può affermare che non ci sono questi casi nella pratica. Voglio solo considerare tale possibilità ipotetica nel mio Expert Advisor. Ho pensato che forse qualcuno potrebbe condividere la sua esperienza in materia...

 
voix_kas:
Sì, ho capito, ho bisogno che il risultato sia un multiplo di VolumeStep. Beh, non ha niente a che fare con le cifre, prima calcola il volume con le cifre e poi riducilo al multiplo più vicino di VolumeStep.
 
voix_kas:

Si tratta di inviare il volume normalizzato all'ordine di compravendita.
Voglio solo considerare questa possibilità ipotetica nel nostro Expert Advisor.

di quale strumento "ipotetico" stiamo parlando?

1. La variante di MetaDriver è adatta a voi. CountSignedDigits mostrerà il numero di caratteri in qualsiasi lotto.

2. Conoscendo il numero di cifre si può fare la normalizzazione:

double MinLot; // минимальный лот по символу
double MaxLot; // максимальный лот по символу
double LotStep; // шаг лота по символу
int dig; // знаковость лота узнали из функции CountSignedDigits

double NL(double lot)
{
  if (lot<=MinLot) return(MinLot); // проверка на минимальный
  double d=MathFloor((lot-MinLot)/StepLot); // сколько ЦЕЛЫХ шагов умещается в проверяемом лоте
  lot=MinLot+StepLot*d; // рассчитали по этому целому числу
  lot=MathMin(lot, MaxLot);  lot=NormalizeDouble(lot, dig);// не забыли проверить на максимальный // нормализовали
  return(lot); // вернули
}
[Eliminato]  

sergeev
Grazie per la funzione di convalida del lotto. Sto usando una costruzione/raccordo di assegni simile.
La mia domanda è focalizzata sulla ricerca del posto più giovane nel lotto, per normalizzarlo.
In particolare, MetaDriver ha dato la sua costruzione per "tutto". :) Tuttavia, non è senza difetti (o il mio compilatore è difettoso). Di seguito il codice e il risultato dell'esecuzione:

void OnStart() {
  Print(CountSignedDigits(110.0));
  Print(CountSignedDigits(11.0));
  Print(CountSignedDigits(1.1));
  Print(CountSignedDigits(0.11));
  Print(CountSignedDigits(0.011));
  Print(CountSignedDigits(0.0011));
  Print(CountSignedDigits(0.00011));
}

int CountSignedDigits(double x) {  
  for (int i = 0; i < 1000; i++, x *= 10)
    if (x - MathFloor(x) < DBL_MIN * 2)
      return i;
  return -1;
}

Risultato:

2011.07.03 13:15:21     test (EURUSD,M5)        5
2011.07.03 13:15:21     test (EURUSD,M5)        4
2011.07.03 13:15:21     test (EURUSD,M5)        18      -    Здесь только у меня бяка вылазиет?
2011.07.03 13:15:21     test (EURUSD,M5)        2
2011.07.03 13:15:21     test (EURUSD,M5)        1
2011.07.03 13:15:21     test (EURUSD,M5)        0
2011.07.03 13:15:21     test (EURUSD,M5)        0

L'opzione successiva (la funzione CountSignedDigits è la stessa):

void OnStart() {
  double value = 110.0;
  int count = 9;
  while (count) {
    Print(DoubleToString(value), " - ", CountSignedDigits(value));
    value /= 10;
    count--;
  }
}

Risultato:

2011.07.03 13:23:32     test (EURUSD,M5)        0.00000110 - 22       -   Почему-то здесь бяка...
2011.07.03 13:23:32     test (EURUSD,M5)        0.00001100 - 21       -
2011.07.03 13:23:32     test (EURUSD,M5)        0.00011000 - 5
2011.07.03 13:23:32     test (EURUSD,M5)        0.00110000 - 4
2011.07.03 13:23:32     test (EURUSD,M5)        0.01100000 - 3        - Здесь уже все нормально. Почему результаты разные?!
2011.07.03 13:23:32     test (EURUSD,M5)        0.11000000 - 2
2011.07.03 13:23:32     test (EURUSD,M5)        1.10000000 - 1
2011.07.03 13:23:32     test (EURUSD,M5)        11.00000000 - 0
2011.07.03 13:23:32     test (EURUSD,M5)        110.00000000 - 0
[Eliminato]  

Modificata la seguente linea in OnStart:

double value = 210.0;

Risultato:

2011.07.03 13:28:01     test (EURUSD,M5)        0.00000021 - 23
2011.07.03 13:28:01     test (EURUSD,M5)        0.00000210 - 22
2011.07.03 13:28:01     test (EURUSD,M5)        0.00002100 - 21
2011.07.03 13:28:01     test (EURUSD,M5)        0.00021000 - 20
2011.07.03 13:28:01     test (EURUSD,M5)        0.00210000 - 19
2011.07.03 13:28:01     test (EURUSD,M5)        0.02100000 - 3
2011.07.03 13:28:01     test (EURUSD,M5)        0.21000000 - 2
2011.07.03 13:28:01     test (EURUSD,M5)        2.10000000 - 1
2011.07.03 13:28:01     test (EURUSD,M5)        21.00000000 - 0
2011.07.03 13:28:01     test (EURUSD,M5)        210.00000000 - 0

O sto facendo qualcosa di sbagliato (per favore correggete), o MetaDriver ha fatto un errore in teoria (quando ha progettato l'algoritmo).

 
voix_kas:

La mia domanda è incentrata sulla determinazione del luogo più basso del lotto per normalizzarlo.

Non c'è bisogno di definire lo scavo per il lotto, basta normalizzarlo al passo giusto:
   lot = NormalizeDouble( lot / lot_step, 0 ) * lot_step;
   if ( lot < lot_min ) lot = lot_min;
   if ( lot > lot_max ) lot = lot_max;


Anche se quando si invia una richiesta di compravendita, il lotto variabile diventerà spazzatura (nella seconda posizione decimale), sarà rifiutato dal terminale stesso.

Almeno, non ho avuto alcun problema durante diversi anni di utilizzo di questo design.


E se vuoi riassicurare, puoi normalizzarlo all'ottavo decimale (con riserva) - se dopo la normalizzazione "corretta" appare la spazzatura, sarà molto più lontano.

Документация по MQL5: Стандартные константы, перечисления и структуры / Структуры данных / Структура торгового запроса
Документация по MQL5: Стандартные константы, перечисления и структуры / Структуры данных / Структура торгового запроса
  • www.mql5.com
Стандартные константы, перечисления и структуры / Структуры данных / Структура торгового запроса - Документация по MQL5