![MQL5 - Lenguaje de estrategias comerciales para el terminal de cliente MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
Está perdiendo oportunidades comerciales:
- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Registro
Entrada
Usted acepta la política del sitio web y las condiciones de uso
Si no tiene cuenta de usuario, regístrese
Ahora tengo un problema. Necesito hacer una ordenación eficiente de arrays con gran "coste" de copia de elementos (es decir, elementos de los cuales son estructuras grandes y "pesadas", objetos de clase, cadenas largas, etc.). El sentido común sugiere que deberíamos dejarlos en su sitio, pero ordenar en su lugar algún tipo de punteros - índices de celdas de su ubicación original. Aquí está la cita de https://www.mql5.com/ru/forum/6476#comment_178318Оставим hasta ahora, y vamos a implementarla en mql5.
Ya nos han robado todo antes :)
Hojas de cálculo en MQL5
La entrada debe ser una copia del array a ordenar, los comentarios deben ser anotados y lo innecesario debe ser comentado
Ya nos han robado todo antes :)
Hojas de cálculo en MQL5
La entrada debe ser una copia del array a ordenar, los comentarios deben ser anotados y lo innecesario comentado.
¡Eres malo! Arruinaste la canción... O mejor dicho, lo intentó. :)
// Está claro que hay buenas aproximaciones. También podría haber sacado una muestra de la biblioteca estándar. :)
Hay patrones. Y también hay algunos excelentes. Pero aún así. Aquí es importante codificar y depurar todo para que funcione un producto utilizable por separado. Además (por eso lo envío aquí) - lo más rápido posible. Es decir, sugiero exprimir todo el rendimiento posible hasta las centésimas de porcentaje inclusive. :)
Esta es la primera. En segundo lugar, para los objetos necesitamos un número de matrices de índices igual al número de criterios de ordenación, que en el caso general pueden ser varios, + (preferentemente) función de inserción en matriz indexada ordenada según varios criterios.
¡Eres malo! Arruinaste la canción... O mejor dicho, lo intentaste. :)
// Está claro que hay buenas aproximaciones. También podría haber sacado una muestra de la biblioteca estándar. :)
Hay muestras. E incluso algunos grandes. Pero aún así. Es importante comprobar y depurar todo hasta conseguir un estado de funcionamiento de un producto utilizable por separado. Y (por eso lo envío aquí) - el más rápido. Es decir, sugiero exprimir todo el rendimiento posible hasta las centésimas de porcentaje inclusive. :)
Eso es lo primero. Segundo - para los objetos necesitamos el número de matrices de índices igual al número de criterios de ordenación, que en general pueden ser varios, + (preferentemente) función de inserción en matriz indexada ordenada por varios criterios.
La misma respuesta Hojas de cálculo en MQL5.
Todo está ahí. Bajo un problema concreto, es posible rehacer bajo manipulación no columnas sino filas, hay columnas hechas para es posible declararlas como tipos diferentes. Si el tipo de tabla es el mismo, todo puede ser reproducido.
Realizado un inluder con índices de ordenación para los tipos de base.
La ordenación por defecto es "descendente", para ordenar en dirección ascendente, ponga el indicador de dirección de ordenación en falso.
Resultados de la prueba: // indexación de matrices double[], int[], string[]; secuencialmente : matriz bruta, matriz descendente, matriz ascendente
Biblioteca y prueba en el remolque.
Ponga el indexador en la carpeta "MQL5\Include\Indexes\".
Aquí hay una clase de ejemplo para trabajar con OCL. Por supuesto, algunas cosas están incompletas y son incómodas, pero tal vez alguien lo encuentre útil.
He reelaborado un poco la inicialización, ahora se pueden realizar cálculos multidimensionales.
¡Gran tema!
Ahora mismo me he enfrentado a un problema de optimización con un algoritmo para encontrar un extremo de precio (mínimo). Las condiciones son las siguientes: hay una barra, n barras a la izquierda y a la derecha de la cual están por debajo (por encima) de su máximo:
n es un valor libre elegido arbitrariamente. El periodo n es siempre impar, porque la suma de las dos barras a la derecha y a la izquierda será siempre un número par al que se le suma la barra central del extremo del precio propiamente dicho.
No pensé mucho en la primera versión del algoritmo y escribí el código más obvio. Ahora lo estoy escribiendo en C# usando la plataforma WealthLab, pero creo que puedes entender fácilmente la esencia del algoritmo problemático, aquí está la parte más problemática:
Todo el problema está en el segundo bucle. Maneja simultáneamente las ramas izquierda y derecha de un extremo potencial y, por lo tanto, sólo pasa por (N - 1)/2 barras, pero eso no es suficiente. Las mediciones muestran que el tiempo empleado en identificar un extremo en una progresión aritmética depende del periodo N, lo cual es muy, muy malo:
Si se intenta recorrer los periodos, se tardará en sumar la progresión aritmética, y ésta es un valor muy grande.
Una posible solución es introducir una variable adicional. Al fin y al cabo, si se identifica un extremo, se garantiza que no hay ninguna barra a su derecha para (N - 1)/2 por lo que se puede identificar un nuevo extremo a partir de barra: barra_actual + (N - 1)/2. Sin embargo, es necesario identificar los extremos junto con los mínimos y se puede encontrar un nuevo mínimo antes de bar_actual + (N - 1)/2. Por lo tanto, será necesario dividir la búsqueda de extremos y mínimos en dos pasadas, lo que reducirá la ganancia de rendimiento a cero. Podemos dividir fácilmente dos pases en dos hilos procesados simultáneamente en dos núcleos en C#, pero me gustaría encontrar el algoritmo óptimo y optimizarlo en primer lugar. Espero la ayuda de los expertos.
Bueno, esto no es un problema de optimización.
Al intentar recorrer los periodos se tomará la suma de la progresión aritmética, y ésta es un valor muy grande.
Encontrar un extremo parece ser un problema del orden de O(n), donde n es el número de datos. Cómo se puede hacer esta asintótica peor, es decir, O(n^2) - no puedo ni imaginar. O estás confundiendo los términos.
El algoritmo más sencillo es ArraySort(), bastante rápido incorporado, algo así como O(n * ln( n ) ). Pero probablemente sea redundante para este problema.
Podrías idear algo recursivo que fuera más rápido.
¿Cuánto tiempo se tarda en encontrar el mínimo y para cuántas barras? Bueno, no creo que para 100 bares estés buscando un máximo de un segundo y medio.
El algoritmo más sencillo es ArraySort(), la ordenación incorporada es suficientemente rápida, pero probablemente sea redundante para esta tarea.
La mejor ordenación es O(n*log(n)). Exactamente redundante.
Podríamos idear algo recursivo que fuera más rápido.
Más lento. La recursividad es, en la mayoría de los casos, maligna. ¿Recursivo? Este es probablemente un caso en el que no importa cómo lo hagas, la velocidad será más o menos la misma.
Por código:
Los ciclos para el mínimo y el máximo deben estar explícitamente separados. Y salir del bucle inmediatamente si falla.
En principio, sí. Pero aún así no es más que O(n).
La OCL ayudaría en este caso. La asintótica seguirá siendo la misma, por supuesto. Pero la velocidad podría multiplicarse por cien.