1. qteasy Enfoque general de arquitectura y diseño

1.1. 1. 引言:为什么需要从“架构”理解 qteasy

qteasy es un conjunto de herramientas comerciales cuantitativas localizadas y reproducibles. Más allá de la guía del usuario y la documentación de la API, comprender cómo los módulos se superponen y colaboran desde las perspectivas de la arquitectura del sistema y la fundamentación del diseño le ayuda a utilizar las interfaces con mayor precisión, solucionar problemas y evitar desvíos al ampliar estrategias o datos personalizados. Este capítulo proporciona un resumen general de la arquitectura de qteasy y tres hilos de diseño principales; Los capítulos siguientes amplían cada módulo.

1.2. 2. 三条设计主线(简述)

2.1 Datos: de “Tablas sin procesar” a “Información mecanografiada” (DataType)

Después de recuperar y limpiar los datos sin procesar del mercado, financieros y de otro tipo, se almacenan en DataSource (archivos o una base de datos) utilizando un esquema de tabla unificado. qteasy no permite que las estrategias lean o escriban estas tablas directamente; en su lugar, abstrae la “información utilizable por estrategias” en DataType (compuesta por nombre, frecuencia, tipo_activo, etc., correspondiente a un dtype_id único). Una estrategia solo declara qué tipos de datos necesita y cuánto tiempo requiere una ventana histórica (window_length); en tiempo de ejecución, el motor recupera datos de DataSource según la declaración, los organiza en una ventana de datos y los inyecta en la estrategia. Los propósitos incluyen: usar la misma vista de datos para pruebas retrospectivas y operaciones en vivo, unificar la interfaz de la estrategia y evitar el «sesgo de anticipación» a nivel del mecanismo (una estrategia solo puede ver los datos anteriores inyectados por el motor en cada paso de tiempo).

2.2 Estrategia: cuatro elementos clave y una realización unificada()

Conceptualmente, una estrategia contiene cuatro categorías de elementos:

  • Tiempo de ejecución: cuándo y con qué frecuencia ejecutar (por ejemplo, diariamente al cierre del mercado). En qteasy 2.0, esto lo administra el Grupo de la estrategia, no está codificado dentro de la clase de estrategia.

  • Datos requeridos: qué tipos de datos se necesitan, cuánto dura la ventana (tipos de datos, longitud de la ventana, etc.), declarados durante la inicialización de la estrategia.

  • Parámetros ajustables: definidos por Parámetro, establecidos antes de ejecutar mediante set_parameter y similares; Durante la optimización, el Optimizador busca en el espacio de parámetros.

  • Lógica: implementada mediante un realize() sin parámetros; dentro del método, use get_pars() y get_data(dtype_id) para obtener los parámetros y datos del paso actual, calcular y devolver señales comerciales.

El mismo realize() se reutiliza tanto en las pruebas retrospectivas como en las operaciones reales para garantizar un comportamiento coherente.

2.3 Ejecución: Operator y grupo, impulsado por pasos de tiempo, ejecución unificada (config)

Operator es a la vez el contenedor de estrategias y el punto de entrada para la ejecución: contiene múltiples Grupos y cada grupo es un conjunto de estrategias con la misma run_freq y run_timing (así como signal_type y blender). group_timing_table es una tabla de “paso de tiempo × grupo” que indica qué grupos deben ejecutarse en cada paso de tiempo. Un flujo de trabajo de un solo paso se puede resumir como: buscar en la tabla el paso actual para que los Grupos se ejecuten → preparar e inyectar una ventana de datos para cada estrategia en esos Grupos → llamar al generate() de cada estrategia (que internamente llama a realize()) → combinar señales dentro del Grupo usando la licuadora del Grupo → obtener la señal combinada para ese paso. Las pruebas retrospectivas, el comercio en vivo y la optimización se basan en el mismo mecanismo de «ejecutar el Operator paso a paso según group_timing_table»; las diferencias radican únicamente en la fuente de datos (históricos versus en tiempo real) y el manejo de resultados (rellenos simulados versus pedidos reales versus búsqueda de parámetros).

2.4 Visualización: HistoryPanel y gráficos multibackend

Además de los datos y la ejecución, qteasy proporciona una pila de visualización basada en HistoryPanel:

  • Como contenedor de datos 3D (compartidos × hdates × htypes), HistoryPanel es tanto el valor de retorno natural de get_history_data como la estructura de datos de requisito previo para la visualización;

  • HistoryPanel.plot(...) es el punto de entrada del trazado unificado. Selecciona automáticamente el tipo de gráfico apropiado (velas, volumen, MACD, gráfico de líneas, etc.) en función de los tipos h y las acciones, y genera especificaciones de gráficos independientes del backend;

  • El backend estático (matplotlib) y el backend interactivo (Plotly) representan gráficos sobre el mismo conjunto de especificaciones, lo que garantiza la coherencia entre las vistas estáticas/interactivas en cuanto a combinación de colores, diseño y semántica;

  • Las API de capa superior, como qt.candle(...), son simplemente contenedores para «obtener datos → crear un HistoryPanel → llamar a hp.plot()».

De esta manera, la lógica de visualización se desacopla de la recuperación de datos y del motor de backtesting, lo que facilita la evolución y las pruebas de forma independiente.

1.3. 3. 总体架构图(三层)

Por responsabilidades, qteasy se puede dividir en tres capas, como se muestra en la siguiente figura (versión de texto):

flowchart TB subgraph dataLayer [数据层] DS[DataSource] Tables[数据表] DT[DataType / dtype_id] GHD[get_history_data] HP[HistoryPanel] DS --> Tables Tables --> DT DT --> GHD GHD --> HP end subgraph strategyLayer [策略层] BS[BaseStrategy 及子类] PAR[Parameter] DTL[data_types / window_length] BS --> PAR BS --> DTL HP --> BS end subgraph runLayer [运行层] OP[Operator] GR[Group] GTT[group_timing_table] BL[blender] BT[Backtester] TR[Trader] OPR[Optimizer] OP --> GR OP --> GTT GR --> BL OP --> BT OP --> TR OP --> OPR end subgraph vizLayer [可视化层] HPPlot[HistoryPanel.plot] SpecBuilder[图表规格/布局] StaticBackend[静态后端(matplotlib)] InteractiveBackend[交互后端(Plotly)] HP --> HPPlot HPPlot --> SpecBuilder SpecBuilder --> StaticBackend SpecBuilder --> InteractiveBackend end dataLayer --> strategyLayer strategyLayer --> runLayer dataLayer --> vizLayer
  • Capa de datos: DataSource, tablas de datos, DataType y get_history_data / HistoryPanel externo, que proporciona información histórica «por tipo, por ventana» para las capas de estrategia y tiempo de ejecución.

  • Capa de estrategia: BaseStrategy y sus subclases (p. ej., RuleIterator, FactorSorter, GeneralStg), parámetro, tipos de datos/longitud de ventana, responsable de declarar los requisitos e implementar realizar().

  • Capa de tiempo de ejecución: Operator, Grupo, group_timing_table, blender y Backtester/Trader/Optimizador, responsables de impulsar estrategias a lo largo del tiempo, agregar señales y ejecutar pruebas retrospectivas/comercio en vivo/optimización.

1.4. 4. 核心对象关系图

flowchart LR subgraph operator [Operator] G1[Group A] G2[Group B] end G1 --> S1[Strategy 1] G1 --> S2[Strategy 2] G2 --> S3[Strategy 3] S1 --> DT[DataType] S1 --> PAR[Parameter] S2 --> DT S2 --> PAR S3 --> DT S3 --> PAR OP_RUN[op.run] CFG[config] DSRC[datasource] OP_RUN --> operator CFG --> OP_RUN DSRC --> OP_RUN
  • Un Operator contiene varios grupos y cada grupo contiene varias estrategias.

  • Cada estrategia declara el DataType (y la longitud de la ventana) del que depende y define parámetros ajustables a través de Parámetro.

  • El punto de entrada es op.run(config, datasource, logger), controlado por la configuración y la fuente de datos.

1.5. 5. 数据与信号的大致流向

Desde las fuentes de datos hasta las estrategias y las pruebas retrospectivas/comercio en vivo/optimización, el flujo general se puede simplificar de la siguiente manera:

sequenceDiagram participant User participant DataSource participant Operator participant Strategy participant Backtester User->>Operator: qt.run(op, mode=1/0/2, ...) Operator->>DataSource: 按策略声明请求历史/实时数据 DataSource-->>Operator: 数据窗口 loop 每个时间步 Operator->>Strategy: 注入数据窗口,调用 realize() Strategy-->>Operator: 信号 Operator->>Operator: blender 混合 end Operator-->>Backtester: 信号序列(回测时) Backtester-->>User: 资金曲线、绩效等
  • Los usuarios ingresan a pruebas retrospectivas (1), operaciones en vivo (0) u optimización (2) a través de qt.run(op, mode=...).

  • Según las declaraciones de configuración y estrategia, Operator solicita datos de DataSource, luego llama estrategias paso a paso de acuerdo con group_timing_table y combina las señales.

  • En el backtesting, la secuencia de señales se entrega al Backtester para rellenos simulados y evaluación; en el comercio real se entrega al Trader/Broker para su ejecución; En optimización, el Optimizador ejecuta pruebas retrospectivas varias veces y agrega los resultados.

1.6. 6. 本系列各章与教程、API、示例的阅读顺序建议

  • Esta serie (arquitectura y diseño): Se recomienda leer este capítulo (00) y Conceptos básicos de un vistazo primero, luego leer según sea necesario Capa de datos, Datos en estrategias, Operator y Grupos, Ejecución y parámetros de la estrategia y Backtesting/Live Trading/Optimización para crear una imagen general.

  • Guía del usuario: se centra en operaciones “prácticas” paso a paso. Es adecuado para leer selectivamente según sea necesario después de comprender la arquitectura, para completar tareas específicas (como descargar datos, escribir estrategias y ejecutar pruebas retrospectivas).

  • Descargar y administrar datos financieros históricos, Referencia de API: se utiliza para buscar configuraciones de datos, parámetros de interfaz y valores de retorno; Esta serie cubre únicamente «estructura y mecanismos» y no reemplaza la documentación de la API.

  • Ejemplos: proporcione ejemplos ejecutables completos que se puedan utilizar junto con los tutoriales y esta serie.