4. Cómo una estrategia declara y utiliza datos
4.1. 1. 策略层在整体中的位置
La capa de estrategia es responsable de dos cosas: declarar “qué datos se necesitan” (y la duración de la ventana, si se debe usar el último período) y en realizar() “usar los datos para calcular señales”. La estrategia no extrae datos activamente; en cambio, el tiempo de ejecución lo prepara en cada paso de acuerdo con las declaraciones y lo inyecta, y la estrategia solo lo recupera por identificación a través de get_data(dtype_id). De esta manera, las pruebas retrospectivas y las operaciones en vivo utilizan exactamente la misma vista de datos y patrón de llamadas.
4.2. 2. 策略如何声明需要的数据
Al inicializar la clase de estrategia (__init__), declare los requisitos de datos mediante los siguientes atributos:
tipos_datos: uno o más objetos DataType (o una lista/dict). Cada DataType corresponde a un tipo de «información referenciable» y se asigna a un dtype_id único (por ejemplo,
close_E_d).window_length: La duración de la ventana de datos históricos (por ejemplo, 20 significa los 20 ciclos más recientes). Puede ser un escalar (se aplica a todos los tipos de datos declarados) o especificarse por separado por dtype.
use_latest_data_cycle: si se utilizan solo los datos del “último ciclo único” (por ejemplo, usar solo la última sección transversal para la selección de acciones). Se puede configurar por separado por tipo de d.
Después de la declaración, el motor sabrá qué dtype_id necesita la estrategia y qué longitud de ventana, por lo que puede preparar las ventanas de datos correspondientes antes de ejecutarlas y actualizarlas/inyectarlas en cada paso.
4.3. 3. 运行时数据如何到达策略
Etapa de preparación: según el período de prueba retrospectiva (o el tiempo actual en operaciones reales) y los tipos de datos y la longitud de la ventana de la estrategia, el motor extrae los datos para el período correspondiente del DataSource y precorta (o corta según demanda) la «ventana de datos» para cada paso de tiempo.
Antes de ejecutar cada paso: para cada estrategia del grupo que se ejecutará en el paso actual, el motor llama a update_running_data_window para escribir la ventana de datos para el paso actual en el estado interno de esa estrategia (indexada por dtype_id).
Dentro de realizar(): la estrategia recupera los datos de la ventana inyectada (una matriz numerosa) por id a través de get_data(dtype_id) para calcular las señales. No se necesitan parámetros y no hay necesidad de preocuparse de qué tabla provienen los datos.
Por lo tanto, el flujo de datos es «declaración → el motor inyecta paso a paso → get_data hace referencia a él». El código de estrategia no contiene ninguna lógica de “lectura de tabla” o de “tirar/buscar”.
4.4. 4. 数据窗口的含义
Dimensión de tiempo: window_length significa «cuántos períodos mirar hacia atrás». Por ejemplo, con frecuencia diaria, window_length=20 significa datos de los 20 días hábiles más recientes; la forma de la matriz suele ser (n_periods) o (n_assets, n_periods), siendo la última dimensión el tiempo y la última columna el período más reciente.
Formas en casos de múltiples activos: diferentes clases base de estrategias organizan los datos de forma ligeramente diferente:
RuleIterator: normalmente se itera por activo; cada realizar() ve una serie de tiempo o sección transversal de un solo activo.
FactorSorter: una sección transversal de múltiples activos (por ejemplo, un valor de factor por acción), que se utiliza para clasificar y seleccionar acciones.
GeneralStg: ventanas de múltiples activos y múltiples tipos, que devuelven una matriz de señales con la misma longitud que la cantidad de activos.
Las formas exactas están sujetas a la API y a la documentación de la clase base de estrategia; esta serie enfatiza que «el motor prepara las ventanas de acuerdo con las declaraciones y la estrategia las recupera por identificación a través de get_data».
4.5. 5. 过程数据(proc.*)
Además de los datos históricos estáticos descritos anteriormente (“declaración → inyección del motor”), qteasy admite datos de proceso: estado que depende de la ruta de ejecución en vivo/backtest (como posiciones actuales, efectivo, registros comerciales históricos, etc.). Los datos del proceso no es necesario declararlos en tipos_de_datos; Backtester (backtesting) o Trader (comercio en vivo) lo mantienen e inyectan en tiempo de ejecución.
Patrón de acceso: en
realize(), recupere según sea necesario a través de formularios comoself.get_data('proc.own_cash'),self.get_data('proc.trade_records', lag=0), etc.; admite los parámetroslag(pasos o tiempo como'1d') ywindow(como'5d').Restricción: una sola llamada permite solo un campo
proc.*y no debe mezclarse con datos estáticos en la misma llamada; cualquier estrategia que utilice datos de proceso seguirá automáticamente el camino del backtesting dinámico (generar señales paso a paso, ejecutar operaciones paso a paso).
Consulte Datos de proceso (proc.*) y Backtesting dinámico para obtener más detalles.
4.6. 6. 参考数据(若有)
Además de los tipos de datos declarados por la estrategia, qteasy admite «datos de referencia» (como el precio de cierre de un índice, utilizado para calcular los rendimientos del mercado, etc.). La diferencia entre los datos de referencia y los datos primarios es que generalmente no tienen una correspondencia uno a uno con el grupo de activos y también se pueden obtener en una estrategia a través del dtype_id correspondiente o una interfaz dedicada. Para conocer métodos de configuración y referencia específicos, consulte la documentación y la API de la versión actual.
4.7. 7. 小结
“Declarar → inyecciones de motor → referencias get_data” garantiza que:
Las pruebas retrospectivas y las operaciones en vivo utilizan la misma vista de datos y patrón de acceso;
La estrategia no puede acceder a datos futuros o no declarados, lo que evita el sesgo de anticipación a nivel del mecanismo;
Una interfaz unificada que es fácil de mantener y ampliar.
«Declaración → inyección de motor → referencia get_data» también se aplica a los datos del proceso, excepto que no es necesario declarar los datos del proceso, la capa de tiempo de ejecución los inyecta paso a paso y solo activa la ruta de backtesting dinámico cuando se usa. Para obtener más información sobre su uso, consulte la “Guía del usuario” y la “Referencia de API”.