3. HistoryPanel (panel de datos históricos)
Este capítulo presenta HistoryPanel: basándose en la comprensión de DataType, demuestra cómo consolidar datos históricos de múltiples objetivos, métricas y la misma línea de tiempo en un solo «panel» y reutilizarlos en la investigación de estrategias, la preparación de pruebas retrospectivas y la visualización. La lectura de este capítulo no requiere la lectura previa de [Fuente de datos local] (3.%20datasource.md), pero si aún no ha completado su fuente de datos local con datos, complete la descarga y configuración antes de usar get_history_data para recuperar datos.
En el capítulo anterior, vimos que qteasy usa DataType para abstraer las «columnas sin procesar en la tabla de datos» en información que puede ser consumida directamente por la estrategia y el backtesting. Cuando es necesario alinear esta información con la misma línea de tiempo con múltiples objetivos y varios tipos de datos (como OHLC, volumen, MACD, etc.), la concatenación manual de múltiples DataFrames no solo es propensa a errores, sino que también dificulta la reutilización de la misma estructura de datos entre el código de estrategia y el código de visualización.
HistoryPanel es un contenedor diseñado para este escenario: internamente, organiza datos en una estructura tridimensional de compartidos × índice × htipos, lo que le permite dividir y filtrar recursos compartidos o métricas utilizando una interfaz unificada y reutilizar el mismo objeto en pruebas retrospectivas, lógica estratégica o trazado posteriores. Para la mayoría de los usuarios, no necesita preocuparse por cómo interactúa internamente el panel con la fuente de datos local; después de obtener HistoryPanel a través de flujos de trabajo familiares como get_history_data, puede usarlo como un «conjunto de datos multimétrico, multicompartido y alineado en el tiempo».
Este capítulo explica los conceptos básicos y los usos comunes de HistoryPanel; el siguiente capítulo, HistoryPanel Visualización, se basa en esto para presentar cómo usar hp.plot() para trazar directamente el mismo panel como un gráfico estático o interactivo. Las funcionalidades de la API de recuperación de datos de nivel inferior solo se enumeran brevemente en Referencia de API para evitar confusiones con rutas comunes.
3.1. Conceptos básicos: estructura 3D y shape
El HistoryPanel corresponde a un numpy.ndarray tridimensional en memoria, con los tres ejes de la siguiente manera:
eje |
Significado |
Propiedades comunes |
|---|---|---|
0ma dimensión |
Objetivo (código de acciones, etc.) |
|
1ra dimensión |
Hora (fecha o momento histórico) |
|
2da dimensión |
Tipos de datos (como |
|
shape devuelve (número de objetivos, duración del tiempo, número de tipos de datos), en el mismo orden que el anterior. Puede entenderse como: muchas tablas bidimensionales de «tiempo × métrica» se apilan una encima de la otra en la dirección objetivo; dentro de un mismo panel, los objetivos y métricas están alineados en el tiempo.
En comparación con una tabla de índice único DataFrame (las filas son tiempo, las columnas son índices), HistoryPanel coloca explícitamente múltiples índices en la dimensión 0, lo que facilita las operaciones por lotes y la división basada en índices, sin tener que mantener múltiples columnas MultiIndex.
(Diagrama ilustrativo: el «bloque 3D» puede entenderse como índice de capa L × tiempo de fila R × índice de columna C; se puede agregar una ilustración en una versión posterior si es necesario).
3.2. Cómo obtener HistoryPanel
El enfoque recomendado es utilizar **qt.get_history_data(..., as_data_frame=False): suponiendo que los datos requeridos ya estén disponibles en la fuente de datos local, puede obtener el HistoryPanel alineado especificando htype_names (consistente con el nombre DataType, consulte el capítulo anterior) junto con shares, el rango de tiempo o rows.
De forma predeterminada, get_history_data establece as_data_frame en True, devolviendo un dict[str, DataFrame] agrupado por índice, adecuado para ver rápidamente datos de un solo índice; cuando se requiera un panel 3D, asegúrese de pasar as_data_frame=False. Para obtener información completa sobre parámetros, frecuencia y ponderación, consulte API de datos históricos.
El siguiente ejemplo no depende de la red y utiliza una pequeña matriz para construir el panel, lo que facilita la comprensión del shape y las etiquetas; en el trabajo real, se puede usar get_history_data para completarlo desde una fuente de datos local.
import numpy as np
import pandas as pd
from qteasy import HistoryPanel
# 2 只标的、4 个交易日、3 种数据类型 → shape (2, 4, 3)
values = np.array(
[
[[1.0, 1.1, 100], [1.2, 1.3, 110], [1.15, 1.2, 105], [1.25, 1.28, 120]],
[[10.0, 10.5, 200], [10.2, 10.8, 210], [10.1, 10.4, 205], [10.3, 10.9, 215]],
],
dtype=float,
)
hp = HistoryPanel(
values=values,
levels=['000001.SZ', '000002.SZ'],
rows=pd.date_range('2025-01-02', periods=4, freq='B'),
columns=['open', 'high', 'vol'],
)
print(hp.shape) # (2, 4, 3)
print(hp.shares) # 标的列表
print(hp.htypes) # 数据类型列表
Si los datos del mercado local ya están disponibles, se pueden cambiar a:
import qteasy as qt
hp = qt.get_history_data(
htype_names='open, high, low, close, vol',
shares='000001.SZ',
rows=60,
as_data_frame=False,
)
print(hp.shape, hp.shares, hp.htypes)
3.3. Operaciones básicas: rango de tiempo, objetivo y subconjunto de indicadores
Los siguientes métodos limitan su enfoque actual sin cambiar la semántica de recuperación de datos; el valor de retorno sigue siendo HistoryPanel (excepto para los paneles vacíos).
Por rango de fechas:
segment(start_date, end_date), todas las filas de tiempo dentro del rango cerrado; las fechas pueden ser consistentes con la granularidad enhdates(frecuencia diaria, intradiario, etc.).Por rango de números de fila:
isegment(start_index, end_index), similar al corte de Python, es adecuado para extraer segmentos por posición.**Líneas recientes:
head(n)/tail(n).Filtrar por objetivo y/o nombre de indicador:
slice(shares='A, B', htypes='close, vol'), se acepta una cadena o una lista.
Al realizar un análisis de pandas en datos de índice único o de índices múltiples, puede usar to_share_frame(share) para obtener un DataFrame para ese índice (con el tiempo como índice y htypes como columnas). Para obtener más información sobre la exportación de datos de índices múltiples, consulte la documentación de la API para to_df_dict y otra documentación relacionada.
En el Operator y el proceso de backtesting, los datos históricos a menudo se inyectan en grupos durante la fase de programación de la ejecución de la estrategia; Los parámetros específicos y las configuraciones de programación se pueden encontrar en el capítulo correspondiente de «Creación y operación de estrategias comerciales». Aquí, basta con establecer lo siguiente: Las estrategias y visualizaciones pueden girar en torno al mismo HistoryPanel (o sus sectores), reduciendo así la organización repetitiva de «un conjunto de datos en múltiples formatos».
3.4. Métricas y extensiones de columnas (kline, etc.)
A partir de la clase de precio existente htypes, puede acceder a columnas derivadas comunes, como promedios móviles, MACD y bandas de Bollinger, a través del descriptor de acceso hp.kline. Estos métodos normalmente devuelven un nuevo HistoryPanel: agregando columnas indicadoras a la tercera dimensión, sin modificar el objeto original y manteniendo shares y hdates consistentes con el panel original. Los nombres de columnas ajustados (como close|b) se alinearán con la lógica de análisis de kline, returns, etc., en versiones más recientes; Si existen nombres de columna sin formato y ajustados en el panel, se recomienda leer la descripción del comportamiento en la HistoryPanel API.
Se pueden encontrar ejemplos más completos de métodos basados en factores (rendimiento, volatilidad, apply_ta, etc.) en el tutorial Uso de HistoryPanel para manipular y analizar datos históricos.
3.5. Resumen y próximos pasos
HistoryPanel proporciona un contenedor unificado de (objetivo × tiempo × tipo de datos), adecuado para la investigación y la preparación de pruebas retrospectivas con múltiples objetivos, múltiples métricas y alineación temporal.
La función
get_history_data(..., as_data_frame=False)se usa comúnmente para recuperar el marco de datos; De forma predeterminada, primero puede leer el capítulo anterior sobre nombres de DataType yget_dtype_map().Rebanadas y subconjuntos: segmento / isegmento / cabeza / cola / rebanada; Exportando un solo fotograma: to_share_frame.
Siguiente capítulo HistoryPanel Visualización: Uso de
hp.plot()para crear gráficos estáticos o interactivos.Si los datos locales no están listos, lea Fuente de datos local y Obtención de datos y canales primero.