ordinamento di una matrice a 2 dimensioni per la seconda dimensione

 

Ho 2 pezzi di dati che ho bisogno di mettere in un array e poi ordinarli.

Per prima cosa divido gli ordini in due array, il primo array è per gli acquisti e l'altro è per le vendite. Quando lo faccio, sto raccogliendo l'OrderTicket così più tardi posso eseguire un'esecuzione sull'ordine. La seconda cosa che sto raccogliendo è il valore OrderClosePrice dell'ordine in modo da poterlo confrontare con un'altra lista esattamente uguale.

Quindi il primo array che ho impostato:

double AryBuys[][2];
doppio ArySells[][2];

AryBuy[1][0] contiene il biglietto, AryBuy[1][1] contiene il prezzo.

Come faccio a ordinare la seconda dimensione in modo da avere l'array ordinato per prezzo decrescente?

Nota: con ArraySort, potete ordinare solo la prima dimensione. Ecco un possibile pensiero, potrei creare un array temporaneo e rendere il prezzo la prima dimensione nell'array temporaneo, ordinarlo, poi reinserirlo nell'array e fare lo stesso al contrario quando avrò bisogno di ordinarlo per biglietto. Funzionerebbe?

 

Non puoi, purtroppo, ma potresti creare un secondo array con i dati delle due dimensioni che si scambiano e ordinare il nuovo array per prezzo (la prima dimensione). Potreste poi (se volete ancora) copiare i dati nell'array originale, ancora una volta scambiando i dati in ogni dimensione. Ora il tuo array originale contiene i dati originali ma è ordinato per i valori della seconda dimensione.

È complicato, ma è l'unico modo pratico (che sono stato in grado di capire) per ottenere i vostri dati ordinati per dimensioni >1

 

Questo è quello a cui ho pensato nei miei appunti. La mia preoccupazione era che la prima dimensione sarebbe stata ordinata, avrebbe riorganizzato anche la seconda dimensione dei dati quando l'ordinamento ha avuto luogo? Immagino che potrei impostare un test per provarlo.

 
LEHayes wrote >>

Questo è quello a cui ho pensato nei miei appunti. La mia preoccupazione era che la prima dimensione sarebbe stata ordinata, avrebbe riorganizzato anche la seconda dimensione dei dati quando ha avuto luogo l'ordinamento? Credo di poter impostare un test per provare questo.


Sì, tutti gli elementi dello stesso indice di base vengono spostati con l'ordinamento della prima dimensione. Proprio come l'ordinamento di un foglio di calcolo contenente più colonne di dati, solo che in MQL si può ordinare solo in base alla prima colonna.
 

Finora, l'ho impostato come discusso. Sono sicuro che lo risolverò entro la fine della conversazione, ma al momento sto ottenendo:
2010.04.15 23:51:01,M1: posizione iniziale 1 non corretta per la funzione ArraySort
All'inizio ho provato in questo modo
ArraySort(AryBuy,WHOLE_ARRAY,0,MODE_DESCEND);
e ho ottenuto lo stesso messaggio solo che il valore di posizione era 0, poi ho cambiato l'inizio (valore di posizione) in 1 per vedere cosa poteva succedere e ho ottenuto quanto sopra.

Gli array dovrebbero avere dati in essi a questo punto. Ho intenzione di resettare il test per vedere se il problema persiste.

 
LEHayes:

.....
doppio AryBuys[][2];
doppio ArySells[][2];

AryBuy[1][0] contiene il biglietto, AryBuy[1][1] contiene il prezzo. ....

Correggimi se sbaglio ma sembra che tu definisca e indirizzi l'array in modo errato. Citato da riferimento variabile:

int    a[50];       // A one-dimensional array of 50 integers.
double m[7][50];    // Two-dimensional array of seven arrays,
                    //each of them consisting of 50 integers

l'ultima coppia di parentesi è la prima dimensione dell'array... assumendo che la dimensione indefinita dell'array sia la prima dimensione. Questo è IMO il corretto:

double AryBuys[2][];
double ArySells[2][];

AryBuy[0][1] contains the ticket, AryBuy[1][1] contains the price. 
 
cameofx:
l'ultima coppia di parentesi è la prima dimensione dell'array... assumendo che la dimensione indefinita dell'array sia la prima dimensione. Questo è IMO il corretto:

Vedi anche il libro...
Per tua informazione, sono più a mio agio a chiamare l'ultima coppia di parentesi graffe come 'prima dimensione' perché la dimensione successiva viene aggiunta (anche se si trova più a sinistra) 'dopo'.
IMHO Considerandolo come 'dimensione delle colonne' anche 'attacca' meglio concettualmente.

 
cameofx:

Per tua informazione, sono più a mio agio nel chiamare l'ultima coppia di parentesi graffe come 'prima dimensione' perché la dimensione successiva viene aggiunta (anche se si trova più a sinistra) 'dopo'.

Indipendentemente da come lo si voglia chiamare, la prima dimensione in un array 2D è il vettore arr_name[0,1,...,n][0], quindi tecnicamente la prima parentesi tiene la prima dimensione; questo è anche il vettore che sarà ordinato da ArraySort(). Dal libro:

Visto che siamo in tema di ArraySort() citerò 2 particolarità non documentate che ho trovato nel tempo (e sarei felice se qualcuno mi confermasse o correggesse...?):

  1. Se alcuni elementi della prima dimensione sono identici, non manterranno necessariamente il loro ordine. Ovviamente questo dovrebbe essere documentato se è "by-design", altrimenti lo considererei un "bug".
  2. OrderSort() non funziona con gli array 4D (restituisce l'errore 4053). Di nuovo, questo dovrebbe essere documentato ma non lo è.
 
cameofx wrote >>

Correggimi se sbaglio, ma sembra che tu definisca e indirizzi l'array in modo errato. Citato dal riferimento alla variabile:

l'ultima coppia di parentesi è la prima dimensione dell'array... assumendo che la dimensione indefinita dell'array sia la prima dimensione. Questo è IMO quello corretto:



Guardo l'indicizzazione e il dimensionamento dell'array nel modo standard dei fogli di calcolo... Row-Column (mnemonico "romano-cattolico").

Array 1D: MyArray[RowNumber-1]

Matrice 2D: MyArray[RowNumber-1][ColumnNumber-1]

Matrice 3D: MyArray[RowNumber-1][ColumnNumber-1][Worksheet-1]

L'insieme di parentesi più a sinistra è la prima dimensione, tutto ciò che si fa che comporta la manipolazione dell'array della prima dimensione sarà fatto con l'indice dell'insieme di parentesi più a sinistra. Il ridimensionamento dell'array (qualcosa che può essere fatto solo alla prima dimensione) per esempio cambia solo il valore dell'insieme di parentesi più a sinistra, non può cambiare l'intervallo di indici della seconda, terza o quarta dimensione (secondo, terzo o quarto insieme di parentesi più a destra).

Tutte le mie righe di dati nell'array sono indicizzate dalla prima serie di parentesi, la serie più a sinistra, e questa è la "prima dimensione" dell'array.

MyArray[0][ColumnNumber-1] -> prima riga di dati

MyArray[1][ColumnNumber-1] -> seconda riga di dati

MyArray[2][ColumnNumber-1] -> terza riga di dati

In MQL posso solo ordinare per i dati contenuti nella prima colonna di dati...cioè i valori trovati in MyArray[i][0]. I valori trovati nella stessa riga (stessa "i" in questo caso) ma in colonne diverse (il valore nella seconda serie di parentesi) non possono essere utilizzati per l'ordinamento.

Ecco un esempio di array 2D:

3 5
1 9
7 6

Quindi MyArray[0][0] = 3, e MyArray[0][1] = 5, e MyArray[2][1] = 6, ecc.

Posso ordinare questo array:

ArraySort(MyArray,WHOLE_ARRAY,0,MODE_ASCEND) e il risultato sarà il seguente:

1 9
3 5
7 6

La prima colonna è ordinata, la seconda colonna di dati (cioè tutti i dati con lo stesso indice di 1a dimensione) si muove insieme all'ordinamento/spostamento fatto nella classificazione della prima colonna.

Non posso ordinare/spostare la seconda colonna di dati in MQL...cioè NON posso ottenere quanto segue (non direttamente comunque):

3 5
7 6
1 9

(notare che la seconda colonna è ora ordinata dal più piccolo al più grande)

Per arrivare a un array che abbia la seconda colonna (o qualsiasi colonna diversa dalla prima) ordinata devo scambiare manualmente i dati tra le colonne (mantenendo l'indice della prima dimensione lo stesso ma scambiando il valore dell'indice della seconda dimensione) e poi ordinare e poi scambiare nuovamente i dati.

MyNewArray:
5 3
9 1
6 7

Ora ordinate per la prima colonna, ArraySort(MyNewArray,WHOLE_ARRAY,0,MODE_ASCEND) e il risultato sarà il seguente:

5 3
6 7
9 1

E poi copiate di nuovo i valori nel mio array originale, ancora una volta trasponendo l'indice della seconda dimensione e mantenendo il valore della prima dimensione uguale:

3 5
7 6
1 9

Ora ho il mio array originale ma i dati sono ordinati per la seconda colonna.

 

Tutta questa cosa si è trasformata in un incubo, non ricordo nemmeno se ho tentato di proseguire. L'idea che avevo era quella di prendere la lista delle compravendite aperte, separare gli acquisti dalle vendite in 2 array, ogni array conteneva il numero del biglietto nella prima colonna, la seconda conteneva il valore del prezzo della compravendita. In generale l'idea era quella di far combaciare tutti i valori di acquisto di prezzo elevato con tutti i valori di vendita di prezzo elevato e se il valore di acquisto più alto superava il valore di vendita più alto, allora si chiudevano entrambe le compravendite e si ripeteva il processo.

Ora il gancio finale che mi ha fatto prendere in considerazione l'idea di fare marcia indietro è che dopo aver seguito questo processo, volevo lasciare almeno 1 operazione di acquisto positiva e 1 operazione di vendita positiva sul tavolo per mantenere un sistema di trading con copertura. Questo è stato fondamentalmente progettato come uno strumento di gestione del drawdown per una strategia di copertura. Quindi voglio mantenere la copertura, ma togliere i guadagni dal tavolo. Mi è venuto in mente che usare un algoritmo di array potrebbe fornire una soluzione per questo.

Sono davvero stanco e consumato dal cercare di spingere il rilascio di circa 5 strategie fuori dalla porta, quindi questo è diventato un po' un piacere invece di una necessità.

Sono disposto a fare un accordo con chiunque possa scrivere questa funzione per me. Vi darò la vostra scelta di prodotti con un anno di licenza, gratuitamente per avermi aiutato su questo e anche per l'avvio, vi darò una copia personale di questa strategia di copertura per l'uso illimitato a vita. Sono troppo occupato per fare tutto questo e il mio team di sviluppo è pesantemente gravato dal rilascio di ciò che è già nei nostri piatti. Penso che il valore medio del sonno in tutta la squadra sia di circa 4-6 ore al giorno.

Quindi, se siete interessati a un piccolo baratto e scambio, questa è la mia offerta.

Obiettivo:
1. Separare gli acquisti dalle vendite
2. ordinare ciascuno secondo il valore del prezzo più alto al più basso
3. Se l'acquisto ha i prezzi positivi più alti e la vendita ha i prezzi positivi più bassi, allora vogliamo chiudere l'operazione di vendita più bassa con l'operazione di acquisto più alta, l'operazione di acquisto deve superare la spesa dell'operazione di vendita. Se la vendita ha prezzi positivi più alti, allora invertiamo questa azione per chiudere il prezzo di acquisto più basso con il prezzo di vendita più alto. L'idea è che per ogni perdita, la chiudiamo con una vittoria a prezzi più alti in modo che le vittorie superino le perdite con un guadagno medio positivo.

esempio:
comprare vendere
$15 $- 12
$5 $ - 6
$ 1.5 $ -1
$ 1 $ - .5

Questo mostra un numero bilanciato di operazioni aperte su entrambi i lati. Notate i 15$ di acquisto e i 12$ di vendita, questi possono essere chiusi perché l'acquisto positivo supera la vendita negativa. Possiamo anche chiudere il 5 e il -6 perché c'è abbastanza guadagno dalle prime due chiusure che l'equilibrio tra la chiusura delle 4 risulterebbe in un positivo. Possiamo fare lo stesso per l'1,5 e il -1, ma non vorremmo chiudere l'1 e il -,5 perché vogliamo mantenere la situazione di copertura.

La maggior parte delle volte, le operazioni non saranno bilanciate come uguali da entrambe le parti. Questa era la base del progetto per compensare il lato più pesante con una dimensione del lotto più alta e ulteriori trade a favore del lato vincente, quindi è possibile che si possa avere solo 1 vendita, nel qual caso, non si farebbe nulla. Nel caso in cui non siano bilanciate ma ci siano almeno 2 compravendite su ogni lato, devi assicurarti di lasciare aperta una compravendita su ogni lato. Nel caso in cui 1 trade positivo superi più di 1 trade negativo, puoi chiuderli tutti tranne quello su ogni lato che è il più piccolo tra loro.

Dovrebbe essere progettato per chiamare una funzione di chiusura che chiuderà un ticketid specifico, quindi non dovete preoccuparvi della chiusura, basta fare la chiamata per far chiudere i trade passando il ticketid. Potresti dover ricostruire la tua lista in modo che la tua lista non confronti le compravendite chiuse ma tutte le nuove compravendite che possono essersi verificate durante la tua elaborazione.

Oh sì, un'altra cosa...
Non dovrebbe essere troppo avido, dovreste fornire un utente esterno che detta la frequenza con cui questa funzione deve essere lanciata, può essere basata su un conteggio di candele o su una base oraria o di minuti, ma non dovrebbe essere lanciata ogni tick o anche ogni nuova candela. Così com'è, c'è uno strumento aggiuntivo in cui sarà incorporato che richiederà prima che l'altro strumento si attivi per invocare questo. Quindi l'altro strumento si attiverà, e il conto alla rovescia inizierà per far sì che il tuo strumento si attivi.

 
Larry, sono abbastanza sicuro che il codice per CloseBy() qui -> https://book.mql4.com/trading/orderclose (è a circa 2/3 della pagina...) può essere esteso per fare quello che vuoi (senza usare nessun array)... Solo un pensiero per la tua mente.
Motivazione: