当前位置: 首页 > news >正文

python量化交易——金融数据管理最佳实践——qteasy创建本地数据源

文章目录

  • qteasy金融历史数据管理
    • 总体介绍
    • 本地数据源——DataSource对象
      • 默认数据源
      • 查看数据表
      • 查看数据源的整体信息
      • 最重要的数据表
        • 其他的数据表
      • 从数据表中获取数据
      • 向数据表中添加数据
      • 删除数据表 —— 请尽量小心,删除后无法恢复!!
      • 总结

qteasy金融历史数据管理

qteasy 是一套功能全面的量化交易工具包,金融数据的获取和使用是qteasy提供的核心功能之一。

总体介绍

目前,网上有很多不同的金融数据获取渠道,可供量化交易者下载金融数据,但是直接从网上下载数据,有许多缺点:

  • 数据格式不统一:同样的数据,例如交易量数据,有些渠道提供的数据单位为“手”,而另一些提供的数据为“股”
  • 可提取的数据量有限:尤其是通过爬虫获取的数据,高频K线数据往往只有过去几天的数据,更久以前的数据无法提供
  • 数据提取不稳定:数据提取速度和成功率不能保证,受网络连接影响很大
  • 下载成本较高:收费数据渠道往往能提供更全面的数据,但是一般都有流量限制,而免费渠道提供的数据不全,也提高成本
  • 信息提取不易:获得原始数据以后,还需要进一步将数据转化为需要的信息,这个过程费力且不直观

qteasy就是为了解决上面提到的这些痛点而设计的。

qteasy的金融数据管理模块提供了三个主要的功能,这三个功能的设计,着眼点都是为了

  • 数据拉取:从多个不同的网络数据提供商拉取多种金融数据,满足不同用户的使用习惯:

    qteasy提供的数据拉取API具备强大的多线程并行下载、数据分块下载、下载流量控制和错误延时重试功能,以适应不同数据供应商各种变态的流量限制,同时数据拉取API可以方便地定期自动运行完成数据批量下载任务,不用担心错过高频数据。

  • 数据清洗和存储:标准化定义本地数据存储,将从网络拉取的数据清洗、整理后保存到本地数据库中:

    qteasy定义了一个专门用于存储金融历史数据的DataSource类,并以标准化的形式预定义了大量金融历史数据存储表,不管数据的来源如何,最终存储的数据始终会被清洗后以统一的格式存储在DataSource中,避免不同时期不同来源的数据产生偏差,确保数据高质量存储。同时提供多种存储引擎,满足不同用户的使用习惯。

  • 信息提取和使用:区分“数据“和”信息,“提供接口将集中在数据表中的真正有意义的信息提取出来,从而直接用于交易策略或数据分析:

    我们知道”数据“并不等于”信息“,光是将数据表保存在本地不代表立即就能使用其中的信息。而qteasy特意将数据表中的可用“信息”以标准化的方式定义为DataType对象,简化数据访问过程和策略的定义过程,统一的API使得获取信息的过程变得更加直接和友好

总体来说,qteasy的数据获取模块的结构可以用下面的示意图来表示:

在这里插入图片描述

如图所示,qteasy的数据功能分为三层,第一层包括多种数据下载接口,用于从网络数据提供商获取数据,这个过程称为DataFetching。第二层是qteasy的核心功能之一,定义了一个本地数据库用于存储大量的数据表,并且支持多种数据引擎,这一层的核心是DataSource类,第三层是数据应用层,将数据表中有意义的信息提取出来定义为DataType对象,提取数据的过程被称为Information Extraction。而这个DataType对象在qteasy内部被广泛使用,创建交易策略,进行数据分析、可视化等后续的一切工作,都是以DataType对象为基础进行的。

正因为金融数据在量化交易过程中的重要性,从下一章节开始,我们将详细介绍qteasy数据功能的所有功能模块:

  • 本地数据源——DataSource对象
  • 本地数据源——内置数据表
  • 拉取网络数据——从不同的渠道
  • 使用本地数据——DataType对象

本地数据源——DataSource对象

本地数据源是qteasy数据管理功能的核心,所有的数据都必须首先下载并保存在本地数据源中,才能为qteasy所用。qteasy使用DataSource对象管理本地数据源,本地数据源类似于一个数据库,包含一系列预先定义的数据表,DataSource类提供了一系列API用于数据表中数据的管理,包括读取、更新、删除和查询其中的数据。

要创建一个新的DataSource对象,可以使用下面的命令:

>>> import qteasy as qt
>>> ds = qt.DataSource()

通过打印DataSource对象,可以查看其最基本的属性:

>>> print(ds)
file://csv@qt_root/data/

DataSource的打印字符串file://csv@qt_root/data/中,可以看出它的基本属性

打印结果包含数据源对象的基本信息:

  • file: – 数据源的类型。qteasy支持两种类型的数据源:文件型和数据库型,file代表数据源中的所有数据表都是以文件的形式保存在磁盘上的,同样,数据也可以保存在mysql数据库中,此时数据源的类型代码为db
  • csv: – 数据文件保存格式。qteasy可以将数据文件以不同的格式保存在磁盘上,最基本的格式为csv文件,但是用户同样可以将数据保存为hdf文件和fth文件(feather文件),以满足不同的性能偏好。
  • qt_root/data/: – 数据文件的保存路径。其中qt_root表示qteasy的安装根路径,默认情况下所有数据文件都保存在根目录下的/data/子路径下

同样,可以创建一个数据保存类型为数据库的数据源对象,并查看其基本属性:
不过,创建类型为数据库的数据源时,需要指定需要连接的Mysql数据库的主机名、用户名、密码、(或者)数据库名称等信息:

>>> ds_db = qt.DataSource(source_type='database', host='localhost', user='您的用户名', password='您的密码', db_name='test_db')
>>> print(ds_db)
db:mysql://localhost@3306/test_db

同样,打印结果中包含数据源的基本信息:

  • db:mysql – 数据源的类型为mysql数据库,所有的数据表都保存在数据库中
  • localhost – 数据库的主机名
  • 3306 – 数据库连接端口
  • test_db – 数据库名称,如果不指定名称,默认数据库qt_db,不过这个数据库必须事先创建好

不同的数据源对象,如果它们的存储方式不同,存储路径不同,那么它们所保存的数据没有关系,互不干扰,但如果两个数据源指向同一个路径,且文件类型相同时,那么它们所保存的数据就会重复。

要查看数据源的更多基本属性,可以调用数据源对象的几个属性查看:

>>> print(ds.source_type)  # 数据源的类型
file
>>> print(ds_db.source_type)
db
>>> print(ds.file_type, ds.file_path)  # 数据源的文件类型和存储路径
csv /Users/jackie/Projects/qteasy/qteasy/data/
>>> print(ds.connection_type, ds_db.connection_type)  # 数据源的连接类型
file://csv@qt_root/data/ db:mysql://localhost@3306/test_db

默认数据源

qteasy有一个内置默认的数据源,不需要用户手动创建,默认情况下,所有的数据都会保存到这个默认数据源,并从这个数据源读取。用户可以通过qteasy的配置文件配置该数据源的参数,确保该数据源指向正确的路径或使用正确的用户名登陆正确的数据库。通过下面的方法查看内置默认数据源的属性:

>>> print(qt.QT_DATA_SOURCE)
db:mysql://www.qteasy.online@3306/ts_db

查看数据表

了解数据源对象的基本属性后,下一步可以进一步了解数据源中保存的数据。

数据源中的数据表都是事先定义好的,每一张数据表都保存一类不同的数据,这些数据涵盖沪深股市、期货市场的股票、指数、基金、期货、期权等各种不同投资产品的基本信息、K线行情、上市公司业绩报表、宏观经济数据等等大量的数据,完整的数据表清单介绍,请参见下一章节,这里主要介绍如何查看各种数据表的基本情况和数据。

数据源中的数据表清单可以通过数据源的all_tables属性获取,它会返回一个列表对象,包含数据源中已经预定义的所有数据表。不过,这里必须厘清一个概念,数据源中虽然已经定义好了很多数据表,但这些数据表仅仅是有了基本的定义,即表头信息,数据表的字段名称、每个字段的含义以及数据类型都定义好了,但是刚刚建立的新数据源,其数据表往往都是空的,还没有任何数据。如果要查看数据源中有哪些数据表已经有了数据,需要用get_table_info()函数来获取:

>>> print('All tables in datasource:', len(ds.all_tables))
All tables in datasource: 108
>>> print('Some tables:', ds.all_tables[5:15])
Some tables: ['hk_trade_calendar', 'us_trade_calendar', 'stock_basic', 'hk_stock_basic', 'us_stock_basic', 'stock_names', 'stock_company', 'stk_managers', 'new_share', 'money_flow']

可见,目前版本的qteasy预定义了108张数据表,其中部分数据表的名称包括stock_basic等。

如果要查看当前数据源中某张数据表的详情,例如该数据表的定义,是否包含数据等信息,使用get_table_info()方法获取:

>>> info = ds.get_table_info('stock_basic')
<stock_basic>--<股票基本信息>
852KB/5K records on disc
primary keys: 
----------------------------------------
1:   ts_code:  <5396> entriesstarts: 000001.SZ, end: 920128.BJcolumns of table:
------------------------------------columns        dtypes remarks
0       ts_code    varchar(9)    证券代码
1        symbol    varchar(6)    股票代码
2          name   varchar(20)    股票名称
3          area   varchar(10)      地域
4      industry   varchar(10)    所属行业
5      fullname   varchar(50)    股票全称
6        enname  varchar(120)    英文全称
7       cnspell   varchar(40)    拼音缩写
8        market    varchar(6)    市场类型
9      exchange    varchar(6)   交易所代码
10    curr_type    varchar(6)    交易货币
11  list_status    varchar(4)    上市状态
12    list_date          date    上市日期
13  delist_date          date    退市日期
14        is_hs    varchar(2)  是否沪深港通

打印的信息包括数据表的名称、说明、数据表的字段定义以及数据类型。

值得说明的是,如果数据表中已经填充了数据,那么就会显示出数据表目前的大小,在上面的例子中,一些关键信息的解释如下:

  • 852KB/5K records on disc – 表示数据表占用磁盘空间大约852K字节,且数据量大约为5000行
  • primary keys – 显示数据的主键列,这里表示ts_code列为数据表的主键,且该列大约有5396条不同的记录。如果数据表有多个主键,那么每个主键列都分别列出,同时会列出该字段数据的范围,例如上例中ts_code列数据范围就是从000001.SZ开始一直到920128.BJ为止,让我们知道股票基本信息表里包含了代码从000001一直到920128为止的共五千多只股票的信息
  • columns of table – 这里显示数据表的字段定义,也就是数据表的schema。列出每一列的名称columns、数据类型dtypes以及说明信息remarks

另外,get_table_info()方法返回一个dict,同样包含该数据表的信息,可以将这些信息打印出来,与上述格式化信息对照了解:

>>> print(info)
{'table': 'stock_basic', 'table_exists': True, 'table_size': '852KB', 'table_rows': '5K', 'primary_key1': 'ts_code', 'pk_records1': 5396, 'pk_min1': '000001.SZ', 'pk_max1': '920128.BJ', 'primary_key2': None, 'pk_records2': None, 'pk_min2': None, 'pk_max2': None}

查看数据源的整体信息

通过上面的方法,我们可以查看每一张数据表的具体定义和已经填充的数据信息。同样,通过overview()方法,我们可以检查所有的数据表,并汇总出整个数据源的整体信息:

>>> overview = ds.overview()
Analyzing local data source tables... depending on size of tables, it may take a few minutes
[########################################]104/104-100.0%  A...zing completed!
Finished analyzing datasource: 
file://csv@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.8MB         70K          CFFEX        SZSE 
stock_basic      True       852KB          5K           None        None 
stock_daily      True      98.8MB        1.3M       20211112    20241231

查看整个数据源的总体信息,可能需要花费数分钟的时间,因为需要统计每张数据表的所有信息。

在统计过程中,qteasy会显示一根进度条显示统计的进度,最终统计分析完成后,qteasy会将数据源中所有数据表的信息以DataFrame的形式返回,并打印出关键的信息。

上面的信息显示了数据源中有3张数据表已经有了数据,包括trade_calendarstock_basicstock_daily,并显示了这些数据表的数据量、占用磁盘空间、数据的起始日期��结束日期等信息。如果想查看所有数据表的信息,可以将返回的DataFrame打印出来:

>>> print(overview)has_data   size records       pk1 records1       min1  \
table                                                                      
trade_calendar         True  1.8MB     70K  cal_date    12865   19901012   
hk_trade_calendar     False      0       0  cal_date  unknown        N/A   
us_trade_calendar     False      0       0  cal_date  unknown        N/A   
stock_basic            True  852KB      5K   ts_code     5396  000001.SZ   
hk_stock_basic        False      0       0   ts_code  unknown        N/A   
...                     ...    ...     ...       ...      ...        ...   
cn_cpi                False      0       0     month  unknown        N/A   
cn_ppi                False      0       0     month  unknown        N/A   
cn_money              False      0       0     month  unknown        N/A   
cn_sf                 False      0       0     month  unknown        N/A   
cn_pmi                False      0       0     month  unknown        N/A   max1       pk2 records2   min2  max2  
table                                                         
trade_calendar      20251231  exchange        7  CFFEX  SZSE  
hk_trade_calendar        N/A      None     None   None  None  
us_trade_calendar        N/A      None     None   None  None  
stock_basic        920128.BJ      None     None   None  None  
hk_stock_basic           N/A      None     None   None  None  
...                      ...       ...      ...    ...   ...  
cn_cpi                   N/A      None     None   None  None  
cn_ppi                   N/A      None     None   None  None  
cn_money                 N/A      None     None   None  None  
cn_sf                    N/A      None     None   None  None  
cn_pmi                   N/A      None     None   None  None  [104 rows x 11 columns]

最重要的数据表

如果您是第一次使用qteasy,很可能数据源中的数据表都是空的,没有任何数据。通常这没有任何问题,因为qteasy的设计初衷就是极大地简化金融数据的获取和使用过程。

您可以非常容易地从网络数据提供商处获取最基本的数据。不过,虽然数据表中的数据可以是空的,但是有几张数据表却比其他的数据表更加重要,您应该优先将这几张数据表的数据填充完整,因为这几张数据表中的数据是很多其他数据表的基础,甚至是qteasy的运行基础:

  • trade_calendar – 交易日历表,包含了所有交易所的交易日历信息,包括交易日、交易所代码、交易所名称等信息。可以说这是qteasy运行的基础,如果缺了这张表,qteasy的很多功能都将无法运行或者将降低效率。 qteasy使用这张表中的数据来判断交易日,如果要下载其他的数据表,通常也必须通过交易日数据表来确定下载的起止日期,因此,这是您应该绝对优先填充的数据表。
  • stock_basic – 股票基本信息表,包含了所有上市股票的基本信息,包括股票代码、股票名称、上市日期、退市日期、所属行业、地域等信息。这张表是很多其他数据表的基础,例如股票日K线数据表、股票财务数据表等,因此,这也是您应该优先填充的数据表。
  • index_basic – 指数基本信息表,包含了所有指数的基本信息,包括指数代码、指数名称、发布日期、退市日期等信息。这张表是很多其他数据表的基础,例如指数日K线数据表、指数成分股表等,因此,这也是您应该优先填充的数据表。
  • fund_basic – 基金基本信息表,包含了所有基金的基本信息,包括基金代码、基金名称、基金类型、基金规模等信息。这张表是很多其他数据表的基础,例如基金日K线数据表、基金净值数据表等,因此,这也是您应该优先填充的数据表。

基本上,如果您能够填充了上面这几张数据表的数据,那么您就可以开始比较顺畅使用qteasy的大部分数据相关的功能了。

另外,qteasy还在数据源中定义了几张系统数据表,这些表一共四张,用于存储跟实盘交易相关的信息:

  • sys_op_live_accounts – 实盘交易账户信息表,包含了所有实盘交易账户的基本信息,包括账户ID、账户名称、账户类型、账户状态等信息。
  • sys_op_positions – 实盘持仓信息表,包括所有实盘交易账户的持仓信息,包括账户ID、证券代码、证券名称、持仓数量、持仓成本等信息。
  • sys_op_trade_orders – 实盘交易委托表,包括所有实盘交易账户的交易委托信息,包括账户ID、委托时间、委托类型、证券代码、委托数量、委托价格等信息。
  • sys_op_trade_results – 实盘交易成交表,包括所有实盘交易账户的交易成交信息,包括账户ID、成交时间、证券代码、成交数量、成交价格等信息。

上面四张表是qteasy实盘交易功能的基础,这几张表中的数据不需要人为填充,而是系统自动生成,您不需要查看、填充或删除这些表

其他的数据表

除了上面提到的几张重要的数据表之外,数据源中还定义了大量的数据表,这些数据表包含了各种各样的金融数据,包括股票、指数、基金、期货、期权等各种金融产品的基本信息、日K线数据、财务数据、分红数据、业绩报表、宏观经济数据等等,主要分类如下:

  • 行情数据表 – 这类数据表包含了股票、基金、指数各个不同频率的K线行情数据
  • 基本信息表 – 这类数据表包含了股票、基金、指数、期货、期权等各种金融产品的基本信息
  • 指标信息表 – 这类数据表包含了各种指标的信息,例如技术指标、基本面指标、宏观经济指标等
  • 财务数据表 – 这类数据表包含了上市公司的财务报表数据,包括资产负债表、利润表、现金流量表等
  • 业绩报表表 – 这类数据表包含了上市公司的业绩报表数据,包括业绩快报、业绩预告、业绩预测等
  • 分红交易数据表 – 这类数据表包含了上市公司的分红数据,以及股票大宗交易、股东交易等信息表
  • 参考数据表 – 这类数据表包含了各种参考数据,例如宏观经济数据、行业数据、交易所数据等

这些数据表的具体定义和数据类型,可以通过get_table_info()方法查看,或者通过本文档的下一章节查询。

从数据表中获取数据

如果数据表中已经填充了数据,那么现在就可以从中读取数据了。DataSource提供了read_table_data()方法,从数据源中直接读取某个数据表中的数据,同时,用户可以筛选数据的起止日期以及证券代码,同时不用考虑数据表的具体结构、存储方式、存储位置等具体的实现方式。

为了避免读取的数据量过大,建议在读取数据时一定要同时给出某些筛选条件。对于read_table_data()方法来说,用户总是可以通过证券代码和起止日期来筛选数据:

  • shares: 给出一个证券代码或者逗号分隔的多个证券代码,如果数据表的主键中含有证券代码,那么根据该证券代码筛选输出的数据
  • start: 给出一个日期,格式为“YYYYMMDD”,如果数据表的主键包含时间或日期,那么根据筛选startend之间的数据,start/end必须成对给出
  • end: 给出一个日期,格式为“YYYYMMDD”,如果数据表的主键包含时间或日期,那么根据筛选startend之间的数据,start/end必须成对给出

DataSource对象会根据输入的筛选条件自动筛选数据,例如:

stock_daily表中读取一只股票(000651.SZ)从2024年1月1日到2024年1月15日之间的股票日K线数据:

>>> ds.read_table_data(table='stock_daily', shares='000651.SZ', start='20240101', end='20240115')open   high    low  ...  pct_chg        vol       amount
ts_code   trade_date                       ...                                 
000651.SZ 2024-01-03  32.00  32.08  31.70  ...  -0.7181  254468.92   810315.0132024-01-04  31.90  32.01  31.45  ...   0.4717  333398.05  1057458.4112024-01-08  33.12  33.21  32.85  ...  -0.2426  415911.34  1372722.0502024-01-02  32.17  32.20  31.96  ...  -0.4352  253797.30   814257.1752024-01-15  33.45  33.95  33.42  ...   0.6544  295681.34   996815.7252024-01-11  33.66  33.82  33.42  ...  -0.2376  284088.74   955075.1002024-01-09  32.81  33.55  32.65  ...   1.7933  438207.66  1454959.6372024-01-10  33.35  33.84  33.28  ...   0.5375  366485.52  1233441.5722024-01-12  33.50  33.83  33.42  ...   0.0893  224012.73   753931.8212024-01-05  32.05  33.29  31.62  ...   3.2238  832156.75  2738167.636[10 rows x 9 columns]

DataSource对象会自动根据数据表的定义来进行正确的筛选,并忽略掉不必要的参数。例如,我们可以筛选出某两支股票的基本信息。对于股票基本信息来说,交易日期是个不必要的参数,此时qteasy会自动忽略掉start/end参数并给出提示信息。同样,shares参数也不一定只能匹配股票代码,对于基金、指数、甚至期货、期权,都可以同样匹配:

>>> ds.read_table_data(table='stock_basic', shares='000651.SZ,000700.SZ', start='20240101', end='20240131')
/Users/jackie/Projects/qteasy/qteasy/database.py:1314: RuntimeWarning: list index out of range
can not find date-like primary key in the table stock_basic!
passed start(2024-01-01) and end(2024-01-31) arguments will be ignored!warnings.warn(msg, RuntimeWarning)symbol  name area industry  ... list_status list_date delist_date is_hs
ts_code                                ...                                        
000651.SZ     651  格力电器   广东     家用电器  ...           L  19961118         NaN     S
000700.SZ     700  模塑科技   江苏     汽车配件  ...           L  19970228         NaN     S[2 rows x 14 columns]

关于read_table_data()方法的更多信息,请参阅DataSource对象的参考信息。

向数据表中添加数据

如果数据表中尚未填充数据,或者数据表中填充的数据不足以满足我们的需求,那么读取数据就会不成功。为了避免这种情况,我们需要向数据表中填充数据。

向数据表中填充数据可以使用数据源的update_table_data()方法。使用这个API,用户可以将保存在一个DataFrame中的数据写入到相应的数据表中。这个API只需要给出三个参数:

  • table: 一个数据表的名称,需要写入数据的数据表
  • df: 一个DataFrame,保存了需要写入数据表中的数据
  • merge_type: 如果是update则更新数据表中已经存在的数据,如果是ignore则忽略重复的数据.

使用update_table_data()方法,用户不需要保证写入的数据格式与数据表完全一致,只要数据格式与数据表大致一致,qteasy就会自动整理数据格式、删除重复数据,确保写入数据表中的数据符合要求。

下面将一些示例数据写入数据源(写入的数据仅为演示效果)

>>> import pandas as pd
>>> df = pd.DataFrame({
...         'ts_code':    ['000001.SZ', '000002.SZ', '000003.SZ', '000004.SZ', '000005.SZ',
...                        '000001.SZ', '000002.SZ', '000003.SZ', '000004.SZ', '000005.SZ'],
...         'trade_date': ['20211112', '20211112', '20211112', '20211112', '20211112',
...                        '20211113', '20211113', '20211113', '20211113', '20211113'],
...         'open':       [1., 2., 3., 4., 5., 6., 7., 8., 9., 10.],
...         'high':       [2., 3., 4., 5., 6., 7., 8., 9., 10., 1.],
...         'low':        [3., 4., 5., 6., 7., 8., 9., 10., 1., 2.],
...         'close':      [4., 5., 6., 7., 8., 9., 10., 1., 2., 3.]
...     })
>>> print(df)ts_code trade_date  open  high   low  close
0  000001.SZ   20211112   1.0   2.0   3.0    4.0
1  000002.SZ   20211112   2.0   3.0   4.0    5.0
2  000003.SZ   20211112   3.0   4.0   5.0    6.0
3  000004.SZ   20211112   4.0   5.0   6.0    7.0
4  000005.SZ   20211112   5.0   6.0   7.0    8.0
5  000001.SZ   20211113   6.0   7.0   8.0    9.0
6  000002.SZ   20211113   7.0   8.0   9.0   10.0
7  000003.SZ   20211113   8.0   9.0  10.0    1.0
8  000004.SZ   20211113   9.0  10.0   1.0    2.0
9  000005.SZ   20211113  10.0   1.0   2.0    3.0

上面的DataFrame中保存了一些示例数据,我们下面将把这个DataFrame的数据写入数据源中的index_daily数据表。
目前我们可以看到,index_daily数据表是空的,而且这个数据表的schema与上面的DataFrame并不完全相同:

  • index_daily数据表的数据定义中包含11列,而上面的数据只有6列,不过DataFrame中的所有列都包含在index_daily数据表的schema
  • index_daily数据表目前是空的,没有填充任何数据
>>> info = ds.get_table_info('index_daily')
<index_daily>--<指数日线行情>
0 MB/0 records on disc
primary keys: 
----------------------------------------
1:   ts_code:  <unknown> entriesstarts: N/A, end: N/A
2:   trade_date:  <unknown> entriesstarts: N/A, end: N/Acolumns of table:
------------------------------------columns       dtypes  remarks
0      ts_code  varchar(20)     证券代码
1   trade_date         date     交易日期
2         open        float      开盘价
3         high        float      最高价
4          low        float      最低价
5        close        float      收盘价
6    pre_close        float      昨收价
7       change        float      涨跌额
8      pct_chg        float      涨跌幅
9          vol       double   成交量()
10      amount       double  成交额(千元)

接下来我们可以将数据写入数据表,如果方法执行正确,它将返回写入数据表中的数据的行数,如下所示:

>>> ds.update_table_data(table='index_daily', df=df)
10

将数据写入数据表之后,我们可以尝试一下从数据表中读取数据,现在我们已经可以读出刚才写入的数据了。

请注意,读出来的数据有许多列都是NaN值,这表明这些列没有写入数据,原因就是我们写入的df并不包含这些数据,因此读出的数据为NaN值。

>>> df = ds.read_table_data('index_daily', shares='000001.SZ, 000002.SZ')
>>> print(df)open  high  low  close  pre_close  change  pct_chg  vol  \
ts_code   trade_date                                                            
000001.SZ 2021-11-12   1.0   2.0  3.0    4.0        NaN     NaN      NaN  NaN   
000002.SZ 2021-11-12   2.0   3.0  4.0    5.0        NaN     NaN      NaN  NaN   
000001.SZ 2021-11-13   6.0   7.0  8.0    9.0        NaN     NaN      NaN  NaN   
000002.SZ 2021-11-13   7.0   8.0  9.0   10.0        NaN     NaN      NaN  NaN   amount  
ts_code   trade_date          
000001.SZ 2021-11-12     NaN  
000002.SZ 2021-11-12     NaN  
000001.SZ 2021-11-13     NaN  
000002.SZ 2021-11-13     NaN  

删除数据表 —— 请尽量小心,删除后无法恢复!!

我们除了可以向数据表中写入数据,从数据表中读取数据之外,当然也可以删除数据,不过请注意,在qteasy中操作DataSource删除数据时,您务必非常小心:因为qteasy不支持从数据表中删除部分数据,您只能删除整张数据表。

这是因为qteasy的数据源被设计为高效地存储和读取数据,但它并不是一个通常的数据库,我们并不需要经常操作其中的数据,这个数据仓库的作用是为了存储巨量的数据,因此,它的重点在于保存和提取数据,而不是删除操作。

qteasyDataSource对象提供了一个删除数据表的方法: drop_table_data(),这个方法将删除整个数据表,而且删除后无法恢复

为了避免在代码中误删除数据表,默认情况下drop_table_data()会导致错误,例如我们想删除之前写入临时数据的index_daily表:

>>> ds.drop_table_data('index_daily')
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Cell In[19], line 1
----> 1 ds.drop_table_data('index_daily')File ~/Projects/qteasy/qteasy/database.py:1587, in DataSource.drop_table_data(self, table)1584 if not self.allow_drop_table:1585     err = RuntimeError('Can\'t drop table from current datasource according to setting, please check: '1586                        'datasource.allow_drop_table')
-> 1587     raise err1589 if self.source_type == 'db':1590     self._drop_db_table(db_table=table)RuntimeError: Can't drop table from current datasource according to setting, please check: datasource.allow_drop_table

这时候我们需要修改数据源的allow_drop_table属性,将其修改为True,这样就可以删除数据表了,请记住删除后将allow_drop_table改为False

下面代码删除了index_daily表,然后就会发现,无法从该表读取数据了:

>>> ds.allow_drop_table = True
>>> ds.drop_table_data('index_daily')
>>> ds.allow_drop_table = False
>>> df = ds.read_table_data(table='index_daily')
>>> print(df)Empty DataFrame
Columns: []
Index: []

总结

至此,我们已经了解了DataSource对象,qteasy中金融历史数据管理的最重要的核心类的基本工作方式,了解了下面内容:

  • 什么是DataSource,如何创建一个数据源
  • 如何从数据源中提取数据
  • 如何操作数据源

在后面的章节中,您将会了解更多的内容:

  • 数据源中有哪些有用的金融数据?
  • 如何批量下载数据并填充到数据源中?
  • 如何从数据源中更有效地提取信息?

相关文章:

python量化交易——金融数据管理最佳实践——qteasy创建本地数据源

文章目录 qteasy金融历史数据管理总体介绍本地数据源——DataSource对象默认数据源查看数据表查看数据源的整体信息最重要的数据表其他的数据表 从数据表中获取数据向数据表中添加数据删除数据表 —— 请尽量小心&#xff0c;删除后无法恢复&#xff01;&#xff01;总结 qteas…...

深入探索Python机器学习算法:监督学习(线性回归,逻辑回归,决策树与随机森林,支持向量机,K近邻算法)

文章目录 深入探索Python机器学习算法&#xff1a;监督学习一、线性回归二、逻辑回归三、决策树与随机森林四、支持向量机五、K近邻算法 深入探索Python机器学习算法&#xff1a;监督学习 在机器学习领域&#xff0c;Python凭借其丰富的库和简洁的语法成为了众多数据科学家和机…...

word转换为pdf后图片失真解决办法、高质量PDF转换方法

1、安装Adobe Acrobat Pro DC 自行安装 2、配置Acrobat PDFMaker &#xff08;1&#xff09;点击word选项卡上的Acrobat插件&#xff0c;&#xff08;2&#xff09;点击“首选项”按钮&#xff0c;&#xff08;3&#xff09;点击“高级配置”按钮&#xff08;4&#xff09;点…...

【MATLAB例程】三维下的IMM(交互式多模型),模型使用CV(匀速)和CA(匀加速)

给出三维下的交互式多模型&#xff08;IMM&#xff09;matlab例程&#xff0c;模型使用匀速运动CV和匀加速运动CA&#xff0c;滤波使用EKF&#xff08;扩展卡尔曼滤波&#xff09; 文章目录 代码运行结果程序结构 代码讲解模型定义&#xff1a;轨迹生成&#xff1a;IMM核心流程…...

千峰React:Hooks(下)

useLayoutEffect useLayoutEffect在useEffect之前触发 这样会闪屏&#xff0c;因为是异步的&#xff0c;两次都渲染了 import {useEffect,useState } from react;function App() {const [msg,setMsg] useState(hello App)useEffect(() > {setMsg(hello useEffect)});retu…...

突破网络壁垒:实现 Mac SSH 访问 Windows WSL Ubuntu 的最佳实践20250301

突破网络壁垒&#xff1a;实现 Mac SSH 访问 Windows WSL Ubuntu 的最佳实践 背景与痛点 在现代开发环境中&#xff0c;开发者通常会面临不同操作系统之间的协同工作。例如&#xff1a; 主要开发环境位于 Windows 的 WSL Ubuntu 子系统需要从局域网内的 Mac 设备进行远程访问…...

【开源-鸿蒙土拨鼠大理石系统】鸿蒙 HarmonyOS Next App+微信小程序+云平台

✨本人自己开发的开源项目&#xff1a;土拨鼠充电系统 ✨踩坑不易&#xff0c;还希望各位大佬支持一下&#xff0c;在GitHub给我点个 Start ⭐⭐&#x1f44d;&#x1f44d; ✍GitHub开源项目地址&#x1f449;&#xff1a;https://github.com/lusson-luo/HarmonyOS-groundhog-…...

RAG 阿里云

RAG-阿里云Spring AI Alibaba官网官网 RAG-阿里云Spring AI Alibaba官网官网 AI应用跑起来&#xff0c;取消一下航班的操作666...

python -ssh学习

def exe_sshcmd(ip,username,userpswd,port,cmd): """ 功能&#xff1a;SSH登录到指定设备&#xff0c;并执行对应的命令 入参&#xff1a;前四项为ssh登录shell的ip和port&#xff0c;具备管理员权限的用户名和密码&#xff0c; cmd可以…...

【Java学习】内部类

面向对象系列六 一、类级别 1.静态成员 2.非静态成员与方法 二、类的创建与成员管理 1.类的创建 2.类的成员管理 三、常见的内部类 1.非静态内部类 2.静态内部类 3.匿名内部类 4.局部内部类 一、类级别 1.1静态成员 静态成员是类级别的是能一路直属都是在类层面的&…...

养生,开启健康生活之门

在这个快节奏的时代&#xff0c;人们在忙碌奔波中&#xff0c;往往忽略了自身健康。养生保健&#xff0c;不再是老年人的专属&#xff0c;而是各个年龄段维持良好生活状态的关键&#xff0c;它是我们开启健康生活的一把钥匙。 规律作息是养生的基石。人体就像一台精密的仪器&am…...

1-3压缩命令

文章目录 1. tar1.1 压缩&#xff08;.tar.gz .tgz .tar.bz2 &#xff09;1.2 解压缩(.tar.gz .tgz .tar.bz2 ) 2.zip2.1 压缩(.zip)2.2 解压缩 3.xz3.1 压缩&#xff08;.tar.xz&#xff09;3.2 解压缩 1. tar 1.1 压缩&#xff08;.tar.gz .tgz .tar.bz2 &#xff09; c…...

Dify使用和入门

第一步&#xff1a;了解 Dify 在开始之前&#xff0c;先简单了解一下 Dify 是什么&#xff1a; Dify 是一个开源的 LLM 应用开发平台&#xff0c;专注于帮助开发者快速构建生产级的生成式 AI 应用。它支持知识库集成、RAG&#xff08;检索增强生成&#xff09;技术、复杂工作…...

AcWing 5933:爬楼梯 ← 递归 / 递推 / 高精度

【题目来源】 https://www.acwing.com/problem/content/5936/ 【题目描述】 树老师爬楼梯&#xff0c;他可以每次走 1 级或者 2 级&#xff0c;输入楼梯的级数&#xff0c;求不同的走法数。 例如&#xff1a;楼梯一共有 3 级&#xff0c;他可以每次都走一级&#xff0c;或者第…...

WebGL 渲染器 WebGLRenderer

目录 Three.js封装的渲染器 .domElement属性 .setSize(width, height)方法 帧缓冲区的相关封装 渲染器方法.clear(color,depth,stencil) 渲染器方法.clearDepth() 渲染器属性.autoClear Three.js封装的渲染器 .domElement属性 如果想通过WebGL渲染一个三维场景&#…...

基于Three.js的3D赛车游戏开发实战详解

目录 一、项目效果预览二、核心技术架构2.1 三维场景构建2.2 赛道与车辆模型2.3 光照系统三、核心运动系统3.1 车辆运动控制3.2 物理模拟公式3.3 边界限制四、摄像机控制系统4.1 第三人称视角数学原理4.2 鼠标交互实现五、星空背景特效5.1 点云生成算法5.2 动态闪烁效果六、性能…...

⭐算法OJ⭐位操作实战【计数】(C++ 实现)

191. Number of 1 Bits Given a positive integer n, write a function that returns the number of set bits in its binary representation (also known as the Hamming weight). int hammingWeight(uint32_t n) {int count 0;while (n) {count n & 1; // 检查最低位…...

【通俗讲解电子电路】——从零开始理解生活中的科技(一)

导言&#xff1a;电子电路为什么重要&#xff1f; ——看不见的“魔法”&#xff0c;如何驱动你的生活&#xff1f; 清晨&#xff0c;当你的手机闹钟响起时&#xff0c;你可能不会想到&#xff0c;是电子电路在精准控制着时间的跳动&#xff1b;当你用微波炉加热早餐时&#…...

浏览器JS打不上断点,一点就跳到其他文件里。浏览器控制台 js打断点,指定的位置打不上断点,一打就跳到其他地方了。

关闭JavaScript 源代码映射&#xff0c;F12开发者模式 设置->偏好设置->源代码/来源->JavaScript 源代码映射。 肯定不是这个原因导致的&#xff0c;但这个办法可以暂时解决问题&#xff0c;点完这个东西就隐藏了webpack&#xff0c;有懂的来讲讲。 又浪费一个小时…...

浅谈人工智能之Windows安装llama factory

浅谈人工智能之Windows安装llama factory Llama Factory 是一个强大的工具&#xff0c;旨在帮助用户轻松管理和优化Llama模型的训练和部署。在某些情况下&#xff0c;您可能需要在部分互联网连接的环境中安装和使用Llama Factory。本文将详细介绍如何在Windows系统上这种情况下…...

mac电脑中使用无线诊断.app查看连接的Wi-Fi带宽

问题 需要检查连接到的Wi-Fi的AP硬件支持的带宽。 步骤 1.按住 Option 键&#xff0c;然后点击屏幕顶部的Wi-Fi图标&#xff1b;2.从下拉菜单中选择 “打开无线诊断”&#xff08;Open Wireless Diagnostics&#xff09;&#xff1b;3.你可能会看到一个提示窗口&#xff0c;…...

Python--内置模块和开发规范(下)

2. 开发规范 2.1 单文件应用 文件结构示例 # 文件注释 import os import jsonDB_PATH "data.json" # 常量放顶部def load_data():"""函数注释&#xff1a;加载数据"""if os.path.exists(DB_PATH):with open(DB_PATH, "r"…...

vue3配置端口,比底部vue调试

import { fileURLToPath, URL } from ‘node:url’ import { defineConfig } from ‘vite’ import vue from ‘vitejs/plugin-vue’ import vueJsx from ‘vitejs/plugin-vue-jsx’ // 关闭vue底部调试模式 // import vueDevTools from ‘vite-plugin-vue-devtools’ // htt…...

代码随想录day51

647. /** lc appleetcode.cn id647 langcpp** [647] 回文子串*/// lc codestart #include<iostream> #include<vector> #include<string> using namespace std; class Solution { public:int countSubstrings(string s) {vector<vector<bool>> …...

B2B2C多语言电商系统代销逻辑设计和开发

随着全球电商市场的快速发展&#xff0c;B2B2C&#xff08;Business-to-Business-to-Consumer&#xff09;模式逐渐成为企业拓展业务的重要方式。特别是在多语言、多文化的国际市场环境中&#xff0c;B2B2C多语言电商系统的代销功能为企业提供了灵活的业务模式&#xff0c;帮助…...

示波器探头衰减值:简单来说就是“信号缩小器

一、什么是衰减值 衰减值就是探头把信号“缩小”多少倍再传给示波器。比如&#xff1a; 1X衰减&#xff1a;信号原样传输&#xff08;不缩小&#xff09;&#xff0c;适合测小电压&#xff08;比如手机电池3.7V&#xff09;。 10X衰减&#xff1a;信号缩小10倍&#xff0c;适…...

Nginx系列06(Nginx 缓存配置、SSL/TLS 配置)

目录 Nginx 缓存配置 SSL/TLS 配置 Nginx 缓存配置 概念&#xff1a;Nginx 缓存配置允许服务器将频繁访问的资源&#xff08;如网页、图片、脚本等&#xff09;存储在内存或磁盘中&#xff0c;当再次接收到相同请求时&#xff0c;直接从缓存中读取并返回&#xff0c;减少对后…...

JavaScript——前端基础3

目录 JavaScript简介 优点 可做的事情 运行 第一个JavaScript程序 搭建开发环境 安装的软件 操作 在浏览器中使用JavaScript文件 分离JS 使用node运行JS文件 语法 变量与常量 原生数据类型 模板字符串 字符串的内置方法 数组 对象 对象数组和JSON if条件语…...

操作系统知识点12

1.在操作系统的结构设计中&#xff0c;采用层次结构的操作系统其最大优点是把整体问题局部化 2.非特权指令是指操作系统和用户均可以使用的指令 3.向处理器发出的中断信号称为中断请求 4.轮转法RR是单纯基于时间片考虑的 5.当进程处于就绪状态时&#xff0c;表示进程已获得…...

(七)趣学设计模式 之 适配器模式!

目录 一、 啥是适配器模式&#xff1f;二、 为什么要用适配器模式&#xff1f;三、 适配器模式的实现方式1. 类适配器模式&#xff08;继承插座 &#x1f468;‍&#x1f469;‍&#x1f467;‍&#x1f466;&#xff09;2. 对象适配器模式&#xff08;插座转换器 &#x1f50c…...

RBF神经网络+NSGAII多目标优化算法,工艺参数优化、工程设计优化(Matlab)

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.RBF神经网络NSGAII多目标优化算法&#xff08;Matlab完整源码和数据&#xff09; 多目标优化是指在优化问题中同时考虑多个目标的优化过程。在多目标优化中&#xff0c;通常存在多个冲突的目标&#xff0c;即改善一…...

IP段转CIDR:原理Java实现

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…...

工会考试知识点分享

工会考试涵盖工会基础知识、劳动法及相关法律法规、时政等内容&#xff0c;以下是一些常见的知识点分享&#xff1a; 工会基础知识 工会的性质与职能&#xff1a;工会是职工自愿结合的工人阶级的群众组织&#xff0c;基本职责是维护职工合法权益&#xff0c;同时还具有组织、…...

Java进阶——Stream流以及常用方法详解

本文详细介绍了 Java Stream 流的重要知识点。包括数据源与操作分离&#xff08;不存储数据&#xff0c;不可复用&#xff09;、惰性求值与短路优化&#xff1b;以及流的创建方式&#xff0c;如集合创建、数组 / 值创建、文件创建&#xff1b;然后介绍中间操作&#xff0c;像过…...

数据如何安全“过桥”?分类分级与风险评估,守护数据流通安全

信息化高速发展&#xff0c;数据已成为企业的核心资产&#xff0c;驱动着业务决策、创新与市场竞争力。随着数据开发利用不断深入&#xff0c;常态化的数据流通不仅促进了信息的快速传递与共享&#xff0c;还能帮助企业快速响应市场变化&#xff0c;把握商业机遇&#xff0c;实…...

Kubernetes LimitRange对于pod 的 update 事件会不会处理?

在 Kubernetes 中&#xff0c;LimitRange 是一个用于限制命名空间中 Pod 或容器资源使用的对象。它主要限制资源请求&#xff08;requests&#xff09;和资源限制&#xff08;limits&#xff09;&#xff0c;如 CPU 和内存。LimitRange 影响的是 Pod 或容器的创建&#xff08;c…...

服务器禁止操作汇总(Server Prohibits 0peration Summary)

服务器禁止操作汇总 一、禁忌操作TOP10 1. 直接断电关机 &#x1f4a5; 血泪案例&#xff1a;某物流公司运维拔电源强制关机&#xff0c;导致数据库事务中断&#xff0c;20万订单状态丢失。 &#x1f4cc; 技术解析&#xff1a; • 直接断电可能引发&#xff1a; ✅ 文件系统…...

Android Studio 新版本Gradle通过JitPack发布Maven仓库示例

发布本地仓库示例&#xff1a;https://blog.csdn.net/loutengyuan/article/details/145938967 以下是基于 Android Studio 24.2.2&#xff08;Gradle 8.10.2 AGP 8.8.0 JDK17&#xff09; 的通过JitPack发布Maven仓库示例&#xff0c;包含aar和jar的不同配置&#xff1a; 1.…...

Spring Boot 测试:单元、集成与契约测试全解析

一、Spring Boot 分层测试策略 Spring Boot 应用采用经典的分层架构&#xff0c;不同层级的功能模块对应不同的测试策略&#xff0c;以确保代码质量和系统稳定性。 Spring Boot 分层架构&#xff1a; Spring Boot分层架构 A[客户端] -->|HTTP 请求| B[Controller 层] …...

一个便捷的web截图库~

随着时间的发展&#xff0c;前端开发的范围越来越广&#xff0c;能够实现的功能也越来越多&#xff0c;要实现的功能也五花八门&#xff0c;今天就给大家介绍一个web截图库,让前端也能实现截图功能—— js-web-screen-shot js-web-screen-shot js-web-screen-shot 是一个基于 …...

【HTML— 快速入门】HTML 基础

准备工作 vscode下载 百度网盘 Subline Text 下载 Sublime Text下载 百度网盘 vscode 下载 Sublime Text 是一款轻量好用的文本编辑器&#xff0c;我们在写前端代码时&#xff0c;使用 Sublime Text 打开比使用记事本打开&#xff0c;得到的代码体验更好&#xff0c;比 vscode…...

github操作

在本地创建一个 Git 仓库并将其上传到 GitHub 的整个流程可以分为以下几个步骤。以下是详细的说明和对应的命令&#xff1a; 1. 安装 Git 确保你的系统已经安装了 Git。如果未安装&#xff0c;可以通过以下方式安装&#xff1a; Windows: 下载 Git for Windows 并安装。macOS…...

基于ArcGIS Pro、R、INVEST等多技术融合下生态系统服务权衡与协同动态分析实践应用

文章目录 前言第一章、生态系统服务第二章、平台基础一、ArcGIS Pro介绍二、R环境配置与基础操作 第三章、数据获取与预处理第四章、生态系统服务估算第五章、生态系统服务权衡与协同第六章、空间统计分析第七章、论文撰写与图表复现了解更多 ————————————————…...

Python Cookbook-2.18 从指定的搜索路径寻找文件

任务 给定一个搜索路径(一个描述目录信息的字符串)&#xff0c;需要根据这个路径和请求的文件名找到第一个符合要求的文件。 解决方案 需要循环指定的搜索路径中的目录: import os def search_file(filename,search path&#xff0c;pathsepos.pathsep): """…...

遗传算法详解及在matlab中的使用

遗传算法分析 一 遗传算法概述1 算法概念2 基本特点3 启发式算法 二 原理与方法1 实现步骤1.1 个体编码1.2 种群初始化1.3 适应度计算1.4 选择运算1.5 交叉运算1.6 变异运算 2 总结 三 应用实例1 GA工具使用教程2 设置目标函数3 搜索最小值4 搜索最大值 一 遗传算法概述 本章简…...

智能AI替代专家系统(ES)、决策支持系统(DSS)?

文章目录 前言一、专家系统&#xff08;ES&#xff09;是什么&#xff1f;二、决策支持系统&#xff08;DSS&#xff09;是什么&#xff1f;1.决策支持系统定义2.决策系统的功能与特点3.决策支持系统的组成 三、专家系统&#xff08;ES&#xff09;与决策支持系统&#xff08;D…...

活在AI原生时代的05后,开始用AI创业

大家好&#xff0c;我是Shelly&#xff0c;一个专注于输出AI工具和科技前沿内容的AI应用教练&#xff0c;体验过300款以上的AI应用工具。关注科技及大模型领域对社会的影响10年。关注我一起驾驭AI工具&#xff0c;拥抱AI时代的到来。 人工智能&AIGC术语100条 Shelly聊AI-重…...

【官方配图】win10/win11 安装cuda 和 cudnn

文章目录 参考资料1.安装cuda toolkit1. 下载安装包2.安装验证 2. 安装cudnn下载cudnn安装包安装cudnn安装后的配置 参考资料 官方nvidia安装cuda官方nvidia安装cudnn 1.安装cuda toolkit 1. 下载安装包 下载地址 https://developer.nvidia.com/cuda-downloads?target_osW…...

释放微软bing的力量:深度剖析其主要功能

在浩瀚无垠的互联网海洋中,搜索引擎就如同指南针,引领我们找到所需要的信息。微软必应凭借其一系列强大功能,在搜索引擎领域脱颖而出,成为极具竞争力的一员。在这篇博客文章中,我们将深入探讨微软必应的主要功能,这些功能使其独具特色,成为全球用户的得力工具。 1. 智能…...

【Nginx 】Nginx 部署前端 vue 项目

1. 项目打包 1.1 安装依赖 在项目部署之前&#xff0c;确保开发环境中已安装Node.js和npm&#xff0c;这是运行Vue项目的基础。通过执行npm install命令&#xff0c;可以安装项目所需的所有依赖。这一步是打包流程的前提&#xff0c;确保了后续编译的顺利进行。 根据npm的官…...