Discusión sobre el artículo "Desarrollamos un Asesor Experto multidivisas (Parte 3): Revisión de la arquitectura"

 

Artículo publicado Desarrollamos un Asesor Experto multidivisas (Parte 3): Revisión de la arquitectura:

Ya hemos avanzado bastante en el desarrollo del asesor multidivisa con varias estrategias funcionando en paralelo. Basándonos en nuestra experiencia, revisaremos la arquitectura de nuestra solución y trataremos de mejorarla antes de avanzar demasiado.

Ya hemos asignado un objeto de experto (de clase CAdvisor o sus descendientes), que supone un agregador de objetos de estrategia comercial (de clase CStrategy o sus descendientes). Al inicio del funcionamiento del asesor, en el manejador OnInit() ocurre lo siguiente:

  • Se crea un objeto de experto.
  • Los objetos de estrategia comercial se crean y se añaden al asesor experto en su array de estrategias comerciales.

En el manejador de eventos OnTick() del asesor sucede lo siguiente:

  • Se llama al método CAdvisor::Tick() para el objeto de asesor.
  • Este método enumera todas las estrategias y llama a su método CStrategy::Tick().
  • Las estrategias en el marco del funcionamiento de CStrategy::Tick() realizan todas las operaciones necesarias para la apertura y el cierre de posiciones en el mercado.

Esquemáticamente, esto puede representarse del modo que sigue:



Figura 1. Esquema de funcionamiento del primer artículo

Fig. 1. Esquema de funcionamiento del primer artículo

La ventaja de tal esquema era que teniendo un código fuente de un asesor que trabaje según una estrategia comercial, podemos modificarlo para que funcionara de forma conjunta con otros ejemplares de estrategias comerciales mediante operaciones no muy complicadas.

Pero la principal desventaja no tarda en hacerse patente: al combinar varias estrategias, debemos reducir en mayor o menor medida el tamaño de las posiciones abiertas por cada ejemplar de estrategia. Y esto puede provocar la eliminación completa de algunos o incluso todos los ejemplares de estrategias comerciales. Cuantos más ejemplares de estrategias incluyamos en el trabajo paralelo o cuanto menor sea el depósito inicial elegido para negociar, más probable será este resultado, ya que el tamaño mínimo de las posiciones abiertas en el mercado es fijo.

Autor: Yuriy Bykov

 
FOREACH(m_orders, if(m_orders[i].IsOpen()) { m_ordersTotal += 1; })

A veces algo en tu interior te impulsa a escribir así.

FOREACH(m_orders, m_ordersTotal += m_orders[i].IsOpen())
 
No he leído hasta el final. Pero la sensación es que el trabajo con el pendiente (no en el probador) no encaja realmente en este, de hecho, mucho mejor arquitectura.
 

Sería bueno añadir una máscara de activación/desactivación de una estrategia para tener en cuenta el volumétrico (receptor de volúmenes virtuales).

Por ejemplo, es necesario desconectar alguna TS de la cartera durante un tiempo: sigue operando virtualmente, pero no afecta al entorno real. Lo mismo ocurre con su activación inversa.

 
No se me ocurre ninguna forma de perfeccionar esta arquitectura desde el principio. Esta es la única manera de hacerlo ahora.
//+------------------------------------------------------------------+
//|| Clase base experta|
//+------------------------------------------------------------------+
class CAdvisor {
protected:
   CStrategy         *m_strategies[];  // Conjunto de estrategias de negociación

Pero en algún lugar debe haber una incrustación competente de algo similar.

 CAdvisor *m_advisors[];  // Matriz de carteras virtuales

con sus propios magos.

 
Оповещение получателя и стратегии должно происходить только при открытии или закрытии виртуальной позиции.

Puede tener dificultades con esto incluso en el Probador si la sesión de cotización está fuera de la sesión de negociación.

El indicador de que la sincronización del volumen se ha realizado correctamente puede salvarle.

 
//+------------------------------------------------------------------+
//| Clase de órdenes y posiciones virtuales
//+------------------------------------------------------------------+
class CVirtualOrder {
private:
//--- Campos estáticos ...
   
//--- Objetos destinatario y estrategia relacionados
   CVirtualReceiver  *m_receiver;
   CVirtualStrategy  *m_strategy;

Es una solución cuestionable insertar una entidad completamente diferente en una orden virtual.

Parece que al crear la arquitectura, el problema de rendimiento se resolvió en paralelo. Yo mismo tengo ese pecado.


Probablemente, sigue siendo correcto diseñar sin mirar el rendimiento. Y luego pensar cómo se puede acelerar.

 
fxsaber #:
No he leído hasta el final. Pero tengo la sensación de que trabajar con órdenes pendientes (no en el Probador) no encaja realmente en esta, de hecho, muy mejorada arquitectura.

No trabajo con órdenes pendientes reales, me parece suficiente con abrir posiciones de mercado cuando se activan órdenes pendientes virtuales. Me doy cuenta de que esto puede estar plagado de entradas no del todo precisas debido a deslizamientos y recotizaciones en el comercio real. Pero en la práctica todavía no me he encontrado con ello. El soporte para órdenes pendientes virtuales estará en la próxima parte.

Si todavía quieres molestarte con órdenes pendientes reales, entonces, en principio, la arquitectura lo permite: tendrás que escribir otra implementación de la clase CVirtualSymbolReceiver. La implementación actual simplemente ignora las órdenes pendientes virtuales.

 
fxsaber #:

Sería una buena idea añadir una máscara de estrategia on/off para tener en cuenta el volumétrico (receptor de volúmenes virtuales).

Por ejemplo, si necesita desconectar algún TS de la cartera durante un tiempo: sigue operando virtualmente, pero no afecta al entorno real. Lo mismo ocurre con su encendido inverso.

No es difícil realizar algo así, pero sin utilizarlo, necesitará criterios claros de encendido/apagado para cada estrategia. Esta es una tarea más compleja, aún no la he abordado; probablemente no lo haga.

 
fxsaber #:

Y debe haber una incorporación competente de algo así en alguna parte.

CAdvisor *m_advisors[];  // Matriz de carteras virtuales

con sus propios magos.

No hay planes para eso. La fusión en carteras se producirá en un nivel intermedio entre CAdvisor y CStrategy. Hay un proyecto de solución, pero es probable que cambie mucho durante la refactorización en curso.

 
fxsaber sesión de negociación.

El indicador de que la sincronización del volumen se ha realizado correctamente puede salvarle.

Parece que ya existe:

class CVirtualSymbolReceiver : public CReceiver {
  ...
   bool              m_isChanged;      // ¿Hay cambios en la composición de los puestos virtuales

Se restablece sólo cuando el volumen real requerido se abre con éxito para cada símbolo.