Un po' sorpreso :) Ho pensato di condividere e fare una domanda NON retorica. - pagina 23

 
Urain:

Avete intenzione di dividere uno (non necessariamente un multiplo di 2) per un altro (non necessariamente un multiplo di 2) con uno spostamento di bit?

Ok, vi butto dentro quello che ho, e poi potete decidere da soli se ne avete bisogno o no.

Joseph Stein (1961):

gcd(n,0) = gcd(0, n) = n

gcd(n,n) = n

gcd(2n,2m) = 2gcd(n, m)

gcd(2n,2m + 1) = gcd(n, 2m + 1)

gcd(2n + 1, 2m) = gcd(2n + 1, m)

gcd(2n + 1, 2(n + k) + 1) = gcd(2(n + k) + 1, 2n + 1) = gcd(2n + 1, k)

--

Due conferenze del creatore di STL Alexander Stepanov su Yandex

// Sul tema del calcolo del NOD - seconda lezione. Ma suggerisco di vedere/ascoltare entrambi. Belle conferenze, uomo intelligente, semplicemente simpatico. Sì, e utile.
File:
gcd_ru.zip  365 kb
 
MetaDriver:
Se con spostamenti di bit, vai avanti. Se con la divisione modulo, no.

Dividendo per offset successivi

cifre interessanti alla fine dell'articolo:

Questo algoritmo verrà eseguito nel caso peggiore in (n-1)! iterazioni, dove n è la profondità di bit del divisibile. In sintesi, rispetto all'algoritmo di addizione sequenziale, questo algoritmo produce un guadagno fino a 9 volte per i numeri a 8 bit, e fino a 546 volte per i numeri a 16 bit.

 

Ecco cosa ho ottenuto:

long gcd(long m, long n) 
{
  if (m<0) m=-m; 
  if (n<0) n=-n;
  if (m==0) return n; 
  if (n==0) return m;
  int d = 0;
  while ((m & 1)==0 && (n & 1)==0) { m >>= 1; n >>= 1; ++d; }
  while ((m & 1)==0) m >>= 1;
  while ((n & 1)==0) n >>= 1;
  while (m!=n)   //  while (true)  // старый вариант 
    if (m < n) 
    {
      n -= m;
      do  n >>= 1;  while ((n & 1)==0);
    } 
    else       // if (n < m) это теперь без надобности
    {
      m -= n;
      do  m >>= 1;  while ((m & 1)==0);
    } 
//    else break;  // старый вариант
    return (m <<= d);
}

sembra funzionare bene. per favore, prova tutti i fori.

// modificato, è più bello così.
File:
gcd.zip  1 kb
 

È strano, non è molto veloce.

2011.04.03 22:56:59 gcdSpeedTest (EURUSD,M20) Tempo comune GreatestCommonDivisor(random(),random()) = 7656ms; // 10000000 chiamate
2011.04.03 22:56:51 gcdSpeedTest (EURUSD,M20) Tempo comune gcd(random(),random()) = 5234ms; // 10000000 chiamate

File:
gcd.zip  2 kb
 
MetaDriver:

È strano, non è molto più veloce.

2011.04.03 22:56:59 gcdSpeedTest (EURUSD,M20) Tempo comune GreatestCommonDivisor(random(),random()) = 7656ms; // 10000000 chiamate
2011.04.03 22:56:51 gcdSpeedTest (EURUSD,M20) Tempo comune gcd(random(),random()) = 5234ms; // 10000000 chiamate

Ho una differenza maggiore. Il tuo è 3-4 volte più veloce, ma non dimenticare che in C++ la differenza si riduce di un fattore 2-2,5, quindi sei onestamente 1,5 volte più veloce.

void OnStart()
  {
//---
   int total=1000000;
   long x=2*3*5*7*9*11*13*17*19*21*23*29;
   long m=55*x,n=34*x;
   uint start=GetTickCount();
   for(int i=0;i<total;i++)x=gcd(m,n);      
   Print("MetaDriver gcd time=",GetTickCount()-start," x=",x);
   start=GetTickCount();
   for(int i=0;i<total;i++)x=GreatestCommonDivisor(m,n); 
   Print("Urain       GCD time=",GetTickCount()-start," x=",x);
  }
2011.04.03 22:35:41     Черновик 30 (EURUSD,M1) Urain       GCD time=1313 x=1222772020470
2011.04.03 22:35:40     Черновик 30 (EURUSD,M1) MetaDriver  gcd time= 312 x=1222772020470
 
Urain:

Ho una differenza maggiore. Il tuo è 3-4 volte più veloce,

ma non dimenticate che in C++ la differenza si riduce di 2-2,5 volte, quindi siete onestamente avanti di 1,5 volte.


E vedremo.

Finora abbiamo una versione preliminare in mql5. Test amichevoli, alla ricerca di bug.

L'ho fatto come struttura.

struct Rational
  {
   long              n;
   long              m;
   void ErrDZ() { Print("Rational error: zero-denominator!"); }
   void Neg() { n=-n; }
   void Norm() { long d=gcd(n,m); n/=d; m/=d; if (m<0) { n=-n; m=-m; } }
   void Assign(long a,long b) { if (b==0) { n=0; m=1; ErrDZ(); } if (b<0) { n=-a; m=-b; } else { n=a; m=b; } }
   void nAssign(long a,long b) { Assign(a,b); Norm(); }
   void Assign(long a) { Assign(a,1); }  // {n=a;m=1;}
   void Add(Rational &a) { if(m==a.m) n+=a.n; else { n*=a.m; n+=m*a.n; m*=a.m; } }
   void nAdd(Rational &a) { Add(a); Norm(); }
   void Add(long a) { n+=a*m; }
   void nAdd(long a) { Add(a); Norm(); }
   void Sub(Rational &a) { if(m==a.m) n-=a.n; else { n*=a.m; n-=m*a.n; m*=a.m; } }
   void nSub(Rational &a) { Sub(a); Norm(); }
   void Sub(long a) { n-=a*m; }
   void nSub(long a) { Sub(a); Norm(); }
   void Mul(Rational &a) { n*=a.n; m*=a.m; }
   void nMul(Rational &a) { Mul(a); Norm(); }
   void Mul(long a) { n*=a; }
   void nMul(long a) { Mul(a); Norm(); }
   void Div(Rational &a) { n*=a.m; m*=a.n; }
   void nDiv(Rational &a) { Div(a); Norm(); }
   void Div(long a) { m*=a; }
   void nDiv(long a) { Div(a); Norm(); }
   string ToString() {return "("+IntegerToString(n)+"/"+IntegerToString(m)+")";}
  };

Ho fatto tutte le operazioni in due forme - con e senza normalizzazione. Ho ottenuto una struttura flessibile.

Se si sospetta la possibilità di overflow - si usa una versione con normalizzazione, senza paura - si risparmia tempo (la normalizzazione può essere fatta dopo, quando la schiuma si è accumulata).

C'è un semplice test in archivio, ma è auspicabile un test più difficile.

File:
 
IgorM:

grazie almeno ammettilo - hai tagliato le emoticon, ma chi rimuove interi post?

A proposito di questo, accademico, Penso che sia fantastico che tu abbia un cosiddetto "calcolatore", ma vorrei chiarire se è possibile ottimizzarlo automaticamente nel corso del trading?

Sì, è solo un programma, se lo eseguite, funzionerà e vi darà i parametri ottimali.
 
Un controllo dell'EMA sarebbe una buona idea.
 

Specialmente per questo thread ho pubblicato gli ultimi risultati del tester MT5 (chiunque sarà in grado di ripetere i test dopo il prossimo aggiornamento).

Questo è ciò che il tester MetaTrader 5 può fare, e ancora di più con un layout completo dell'infrastruttura (rapporti, grafici, risultati, visualizzazione).

 
Renat:

Specialmente per questo thread ho pubblicato gli ultimi risultati del tester MT5 (chiunque sarà in grado di ripetere i test dopo il prossimo aggiornamento).

Questo è quello che il tester MetaTrader 5 può fare, e anche con un layout completo (rapporti, grafici, risultati, visualizzazione).

7 simboli, tutti i tick, dal 2000, due parametri ( varianti 200 * 200 )- 40000 passaggi, con un centinaio di ordini al giorno per ogni simbolo.

Quanto tempo ci vuole?

prendere 10 anni - 356 * 10 * 100 * 7 = 25 000 000 offerte

prendiamo circa 10 tick al minuto

e 10 anni - 365 * 10 * 1440 * 10 = 52 000 000 tick su un simbolo. E se vogliamo essere onesti, ticchettano su ogni simbolo, quindi, onestamente, dovremmo moltiplicare per altri 7. E non sono 10 tick al minuto. E a volte sono 300.


Quanto tempo ci vuole?