Reglas de estructura. Aprender a estructurar los programas, explorar las posibilidades, los errores, las soluciones, etc. - página 7

 
Urain:

Sugiero que se establezcan los patrones básicos de diseño:

1. Funcional

2. modelo de objeto

3. Impulsado por eventos .

...

teclear

4. Componente

--

En general, cualquier programa (incluido el que usted pretende) puede verse desde diferentes ángulos. // es comprensible.

Durante el análisis inicial de un proyecto, intento considerar al menos 4 aspectos:

1. Estructural: Organización física y lógica del código y de los componentes del programa.

2. Funcional (no confundir con el enfoque funcional en el desarrollo): Qué tareas resuelve el programa (qué producto produce), cuál es su uso, qué salida debe producir, etc.

3. Comunicativo: qué tipo de interfaz de usuario debe tener el programa, con qué programas se comunica y cómo, protocolos de comunicación, etc.

4. Gestión: cómo se gestiona el software, qué ajustes hay que hacer, grados de libertad, etc.

Todos los aspectos están inextricablemente unidos, pero mirar desde estos diferentes ángulos (+ algunos más) permite no perderse sutilezas importantes, y en las primeras etapas simplemente no bostezar algo importante con consecuencias de largo alcance... )

 
MetaDriver:

...En general, cualquier programa (incluso uno concebido) puede ser analizado desde diferentes ángulos. // esto es comprensible...

Estoy totalmente de acuerdo. Es un principio filosófico general: estudiar un fenómeno desde diferentes puntos de vista...

Y trato de responder a la pregunta "¿Qué debe hacer un programa y qué no debe hacer?" al principio del desarrollo. La primera parte de la pregunta entra dentro del sistema (aquí MTS), la segunda parte no, está fuera.

En mi opinión, es muy importante, independientemente del modelo de diseño, tener una jerarquía de elementos del modelo. El método deductivo - "de lo general a lo particular"- funciona entonces bien, descomponiendo el modelo en sus bloques principales y constitutivos.

 
MetaDriver:

Para intercambiar ideas / aprender unos de otros, propongo tomar un problema más o menos práctico y reestructurarlo juntos.

Por ejemplo, al menos esbozar la estructura básica (o más exactamente, las variantes de dichas estructuras) para dicho problema:

Hay un Asesor Experto escrito así (por ejemplo, para probar una idea de trading). Supongamos que la idea en el Probador de Estrategias (en el cliente) muestra resultados prometedores. Ahora tenemos que reescribir el Asesor Experto para que sea más fácil de desarrollar. Y en particular, para dotarlo de un panel de control gráfico para el usuario.

Es deseable, o bien hacer el panel conmutable (para la optimización en el probador), o bien trasladar toda la realización "no gráfica" del EA a un archivo conectable (.mqh), que puede entonces conectarse a la interfaz gráfica sin cambios (para excluir) las diferencias en el funcionamiento de las versiones "probadora" y "gráfica".

Me gustaría escuchar-leer las consideraciones sobre la estructuración de un proyecto de este tipo. En particular, sobre la implementación del modelo de control dirigido por eventos en un proyecto de este tipo. Supongamos que la implementación dual (probador + panel) es un requisito estricto del cliente (es decir, el proyecto debe realizarse de cualquier manera, sólo se puede elegir el método de implementación).

¿Intentamos la tarea?

Creo que es obvio que el panel de control del Asesor Experto y el Asesor Experto son dos módulos completamente diferentes en un solo programa. Por lo tanto, es necesario separarlas de manera que cada parte sea independiente de la otra. Esto significa que si usted cambia una parte de un Asesor Experto (por ejemplo, cambio en la lógica de colocación de órdenes), no tiene que cambiar la lógica del panel y viceversa (cambio en la interfaz del panel - no es necesario cambiar la lógica del Asesor Experto). Lo primero que se me ocurre es la creación de una interfaz unificada a través de la cual el panel y el Asesor Experto puedan comunicarse. Pero, por desgracia, los creadores de MQL5 no han considerado la posibilidad de crear enlaces horizontales, y por lo tanto, describir la interfaz entre ellos por medio de MQL5 no funcionará. Entonces queda la vía de la integración vertical. Un Asesor Experto debe heredar de una clase base, que a su vez contiene métodos y datos suficientes para interactuar con el panel. Significa que cualquier EA heredado de la clase base también podrá mostrar e interactuar con el panel. La implementación de los métodos, responsables de la interacción con el panel, no debe ser delegada a los descendientes, sino que debe hacerse detrás de las escenas de la clase base, es decir, el mensaje "¡Descendiente! Si quieres interactuar con el panel, debes llamar a tal o cual de mis métodos con tales o cuales parámetros" no funciona en absoluto. Lo ideal es que cualquier Asesor Experto derivado que herede de la clase base simplemente opere de forma conveniente y sus acciones se muestren automáticamente en este panel.

Cómo organizar una clase base universal es un tema interesante aparte. Varios años de práctica en esta materia me han llevado finalmente a mi esquema universal. Ha resultado ser transparente y universal. Si te interesa, puedo proporcionarte su diagrama de flujo básico (ja, ja, dibujar diagramas de flujo es una actividad muy útil después de todo). Pero en cualquier caso, cada uno tiene su propio camino, y una buena solución para uno no será una buena solución para otro.

 
C-4:

Si te interesa, puedo darte un diagrama esquemático (ja, ja, dibujar diagramas de bloques es una actividad útil después de todo).

 
sergeev:
Por fin algo aclarado.... )
 
C-4:

Lo primero que se me ocurre es crear una interfaz unificada a través de la cual el panel y el EA puedan intercambiar datos. 2.

Desgraciadamente, los creadores de MQL5 no ofrecieron la posibilidad de crear enlaces horizontales y, por lo tanto, describir la interfaz entre ellos utilizando las herramientas de MQL5 es imposible.

1. Sin ambigüedades.

2. ¿Qué pasa con los eventos personalizados? Es bastante horizontal y universal.

3. entonces queda la vía de la integración vertical. Un Asesor Experto debe heredar de una clase base, que a su vez contiene métodos y datos suficientes para interactuar con el panel. Esto significa que cualquier Asesor Experto heredado de la clase base también obtiene la capacidad de mostrar e interactuar con el panel. La implementación de los métodos, responsables de la interacción con el panel, no debe ser delegada a los descendientes, sino que debe hacerse detrás de las escenas de la clase base, es decir, el mensaje "¡Descendiente! Si quieres interactuar con el panel, debes llamar a tal o cual de mis métodos con tales o cuales parámetros" no funciona en absoluto. Idealmente, cualquier Asesor Experto derivado heredado de una clase base debería simplemente operar de forma conveniente, mientras que sus acciones se mostrarían automáticamente en ese panel.

Como no estoy de acuerdo con el punto 2, todavía no me gusta esta variante.

--

Tengo una alternativa que me parece muy atractiva (una variante de "desactivar" el panel). Hacer el panel en forma de indicador. Si su Asesor Experto está en el Probador de Estrategias, simplemente no carga el panel. La ventaja adicional es que el panel se ejecuta en un hilo diferente dejando más recursos para el Asesor Experto.

En cuanto a la versatilidad del panel, no veo mayores obstáculos para que el panel sea totalmente configurable a través de un archivo ini. En otras palabras, puedes prescribir allí absolutamente todos los datos necesarios para crear cualquier panel a partir de un conjunto limitado de componentes visuales + códigos de eventos que deben generar al interactuar con un usuario.

La forma de organizar una clase básica de comercio universal es un tema interesante aparte. Varios años de práctica sobre este tema me han llevado finalmente a mi esquema universal. Resultó ser transparente y universal. Si te interesa, puedo mostrarte su diagrama de bloques básico.....

Vamos, incluso me interesa mucho. Y prácticamente puede ser útil.
 
MetaDriver:

1. Sin ambigüedades.

Nahr ¿Por qué? La sobreuniversalización es tan mala como la optimización prematura.

Y la vinculación de bloques de un módulo a través de eventos... ...es lento e inconveniente.

 
MetaDriver:

Vamos, la verdad es que me interesa bastante, y podría ser útil en la práctica.

El marco azul son las entidades de la clase base. El marco rojo son las entidades de la clase derivada. Puedes ver que la clase base impone la definición de su lógica a la descendiente en cuatro métodos. Así reduce la descripción de cualquier estrategia a una descripción de sólo cuatro situaciones:

1. Si se han cumplido todas las reglas para la apertura de la posición larga, ésta se abre en el método InitBuy()

2. Si se cumplen todas las reglas para el cierre de la posición larga - la posición larga se cierra con el método SupportBuy()

3. Si se cumplen todas las reglas para la apertura de la posición corta - entonces la posición corta se abre utilizando el método InitSell()

4. Si se cumplen todas las reglas para el cierre de la posición corta - entonces la posición corta se cierra en el método SupportSell()

Según esta lógica, la inversión de la estrategia se describe no en un método (por ejemplo, cerrar largo abrir corto), sino en dos métodos que no dependen el uno del otro. Resulta que este enfoque es muy conveniente porque nos permite, por ejemplo, prohibir la venta o cerrar forzosamente las posiciones con un clic después de que se cumplan algunas condiciones generales que pueden describirse en una clase base.

En algunos casos, una estrategia tiene datos generales tanto de ventas como de compras que deben recalcularse al producirse algún evento, por ejemplo, la llegada de un nuevo bar. En estos casos, es posible que una estrategia suscriba sus propios métodos de procesamiento a los eventos. No es posible abrir posiciones en estos métodos, pero sí es posible hacer varios cálculos.

Otro punto interesante es cómo manejar las posiciones abiertas. La clase base almacena una lista separada de posiciones largas y cortas. Cuando se produce un nuevo evento (por ejemplo, OnTick), la clase comienza a listar todas las posiciones abiertas y ofrece procesar cada una de estas posiciones una por una utilizando los métodos SupportBuy SupportSell. Estos métodos sólo pueden cerrar la posición que les ofrece la clase base en ese momento. Todas las demás posiciones son de sólo lectura. Así, la clase base impone a sus descendientes la idea de que, por el momento, deben centrarse en una sola posición. Cuando probé esta idea, resultó que la lógica del Asesor Experto más complejo es mucho más simple. Además, da soporte automático a la noción de cobertura, porque el Asesor Experto mantiene información sobre sus posiciones largas y cortas.
 
TheXpert: ... La aplicación de la parte comercial depende de la estrategia, por lo que no hay nada que discutir en el marco de una estrategia hipotética. La aplicación de la estrategia, curiosamente, también depende de la estrategia :)
MetaDriver: ... Toda la parte de negociación está escrita en forma de una clase (CMarketDriver) que implementa completamente la colocación de órdenes, el seguimiento de posiciones, las recotizaciones y otras cosas relacionadas con la negociación. Para todos los símbolos a la vez. La parte de la estrategia sólo introduce las posiciones de mercado recomendadas para los símbolos, es decir, llena un array de estructuras de formato {string Instrument; double Position} y solicita la sincronización con el servidor: MD.Synchronize(PositionArray). Eso es todo. Por ahora sólo opera con órdenes de mercado , pero está en camino una versión que opera con límites fijados dentro del spread (para reducir los costes de las operaciones). Para el comercio no se utilizan takeprofits/stops, pero MarketDriver puede poner stops de protección en caso de una larga pérdida de conexión con el servidor (los parámetros de stop se especifican una vez en la configuración del driver). Por cierto, una solución estructural muy exitosa, casi sin problemas. Para probar las ideas estratégicas en el probador - no hay problemas con el comercio, toda la atención se puede dedicar a la estrategia - todo el comercio ha sido largamente depurado y encapsulado en el driver de comercio.

En cuanto empiece a trasladar la ejecución de una estrategia a órdenes limitadas, recibirá muchas preguntas, de alguna manera:

  • el efecto de sus limitadores sobre el precio que alcanza su parte de estrategia (analizador/pronóstico/cerebro).
  • sincronización para una estrategia multidivisa
  • Ausencia de ejecución en una operación de tendencia (¿arrastrar? si es así, cómo, o escupir y seguir el mercado)
  • Ejecución parcial
  • ...

Entonces habrá que implementar una retroalimentación entre el "ejecutor" y el "analizador" y, además, los parámetros de este movimiento no ideal deberán incorporarse de alguna manera al modelo matemático del analizador

MetaDriver: ... Para comprobar las ideas estratégicas en el probador, una canción - sin problemas con el comercio ...

Sí, para los limitadores es realmente una canción.
 
GaryKa:

Al comenzar a convertir a fondo la ejecución en la estrategia a órdenes limitadas

Esto es sólo un ejemplo de lo que estaba hablando - la parte de la negociación depende de la estrategia.
Razón de la queja: