![MQL5 - Linguaggio delle strategie di trading integrato nel client terminal MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
Ti stai perdendo delle opportunità di trading:
- App di trading gratuite
- Oltre 8.000 segnali per il copy trading
- Notizie economiche per esplorare i mercati finanziari
Registrazione
Accedi
Accetti la politica del sito e le condizioni d’uso
Se non hai un account, registrati
Simpleton, ho seguito la stessa strada, ma ho usato la conversione esplicita al tipo int. Ho supposto che la dimensione massima possibile del lotto sarà limitata o dal broker/dealer, o dalla dimensione dei miei fondi. Quindi usare int dovrebbe essere sufficiente. Pensi che ci siano delle insidie in questo approccio (arrotondare dal basso usando int)?
Per il commercio reale, probabilmente, sì, int/uint è sufficiente.
Ma se si esegue in un tester, potrebbe non essere sufficiente per alcuni esperimenti.
Non ci sono insidie, oltre a possibili glitch successivi nell'implementazione di MQL5, quando si usa int, se possiamo garantire che l'intero N dalla formula cadrà nell'intervallo 0...INT_MAX e quindi non traboccherà. Cioè, sostituire il controllo
tmp < ULONG_MAX * stepvol
a
tmp < INT_MAX * stepvol
In realtà il tipo int è firmato e la metà dei suoi possibili valori si trova nell'area dei numeri negativi, mentre qui saranno sempre non negativi. È irrazionale usare int quando c'è un unsigned uint che ha la stessa dimensione ma il doppio del range nell'area non negativa. Pertanto, se abbiamo intenzione di usare int/uint, è meglio usare uint e sostituire il controllo con uint, rispettivamente:
tmp < UINT_MAX * stepvol
gumgum:
#property script_show_inputs
Per il commercio reale, molto probabilmente sì, int/uint è sufficiente.
...In realtà, il tipo int è firmato, la metà dei suoi possibili valori si trova nell'area dei numeri negativi, e qui sarà sempre non negativo. È irrazionale usare int, quando c'è un unsigned uint che ha la stessa dimensione ma il doppio del range nell'area non negativa. Pertanto, se abbiamo intenzione di usare int/uint, è meglio usare uint e sostituire il controllo con uint, rispettivamente:
Non è un bug, ma un'osservazione interessante sui tipi
Cosa pensi che sia 2 volte 2, cioè 2*2?
pensi 4 forse hai ragione!
OK, che ne dici di questo
duecentomila volte duecentomila
200000 * 200000
Qualsiasi scolaro può moltiplicare i due e i quattro e aggiungere gli zeri e ottenere...
40000000000.
Ora scriviamo un semplice codice nel linguaggio della macchina.
lotti lunghi = 200000*200000;
notate che il tipo di host della variabile è lungo, cioè
Il valore minimo è -9 223 372 036 854 775 808; il valore massimo è 9 223 372 036 854 775 807.
Stampa il totale e ottieni
lotti = 1345294336
che è molto diverso da due volte due e otterrete due.
Ho riletto la sezione di aiuto sui tipi e le conversioni di tipo.
Non ho trovato alcuna informazione che i numeri regolari devono essere esplicitamente castati al tipo giusto
quindi è così che dovrebbe essere
lotti lunghi = (lungo) 200000 * (lungo) 200000;
In alternativa, è possibile utilizzare ulteriori variabili ausiliarie.
C'è di più.
Se volete recuperare e moltiplicare per grandi numeri alcune proprietà....
Ecco il codice
Ed ecco il risultato
gli input sono gli stessi, ma il risultato è diversoSHOOTER777:
E ora un semplice codice in linguaggio macchina
lotti lunghi = 200000*200000;
Notate che il tipo ricevente della variabile long è long, cioè
Il valore minimo è -9 223 372 036 854 775 808, il valore massimo è 9 223 372 036 854 775 807.
Stampa il totale e ottieni
lotti = 1345294336
che è molto diverso da due volte due e otterrete due.
Ho riletto la sezione di aiuto sui tipi e le conversioni di tipo.
Non ho trovato alcuna informazione sul fatto che si debbano castare esplicitamente i numeri regolari in un certo tipo.
quindi è così che dovrebbe essere
lotti lunghi = (lungo) 200000 * (lungo) 200000;
In alternativa, potete anche usare variabili ausiliarie.
I "numeri ordinari" sono espressioni costanti che hanno anche un tipo. In questo caso, è il tipo int.
L'espressione che consiste nella moltiplicazione di due sottoespressioni, ciascuna delle quali è di tipo int, è anch'essa di tipo int. È qui che si verifica l'overflow.
E solo allora la conversione implicita dal tipo dell'espressione int al tipo long avviene durante l'inizializzazione della variabile di tipo long.
Qui tutto è chiaro. A proposito, ciascuno degli operandi in questo caso non ha bisogno di essere castato al tipo lungo. È sufficiente lanciarne uno, e il secondo sarà lanciato implicitamente.
C'è di più.
Se volete recuperare e moltiplicare per grandi numeri alcune proprietà....
Ecco il codice
Ed ecco il risultato.
I dati di partenza sono gli stessi, ma il risultato è diverso.Sembra che il registro e il codice siano confusi. Il codice di cui sopra funziona "pulito". E, per ottenere un tale registro, ho dovuto rendere le variabili A e B di tipo int o uint, e la variabile X di tipo uint:
Ed ecco come funziona il codice originale:
Build 314 (20 agosto 2010).
Potete dirmi, per esempio, se voglio ottenere il valore di qualche indicatore. Lo ottenevo esattamente e con certezza usando la funzione built-in. Ora devo scriverlo da solo usando un mucchio di codice, buffer, handle, ecc. Ma non è questo il punto. La cosa principale per me è che il codice diventa glitch letteralmente su ogni linea, perché devo controllare ogni linea di codice per assicurarmi che non si sia verificato alcun errore... In generale, pensavo che tutte queste complessità, classi e cose che erano elementari ma che diventavano ingombranti e scomode fossero fatte per aumentare la velocità, l'affidabilità, ecc. Ho letto un articolo su 20 segnali... c'è scritto:
"Non potete accedere ai dati dell'indicatore subito dopo la sua creazione, poiché ci vuole un po' di tempo per calcolare i valori dell'indicatore, quindi è meglio creare gli handle dell'indicatore in OnInit()".
Poi ci sono controlli per ogni linea
"Controlliamoli: se ci sono meno dati di quelli di cui abbiamo bisogno, significa che si è verificato un errore di copia e un ulteriore accesso all'array, dove i dati dovrebbero essere memorizzati, porterà a un errore. Per escludere questo, abbandoneremo la funzione".
Così, invece di accelerare, devo fare un ciclo (quante volte?) attraverso questa funzione per ottenere un risultato alla fine... E se ho bisogno di valori individuali di linee separate di indicatori diversi periodicamente... Questa è una funzione separata per ogni valore... Sono un sacco di variabili e codice extra...
Insomma, spiegatemi, datemi un link, voglio capire il senso di tutto questo, perché è così e non così affidabile...
E sarebbe bene che le risposte a tali domande potessero essere messe nella sezione di aiuto alla migrazione da µl4 a µl5 o creare una sezione apposita sul forum, senza alcuna discussione, in particolare una domanda e risposta, con una spiegazione del perché è così... per esempio, il periodo è spiegato qui in modo molto accessibile, e allo stesso modo vorremmo avere risposte a domande elementari
Potete dirmi, per esempio, se voglio ottenere il valore di qualche indicatore. Lo ottenevo esattamente e con certezza usando la funzione built-in. Ora devo scriverlo da solo usando un mucchio di codice, buffer, handle, ecc. Ma non è questo il punto. La cosa principale per me è che il codice diventa glitch letteralmente su ogni linea, perché devo controllare ogni linea di codice per assicurarmi che non si sia verificato alcun errore... In generale, pensavo che tutte queste complessità, classi e cose che erano elementari ma che diventavano ingombranti e scomode fossero fatte per aumentare la velocità, l'affidabilità, ecc. Ho letto un articolo su 20 segnali... c'è scritto:
"Non potete accedere ai dati dell'indicatore subito dopo la sua creazione, poiché ci vuole un po' di tempo per calcolare i valori dell'indicatore, quindi è meglio creare gli handle dell'indicatore in OnInit()".
Poi ci sono controlli per ogni linea
"Controlliamoli: se ci sono meno dati di quelli di cui abbiamo bisogno, significa che si è verificato un errore di copia e un ulteriore accesso all'array, dove i dati dovrebbero essere memorizzati, porterà a un errore. Per escludere questo, abbandoneremo la funzione".
Così, invece di accelerare, devo fare un ciclo (quante volte?) attraverso questa funzione per ottenere un risultato alla fine... E se ho bisogno di valori individuali di linee separate di indicatori diversi periodicamente... Questa è una funzione separata per ogni valore... Sono un sacco di variabili e codice extra...
Insomma, spiegatemi, datemi un link, voglio capire il senso di tutto questo, perché è così e non così affidabile...
E sarebbe bene che le risposte a tali domande potessero essere messe nella sezione di aiuto alla migrazione da µl4 a µl5 o creare una sezione apposita sul forum, senza alcuna discussione, nello specifico una domanda e risposta, con una spiegazione del perché è così... per esempio, il periodo è spiegato qui in un modo molto accessibile, quindi sarebbe bene avere risposte a domande elementari nello stesso modo
È più affidabile? Perché è inaffidabile ottenere gli handle all'inizializzazione? Perché non è affidabile controllare la disponibilità dei dati richiesti? E inoltre, perché non è affidabile avere dei controlli?
Potrebbe non essere così facile per i principianti, ma con il tempo diventerà chiaro...
Più affidabile? Perché ottenere gli handle all'inizializzazione non è affidabile? Perché è inaffidabile controllare i dati necessari? E ancora di più, perché avere dei controlli non è affidabile?
Potrebbe non essere così semplice per i neofiti, ma diventerà chiaro col tempo...