2. Adquirir y gestionar datos financieros
qteasy es un conjunto de herramientas de análisis comercial cuantitativo totalmente implementado y ejecutado localmente con las siguientes características:
Adquisición, limpieza, almacenamiento, procesamiento, visualización y uso de datos financieros.
Creación de estrategias comerciales cuantitativas, con una gran cantidad de estrategias comerciales básicas integradas proporcionadas.
Backtesting vectorizado de alta velocidad de estrategias comerciales y evaluación de resultados comerciales
Optimización y evaluación de parámetros de estrategia comercial.
Implementación y negociación en vivo de estrategias comerciales.
A través de esta serie de tutoriales, obtendrá una comprensión profunda de las características principales de qteasy y cómo utilizarlas a través de una serie de ejemplos prácticos.
2.1. Preparativos antes de comenzar
Antes de comenzar este tutorial, complete lo siguiente:
Complete la instalación de
qteasyy actualice a la última versión数据通道(二选一或组合):
使用 Tushare:注册
tushare pro账户并确保有一定的积分(大多数高级数据需要较多积分才能下载),在qteasy.cfg中配置tushare_token使用 AKShare 或其他通道:安装
pip install akshare(若选 AKShare),无需 Tushare token;部分表覆盖范围小于 Tushare,详见数据通道文档
完成
mysql数据库的配置,并将数据库配置写入qteasy.cfg(可选项)Complete la instalación de
ta-lib(opcional)
En el [tutorial anterior] (1-get-started.md), expliqué cómo crear un nuevo entorno virtual e instalar e inicializar qteasy en él. Si aún no ha completado este paso, consulte el tutorial anterior para finalizar la instalación de qteasy y la configuración básica.
Además, para facilitar el uso de funciones como los gráficos en el futuro, se recomienda utilizar jupyter notebook para el desarrollo. Puede ejecutar el siguiente comando en el entorno virtual recién creado para instalar jupyter notebook:
(bash): pip install notebook
Una vez completada la instalación, puede utilizar el siguiente comando para iniciar jupyter notebook:
(bash): jupyter notebook
Después del inicio, puede ejecutar código en un entorno de desarrollo interactivo en su navegador, como se muestra en la siguiente figura:

Si no usa jupyter notebook, también puede usar ipython:
(bash): pip install ipython
ipython se ejecuta en la terminal, pero su soporte para gráficos no es tan bueno.
2.2. Obtener datos básicos y datos de precios.
Como se introdujo en el tutorial anterior, un qteasy recién inicializado no puede acceder a ningún dato histórico. Todos los datos históricos primero deben descargarse localmente y guardarse en un repositorio de datos llamado Datasource antes de poder realizar cualquier trabajo posterior dependiente de los datos, como recuperar datos históricos, realizar pruebas retrospectivas y optimizar estrategias, etc.
qteasy necesita utilizar muchos tipos de datos. Todos los datos se almacenan en algunas tablas de datos predefinidas y Datasource es una colección de una serie de tablas de datos. Las tablas de datos más básicas incluyen:
trade_calendar: datos del calendario de operaciones, incluidas las fechas planificadas de apertura y cierre del mercado para diferentes intercambios; El calendario comercial para el próximo año se actualiza al final de cada año.stock_basics: información bursátil básica, incluida información básica de todas las acciones en los mercados de valores de Shanghai y Shenzhen, como código, nombre, nombre completo, fecha de cotización, categoría, etc.index_basics: información básica del índice, incluida información básica de todos los índices de los mercados bursátiles de Shanghai y Shenzhen, como código, nombre, nombre completo, etc.
Después de configurar tushare_token, cuando importe qteasy por primera vez, si el sistema no puede encontrar datos del calendario comercial, mostrará un mensaje indicando que el calendario comercial no se puede leer.
Para obtener más información sobre el objeto de fuente de datos DataSource, consulte DataSource Referencia.
>>> import qteasy as qt
Consejo:
UserWarning: trade calendar is not loaded, some utility functions may not work properly, to download trade calendar, run
"qt.refill_data_source(tables='trade_calendar')"
qteasy proporciona una función get_table_overview() para mostrar información sobre datos almacenados localmente. Al ejecutar esta función se imprime una lista de las tablas de datos guardadas localmente, la cantidad de datos almacenados, el espacio en disco utilizado, el rango de datos, etc.
>>> qt.get_table_overview()
El proceso de análisis de la tabla de datos puede tardar unos minutos. Durante este tiempo, se mostrará una barra de progreso para mostrar el progreso del análisis. Una vez completado el análisis, se mostrará una lista de tablas en la fuente de datos local, junto con información como el rango de datos de cada tabla.
Si no hay datos en la fuente de datos actual, se generará lo siguiente:
Analyzing local data source tables... depending on size of tables, it may take a few minutes
Analyzing completed!
Analyzing tables: 100%|█████████████████████████| 104/104 [00:00<00:00, 9107.58it/s]
Finished analyzing datasource:
file://csv@qt_root/data/
0 table(s) out of 104 contain local data as summary below, to view complete list, print returned DataFrame
===============================tables with local data===============================
Empty DataFrame
Columns: [has_data, size, records, min2, max2]
Index: []
Si no hay datos en la fuente de datos local, se mostrará el contenido anterior. En este caso, deberá descargar los datos a la fuente de datos local.
Descargue el calendario comercial y los datos básicos.
我们可以调用refill_data_source函数下载交易日历和基础数据。这个函数是qteasy的标准数据下载接口函数,所有的历史数据类型均可以通过此接口下载。这个函数的基本参数是tables,传入数据表的名称即可下载相应的数据到本地存储了。使用refill_data_source下载交易数据时,qteasy会自动进行数据清洗,排除重复数据,去除错误数据,发生错误自动重试,并将下载的数据合并到本地数据表中。
qteasy支持通过 tushare、akshare、eastmoney、sina 等多个内置通道下载数据(参数 channel,未指定时默认为 tushare)。不同通道支持的表范围与前置条件不同,切换方式与能力对照见数据通道文档。
要下载前面提到的交易日历、股票和指数的基本信息,只需要运行下面的代码(默认使用 Tushare,需已配置 tushare_token):
>>> qt.refill_data_source(tables='trade_calendar, stock_basic, index_basic')
Durante el proceso de descarga de datos, se mostrará una barra de progreso para mostrar el progreso de la descarga.
El resultado es el siguiente:
Filling data source file://csv@qt_root/data/ ...
into 3 table(s) (parallely): {'trade_calendar', 'index_basic', 'stock_basic'}
<trade_calendar> 72609 wrn: 100%|███████████████| 8/8 [00:03<00:00, 2.39task/s]
<index_basic> 12456 wrn: 100%|██████████████████| 8/8 [00:00<00:00, 9.68task/s]
<stock_basic> 5484 wrn: 100%|███████████████████| 4/4 [00:00<00:00, 5.45task/s]
Data refill completed! 90549 rows written into 3/3 table(s)!
Una vez completada la descarga, ejecute la función qt.get_table_overview() nuevamente.
>>> qt.get_table_overview()
Puede ver que los datos se han descargado correctamente localmente:
Analyzing local data source tables... depending on size of tables, it may take a few minutes
Analyzing tables: 100%|████████████████████████| 104/104 [00:00<00:00, 967.60it/s]
Analyzing completed!
Finished analyzing datasource:
file://fth@qt_root/data/
3 table(s) out of 104 contain local data as summary below, to view complete list, print returned DataFrame
===============================tables with local data===============================
Has_data Size_on_disk Record_count Record_start Record_end
table
trade_calendar True 1.3MB 73K CFFEX SZSE
stock_basic True 651KB 5K None None
index_basic True 1.1MB 12K None None
Como puede ver, las tres tablas de datos ya se descargaron a la fuente de datos local. El tipo de fuente de datos es "file://csv@qt_root/data/" (es decir, los datos se almacenan como archivos csv en la ruta /data/ en el directorio raíz qt). Contiene tres tablas de datos y el calendario comercial abarca hasta finales de 2024.
Ver datos básicos de acciones e índices
Después de descargar los datos básicos anteriores, se recomienda reiniciar el IDE y volver a importar qteasy. En este punto, podemos usar qteasy para filtrar y buscar acciones/índices.
Para buscar información detallada sobre acciones/índices, puede utilizar la función get_stock_info() o get_basic_info(). Las dos funciones tienen la misma funcionalidad: ambas pueden buscar información de seguridad según el código de seguridad ingresado, el nombre o las palabras clave, y admiten comodines o búsqueda difusa. Si el mismo código corresponde a diferentes qt_code, por ejemplo, la acción 000001 representa Ping An Bank, con qt_code: 000001.SZ, mientras que el índice 000001 representa el índice compuesto SSE, con qt_code: 000001.SZ—qteasy enumerará toda la información de seguridad:
# 通过完整的qt_code获取信息
>>> qt.get_basic_info('000001.SZ')
El resultado es el siguiente:
found 1 matches, matched codes are {'E': {'000001.SZ': '平安银行'}, 'count': 1}
More information for asset type E:
------------------------------------------
ts_code 000001.SZ
name 平安银行
area 深圳
industry 银行
fullname 平安银行股份有限公司
list_status L
list_date 1991-04-03
-------------------------------------------
Se pueden ver más resultados en la siguiente figura:

En el ejemplo anterior, el sistema solo encontró valores de tipo acción e índice. Si también necesitas consultar más información sobre valores como fondos y futuros, puedes descargar más tablas de datos básicos de la misma forma:
fund_basic: Datos básicos del fondo
future_basic: Datos básicos de futuros
Además de buscar información básica sobre acciones o valores, también podemos utilizar la función qt.filter_stock() para filtrar acciones:
>>> qt.filter_stocks(date='20240212', industry='银行', area='上海')
El resultado es el siguiente:
name area industry market list_date exchange
qt_code
600000.SH 浦发银行 上海 银行 主板 1999-11-10 SSE
601229.SH 上海银行 上海 银行 主板 2016-11-16 SSE
601328.SH 交通银行 上海 银行 主板 2007-05-15 SSE
601825.SH 沪农商行 上海 银行 主板 2021-08-19 SSE
Descargue los datos bursátiles que cotizan en Shanghai
Entre los datos financieros, el tipo más importante son, sin duda, los datos de precios y volúmenes. A continuación, descargaremos datos históricos de precios.
Todos los datos históricos en qteasy se almacenan en tablas de datos en forma de datos de velas japonesas (línea K). Los datos de velas actualmente admitidos incluyen:
Gráficos de velas de minutos: gráficos de velas de 1 minuto/5 minutos/15 minutos/30 minutos/60 minutos
Gráfico de velas diario
Gráfico de velas semanales
Gráfico de velas mensuales
También utilizamos la función qt.refill_data_source() para descargar datos bursátiles. Los datos de velas bursátiles diarias (línea K) más utilizados se almacenan en la tabla stock_daily. Sin embargo, debido a que el volumen de datos es grande, es mejor limitar el rango de datos al descargar. Utilice los parámetros start_date/end_date para especificar las fechas de inicio y finalización y descargar datos históricos en lotes; de lo contrario, el proceso de descarga llevará mucho tiempo:
>>> qt.refill_data_source(tables='stock_daily', start_date='20230101', end_date='20231231')
El código anterior descarga datos de velas diarias (línea K) para todas las acciones cotizadas durante todo el año 2023. Del mismo modo, el siguiente código se puede utilizar para descargar datos de velas diarias (línea K) para índices de uso común (el índice compuesto SSE y el índice CSI 300):
>>> qt.refill_data_source(tables='index_daily', symbols='000001, 000300', start_date='20231231', end_date='20240208')
Obtenga datos sobre el precio de las acciones desde el almacenamiento local
Una vez que los datos del precio de las acciones se guardan localmente, puede extraerlos y utilizarlos en cualquier momento.
Podemos utilizar la función qt.get_history_data() para obtener los datos de precio y volumen de una acción. Esta función es una interfaz de propósito general en qteasy y se puede utilizar para recuperar varios tipos de datos. Al especificar el tipo de datos (a través del ID del tipo de datos), el ticker bursátil y otros parámetros en los argumentos de la función, puede obtener los datos correspondientes. Si desea recuperar los precios de velas (línea K) que acaba de descargar, configure el tipo de datos en "open, high, low, close, vol" para obtener el volumen de apertura, máximo, mínimo, cierre y negociación:
>>> qt.get_history_data(
... 'open, high, low, close, vol', # 数据类型,分别为开盘价、最高价、最低价、收盘价、成交量
... shares='000001.SZ', # 股票代码:平安银行
... start='20230101', # 数据开始日期
... end='20230301', # 数据结束日期
... )
El resultado es el siguiente:
{'000001.SZ':
open high low close vol
2023-01-04 13.71 14.42 13.63 14.32 2189682.53
2023-01-05 14.40 14.74 14.37 14.48 1665425.18
2023-01-06 14.50 14.72 14.48 14.62 1195744.71
2023-01-09 14.75 14.88 14.52 14.80 1057659.11
2023-01-10 14.76 14.89 14.39 14.44 1269423.39
2023-01-11 14.45 14.78 14.39 14.67 830566.12
2023-01-12 14.77 14.77 14.53 14.67 625694.84
2023-01-13 14.67 14.95 14.55 14.95 949085.83
2023-01-16 14.95 15.28 14.85 15.08 1560039.89
2023-01-17 15.13 15.18 14.77 14.97 935834.54
2023-01-18 14.95 15.18 14.91 15.11 718434.03
2023-01-19 15.13 15.25 14.87 15.09 641875.20
2023-01-20 15.16 15.24 15.00 15.13 608590.08
2023-01-30 15.60 15.74 14.89 15.15 1374317.50
2023-01-31 15.24 15.51 14.96 14.99 1030497.84
2023-02-01 15.03 15.08 14.51 14.70 1653421.48}
El resultado de la función anterior es un diccionario: sus claves son los tickers de todas las acciones especificadas por el parámetro shares, y sus valores son DataFrame que contienen los datos históricos de cada acción para el período especificado. Aquí especificamos el tipo de datos como datos de precio y volumen de velas japonesas (línea K). Por supuesto, también podemos especificar otros tipos de datos; siempre que esos datos ya se hayan descargado localmente, se pueden leer directamente.
Por ejemplo, especificar los tipos de datos htypes='pe, pb, total_mv' le permite obtener tres indicadores financieros, como la relación precio-beneficio de una acción, la relación precio-valor contable y la capitalización de mercado total. Si a algunos indicadores les faltan valores, puede definir un método de llenado para completar los valores faltantes. También puede volver a muestrear los datos, convirtiendo datos diarios en datos semanales u horarios.
Para obtener una explicación detallada de los parámetros de la función get_history_data, consulte la qteasy documentación
Generar un gráfico de velas
Cuando se utilizan datos de volumen y precio, un enfoque más conveniente y legible es mostrar los datos como un gráfico de velas.
qteasy proporciona la función qt.candle() para mostrar gráficos de velas profesionales. Siempre que los datos se hayan descargado localmente, puedes mostrar un gráfico de velas inmediatamente:
>>> qt.candle('600004.SH', start='20230101', end='20230301')

Después de descargar los datos del factor de ajuste a su máquina local, puede mostrar los precios ajustados:
>>> qt.refill_data_source(tables='adj', start_date='20230101', end_date='20230601')
>>> qt.candle('600004.SH', start='20230101', end='20230301', adj='b')

La función qt.candle() admite pasar la fecha de inicio, la fecha de finalización, la frecuencia de la vela (línea K) y el método de ajuste para mostrar gráficos de velas para diferentes rangos y frecuencias. También admite pasar las duraciones de las medias móviles y diferentes parámetros MACD para mostrar diferentes medias móviles. Además, qt.candle() admite la visualización de gráficos de velas japonesas por nombre de acción: si la entrada es el nombre de una acción, realizará automáticamente una búsqueda difusa y también admite comodines.
A continuación se muestran más ejemplos de gráficos de velas que muestran diferentes clases de activos, como acciones, fondos e índices; diferentes frecuencias de datos; diferentes configuraciones de media móvil; diferentes tipos de gráficos; etcétera. Para mostrar los gráficos de velas en los ejemplos siguientes, debe descargar los datos correspondientes.
>>> import qteasy as qt
>>> df = qt.candle('159601', start='20210420', freq='d')
>>> df = qt.candle('000001.SH', start = '20211221', asset_type='IDX', plot_type='c')
>>> df = qt.candle('000300.SH', start = '20220331', asset_type='IDX', mav=[], plot_type='c')
>>> df = qt.candle('000300.SH', start = '20221021', asset_type='IDX', mav=[], plot_type='c',
>>> freq='30min')
>>> df = qt.candle('601728', freq='30min', adj='b', plot_type='c')
>>> df = qt.candle('沪镍主力', start = '20211130', mav=[5, 12, 36])
>>> df = qt.candle('510300', start='20200101', asset_type='FD', adj='b', mav=[])
>>> df = qt.candle('格力电器', start='20220101', asset_type='E', adj='f', mav=[5, 10, 20, 30])
>>> df = qt.candle('513100', asset_type='FD', adj='f', mav=[])
>>> df = qt.candle('110025', asset_type='FD', adj='f', mav=[9, 28])
>>> df = qt.candle('001104', asset_type='FD', adj='f', mav=[12, 26])











2.3. Buscando el tipo de datos DataType
Como se mencionó anteriormente, todos los tipos de datos en qteasy están encapsulados como objetos DataType, lo que representa un tipo de datos históricos que se pueden usar directamente. Cada DataType tiene una identificación única. Con esta identificación, puede extraer datos, hacer referencia a ese tipo de datos en estrategias comerciales y realizar las tareas requeridas en qteasy.
Para comprender mejor los tipos de datos en qteasy, podemos usar la función qt.find_history_data() para consultar los tipos de datos que necesitamos. Los tipos de datos definidos en qteasy están vinculados a la frecuencia de los datos y al tipo de activo. En otras palabras, el precio de cierre de diferentes activos es un tipo de datos diferente, y el precio de cierre en diferentes frecuencias también es un tipo de datos diferente.
La función qt.find_history_data() puede buscar tipos de datos relevantes según su entrada y mostrar sus ID, tablas de datos, descripciones y otra información relacionada. Por ejemplo, al buscar ‘close’ (precio de cierre) se pueden encontrar todos los tipos de datos relacionados:
>>> qt.find_history_data('close')
Obtendrá el siguiente resultado:
matched following history data,
use "qt.get_history_data()" to load these historical data by its data_id:
------------------------------------------------------------------------
freq asset table desc
data_id
close d E stock_daily 股票日K线 - 收盘价
close w E stock_weekly 股票周K线 - 收盘价
close m E stock_monthly 股票月K线 - 收盘价
close 1min E stock_1min 股票60秒K线 - 收盘价
... ... ... ... ...
close h FD fund_hourly 基金小时K线 - 收盘价
close d Any top_list 融资融券交易明细 - 收盘价
========================================================================
Para otro ejemplo, la búsqueda de la relación precio-beneficio (pe) produce:
>>> qt.find_history_data('pe')
Obtendrá el siguiente resultado:
matched following history data,
use "qt.get_history_data()" to load these historical data by its data_id:
------------------------------------------------------------------------
freq asset table desc
data_id
initial_pe d E new_share 新股上市信息 - 发行市盈率
pe d IDX index_indicator 指数技术指标 - 市盈率
pe d E stock_indicator 股票技术指标 - 市盈率(总市值/净利润, 亏损的PE为空)
pe_2 d E stock_indicator2 股票技术指标 - 动态市盈率
========================================================================
Después de encontrar los datos correspondientes, solo necesita verificar a qué tabla de datos pertenece, descargar esa tabla en la fuente de datos local (refill_data_source(tables, ...)) y luego podrá usar estos datos (qt.get_history_data(htype, shares, ...)).
Una breve introducción al objeto DataType
Como se muestra arriba, los tipos de datos en qteasy existen en forma de objetos DataType. Cada tipo de datos tiene una identificación única. Con esta ID puede extraer datos, hacer referencia al tipo de datos en estrategias comerciales y completar el trabajo requerido en qteasy.
DataType representa un tipo de datos históricos que se pueden extraer de una fuente de datos. Por ejemplo, el precio de cierre de una vela diaria de acciones (línea K) es un tipo de datos históricos; el precio de cierre de una vela semanal de acciones es otro tipo de dato histórico; y el precio de cierre de una vela mensual de acciones es otro tipo de dato histórico. Aunque todos son precios de cierre, debido a que sus frecuencias difieren, se encapsulan como tipos de datos diferentes.
La clase DataType encapsula una API y atributos de recuperación de datos unificados, lo que facilita enormemente el uso de datos históricos en qteasy. Cuando necesitamos cierto tipo de datos históricos, solo necesitamos usar su ID y llamar a get_history_data para recuperarlos directamente.
Y si necesita utilizar cierto tipo de datos en una estrategia comercial, sólo necesita registrar el ID de esos datos durante el proceso de definición de la estrategia. Luego podrás usarlo directamente en la estrategia sin preocuparte por detalles como cómo se almacenan los datos, cómo se descargan, cómo se limpian, etc.
2.4. Descargar datos al almacenamiento local de forma regular
Para mantener actualizada la fuente de datos local, podemos usar la función qt.refill_data_source() para descargar datos localmente periódicamente. Crea un archivo refill_data.py y escribe el siguiente código en él:
import qteasy as qt
if __name__ == '__main__':
# 解析命令行参数,--tabls参数表示数据表类型,--start_date和--end_date表示下载数据的起始日期和结束日期
import argparse
parser = argparse.ArgumentParser(description='refill data source')
parser.add_argument('--tables', type=str, default='stock_daily', help='data table type')
parser.add_argument('--start_date', type=str, default='20230101', help='start date')
parser.add_argument('--end_date', type=str, default='20231231', help='end date')
parser.add_argument('--parallel', type=bool, default=True, help='parallel download')
parser.add_argument('--merge_type', type=str, default='update', help='merge type')
args = parser.parse_args()
tables = args.tables
start_date = args.start_date
end_date = args.end_date
parallel = args.parallel
merge_type = args.merge_type
if tables == 'events':
# 下载低频data和event数据,下载周期较长以cover所有的季度月度周度数据 (每周下载或每月下载)
tables = 'stock_weekly, stock_monthly, index_weekly, index_monthly, '
tables += 'income, balance, cashflow, financial, forecast, express, comp, report, events'
elif tables == 'basics':
# 下载基础数据,下载周期较长以cover所有的季度月度周度数据 (每周下载或每月下载)
tables = 'basics'
elif tables == 'daily':
# 下载日频数据,下载周期较短以减少下载负载 (每天或每周下载)
tables = 'adj, stock_daily, fund_daily, future_daily, options_daily, stock_indicator, stock_indicator2, index_indicator, shibor, libor, hibor, index_daily'
elif tables == 'stock_mins':
tables = 'adj, stock_1min, stock_5min, stock_15min, stock_30min, stock_hourly'
elif tables == 'index_mins':
tables = 'adj, index_1min, index_5min, index_15min, index_30min, index_hourly'
elif tables == 'fund_mins':
tables = 'adj, fund_1min, fund_5min, fund_15min, fund_30min, fund_hourly'
else:
tables == tables
qt.refill_data_source(tables=tables,
start_date=start_date,
end_date=end_date,
parallel= parallel,
merge_type=merge_type)
El archivo de script anterior proporciona la funcionalidad de descarga de datos más básica. Puede modificar los parámetros tables y start_date/end_date, así como los parámetros parallel y merge_type, según sea necesario para descargar diferentes tipos de datos y diferentes rangos de fechas. También puede mejorar el archivo de secuencia de comandos usted mismo para implementar más funciones.
Para descargar los datos stock_daily del año completo 2023, solo necesita ejecutar el siguiente comando en la línea de comando:
(bash): python -m refill_data --tables stock_daily --start_date 20230101 --end_date 20231231
2.5. Revisión y resumen
En este punto, hemos obtenido una comprensión preliminar de cómo qteasy administra los datos y cómo descargarlos. Descargamos datos básicos, así como algunos datos de precio y volumen. Aprendimos cómo extraer datos y cómo mostrar gráficos de velas. Finalmente, también aprendimos cómo consultar datos: si necesita un determinado tipo de datos, sabrá cómo buscarlos, cómo descargarlos y cómo llamarlos.
En el próximo tutorial, profundizaremos nuestra comprensión de qteasy. Aprenderemos cómo crear estrategias comerciales y cómo ejecutarlas y realizar pruebas retrospectivas.
Para obtener más información sobre qteasy, consulte la qteasy documentación