ordenar un array de 2 dimensiones por la segunda dimensión

 

Tengo 2 datos que necesito poner en un array y luego ordenarlos.

Primero divido las órdenes en dos arrays, el primero para las compras y el otro para las ventas. Al hacerlo, estoy recogiendo el OrderTicket para que luego pueda realizar una ejecución de la orden. Lo segundo que estoy recogiendo es el valor de OrderClosePrice de la orden para poder compararla con otra lista exactamente igual.

Así que el primer array que configuro:

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

AryBuy[1][0] contiene el billete, AryBuy[1][1] contiene el precio.

¿Cómo ordeno la segunda dimensión para que tengamos el array ordenado por precio de forma descendente?

Nota: con ArraySort, sólo se puede ordenar la primera dimensión. Una posible idea es crear un array temporal y hacer que el precio sea la primera dimensión en el array temporal, ordenarlo, y luego devolverlo al array y hacer lo mismo a la inversa cuando más tarde necesite ordenarlo por ticket. ¿Funcionaría?

 

no puedes, por desgracia, pero podrías crear un segundo array con los datos de las dos dimensiones intercambiando lugares y ordenar ese nuevo array por precio (la primera dimensión). A continuación (si todavía quieres) podrías copiar los datos de nuevo en la matriz original, intercambiando los datos en cada dimensión. Ahora tu matriz original contiene los datos originales pero ordenados por los valores de la segunda dimensión.

Es complicado pero es la única manera práctica (que he podido descubrir) de ordenar los datos por dimensiones >1

 

Eso es lo que pensé en mis notas. Mi preocupación era que la primera dimensión se ordenara, ¿también se reorganizaría la segunda dimensión de datos cuando se realizara la ordenación? Supongo que podría hacer una prueba para comprobarlo.

 
LEHayes wrote >>

Eso es lo que pensé en mis notas. Mi preocupación era que la primera dimensión se ordenara, ¿también se reorganizaría la segunda dimensión de datos cuando se realizara la ordenación? Supongo que podría hacer una prueba para comprobarlo.


Sí, todos los elementos del mismo índice base se mueven con la ordenación de la primera dimensión. Al igual que la ordenación de una hoja de cálculo que contiene varias columnas de datos, sólo en MQL sólo puede ordenar por la primera columna.
 

De momento, he conseguido que se configure como se ha comentado. Estoy seguro de que voy a trabajar esto para el momento en que terminamos la conversación, pero actualmente conseguir:
2010.04.15 23:51:01,M1: posición de inicio 1 incorrecta para la función ArraySort
Al principio lo intenté así
ArraySort(AryBuy,WHOLE_ARRAY,0,MODE_DESCEND);
y obtuve el mismo mensaje sólo que el valor de la posición era 0, entonces cambié el inicio (valor de la posición) a 1 para ver qué podía pasar y obtuve lo anterior.

Los arrays deberían tener datos en este punto. Voy a reiniciar la prueba para ver si el problema persiste.

 
LEHayes:

.....
double AryBuys[][2];
double AryVende[][2];

AryBuy[1][0] contiene el billete, AryBuy[1][1] contiene el precio. ....

Corrígeme si me equivoco pero parece que defines y direccionas el array de forma incorrecta. Citado desde la referencia de la variable :

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

el último par de llaves es la primera dimensión del array... asumiendo que el tamaño indefinido del array es la primera dimensión. Esta es la OMI la correcta:

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

AryBuy[0][1] contains the ticket, AryBuy[1][1] contains the price. 
 
cameofx:
el último par de llaves es la primera dimensión del array... asumiendo que el tamaño indefinido del array es la primera dimensión. Esta es la OMI la correcta:

Ver también el libro...
Para tu información, me siento más cómodo nombrando el último par de llaves como 'primera dimensión' porque la siguiente dimensión se añade (aunque esté situada más a la izquierda) 'después'.
IMHO En cuanto a como 'tamaño de las columnas' también 'stick' mejor concepto-sabio.

 
cameofx:

Para tu información, me siento más cómodo nombrando el último par de llaves como 'primera dimensión' porque la siguiente dimensión se añade (aunque esté situada más a la izquierda) 'después'.

Independientemente de cómo quieras llamarlo, la primera dimensión en un array 2D es el vector arr_name[0,1,...,n][0], así que técnicamente el primer paréntesis contiene la primera dimensión; este es también el vector que será ordenado por ArraySort(). Del libro:

Ya que estamos en el tema de ArraySort() mencionaré 2 peculiaridades no documentadas que he encontrado a lo largo del tiempo (y estaría encantado si alguien me confirma o corrige...?):

  1. Si algunos de los elementos de la primera dimensión son idénticos, no necesariamente conservarán su orden. Obviamente, esto debería estar documentado si es "por diseño", de lo contrario lo consideraría un "bug".
  2. OrderSort() no funciona con matrices 4D (devuelve el error 4053). De nuevo, esto debería estar documentado pero no lo está.
 
cameofx wrote >>

Corrígeme si me equivoco pero parece que defines y direccionas el array de forma incorrecta. Citado desde la referencia de la variable :

el último par de llaves es la primera dimensión del array... asumiendo que el tamaño indefinido del array es la primera dimensión. Esta es, en mi opinión, la correcta:



Yo veo la indexación y dimensionamiento de los arrays de la manera estándar de las hojas de cálculo... Fila-Columna (mnemónico "romano-católico").

Array 1D: MiMatriz[NúmeroDeFila-1]

Array 2D: MiMatriz[NúmeroDeFila-1][NúmeroDeColumna-1]

Matriz 3D: MiMatriz[NúmeroDeFila-1][NúmeroDeColumna-1][HojaDeTrabajo-1]

El conjunto de corchetes más a la izquierda es la primera dimensión, todo lo que haga que implique la manipulación del array de la primera dimensión se hará con el índice del conjunto de corchetes más a la izquierda. El redimensionamiento del array (algo que sólo se puede hacer en la primera dimensión), por ejemplo, sólo cambia el valor del conjunto de corchetes más a la izquierda, no puede cambiar el rango de índices de la segunda, tercera o cuarta dimensión (segundo, tercero o cuarto conjunto de corchetes más a la derecha).

Todas mis filas de datos en el array están indexadas por el primer conjunto de corchetes, el más a la izquierda, y esta es la "primera dimensión" del array.

MiMatriz[0][NúmeroColumna-1] -> primera fila de datos

MiMatriz[1][NúmeroColumna-1] -> segunda fila de datos

MyArray[2][ColumnNumber-1] -> tercera fila de datos

En MQL sólo puedo ordenar por los datos contenidos en la primera columna de datos... es decir, los valores encontrados en MyArray[i][0]. Los valores que se encuentran en la misma fila (la misma "i" en este caso) pero diferentes columnas (el valor en el segundo conjunto de paréntesis) no se puede utilizar para ordenar / clasificación.

Este es un ejemplo de array 2D:

3 5
1 9
7 6

Así que MiMatriz[0][0] = 3, y MiMatriz[0][1] = 5, y MiMatriz[2][1] = 6, etc.

Puedo ordenar este array:

ArraySort(MiMatriz,TodaLaMatriz,0,MODO_ASCEND) y el resultado será el siguiente:

1 9
3 5
7 6

La primera columna está ordenada, la segunda columna de datos (es decir, todos los datos con el mismo índice de la primera dimensión) se mueve junto con la ordenación/desplazamiento realizado en la clasificación de la primera columna.

No puedo ordenar/clasificar la segunda columna de datos en MQL... es decir, NO PUEDO obtener lo siguiente (no directamente, de todos modos):

3 5
7 6
1 9

(nota la segunda columna está ahora ordenada de menor a mayor)

Para llegar a un array que tenga la segunda columna (o cualquier otra columna que no sea la primera) ordenada debo intercambiar manualmente los datos entre columnas (manteniendo el índice de la primera dimensión igual pero intercambiando el valor del índice de la segunda dimensión) y luego ordenar y volver a intercambiar los datos.

MiNuevoArreglo:
5 3
9 1
6 7

Ahora ordena por la primera columna, ArraySort(MyNewArray,WHOLE_ARRAY,0,MODE_ASCEND) y el resultado será el siguiente

5 3
6 7
9 1

Y luego copiamos los valores de nuevo en mi array original transponiendo una vez más el índice de la segunda dimensión mientras mantenemos el valor de la primera dimensión igual:

3 5
7 6
1 9

Ahora tengo mi matriz original pero los datos están ordenados por la segunda columna.

 

Todo esto se convirtió en una pesadilla, ni siquiera recuerdo si intenté continuar. La idea que tenía era tomar la lista de operaciones abiertas, separar las compras de las ventas en 2 matrices, cada matriz contenía el ticket# en la primera columna, la segunda contenía el valor del precio de la operación. En general, la idea era emparejar todos los valores de compra de gran precio con todos los valores de venta de gran precio y si el valor de compra más alto superaba el valor de venta más alto, entonces cerrar ambas operaciones y repetir el proceso.

Ahora, el gancho final que me hizo considerar el retroceso de esta idea fue que después de que pasé por este proceso, quería dejar al menos 1 operación de compra positiva y 1 operación de venta positiva en la mesa para mantener un sistema de comercio cubierto. Esto está siendo diseñado básicamente como una herramienta de gestión de reducción para una estrategia de cobertura. Así que quiero mantener la cobertura, pero tomar las ganancias fuera de la mesa. Se me ocurrió que el uso de un algoritmo de matriz podría proporcionar una solución para esto.

Estoy muy cansado y agotado de tratar de empujar la liberación de cerca de 5 estrategias de la puerta, por lo que este se convirtió en un poco de un agradable-dad en lugar de una neccessity.

Estoy dispuesto a hacer un trato con cualquiera que pueda escribir esta función para mí. Le daré su elección de productos con una licencia de años, de forma gratuita por ayudarme en esto y también arrancar, le daré una copia personal de esta estrategia de cobertura para el uso ilimitado de por vida. Estoy demasiado abrumado para hacerlo todo y mi equipo de desarrollo está muy cargado con la liberación de lo que ya está en nuestras placas. Creo que el valor medio del sueño en todo el equipo es de 4 a 6 horas al día.

Así que si estáis interesados en un pequeño trueque e intercambio, esa es mi oferta.

Objetivo:
1. Separar las compras de las ventas
2. Ordenar cada una de ellas según el valor de precio más alto al más bajo
3. Si la compra tiene precios positivos más altos y la venta tiene precios positivos más bajos, entonces queremos cerrar la operación de venta más baja con la operación de compra más alta, la operación de compra debe superar el gasto de la operación de venta. Si la venta tiene precios positivos más altos, entonces invertimos esta acción para cerrar el precio de compra más bajo con el precio de venta más alto. La idea es que por cada pérdida, la cerremos con una ganancia de precios más altos para que las ganancias superen a las pérdidas con una ganancia media positiva.

ejemplo:
compra venta
$15 $- 12
$5 $ - 6
$ 1.5 $ -1
$ 1 $ - .5

Esto muestra un número equilibrado de operaciones abiertas en ambos lados. Observe la compra de $15 y la venta de $-12, éstas pueden cerrarse porque la compra positiva supera la venta negativa. También podemos cerrar la 5 y la -6 porque hay suficientes ganancias de los dos primeros cierres que el balance entre el cierre de las 4 de ellas resultaría positivo. Podemos hacer lo mismo con el 1,5 y el -1, pero no querríamos cerrar el 1 y el -,5 porque queremos mantener la situación de cobertura.

La mayoría de las veces, las operaciones no estarán equilibradas como iguales en ambos lados. Esta fue la base del diseño para compensar el lado más pesado con un mayor tamaño de lote y operaciones adicionales a favor del lado ganador, por lo que es posible que sólo tenga 1 venta, en cuyo caso, no haría nada. En el caso de que no estén equilibradas pero haya al menos 2 operaciones en cada lado, debe asegurarse de dejar una operación en cada lado abierta. En el caso de que 1 operación positiva supere a 1 negativa, puede cerrarlas todas excepto la de cada lado que sea la más pequeña.

Debe ser diseñado para llamar a una función de cierre que cerrará un ticketid específico, por lo que no tiene que preocuparse por el cierre, sólo hacer la llamada para tener los oficios cerrados pasando el ticketid. Puede que tenga que reconstruir su lista para que su lista no compare las operaciones cerradas sino las nuevas operaciones que puedan haber ocurrido durante su procesamiento.

Ah sí, una cosa más...
No debería ser demasiado codicioso, debería proporcionar un usuario externo que dicte la frecuencia con la que esta función debe ser disparada, puede estar basada en un recuento de velas o en una base de horas o minutos, pero no debería disparar cada tick o incluso cada nueva vela. Tal y como está, hay una herramienta adicional en la que se incrustará y que requerirá primero que la otra herramienta se dispare para poder invocar ésta. Así que la otra herramienta se disparará, y la cuenta atrás comenzará para que su herramienta se dispare.

 
Larry, estoy bastante seguro de que el código para CloseBy() aquí -> https://book.mql4.com/trading/orderclose (está como 2/3 abajo de la página...) puede ser extendido para hacer lo que quieres (sin usar ningún array)... Solo una idea para tu mente.