Domande dai principianti MQL5 MT5 MetaTrader 5 - pagina 856

 
Алексей Барбашин:

Hmmm... Probabilmente non ho guardato molto attentamente l'API, ma non ho visto questa funzione.... E probabilmente sarebbe utile.

Altri suggerimenti... forse la domanda è troppo... ridicola... Come faccio a tradurre un numero, ad esempio doppio, in un array di char? Cioè, in alcune API è richiesto di passare i numeri come puntatore. I puntatori sono passati come array unidimensionali... Con le stringhe capisco, le funzioni StringToShortArray e StringToCharArray sono previste per loro, ma con i numeri non capisco ancora come convertirli in array di byte (char).

Forse qualche esempio?
 
. ... Rick D. ... .:
Forse qualche esempio?

Non andremo abbastanza lontano. Diamo un'occhiata al lavoro con il registro. Il registro può memorizzare sia valori stringa che valori numerici (non come stringa). Passare un numero al registro e ottenere indietro un puntatore ad esso è fatto attraverso gli array (secondo la vostra correzione). Un esempio del genere funzionerebbe?

 
pivomoe:

Studio la storia delle zecche. Non sempre si riesce a capire cosa stava succedendo nel mercato al momento dei tick.

SBER

i=987 2016.06.27 10:00:30.274 Ask=133.91 Bid=133.9 Last=133.9 Vol=50 TICK_FLAG_ASK

i=988 2016.06.27 10:00:30.280 Ask=133.93 Bid=133.9 Last=133.9 Vol=50 TICK_FLAG_ASK

i=989 2016.06.27 10:00:30.280 Ask=133.93 Bid=133.9 Last=133.91 Vol=100 TICK_FLAG_LAST TICK_FLAG_VOLUME TICK_FLAG_BUY TICK_FLAG_SELL

i=990 2016.06.27 10:00:30.280 Ask=133.93 Bid=133.9 Last=133.92 Vol=300 TICK_FLAG_LAST TICK_FLAG_VOLUME TICK_FLAG_BUY TICK_FLAG_SELL

i=991 2016.06.27 10:00:30.280 Ask=133.93 Bid=133.9 Last=133.92 Vol=100 TICK_FLAG_LAST TICK_FLAG_VOLUME TICK_FLAG_BUY TICK_FLAG_SELL

i=992 2016.06.27 10:00:30.281 Ask=133.94 Bid=133.9 Last=133.92 Vol=100 TICK_FLAG_ASK

1. Cos'è questo misterioso tick con i flag simultaneiTICK_FLAG_BUY e TICK_FLAG_SELL? Sono riuscito a trovare tali tick anche con un volume di 1 lotto.

2. Sul tick 988. Ask=133.93 Bid=133.9 Da dove viene l'ultimo 133.91 su 989?

Cosa è successo sul mercato?

Tali domande sono meglio da postare in un thread separato nella sezione "Stock Trading" del forum.

In breve, se vedi che un tick ha una bandiera di acquisto e una di vendita allo stesso tempo, significa che il server del broker non è aggiornato e trasmette operazioni di direzione sconosciuta.

Su quale server guardate i tick?
 
Vladimir Karputov:

Per favore, riscrivi la tua domanda o metti dei segni di punteggiatura, o meglio ancora aggiungi un'immagine di cosa, dove e chi. Altrimenti, vedo lettere familiari, ma non riesco a capire il significato e il tuo pensiero.

Ecco una foto


 
Seric29:

Ecco una foto.


Allora, perché mettere la mia foto (o la cache è pazza?)?

 
Seric29:

Ecco una foto


Chiarire: volete spostare il mouse direttamente nel terminale e copiare il prezzo della POSIZIONE tramite il tasto destro del mouse?

 
Алексей Барбашин:

Non andremo abbastanza lontano. Diamo un'occhiata al lavoro con il registro. Il registro può memorizzare sia valori stringa che valori numerici (non come stringa). Passare un numero al registro e ottenere indietro un puntatore ad esso è fatto attraverso gli array (secondo la vostra correzione). Un esempio come questo potrebbe funzionare?

Ecco fatto. Penso che si possa capire.
File:
TestReg.mq5  33 kb
 
. ... Rick D. ... .:
Ecco a voi. Credo che lo capirete.

Questo è originale! Non ci avevo nemmeno pensato. )))

Seguendo il mio esempio precedente ho cercato di capire cosa causa il crash della memoria e del terminale.

Prima di tutto, ho rifiutato gli array per ottenere puntatori a una sezione del registro aperta. Cioè, ho semplicemente passato uint& phkResult in API. Tutto è andato bene e nessun errore. La documentazione di mql dice che i tipi semplici possono essere passati per riferimento, che, quando si lavora con API, è l'indirizzo della variabile, cioè il puntatore. Tutto ha avuto successo in questa parte. Ho restituito anche i parametri NULL e li ho passati senza usare gli array.

Inoltre, ho lavorato sul passaggio del valore stesso al registro. La descrizione della funzione ha indicato che dovrebbe passare una stringa con uno zero finale alla fine. Questo è esattamente il tipo di stringa, quindi nella prima versione stavo passando solo una variabile. Non avete cambiato questo nella versione precedente basandovi sulla stessa. Ma ho deciso di sperimentare con gli array e ho introdotto l'array ushort e l'ho riempito con il valore necessario. Uno dei parametri quando lo si passa alla funzione

uint RegSetValueExW(uint hKey, string lpValueName, uint Reserved, uint dwType, ushort &lpData[], uint cbData)

è la dimensione dei dati che vengono passati. Nel tuo esempio era così:

uint cbData = (StringLen(value)+1)*2;

Qui tutto è chiaro. Prendiamo la lunghezza della stringa, aggiungiamo uno zero "finale" e moltiplichiamo per 2 byte, per la dimensione ushort;

Ho provato in questo modo:

ushort Data[];

StringToShortArray(valore, dati);

uint cbData = sizeof(Data);

Immaginate la mia sorpresa quando la dimensione dei dati non era uguale a quella dell'esempio precedente!

Ho controllato la dimensione dell'array ed era assolutamente uguale a StringLen(value)+1, ma la dimensione dei dati non era la stessa... Ancora non capisco perché.

Ma non importa.

Il problema originale alla fine era ottenere il valore dal registro, perché stavo passando una variabile stringa per riferimento come puntatore. È qui che si è verificato l'incidente.

"Se passate questa struttura o un riferimento ad essa in una DLL invece della stringa stessa, non potete aspettarvi un risultato corretto - perché la DLL di sistema accetterà sicuramente una stringa onesta con un carattere zero alla fine e non questa struttura" - questa citazione è vecchia di dieci anni, non ha perso la sua rilevanza.

Pertanto, quando si passa qualsiasi valore costante di stringa, come il nome della sezione del registro o il valore del parametro stringa, tutto è corretto. E quando si passa una variabile stringa per riferimento, come ho fatto io, porta al problema indicato nella citazione. )))

E per quanto riguarda la dimensione ricevuta, c'è un esempio nella documentazione API, quando in caso di errore "ci sono più dati" aumentiamo la dimensione del buffer di ricezione nel ciclo e otteniamo nuovamente i dati.

Quindi va così.

Grazie ancora per l'aiuto! )))


 
Алексей Барбашин:

Questo è originale! Non ci avevo nemmeno pensato. )))

L'Unione è comoda da usare. Non devi pensare dove sia il byte alto e dove sia il byte basso. L'unione può essere usata anche per REG_BINARY. Tu descrivi la tua struttura di dati. E lo aggiungi in Union insieme a un array di byte per dimensione della struttura. Ma penso che non ne abbiate davvero bisogno. Qualsiasi dato può essere convertito in una stringa e memorizzato come tale.

A giudicare dall'esempio precedente, ho cercato di capire cosa ha causato esattamente il crash della memoria e del terminale.

Forse perché lo stack stava volando, potresti aver specificato long invece di int nella descrizione della funzione.

La documentazione di mql dice che i tipi semplici possono essere passati per riferimento, che quando si lavora con API è l'indirizzo di una variabile, cioè un puntatore.

Puoi scaricare un link a questa sezione della documentazione?

uint cbData = sizeof(Data);

Hai bisogno di uint cbData = ArraySize(Data) * 2 se passi un array ushort.

e uint cbData = ArraySize(Data) se si passa un array uchar.

Nell'ultimo esempio passo un array uchar come parametro della funzione API, per una piena compatibilità con LPBYTE lpData di Wind.

È corretto. Ma aggiunge confusione per convertire tutti i dati in un array di byte.

E per quanto riguarda la dimensione ricevuta, la documentazione API dà un esempio, dove in caso di errore "ci sono più dati" aumentiamo la dimensione del buffer ricevuto nel ciclo e riceviamo nuovamente i dati.

Date un'occhiata all'ultimo codice. Lì nell'implementazione arriva prima una richiesta per ottenere la dimensione dei dati, poi viene impostata la dimensione dell'array, poi vengono presi tutti i dati nella loro interezza.

 
. ... Rick D. ... .:

L'Unione è comoda da usare. Non c'è bisogno di pensare dove sia il byte alto e dove sia il byte basso. Potete usare Union anche per REG_BINARY. Tu descrivi la tua struttura di dati. E lo aggiungi in Union insieme all'array di byte per dimensione della struttura. Ma penso che non ne abbiate davvero bisogno. Qualsiasi dato può essere convertito in una stringa e memorizzato come tale.

Forse anche perché lo stack stava volando, avete specificato long invece di int nella descrizione della funzione.

Puoi scaricare un link a questa sezione della documentazione?

Hai bisogno di uint cbData = ArraySize(Data) * 2 se passi un array ushort.

e uint cbData = ArraySize(Data) se si passa un array uchar.

Nell'ultimo esempio, passo l'array uchar come parametro di una funzione API, per una piena compatibilità con il LPBYTE lpData di Windows.

È corretto. Ma aggiunge confusione per convertire tutti i dati in un array di byte.

Date un'occhiata all'ultimo codice. L'implementazione chiede prima la dimensione dei dati, poi imposta la dimensione dell'array, quindi recupera tutti i dati.

Saluti di nuovo!

Spero davvero che la nostra discussione in questo thread sia utile non solo ai neofiti, ma anche ai programmatori esperti.

Che dire di lungo. Sì, è un mio errore, ma era l'int che veniva usato all'inizio. Ho usato Long perché sto usando un terminale a 64 bit. Ma tutto funziona bene con int.

Sui puntatori. Penso che i seguenti articoli descrivano tutto molto bene:https://www.mql5.com/ru/docs/basis/types/this,https://www.mql5.com/ru/docs/runtime/imports.

Ammetto anche il mio errore con sizeof. Stiamo usando un array dinamico per lo scambio, mentre per gli array dinamici sizeof restituisce semplicemente la dimensione dell'array stesso invece della dimensione dei dati:https://www.mql5.com/ru/docs/basis/operations/other.

Per quanto riguarda l'ottenimento della dimensione completa dei dati. Sì, hai ragione. Infatti, alla prima chiamata la funzione restituisce la dimensione dei dati inseriti nel parametro, quindi si può fare a meno del ciclo di cui ho scritto. Devo aver frainteso la descrizione della funzione qui, perché dice che la variabile restituisce la dimensione dei dati letti.

Torniamo a stringere... In linea di principio, come si è scoperto, quando si ricevono i dati, potremmo passare la variabile per riferimento, ma prima potremmo inizializzarla con qualche valore fino alla lunghezza massima. Questo mi sembra una stampella perché dopo il valore stesso dovrebbe essere tagliato fuori da questa stringa. Ottenere i dati dal buffer dell'array è una variante più ottimale, cioè la nostra soluzione è migliore secondo me ))).

Qui sul passaggio di una stringa come puntatore:https://www.mql5.com/ru/forum/103532/page2#comment_2983919

E Andriy ci parla molto bene del lavoro con dll:https://www.mql5.com/ru/articles/96


Penso che con il vostro aiuto abbiamo coperto interamente l'argomento di lavorare non solo con il registro, ma con le sfumature della libreria API.

La classe di lavoro con il registro è molto utile per lo scambio di dati sia tra strumenti su un grafico che tra grafici e terminali in generale.

Una volta su questo forum hanno detto che usare il registro per questi scopi equivale a piantare chiodi con una lampadina e suggeriscono di usare file virtuali (mappatura). Ma non sono d'accordo, perché prima di scrivere il registro su disco è solo un file virtuale. E quando si usa l'attributo REG_OPTION_VOLATILE il valore sarà sempre virtuale. Ed è molto conveniente memorizzare i dati tra le sessioni nel registro. IMHO.

Документация по MQL5: Основы языка / Типы данных / Ссылки. Модификатор & и ключевое слово this
Документация по MQL5: Основы языка / Типы данных / Ссылки. Модификатор & и ключевое слово this
  • www.mql5.com
В MQL5 параметры простых типов можно передавать как по значению, так и по ссылке, в то время как параметры сложных типов всегда передаются по ссылке. Для указания компилятору на необходимость передачи параметра по ссылке, перед именем параметра ставится знак амперсанда Передача параметра по ссылке означает передачу адреса переменной, поэтому...