diff --git a/README.md b/README.md index e5494f51..cbbe5c8e 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,8 @@ **Read this in other languages: [English](README-en.md).** -## 开始之前 - -zvt将市场抽象为如下的模型: +## 市场模型 +ZVT 将市场抽象为如下的模型:

@@ -19,14 +18,6 @@ zvt将市场抽象为如下的模型: * ActorEntity (市场参与者) * EntityEvent (交易标的 和 市场参与者 发生的事件) -基于一些 **简单自然** 的规则,你可以方便的组合,设计,创造自己的世界。比如: -* 数据是可以 **记录** 和 **查询** 的 -* 数据是可以有多个 **提供商** 的 -* 数据是可以 **增量更新** 的 -* 数据的 **分类** 是明确的 -* **策略** 是容易组合验证的 -* 不同 **空间** 的 **样本** 是容易生成的 - ## 快速开始 ### 安装 @@ -34,11 +25,26 @@ zvt将市场抽象为如下的模型: python3 -m pip install -U zvt ``` -### 数据 +### 运行界面 + +这里是[入口脚本](https://github.com/zvtvz/zvt/blob/master/zvt/main.py),可直接源码运行;或者pip安装后直接在命令行下输入zvt,然后打开[http://127.0.0.1:8050/](http://127.0.0.1:8050/)即可。 + +> 这里展示的例子依赖后面的下载历史数据,数据更新请参考后面文档 + +

+

+> 系统的核心概念是可视化的,界面的名称与其一一对应,因此也是统一可扩展的。 + +> 你可以在你喜欢的ide里编写和运行策略,然后运行界面查看其相关的标的,因子,信号和净值展示。 + +### 导入 ``` >>> from zvt.domain import * ``` + +### TradableEntity (交易标的) + #### A股交易标的 ``` >>> Stock.record_data() @@ -118,8 +124,68 @@ code ``` +#### 还有更多 +``` +>>> from zvt.contract import * +>>> zvt_context.tradable_schema_map + +{'stockus': zvt.domain.meta.stockus_meta.Stockus, + 'stockhk': zvt.domain.meta.stockhk_meta.Stockhk, + 'index': zvt.domain.meta.index_meta.Index, + 'etf': zvt.domain.meta.etf_meta.Etf, + 'stock': zvt.domain.meta.stock_meta.Stock, + 'block': zvt.domain.meta.block_meta.Block, + 'fund': zvt.domain.meta.fund_meta.Fund} +``` + +其中key为交易标的的类型,value为其schema,系统为schema提供了统一的 **记录(record_data)** 和 **查询(query_data)** 方法。 + +``` +>>> Index.record_data() +>>> df=Index.query_data(filters=[Index.category=='scope',Index.exchange='sh']) +>>> print(df) + id entity_id timestamp entity_type exchange code name list_date end_date publisher category base_point +0 index_sh_000001 index_sh_000001 1990-12-19 index sh 000001 上证指数 1991-07-15 None csindex scope 100.00 +1 index_sh_000002 index_sh_000002 1990-12-19 index sh 000002 A股指数 1992-02-21 None csindex scope 100.00 +2 index_sh_000003 index_sh_000003 1992-02-21 index sh 000003 B股指数 1992-08-17 None csindex scope 100.00 +3 index_sh_000010 index_sh_000010 2002-06-28 index sh 000010 上证180 2002-07-01 None csindex scope 3299.06 +4 index_sh_000016 index_sh_000016 2003-12-31 index sh 000016 上证50 2004-01-02 None csindex scope 1000.00 +.. ... ... ... ... ... ... ... ... ... ... ... ... +25 index_sh_000020 index_sh_000020 2007-12-28 index sh 000020 中型综指 2008-05-12 None csindex scope 1000.00 +26 index_sh_000090 index_sh_000090 2009-12-31 index sh 000090 上证流通 2010-12-02 None csindex scope 1000.00 +27 index_sh_930903 index_sh_930903 2012-12-31 index sh 930903 中证A股 2016-10-18 None csindex scope 1000.00 +28 index_sh_000688 index_sh_000688 2019-12-31 index sh 000688 科创50 2020-07-23 None csindex scope 1000.00 +29 index_sh_931643 index_sh_931643 2019-12-31 index sh 931643 科创创业50 2021-06-01 None csindex scope 1000.00 + +[30 rows x 12 columns] + +``` + + +### EntityEvent (交易标的 发生的事件) +有了交易标的,才有交易标的 发生的事。 #### 行情数据 +交易标的的行情schema遵从如下的规则: +``` +{entity_shema}{level}{adjust_type}Kdata +``` +* entity_schema +就是前面说的TradableEntity,比如Stock,Stockus等。 + +* level +``` +>>> for level in IntervalLevel: + print(level.value) +``` + +* adjust type +``` +>>> for adjust_type in AdjustType: + print(adjust_type.value) +``` +> 注意: 为了兼容历史数据,前复权是个例外,{adjust_type}不填 + 前复权 ``` >>> Stock1dKdata.record_data(code='000338', provider='em') @@ -182,7 +248,7 @@ code [3431 rows x 15 columns] ``` -#### 财务数据 +#### 财务因子 ``` >>> FinanceFactor.record_data(code='000338') >>> FinanceFactor.query_data(code='000338',columns=FinanceFactor.important_cols(),index='timestamp') @@ -204,6 +270,100 @@ timestamp [66 rows x 10 columns] ``` +#### 财务三张表 +``` +#资产负债表 +>>> BalanceSheet.record_data(code='000338') +#利润表 +>>> IncomeStatement.record_data(code='000338') +#现金流量表 +>>> CashFlowStatement.record_data(code='000338') +``` + +#### 还有更多 +``` +>>> zvt_context.schemas +[zvt.domain.dividend_financing.DividendFinancing, + zvt.domain.dividend_financing.DividendDetail, + zvt.domain.dividend_financing.SpoDetail...] +``` +zvt_context.schemas为系统支持的schema,schema即表结构,即数据,其字段含义的查看方式如下: + +* help + +输入schema.按tab提示其包含的字段,或者.help() +``` +>>> FinanceFactor.help() +``` + +* 源码 + +[domain](https://github.com/zvtvz/zvt/tree/master/zvt/domain)里的文件为schema的定义,查看相应字段的注释即可。 + +通过以上的例子,你应该掌握了统一的记录数据的方法: + +> Schema.record_data(provider='your provoder',codes='the codes') + +注意可选参数provider,其代表数据提供商,一个schema可以有多个provider,这是系统稳定的基石。 + +查看**已实现**的provider +``` +>>> Stock.provider_map_recorder +{'joinquant': zvt.recorders.joinquant.meta.jq_stock_meta_recorder.JqChinaStockRecorder, + 'exchange': zvt.recorders.exchange.exchange_stock_meta_recorder.ExchangeStockMetaRecorder, + 'em': zvt.recorders.em.meta.em_stock_meta_recorder.EMStockRecorder, + 'eastmoney': zvt.recorders.eastmoney.meta.eastmoney_stock_meta_recorder.EastmoneyChinaStockListRecorder} + +``` +你可以使用任意一个provider来获取数据,默认使用第一个。 + + +再举个例子,股票板块数据获取: +``` +>>> Block.provider_map_recorder +{'eastmoney': zvt.recorders.eastmoney.meta.eastmoney_block_meta_recorder.EastmoneyChinaBlockRecorder, + 'sina': zvt.recorders.sina.meta.sina_block_recorder.SinaBlockRecorder} + +>>> Block.record_data(provider='sina') +Block registered recorders:{'eastmoney': , 'sina': } +2020-03-04 23:56:48,931 INFO MainThread finish record sina blocks:industry +2020-03-04 23:56:49,450 INFO MainThread finish record sina blocks:concept +``` + +再多了解一点record_data: +* 参数code[单个],codes[多个]代表需要抓取的股票代码 +* 不传入code,codes则是全市场抓取 +* 该方法会把数据存储到本地并只做增量更新 + +定时任务的方式更新可参考[东财数据定时更新](https://github.com/zvtvz/zvt/blob/master/examples/recorders/eastmoney_data_runner1.py) + +#### 全市场选股 +查询数据使用的是query_data方法,把全市场的数据记录下来后,就可以在本地快速查询需要的数据了。 + +一个例子:2018年年报 roe>8% 营收增长>8% 的前20个股 +``` +>>> df=FinanceFactor.query_data(filters=[FinanceFactor.roe>0.08,FinanceFactor.report_period=='year',FinanceFactor.op_income_growth_yoy>0.08],start_timestamp='2019-01-01',order=FinanceFactor.roe.desc(),limit=20,columns=["code"]+FinanceFactor.important_cols(),index='code') + + code basic_eps total_op_income net_profit op_income_growth_yoy net_profit_growth_yoy roe rota gross_profit_margin net_margin timestamp +code +000048 000048 2.7350 4.919000e+09 1.101000e+09 0.4311 1.5168 0.7035 0.1988 0.5243 0.2355 2020-04-30 +000912 000912 0.3500 4.405000e+09 3.516000e+08 0.1796 1.2363 4.7847 0.0539 0.2175 0.0795 2019-03-20 +002207 002207 0.2200 3.021000e+08 5.189000e+07 0.1600 1.1526 1.1175 0.1182 0.1565 0.1718 2020-04-27 +002234 002234 5.3300 3.276000e+09 1.610000e+09 0.8023 3.2295 0.8361 0.5469 0.5968 0.4913 2020-04-21 +002458 002458 3.7900 3.584000e+09 2.176000e+09 1.4326 4.9973 0.8318 0.6754 0.6537 0.6080 2020-02-20 +... ... ... ... ... ... ... ... ... ... ... ... +600701 600701 -3.6858 7.830000e+08 -3.814000e+09 1.3579 -0.0325 1.9498 -0.7012 0.4173 -4.9293 2020-04-29 +600747 600747 -1.5600 3.467000e+08 -2.290000e+09 2.1489 -0.4633 3.1922 -1.5886 0.0378 -6.6093 2020-06-30 +600793 600793 1.6568 1.293000e+09 1.745000e+08 0.1164 0.8868 0.7490 0.0486 0.1622 0.1350 2019-04-30 +600870 600870 0.0087 3.096000e+07 4.554000e+06 0.7773 1.3702 0.7458 0.0724 0.2688 0.1675 2019-03-30 +688169 688169 15.6600 4.205000e+09 7.829000e+08 0.3781 1.5452 0.7172 0.4832 0.3612 0.1862 2020-04-28 + +[20 rows x 11 columns] +``` + +以上,基本上就可以应付大部分日常数据的使用了。 +如果你想扩展数据,可以参考详细文档里的数据部分。 + ### 跑个策略 ``` >>> from zvt.samples import * @@ -211,10 +371,9 @@ timestamp >>> t.run() ``` -## 2. 📝环境设置 -项目支持多环境切换,默认情况下,不设置环境变量TESTING_ZVT即为正式环境 - ``` -In [1]: from zvt import * +### 环境设置 +``` +>>> from zvt import * {'data_path': '/Users/xuanqi/zvt-home/data', 'domain_module': 'zvt.domain', 'email_password': '', @@ -234,26 +393,19 @@ In [1]: from zvt import * >如果你不想使用使用默认的zvt_home目录,请设置环境变量ZVT_HOME再运行。 -所有操作跟测试环境是一致的,只是操作的目录不同。 - -### 2.1 配置(可选) +#### 配置(可选) 在zvt_home目录中找到config.json进行配置: -#### 使用聚宽数据需要设置: * jq_username 聚宽数据用户名 * jq_password 聚宽数据密码 - -#### 使用邮箱推送需要设置: * smtp_host 邮件服务器host * smtp_port 邮件服务器端口 * email_username smtp邮箱账户 * email_password smtp邮箱密码 - -#### 使用微信公众号推送需要设置: * wechat_app_id * wechat_app_secrect -### 2.2 下载历史数据(可选) +#### 下载历史数据(可选) 百度网盘: https://pan.baidu.com/s/1kHAxGSxx8r5IBHe5I7MAmQ 提取码: yb6c google drive: https://drive.google.com/drive/folders/17Bxijq-PHJYrLDpyvFAm5P6QyhKL-ahn?usp=sharing @@ -264,7 +416,7 @@ google drive: https://drive.google.com/drive/folders/17Bxijq-PHJYrLDpyvFAm5P6Qyh 数据的更新是增量的,下载历史数据只是为了节省时间,全部自己更新也是可以的。 -### 2.3 注册聚宽(可选) +#### 注册聚宽(可选) 项目数据支持多provider,在数据schema一致性的基础上,可根据需要进行选择和扩展,目前支持新浪,东财,交易所等免费数据。 #### 数据的设计上是让provider来适配schema,而不是反过来,这样即使某provider不可用了,换一个即可,不会影响整个系统的使用。 @@ -279,123 +431,11 @@ https://www.joinquant.com/default/index/sdk?channelId=953cbf5d1b8683f81f0c40c9d4 > 添加其他数据提供商, 请参考[数据扩展教程](https://zvtvz.github.io/zvt/#/data_extending) -## 3. 数据 -下面介绍如何用一种**统一**的方式来回答三个问题:**有什么数据?如何更新数据?如何查询数据?** - -### 3.1 有什么数据? -``` -In [1]: from zvt.contract import zvt_context -In [2]: from zvt.domain import * -In [3]: zvt_context.schemas -[zvt.domain.dividend_financing.DividendFinancing, - zvt.domain.dividend_financing.DividendDetail, - zvt.domain.dividend_financing.SpoDetail...] -``` -zvt_context.schemas为系统支持的schema,schema即表结构,即数据,其字段含义的查看方式如下: - -* 源码 - -[domain](https://github.com/zvtvz/zvt/tree/master/zvt/domain)里的文件为schema的定义,查看相应字段的注释即可。 - -* help - -输入schema.按tab提示其包含的字段,或者.help() -``` -In [4]: FinanceFactor.help() -``` - -### 3.2 如何更新数据? -#### 只需要一个方法:record_data() - -``` -#股票列表 -In [2]: Stock.record_data(provider='eastmoney') -#财务指标 -In [3]: FinanceFactor.record_data(codes=['000338']) -#资产负债表 -In [4]: BalanceSheet.record_data(codes=['000338']) -#利润表 -In [5]: IncomeStatement.record_data(codes=['000338']) -#现金流量表 -In [5]: CashFlowStatement.record_data(codes=['000338']) -``` - -其他数据依样画葫芦即可。 - -> 标准流程就是: Schema.record_data(provoder='your provoder',codes='the codes') - -注意可选参数provider,其代表数据提供商,一个schema可以有多个provider,这是系统稳定的基石。 - -查看**已实现**的provider -``` -In [12]: Stock.provider_map_recorder -Out[12]: -{'joinquant': zvt.recorders.joinquant.meta.china_stock_meta_recorder.JqChinaStockRecorder, - 'exchange': zvt.recorders.exchange.china_stock_list_spider.ExchangeChinaStockListRecorder, - 'eastmoney': zvt.recorders.eastmoney.meta.china_stock_meta_recorder.EastmoneyChinaStockListRecorder} -``` -你可以使用任意一个provider来获取数据,默认使用第一个。 - - -再举个例子,股票板块数据获取: -``` -In [13]: Block.provider_map_recorder -Out[13]: -{'eastmoney': zvt.recorders.eastmoney.meta.china_stock_category_recorder.EastmoneyChinaBlockRecorder, - 'sina': zvt.recorders.sina.meta.sina_china_stock_category_recorder.SinaChinaBlockRecorder} -In [14]: Block.record_data(provider='sina') -Block registered recorders:{'eastmoney': , 'sina': } -2020-03-04 23:56:48,931 INFO MainThread finish record sina blocks:industry -2020-03-04 23:56:49,450 INFO MainThread finish record sina blocks:concept -``` - -再多了解一点record_data: -* 参数codes代表需要抓取的股票代码 -* 不传入codes则是全市场抓取 -* 该方法会把数据存储到本地并只做增量更新 - -定时任务的方式更新可参考[东财数据定时更新](https://github.com/zvtvz/zvt/blob/master/examples/recorders/eastmoney_data_runner1.py) - -### 3.3 如何查询数据? -#### 只需要一个方法:query_data() - -2018年年报 roe>8% 营收增长>8% 的前20个股 -``` -In [38]: df=FinanceFactor.query_data(filters=[FinanceFactor.roe>0.08,FinanceFactor.report_period=='year',FinanceFactor.op_income_growth_yoy>0.08],start_timestamp='2019-01-01',order=FinanceFactor.roe.desc(),limit=20,columns=["code"]+FinanceFactor.important_cols(),index='code') - -In [39]: df -Out[39]: - code basic_eps total_op_income net_profit op_income_growth_yoy net_profit_growth_yoy roe rota gross_profit_margin net_margin timestamp -code -000048 000048 1.1193 3.437000e+09 4.374000e+08 1.2179 3.8122 0.5495 0.0989 0.4286 0.1308 2019-04-15 -000629 000629 0.3598 1.516000e+10 3.090000e+09 0.6068 2.5796 0.5281 0.2832 0.2752 0.2086 2019-03-26 -000672 000672 1.8100 5.305000e+09 1.472000e+09 0.1563 0.8596 0.5047 0.2289 0.4670 0.2803 2019-04-11 -000912 000912 0.3500 4.405000e+09 3.516000e+08 0.1796 1.2363 4.7847 0.0539 0.2175 0.0795 2019-03-20 -000932 000932 2.2483 9.137000e+10 6.780000e+09 0.1911 0.6453 0.4866 0.1137 0.1743 0.0944 2019-03-28 -002607 002607 0.2200 6.237000e+09 1.153000e+09 0.5472 1.1967 0.7189 0.2209 0.5908 0.1848 2019-04-09 -002959 002959 2.0611 2.041000e+09 1.855000e+08 0.2396 0.2657 0.5055 0.2075 0.3251 0.0909 2019-07-15 -300107 300107 1.1996 1.418000e+09 6.560000e+08 1.6467 6.5338 0.5202 0.4661 0.6379 0.4625 2019-03-15 -300618 300618 3.6900 2.782000e+09 7.076000e+08 0.8994 0.5746 0.4965 0.2504 0.4530 0.2531 2019-04-26 -300776 300776 3.3900 3.649000e+08 1.679000e+08 1.2059 1.5013 0.7122 0.2651 0.6207 0.4602 2019-02-18 -300792 300792 2.7100 1.013000e+09 1.626000e+08 0.4378 0.1799 0.4723 0.3797 0.4259 0.1606 2019-09-16 -600399 600399 2.0100 5.848000e+09 2.607000e+09 0.1732 2.9493 9.6467 0.2979 0.1453 0.4459 2019-03-29 -600408 600408 0.8100 8.816000e+09 8.202000e+08 0.3957 3.9094 0.7501 0.1681 0.1535 0.1020 2019-03-22 -600423 600423 0.9000 2.009000e+09 3.903000e+08 0.0975 5.3411 1.6695 0.1264 0.1404 0.1871 2019-03-19 -600507 600507 2.0800 1.729000e+10 2.927000e+09 0.2396 0.1526 0.5817 0.3216 0.3287 0.1696 2019-02-22 -600678 600678 0.0900 4.240000e+08 3.168000e+07 1.2925 0.0948 0.7213 0.0689 0.2183 0.0742 2019-03-14 -600793 600793 1.6568 1.293000e+09 1.745000e+08 0.1164 0.8868 0.7490 0.0486 0.1622 0.1350 2019-04-30 -600870 600870 0.0087 3.096000e+07 4.554000e+06 0.7773 1.3702 0.7458 0.0724 0.2688 0.1675 2019-03-30 -601003 601003 1.7987 4.735000e+10 4.610000e+09 0.1394 0.7420 0.5264 0.1920 0.1439 0.0974 2019-03-29 -603379 603379 2.9400 4.454000e+09 1.108000e+09 0.1423 0.1609 0.5476 0.3547 0.3959 0.2488 2019-03-13 -``` - -以上,基本上就可以应付大部分日常数据的使用了。 -如果你想扩展数据,可以参考详细文档里的数据部分。 -## 4. 数据即策略 +### 数据即策略 在介绍系统设计的二维索引多标的计算模型之前,我们先来介绍一种自由(solo)的策略模式。 所谓策略回测,无非就是,重复以下过程: -### 在某时间点,找到符合条件的标的,对其进行买卖,看其表现。 +#### 在某时间点,找到符合条件的标的,对其进行买卖,看其表现。 因为系统所有的数据都是时间序列数据,有着统一的查询方式,通过query_data可以快速得到符合条件的标的,所以,即使只会query_data,也可以solo一把了。 [例子](https://github.com/zvtvz/zvt/blob/master/examples/trader/solo_traders.py) @@ -425,7 +465,7 @@ class MySoloTrader(StockTrader): 更多可参考[策略例子](https://github.com/zvtvz/zvt/tree/master/examples/trader) -## 5. 计算 +## 计算 简单的计算可以通过query_data来完成,这里说的是系统设计的二维索引多标的计算模型。 下面以技术因子为例对**计算流程**进行说明: @@ -513,9 +553,9 @@ stock_sz_000338 2019-06-03 False 结合选股器和回测,整个流程如下:

-## 5. 🚀开发 +## 开发 -### 5.1 clone代码 +### clone代码 ``` git clone https://github.com/zvtvz/zvt.git @@ -527,14 +567,14 @@ pip3 install -r requirements.txt pip3 install pytest ``` -### 5.2 测试案例 +### 测试案例 pycharm导入工程(推荐,你也可以使用其他ide),然后pytest跑测试案例

大部分功能使用都可以从tests里面参考 -## 💡贡献 +## 贡献 期待能有更多的开发者参与到 zvt 的开发中来,我会保证尽快 Reivew PR 并且及时回复。但提交 PR 请确保 先看一下[1分钟代码规范](https://github.com/zvtvz/zvt/blob/master/code_of_conduct.md) @@ -545,13 +585,13 @@ pycharm导入工程(推荐,你也可以使用其他ide),然后pytest跑测试 也非常欢迎开发者能为 zvt 提供更多的示例,共同来完善文档。 -## 💌请作者喝杯咖啡 +## 请作者喝杯咖啡 如果你觉得项目对你有帮助,可以请作者喝杯咖啡 Alipay      Wechat -## 🤝联系方式 +## 联系方式 加微信进群:foolcage 添加暗号:zvt Wechat diff --git a/setup.py b/setup.py index bc07bf01..ab74ba86 100644 --- a/setup.py +++ b/setup.py @@ -32,7 +32,7 @@ setup( name='zvt', - version='0.9.5', + version='0.9.6', description='unified,modular quant framework for human beings ', long_description=long_description, url='https://github.com/zvtvz/zvt', @@ -49,7 +49,8 @@ 'License :: OSI Approved :: MIT License', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8' + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9' ], keywords='quant stock finance fintech big-data zvt technical-analysis trading-platform pandas fundamental-analysis', packages=find_packages(include=['zvt.*', 'zvt']),