Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/zvtvz/zvt
modular quant framework.
https://github.com/zvtvz/zvt
algorithmic-trading backtesting cryptocurrency fintech fundamental-analysis machine-learning ml python quant quantitative-finance quantitative-trading stock stock-market technical-analysis trading-bot trading-platform trading-strategies zvt
Last synced: 24 days ago
JSON representation
modular quant framework.
- Host: GitHub
- URL: https://github.com/zvtvz/zvt
- Owner: zvtvz
- License: mit
- Created: 2019-04-04T08:06:57.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2024-04-11T14:17:14.000Z (7 months ago)
- Last Synced: 2024-04-13T02:15:30.551Z (7 months ago)
- Topics: algorithmic-trading, backtesting, cryptocurrency, fintech, fundamental-analysis, machine-learning, ml, python, quant, quantitative-finance, quantitative-trading, stock, stock-market, technical-analysis, trading-bot, trading-platform, trading-strategies, zvt
- Language: Python
- Homepage: https://zvt.readthedocs.io/en/latest/
- Size: 41.8 MB
- Stars: 2,972
- Watchers: 132
- Forks: 837
- Open Issues: 24
-
Metadata Files:
- Readme: README-cn.md
- License: LICENSE
- Code of conduct: code_of_conduct.md
Awesome Lists containing this project
- awesome-systematic-trading - zvt - with-python](https://img.shields.io/badge/Made%20with-Python-1f425f.svg) | (Backtesting and Live Trading / General - Event Driven Frameworks)
- awesome-systematic-trading - zvt - commit/zvtvz/zvt/master) ![GitHub Repo stars](https://img.shields.io/github/stars/zvtvz/zvt?style=social) | Python, Stock, Backtest | - Modular quant framework (Backtest + live trading / General purpose)
- awesome-quant - zvt - the project using sql, pandas to provide an uniform and extendable way to record data, computing factors, select securities, backtesting, realtime trading and it could show all of them in clearly charts in realtime. (Python / Trading & Backtesting)
- awesome-ai-in-finance - zvt - Zero vector trader. (Research Tools / Arbitrage)
- awesome-quant - zvt - write trading algorithm once, run it on all markets (Python / Trading & Backtesting)
- awesome-quant - zvt - ZVT是在fooltrader的基础上重新思考后编写的量化项目,其包含可扩展的数据recorder,api,因子计算,选股,回测,定位为中低频 多级别 多标的 全市场分析和交易框架。 (数据源)
README
[![github](https://img.shields.io/github/stars/zvtvz/zvt.svg)](https://github.com/zvtvz/zvt)
[![image](https://img.shields.io/pypi/v/zvt.svg)](https://pypi.org/project/zvt/)
[![image](https://img.shields.io/pypi/l/zvt.svg)](https://pypi.org/project/zvt/)
[![image](https://img.shields.io/pypi/pyversions/zvt.svg)](https://pypi.org/project/zvt/)
[![build](https://github.com/zvtvz/zvt/actions/workflows/build.yaml/badge.svg)](https://github.com/zvtvz/zvt/actions/workflows/build.yml)
[![package](https://github.com/zvtvz/zvt/actions/workflows/package.yaml/badge.svg)](https://github.com/zvtvz/zvt/actions/workflows/package.yaml)
[![Documentation Status](https://readthedocs.org/projects/zvt/badge/?version=latest)](https://zvt.readthedocs.io/en/latest/?badge=latest)
[![codecov.io](https://codecov.io/github/zvtvz/zvt/coverage.svg?branch=master)](https://codecov.io/github/zvtvz/zvt)
[![Downloads](https://pepy.tech/badge/zvt/month)](https://pepy.tech/project/zvt)**缘起**
[炒股的三大原理](https://mp.weixin.qq.com/s/FoFR63wFSQIE_AyFubkZ6Q)
**Read this in other languages: [English](README-cn.md).**
**详细文档:[https://zvt.readthedocs.io/en/latest/](https://zvt.readthedocs.io/en/latest/)**
## 市场模型
ZVT 将市场抽象为如下的模型:* TradableEntity (交易标的)
* ActorEntity (市场参与者)
* EntityEvent (交易标的 和 市场参与者 发生的事件)## 快速开始
### 安装
```
python3 -m pip install -U zvt
```### 使用展示
#### 主界面
#### Dash & Plotly UI
> 适用于回测和研究,不太适用于实时行情和用户交互安装完成后,在命令行下输入 zvt
```shell
zvt
```
打开 [http://127.0.0.1:8050/](http://127.0.0.1:8050/)> 这里展示的例子依赖后面的下载历史数据,数据更新请参考后面文档
> 系统的核心概念是可视化的,界面的名称与其一一对应,因此也是统一可扩展的。
> 你可以在你喜欢的ide里编写和运行策略,然后运行界面查看其相关的标的,因子,信号和净值展示。
#### 前后端分离的UI
> 更灵活和可扩展,更适合于处理实时行情和用户交互,结合ZVT的动态tag系统,提供了一种量化结合主观的交易方式- 初始化tag系统
运行以下脚本:
https://github.com/zvtvz/zvt/blob/master/src/zvt/tasks/init_tag_system.py
https://github.com/zvtvz/zvt/blob/master/src/zvt/tasks/stock_pool_runner.py
https://github.com/zvtvz/zvt/blob/master/src/zvt/tasks/qmt_data_runner.py
https://github.com/zvtvz/zvt/blob/master/src/zvt/tasks/qmt_tick_runner.py- 安装 uvicorn
```shell
pip install uvicorn
```
- 运行 zvt server安装完成后,在命令行下输入 zvt_server
```shell
zvt_server
```
或者从代码运行:
https://github.com/zvtvz/zvt/blob/master/src/zvt/zvt_server.py- api 文档
open [http://127.0.0.1:8090/docs](http://127.0.0.1:8090/docs)
- 部署前端
前端代码: https://github.com/zvtvz/zvt_ui
修改前端环境文件:
https://github.com/zvtvz/zvt_ui/blob/main/.env设置 {your server IP}, 即zvt_server服务的地址
```text
NEXT_PUBLIC_SERVER = {your server IP}
```然后参考前端的readme启动前端服务
打开 [http://127.0.0.1:3000/trade](http://127.0.0.1:3000/trade)
#### 见证奇迹的时刻
```
>>> from zvt.domain import Stock, Stock1dHfqKdata
>>> from zvt.ml import MaStockMLMachine
>>> Stock.record_data(provider="em")
>>> entity_ids = ["stock_sz_000001", "stock_sz_000338", "stock_sh_601318"]
>>> Stock1dHfqKdata.record_data(provider="em", entity_ids=entity_ids, sleeping_time=1)
>>> machine = MaStockMLMachine(entity_ids=["stock_sz_000001"], data_provider="em")
>>> machine.train()
>>> machine.predict()
>>> machine.draw_result(entity_id="stock_sz_000001")
```> 以上几行代码实现了:数据的抓取,持久化,增量更新,机器学习,预测,展示结果。
> 熟悉系统的核心概念后,可以应用到市场中的任何标的。### 核心概念
```
>>> from zvt.domain import *
```### TradableEntity (交易标的)
#### A股交易标的
```
>>> Stock.record_data()
>>> df = Stock.query_data(index='code')
>>> print(df)id entity_id timestamp entity_type exchange code name list_date end_date
code
000001 stock_sz_000001 stock_sz_000001 1991-04-03 stock sz 000001 平安银行 1991-04-03 None
000002 stock_sz_000002 stock_sz_000002 1991-01-29 stock sz 000002 万 科A 1991-01-29 None
000004 stock_sz_000004 stock_sz_000004 1990-12-01 stock sz 000004 国华网安 1990-12-01 None
000005 stock_sz_000005 stock_sz_000005 1990-12-10 stock sz 000005 世纪星源 1990-12-10 None
000006 stock_sz_000006 stock_sz_000006 1992-04-27 stock sz 000006 深振业A 1992-04-27 None
... ... ... ... ... ... ... ... ... ...
605507 stock_sh_605507 stock_sh_605507 2021-08-02 stock sh 605507 国邦医药 2021-08-02 None
605577 stock_sh_605577 stock_sh_605577 2021-08-24 stock sh 605577 龙版传媒 2021-08-24 None
605580 stock_sh_605580 stock_sh_605580 2021-08-19 stock sh 605580 恒盛能源 2021-08-19 None
605588 stock_sh_605588 stock_sh_605588 2021-08-12 stock sh 605588 冠石科技 2021-08-12 None
605589 stock_sh_605589 stock_sh_605589 2021-08-10 stock sh 605589 圣泉集团 2021-08-10 None[4136 rows x 9 columns]
```#### 美股交易标的
```
>>> Stockus.record_data()
>>> df = Stockus.query_data(index='code')
>>> print(df)id entity_id timestamp entity_type exchange code name list_date end_date
code
A stockus_nyse_A stockus_nyse_A NaT stockus nyse A 安捷伦 None None
AA stockus_nyse_AA stockus_nyse_AA NaT stockus nyse AA 美国铝业 None None
AAC stockus_nyse_AAC stockus_nyse_AAC NaT stockus nyse AAC Ares Acquisition Corp-A None None
AACG stockus_nasdaq_AACG stockus_nasdaq_AACG NaT stockus nasdaq AACG ATA Creativity Global ADR None None
AACG stockus_nyse_AACG stockus_nyse_AACG NaT stockus nyse AACG ATA Creativity Global ADR None None
... ... ... ... ... ... ... ... ... ...
ZWRK stockus_nasdaq_ZWRK stockus_nasdaq_ZWRK NaT stockus nasdaq ZWRK Z-Work Acquisition Corp-A None None
ZY stockus_nasdaq_ZY stockus_nasdaq_ZY NaT stockus nasdaq ZY Zymergen Inc None None
ZYME stockus_nyse_ZYME stockus_nyse_ZYME NaT stockus nyse ZYME Zymeworks Inc None None
ZYNE stockus_nasdaq_ZYNE stockus_nasdaq_ZYNE NaT stockus nasdaq ZYNE Zynerba Pharmaceuticals Inc None None
ZYXI stockus_nasdaq_ZYXI stockus_nasdaq_ZYXI NaT stockus nasdaq ZYXI Zynex Inc None None[5826 rows x 9 columns]
>>> Stockus.query_data(code='AAPL')
id entity_id timestamp entity_type exchange code name list_date end_date
0 stockus_nasdaq_AAPL stockus_nasdaq_AAPL None stockus nasdaq AAPL 苹果 None None
```#### 港股交易标的
```
>>> Stockhk.record_data()
>>> df = Stockhk.query_data(index='code')
>>> print(df)id entity_id timestamp entity_type exchange code name list_date end_date
code
00001 stockhk_hk_00001 stockhk_hk_00001 NaT stockhk hk 00001 长和 None None
00002 stockhk_hk_00002 stockhk_hk_00002 NaT stockhk hk 00002 中电控股 None None
00003 stockhk_hk_00003 stockhk_hk_00003 NaT stockhk hk 00003 香港中华煤气 None None
00004 stockhk_hk_00004 stockhk_hk_00004 NaT stockhk hk 00004 九龙仓集团 None None
00005 stockhk_hk_00005 stockhk_hk_00005 NaT stockhk hk 00005 汇丰控股 None None
... ... ... ... ... ... ... ... ... ...
09996 stockhk_hk_09996 stockhk_hk_09996 NaT stockhk hk 09996 沛嘉医疗-B None None
09997 stockhk_hk_09997 stockhk_hk_09997 NaT stockhk hk 09997 康基医疗 None None
09998 stockhk_hk_09998 stockhk_hk_09998 NaT stockhk hk 09998 光荣控股 None None
09999 stockhk_hk_09999 stockhk_hk_09999 NaT stockhk hk 09999 网易-S None None
80737 stockhk_hk_80737 stockhk_hk_80737 NaT stockhk hk 80737 湾区发展-R None None[2597 rows x 9 columns]
>>> df[df.code=='00700']
id entity_id timestamp entity_type exchange code name list_date end_date
2112 stockhk_hk_00700 stockhk_hk_00700 None stockhk hk 00700 腾讯控股 None None```
#### 还有更多
```
>>> 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')
>>> df = Stock1dKdata.query_data(code='000338', provider='em')
>>> print(df)id entity_id timestamp provider code name level open close high low volume turnover change_pct turnover_rate
0 stock_sz_000338_2007-04-30 stock_sz_000338 2007-04-30 None 000338 潍柴动力 1d 2.33 2.00 2.40 1.87 207375.0 1.365189e+09 3.2472 0.1182
1 stock_sz_000338_2007-05-08 stock_sz_000338 2007-05-08 None 000338 潍柴动力 1d 2.11 1.94 2.20 1.87 86299.0 5.563198e+08 -0.0300 0.0492
2 stock_sz_000338_2007-05-09 stock_sz_000338 2007-05-09 None 000338 潍柴动力 1d 1.90 1.81 1.94 1.66 93823.0 5.782065e+08 -0.0670 0.0535
3 stock_sz_000338_2007-05-10 stock_sz_000338 2007-05-10 None 000338 潍柴动力 1d 1.78 1.85 1.98 1.75 47720.0 2.999226e+08 0.0221 0.0272
4 stock_sz_000338_2007-05-11 stock_sz_000338 2007-05-11 None 000338 潍柴动力 1d 1.81 1.73 1.81 1.66 39273.0 2.373126e+08 -0.0649 0.0224
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
3426 stock_sz_000338_2021-08-27 stock_sz_000338 2021-08-27 None 000338 潍柴动力 1d 19.39 20.30 20.30 19.25 1688497.0 3.370241e+09 0.0601 0.0398
3427 stock_sz_000338_2021-08-30 stock_sz_000338 2021-08-30 None 000338 潍柴动力 1d 20.30 20.09 20.31 19.78 1187601.0 2.377957e+09 -0.0103 0.0280
3428 stock_sz_000338_2021-08-31 stock_sz_000338 2021-08-31 None 000338 潍柴动力 1d 20.20 20.07 20.63 19.70 1143985.0 2.295195e+09 -0.0010 0.0270
3429 stock_sz_000338_2021-09-01 stock_sz_000338 2021-09-01 None 000338 潍柴动力 1d 19.98 19.68 19.98 19.15 1218697.0 2.383841e+09 -0.0194 0.0287
3430 stock_sz_000338_2021-09-02 stock_sz_000338 2021-09-02 None 000338 潍柴动力 1d 19.71 19.85 19.97 19.24 1023545.0 2.012006e+09 0.0086 0.0241[3431 rows x 15 columns]
>>> Stockus1dKdata.record_data(code='AAPL', provider='em')
>>> df = Stockus1dKdata.query_data(code='AAPL', provider='em')
>>> print(df)id entity_id timestamp provider code name level open close high low volume turnover change_pct turnover_rate
0 stockus_nasdaq_AAPL_1984-09-07 stockus_nasdaq_AAPL 1984-09-07 None AAPL 苹果 1d -5.59 -5.59 -5.58 -5.59 2981600.0 0.000000e+00 0.0000 0.0002
1 stockus_nasdaq_AAPL_1984-09-10 stockus_nasdaq_AAPL 1984-09-10 None AAPL 苹果 1d -5.59 -5.59 -5.58 -5.59 2346400.0 0.000000e+00 0.0000 0.0001
2 stockus_nasdaq_AAPL_1984-09-11 stockus_nasdaq_AAPL 1984-09-11 None AAPL 苹果 1d -5.58 -5.58 -5.58 -5.58 5444000.0 0.000000e+00 0.0018 0.0003
3 stockus_nasdaq_AAPL_1984-09-12 stockus_nasdaq_AAPL 1984-09-12 None AAPL 苹果 1d -5.58 -5.59 -5.58 -5.59 4773600.0 0.000000e+00 -0.0018 0.0003
4 stockus_nasdaq_AAPL_1984-09-13 stockus_nasdaq_AAPL 1984-09-13 None AAPL 苹果 1d -5.58 -5.58 -5.58 -5.58 7429600.0 0.000000e+00 0.0018 0.0004
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
8765 stockus_nasdaq_AAPL_2021-08-27 stockus_nasdaq_AAPL 2021-08-27 None AAPL 苹果 1d 147.48 148.60 148.75 146.83 55802388.0 8.265452e+09 0.0072 0.0034
8766 stockus_nasdaq_AAPL_2021-08-30 stockus_nasdaq_AAPL 2021-08-30 None AAPL 苹果 1d 149.00 153.12 153.49 148.61 90956723.0 1.383762e+10 0.0304 0.0055
8767 stockus_nasdaq_AAPL_2021-08-31 stockus_nasdaq_AAPL 2021-08-31 None AAPL 苹果 1d 152.66 151.83 152.80 151.29 86453117.0 1.314255e+10 -0.0084 0.0052
8768 stockus_nasdaq_AAPL_2021-09-01 stockus_nasdaq_AAPL 2021-09-01 None AAPL 苹果 1d 152.83 152.51 154.98 152.34 80313711.0 1.235321e+10 0.0045 0.0049
8769 stockus_nasdaq_AAPL_2021-09-02 stockus_nasdaq_AAPL 2021-09-02 None AAPL 苹果 1d 153.87 153.65 154.72 152.40 71171317.0 1.093251e+10 0.0075 0.0043[8770 rows x 15 columns]
```
后复权
```
>>> Stock1dHfqKdata.record_data(code='000338', provider='em')
>>> df = Stock1dHfqKdata.query_data(code='000338', provider='em')
>>> print(df)id entity_id timestamp provider code name level open close high low volume turnover change_pct turnover_rate
0 stock_sz_000338_2007-04-30 stock_sz_000338 2007-04-30 None 000338 潍柴动力 1d 70.00 64.93 71.00 62.88 207375.0 1.365189e+09 2.1720 0.1182
1 stock_sz_000338_2007-05-08 stock_sz_000338 2007-05-08 None 000338 潍柴动力 1d 66.60 64.00 68.00 62.88 86299.0 5.563198e+08 -0.0143 0.0492
2 stock_sz_000338_2007-05-09 stock_sz_000338 2007-05-09 None 000338 潍柴动力 1d 63.32 62.00 63.88 59.60 93823.0 5.782065e+08 -0.0313 0.0535
3 stock_sz_000338_2007-05-10 stock_sz_000338 2007-05-10 None 000338 潍柴动力 1d 61.50 62.49 64.48 61.01 47720.0 2.999226e+08 0.0079 0.0272
4 stock_sz_000338_2007-05-11 stock_sz_000338 2007-05-11 None 000338 潍柴动力 1d 61.90 60.65 61.90 59.70 39273.0 2.373126e+08 -0.0294 0.0224
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
3426 stock_sz_000338_2021-08-27 stock_sz_000338 2021-08-27 None 000338 潍柴动力 1d 331.97 345.95 345.95 329.82 1688497.0 3.370241e+09 0.0540 0.0398
3427 stock_sz_000338_2021-08-30 stock_sz_000338 2021-08-30 None 000338 潍柴动力 1d 345.95 342.72 346.10 337.96 1187601.0 2.377957e+09 -0.0093 0.0280
3428 stock_sz_000338_2021-08-31 stock_sz_000338 2021-08-31 None 000338 潍柴动力 1d 344.41 342.41 351.02 336.73 1143985.0 2.295195e+09 -0.0009 0.0270
3429 stock_sz_000338_2021-09-01 stock_sz_000338 2021-09-01 None 000338 潍柴动力 1d 341.03 336.42 341.03 328.28 1218697.0 2.383841e+09 -0.0175 0.0287
3430 stock_sz_000338_2021-09-02 stock_sz_000338 2021-09-02 None 000338 潍柴动力 1d 336.88 339.03 340.88 329.67 1023545.0 2.012006e+09 0.0078 0.0241[3431 rows x 15 columns]
```#### 财务因子
```
>>> FinanceFactor.record_data(code='000338')
>>> FinanceFactor.query_data(code='000338',columns=FinanceFactor.important_cols(),index='timestamp')basic_eps total_op_income net_profit op_income_growth_yoy net_profit_growth_yoy roe rota gross_profit_margin net_margin timestamp
timestamp
2002-12-31 NaN 1.962000e+07 2.471000e+06 NaN NaN NaN NaN 0.2068 0.1259 2002-12-31
2003-12-31 1.27 3.574000e+09 2.739000e+08 181.2022 109.8778 0.7729 0.1783 0.2551 0.0766 2003-12-31
2004-12-31 1.75 6.188000e+09 5.369000e+08 0.7313 0.9598 0.3245 0.1474 0.2489 0.0868 2004-12-31
2005-12-31 0.93 5.283000e+09 3.065000e+08 -0.1463 -0.4291 0.1327 0.0603 0.2252 0.0583 2005-12-31
2006-03-31 0.33 1.859000e+09 1.079000e+08 NaN NaN NaN NaN NaN 0.0598 2006-03-31
... ... ... ... ... ... ... ... ... ... ...
2020-08-28 0.59 9.449000e+10 4.680000e+09 0.0400 -0.1148 0.0983 0.0229 0.1958 0.0603 2020-08-28
2020-10-31 0.90 1.474000e+11 7.106000e+09 0.1632 0.0067 0.1502 0.0347 0.1949 0.0590 2020-10-31
2021-03-31 1.16 1.975000e+11 9.207000e+09 0.1327 0.0112 0.1919 0.0444 0.1931 0.0571 2021-03-31
2021-04-30 0.42 6.547000e+10 3.344000e+09 0.6788 0.6197 0.0622 0.0158 0.1916 0.0667 2021-04-30
2021-08-31 0.80 1.264000e+11 6.432000e+09 0.3375 0.3742 0.1125 0.0287 0.1884 0.0653 2021-08-31[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 provider',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/data_runner)
#### 全市场选股
查询数据使用的是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]
```以上,你应该会回答如下的三个问题了:
* 有什么数据?
* 如何记录数据?
* 如何查询数据?更高级的用法以及扩展数据,可以参考详细文档里的数据部分。
### 写个策略
有了 **交易标的** 和 **交易标的发生的事**,就可以写策略了。所谓策略回测,无非就是,重复以下过程:
#### 在某时间点,找到符合条件的标的,对其进行买卖,看其表现。系统支持两种模式:
* solo (随意的)在 某个时间 根据发生的事件 计算条件 并买卖
* formal (正式的)
系统设计的二维索引多标的计算模型
#### 一个很随便的人(solo)
嗯,这个策略真的很随便,就像我们大部分时间做的那样。
> 报表出来的时,我看一下报表,机构加仓超过5%我就买入,机构减仓超过50%我就卖出。代码如下:
```
# -*- coding: utf-8 -*-
import pandas as pdfrom zvt.api import get_recent_report_date
from zvt.contract import ActorType, AdjustType
from zvt.domain import StockActorSummary, Stock1dKdata
from zvt.trader import StockTrader
from zvt.utils import pd_is_not_null, is_same_date, to_pd_timestampclass FollowIITrader(StockTrader):
finish_date = Nonedef on_time(self, timestamp: pd.Timestamp):
recent_report_date = to_pd_timestamp(get_recent_report_date(timestamp))
if self.finish_date and is_same_date(recent_report_date, self.finish_date):
return
filters = [StockActorSummary.actor_type == ActorType.raised_fund.value,
StockActorSummary.report_date == recent_report_date]if self.entity_ids:
filters = filters + [StockActorSummary.entity_id.in_(self.entity_ids)]df = StockActorSummary.query_data(filters=filters)
if pd_is_not_null(df):
self.logger.info(f'{df}')
self.finish_date = recent_report_datelong_df = df[df['change_ratio'] > 0.05]
short_df = df[df['change_ratio'] < -0.5]
try:
self.trade_the_targets(due_timestamp=timestamp, happen_timestamp=timestamp,
long_selected=set(long_df['entity_id'].to_list()),
short_selected=set(short_df['entity_id'].to_list()))
except Exception as e:
self.logger.error(e)if __name__ == '__main__':
entity_id = 'stock_sh_600519'
Stock1dKdata.record_data(entity_id=entity_id, provider='em')
StockActorSummary.record_data(entity_id=entity_id, provider='em')
FollowIITrader(start_timestamp='2002-01-01', end_timestamp='2021-01-01', entity_ids=[entity_id],
provider='em', adjust_type=AdjustType.qfq, profit_threshold=None).run()
```所以,写一个策略其实还是很简单的嘛。
你可以发挥想象力,社保重仓买买买,外资重仓买买买,董事长跟小姨子跑了卖卖卖......然后,刷新一下[http://127.0.0.1:8050/](http://127.0.0.1:8050/),看你运行策略的performance
更多可参考[策略例子](https://github.com/zvtvz/zvt/tree/master/examples/trader)
#### 严肃一点(formal)
简单的计算可以通过query_data来完成,这里说的是系统设计的二维索引多标的计算模型。下面以技术因子为例对**计算流程**进行说明:
```
In [7]: from zvt.factors.technical_factor import *
In [8]: factor = BullFactor(codes=['000338','601318'],start_timestamp='2019-01-01',end_timestamp='2019-06-10', transformer=MacdTransformer())
```
### data_df
data_df为factor的原始数据,即通过query_data从数据库读取到的数据,为一个**二维索引**DataFrame
```
In [11]: factor.data_df
Out[11]:
level high id entity_id open low timestamp close
entity_id timestamp
stock_sh_601318 2019-01-02 1d 54.91 stock_sh_601318_2019-01-02 stock_sh_601318 54.78 53.70 2019-01-02 53.94
2019-01-03 1d 55.06 stock_sh_601318_2019-01-03 stock_sh_601318 53.91 53.82 2019-01-03 54.42
2019-01-04 1d 55.71 stock_sh_601318_2019-01-04 stock_sh_601318 54.03 53.98 2019-01-04 55.31
2019-01-07 1d 55.88 stock_sh_601318_2019-01-07 stock_sh_601318 55.80 54.64 2019-01-07 55.03
2019-01-08 1d 54.83 stock_sh_601318_2019-01-08 stock_sh_601318 54.79 53.96 2019-01-08 54.54
... ... ... ... ... ... ... ... ...
stock_sz_000338 2019-06-03 1d 11.04 stock_sz_000338_2019-06-03 stock_sz_000338 10.93 10.74 2019-06-03 10.81
2019-06-04 1d 10.85 stock_sz_000338_2019-06-04 stock_sz_000338 10.84 10.57 2019-06-04 10.73
2019-06-05 1d 10.92 stock_sz_000338_2019-06-05 stock_sz_000338 10.87 10.59 2019-06-05 10.59
2019-06-06 1d 10.71 stock_sz_000338_2019-06-06 stock_sz_000338 10.59 10.49 2019-06-06 10.65
2019-06-10 1d 11.05 stock_sz_000338_2019-06-10 stock_sz_000338 10.73 10.71 2019-06-10 11.02[208 rows x 8 columns]
```### factor_df
factor_df为transformer对data_df进行计算后得到的数据,设计因子即对[transformer](https://github.com/zvtvz/zvt/blob/master/zvt/factors/factor.py#L18)进行扩展,例子中用的是MacdTransformer()。```
In [12]: factor.factor_df
Out[12]:
level high id entity_id open low timestamp close diff dea macd
entity_id timestamp
stock_sh_601318 2019-01-02 1d 54.91 stock_sh_601318_2019-01-02 stock_sh_601318 54.78 53.70 2019-01-02 53.94 NaN NaN NaN
2019-01-03 1d 55.06 stock_sh_601318_2019-01-03 stock_sh_601318 53.91 53.82 2019-01-03 54.42 NaN NaN NaN
2019-01-04 1d 55.71 stock_sh_601318_2019-01-04 stock_sh_601318 54.03 53.98 2019-01-04 55.31 NaN NaN NaN
2019-01-07 1d 55.88 stock_sh_601318_2019-01-07 stock_sh_601318 55.80 54.64 2019-01-07 55.03 NaN NaN NaN
2019-01-08 1d 54.83 stock_sh_601318_2019-01-08 stock_sh_601318 54.79 53.96 2019-01-08 54.54 NaN NaN NaN
... ... ... ... ... ... ... ... ... ... ... ...
stock_sz_000338 2019-06-03 1d 11.04 stock_sz_000338_2019-06-03 stock_sz_000338 10.93 10.74 2019-06-03 10.81 -0.121336 -0.145444 0.048215
2019-06-04 1d 10.85 stock_sz_000338_2019-06-04 stock_sz_000338 10.84 10.57 2019-06-04 10.73 -0.133829 -0.143121 0.018583
2019-06-05 1d 10.92 stock_sz_000338_2019-06-05 stock_sz_000338 10.87 10.59 2019-06-05 10.59 -0.153260 -0.145149 -0.016223
2019-06-06 1d 10.71 stock_sz_000338_2019-06-06 stock_sz_000338 10.59 10.49 2019-06-06 10.65 -0.161951 -0.148509 -0.026884
2019-06-10 1d 11.05 stock_sz_000338_2019-06-10 stock_sz_000338 10.73 10.71 2019-06-10 11.02 -0.137399 -0.146287 0.017776[208 rows x 11 columns]
```### result_df
result_df为可用于选股器的**二维索引**DataFrame,通过对data_df或factor_df计算来实现。
该例子在计算macd之后,利用factor_df,黄白线在0轴上为True,否则为False,[具体代码](https://github.com/zvtvz/zvt/blob/master/zvt/factors/technical_factor.py#L56)```
In [14]: factor.result_df
Out[14]:
score
entity_id timestamp
stock_sh_601318 2019-01-02 False
2019-01-03 False
2019-01-04 False
2019-01-07 False
2019-01-08 False
... ...
stock_sz_000338 2019-06-03 False
2019-06-04 False
2019-06-05 False
2019-06-06 False
2019-06-10 False[208 rows x 1 columns]
```result_df的格式如下:
filter_result 为 True 或 False, score_result 取值为 0 到 1。
结合选股器和回测,整个流程如下:
## 环境设置(可选)
```
>>> from zvt import *
>>> zvt_env
{'zvt_home': '/Users/foolcage/zvt-home',
'data_path': '/Users/foolcage/zvt-home/data',
'tmp_path': '/Users/foolcage/zvt-home/tmp',
'ui_path': '/Users/foolcage/zvt-home/ui',
'log_path': '/Users/foolcage/zvt-home/logs'}>>> zvt_config
```* jq_username 聚宽数据用户名
* jq_password 聚宽数据密码
* smtp_host 邮件服务器host
* smtp_port 邮件服务器端口
* email_username smtp邮箱账户
* email_password smtp邮箱密码
* wechat_app_id
* wechat_app_secrect```
>>> init_config(current_config=zvt_config, jq_username='xxx', jq_password='yyy')
```
> 通用的配置方式为: init_config(current_config=zvt_config, **kv)### 历史数据
ZVT支持数据增量更新,用户之间可以共享历史数据,这样可以节省很多时间。
#### 数据源
> 新UI实时行情的计算基于QMT数据源,需要开通的同学可联系作者。项目数据支持多provider,在数据schema一致性的基础上,可根据需要进行选择和扩展,目前支持新浪,东财,交易所等免费数据。
#### 数据的设计上是让provider来适配schema,而不是反过来,这样即使某provider不可用了,换一个即可,不会影响整个系统的使用。
但免费数据的缺点是显而易见的:不稳定,爬取清洗数据耗时耗力,维护代价巨大,且随时可能不可用。
个人建议:如果只是学习研究,可以使用免费数据;如果是真正有意投身量化,还是选一家可靠的数据提供商。> 项目中大部分的免费数据目前都是比较稳定的,且做过严格测试,特别是东财的数据,可放心使用
> 添加其他数据提供商, 请参考[数据扩展教程](https://zvtvz.github.io/zvt/#/data_extending)
## 开发
### clone代码
```
git clone https://github.com/zvtvz/zvt.git
```设置项目的virtual env(python>=3.6),安装依赖
```
pip3 install -r requirements.txt
pip3 install pytest
```### 测试案例
pycharm导入工程(推荐,你也可以使用其他ide),然后pytest跑测试案例大部分功能使用都可以从tests里面参考
## 贡献
期待能有更多的开发者参与到 zvt 的开发中来,我会保证尽快 Reivew PR 并且及时回复。但提交 PR 请确保先看一下[1分钟代码规范](https://github.com/zvtvz/zvt/blob/master/code_of_conduct.md)
1. 通过所有单元测试,如若是新功能,请为其新增单元测试
2. 遵守开发规范
3. 如若需要,请更新相对应的文档也非常欢迎开发者能为 zvt 提供更多的示例,共同来完善文档。
## 请作者喝杯咖啡
如果你觉得项目对你有帮助,可以请作者喝杯咖啡
## 联系方式
加微信进群:foolcage 添加暗号:zvt
------
微信公众号:知乎专栏:
https://zhuanlan.zhihu.com/automoney## Thanks