├── .gitattributes
├── result.jpg
├── sh.600000_predict.jpg
├── sh.600004_predict.jpg
├── sh.600009_predict.jpg
├── sh.600010_predict.jpg
├── sh.600011_predict.jpg
├── requirements.txt
├── .gitignore
├── stock_concept.py
├── README.md
├── data_downloader.py
├── data
├── hs300_stocks.csv
└── stocks
│ └── sh.000300.csv
├── strategy.py
├── backtest.py
├── prediction.py
├── LICENSE
└── stock_indicator.py
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/result.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AkatsukiYamisora/stock-prediction-with-DL/HEAD/result.jpg
--------------------------------------------------------------------------------
/sh.600000_predict.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AkatsukiYamisora/stock-prediction-with-DL/HEAD/sh.600000_predict.jpg
--------------------------------------------------------------------------------
/sh.600004_predict.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AkatsukiYamisora/stock-prediction-with-DL/HEAD/sh.600004_predict.jpg
--------------------------------------------------------------------------------
/sh.600009_predict.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AkatsukiYamisora/stock-prediction-with-DL/HEAD/sh.600009_predict.jpg
--------------------------------------------------------------------------------
/sh.600010_predict.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AkatsukiYamisora/stock-prediction-with-DL/HEAD/sh.600010_predict.jpg
--------------------------------------------------------------------------------
/sh.600011_predict.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AkatsukiYamisora/stock-prediction-with-DL/HEAD/sh.600011_predict.jpg
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | torch==1.7.0+cu101
2 | pandas>=1.0.5
3 | baostock>=0.8.8
4 | matplotlib>=3.2.2
5 | tqdm>=4.48.2
6 | numpy>=1.19.3
7 | tushare>=1.2.62
8 | requests
9 | bs4
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | /.idea/
3 | /__pycache__/
4 | *.csv
5 | *.pkl
6 | *.pt
7 | tushare_apikey.txt
8 | !./data/*.csv
9 | !./data/stocks/sh.000016.csv
10 | !./data/stocks/sh.000300.csv
11 | !./data/stocks/sh.000905.csv
12 |
--------------------------------------------------------------------------------
/stock_concept.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | @version: 3.8.3
4 | @author: Yamisora
5 | @file: stock_concept.py
6 | """
7 | import requests
8 | from bs4 import BeautifulSoup
9 | import pandas as pd
10 |
11 |
12 | base_data_path = './data/'
13 | url = 'http://stockpage.10jqka.com.cn/'
14 | header = {
15 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
16 | 'Chrome/96.0.4664.55 Safari/537.36 Edg/96.0.1054.34 '
17 | }
18 | hs300 = pd.read_csv(base_data_path + 'hs300_stocks.csv')
19 | codes = [a[3:]+'/' for a in hs300['code']]
20 | hs300['concept'] = ''
21 |
22 | for i in range(len(hs300)):
23 | print('正在爬取'+codes[i]+'概念数据')
24 | response = requests.get(url+codes[i], headers=header)
25 | soup = BeautifulSoup(response.text, 'lxml')
26 | company_details = soup.find('dl', class_='company_details')
27 | details = company_details.find_all('dd')
28 | concept = details[1]['title']
29 | hs300.loc[i, 'concept'] = concept
30 |
31 | hs300.to_csv(base_data_path+'hs300_stocks.csv')
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # stock-prediction-with-DL/深度学习与股票分析预测
2 |
3 | 
4 | 
5 | 
6 | 
7 | 
8 |
9 | 目前新增了100多个技术指标,优化了一部分代码,正在做图神经网络部分内容,预计做一个小论文,等论文见刊再更新仓库^-^
10 |
11 | ## data_downloader.py
12 |
13 | 通过baostock下载上证50,沪深300,中证500的日线数据
14 |
15 | ## backtest.py
16 |
17 | 回测模块,根据调仓周期,通过模型选股,按开盘价买入卖出(暂定),计算收益,与指数比较并绘图
18 |
19 | 当前回测结果:
20 |
21 | 
22 |
23 | ## strategy.py
24 |
25 | 按价值因子(选择账面市值比BM)进行选股(效果差,由于BM在大市值公司的效果不佳)
26 |
27 | 用CNN预测模型进行选股
28 |
29 | 用动量因子(MF)进行选股
30 |
31 | 用换手率因子(TR)进行选股(思路参考自Liu et al.(2019) Size and value in China, 修改了数据选取)
32 |
33 | 用LSTM与reluRNN预测模型进行选股
34 |
35 | 用GRU与tanhRNN预测模型进行选股(效果不佳已放弃)
36 |
37 | 用ResNet18,34,50预测模型进行选股
38 |
39 | 用DenseNet预测模型进行选股
40 |
41 | 用综合几种网络预测结果的集成学习策略进行选股
42 |
43 | 其余策略待更新
44 |
45 | ## prediction.py
46 |
47 | 使用CNN对股票数据进行预测
48 |
49 | 使用LSTM与reluRNN对股票数据进行预测(GRU与tanhRNN由于效果不佳放弃)
50 |
51 | 使用ResNet18,34,50对股票数据进行预测(101与152由于效果不佳放弃)
52 |
53 | 使用DenseNet对股票数据进行预测
54 |
55 | 当前预测结果
56 |
57 | sh.600000,浦发银行
58 |
59 | 
60 |
61 | sh.600004,白云机场
62 |
63 | 
64 |
65 | sh.600009,上海机场
66 |
67 | 
68 |
69 | sh.600010,包钢股份
70 |
71 | 
72 |
73 | sh.600011,华能国际
74 |
75 | 
76 |
77 | ## tushare_apikey.txt
78 |
79 | 本地保存tushare pro的apikey
80 |
81 | ## /data/hs300_stocks.csv
82 |
83 | 存放指数股票列表数据
84 |
85 | ## /data/stocks/sh.000300.csv
86 |
87 | 存放指数日线数据
88 |
89 | ## /data/stocks/*.csv
90 |
91 | 存放回测个股日线数据
92 |
93 | ## /data/train_data/*.csv
94 |
95 | 存放训练集个股日线数据
96 |
97 | ## /data/*.pkl
98 |
99 | 存放训练集数据
100 |
101 | ## /data/*.pt
102 |
103 | 存放训练完成的模型数据
104 |
105 | ## result.jpg
106 |
107 | 回测结果展示图片
108 |
109 | ## *_predict.jpg
110 |
111 | 单只股票预测结果展示图片
112 |
--------------------------------------------------------------------------------
/data_downloader.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | @version: 3.8.3
4 | @time: 21/4/25 23:49
5 | @author: Yamisora
6 | @file: data_downloader.py
7 | """
8 | import os
9 | import baostock as bs
10 | import tushare as ts
11 | import pandas as pd
12 | import numpy as np
13 | from tqdm import tqdm
14 | import time
15 |
16 | # 设置数据下载时间段
17 | data_start_date = '2019-01-01'
18 | data_end_date = '2021-06-02'
19 | train_data_start_date = '2015-01-01'
20 | train_data_end_date = '2018-12-31'
21 | # 存储路径
22 | base_data_path = './data/'
23 | data_path = './data/stocks/'
24 | train_data_path = './data/train_data/'
25 |
26 | # 使用tushare数据api
27 | apikey = ''
28 | if os.path.exists('tushare_apikey.txt'):
29 | with open('tushare_apikey.txt', 'r') as f:
30 | apikey = f.read()
31 | pro = ts.pro_api(apikey)
32 |
33 | # 设置是否下载数据
34 | download_stocks = True
35 | download_indexes = True
36 | # 下载个股参数列表
37 | fields = "date,code,open,high,low,close,preclose,volume," \
38 | "amount,turn,peTTM,psTTM,pcfNcfTTM,pbMRQ"
39 | ts_basic_fields = "trade_date,total_share,float_share,free_share,total_mv,circ_mv"
40 |
41 | # baostock数据下载
42 | lg = bs.login()
43 | # 显示登陆返回信息
44 | if lg.error_code != '0':
45 | print('login respond error_code:' + lg.error_code)
46 | print('login respond error_msg:' + lg.error_msg)
47 |
48 |
49 | def status(raw):
50 | if raw.error_code != '0':
51 | print('query_history_k_data_plus respond error_code:' + rs.error_code)
52 | print('query_history_k_data_plus respond error_msg:' + rs.error_msg)
53 |
54 |
55 | def data_load(raw):
56 | """读取baostock数据"""
57 | data = []
58 | while (raw.error_code == '0') & raw.next():
59 | # 获取一条记录,将记录合并在一起
60 | data.append(raw.get_row_data())
61 | df = pd.DataFrame(data, columns=raw.fields)
62 | return df
63 |
64 |
65 | def ts_c(bs_stock_code: str) -> str:
66 | """转换baostock股票代码为tushare股票代码"""
67 | return bs_stock_code[3:]+'.'+bs_stock_code[0:2].upper()
68 |
69 |
70 | def ts_d(date):
71 | """转换baostock日期为tushare日期"""
72 | return date.replace('-', '')
73 |
74 |
75 | def bs_d(ts_date_series):
76 | """转换tushare日期序列为baostock日期序列"""
77 | date_series = []
78 | for ts_date in ts_date_series:
79 | date = str(ts_date)
80 | date_series.append(date[:4] + '-' + date[4:6] + '-' + date[6:])
81 | return date_series
82 |
83 |
84 | if download_stocks:
85 | rs = bs.query_hs300_stocks()
86 | # 获取股票名称与代码
87 | result = data_load(rs)
88 | result.to_csv(base_data_path+'hs300_stocks.csv')
89 | for code in tqdm(result['code']):
90 | for start_date, end_date, path in ((data_start_date, data_end_date, data_path),
91 | (train_data_start_date, train_data_end_date, train_data_path)):
92 | rs = bs.query_history_k_data_plus(code, fields,
93 | start_date=start_date, end_date=end_date,
94 | frequency="d", adjustflag="3")
95 | status(rs)
96 |
97 | # baostock日线数据
98 | df1 = data_load(rs)
99 | df1.set_index('date', inplace=True)
100 |
101 | # tushare指标数据
102 | df2 = pro.daily_basic(ts_code=ts_c(code), start_date=ts_d(start_date),
103 | end_date=ts_d(end_date), fields=ts_basic_fields)
104 | df2['trade_date'] = bs_d(df2['trade_date'])
105 | df2.set_index('trade_date', inplace=True)
106 |
107 | # 按index横向拼接
108 | df1 = df1.join(df2)
109 | # 去除无效空值,补0
110 | df1.replace(to_replace=r'^\s*$', value=np.nan, regex=True, inplace=True)
111 | df1.fillna(0, inplace=True)
112 |
113 | df1.to_csv(path+code+'.csv')
114 | del df1, df2
115 | time.sleep(0.2) # 防止tushare调用到分钟上限
116 |
117 |
118 | if download_indexes:
119 | rs = bs.query_history_k_data_plus('sh.000300',
120 | "date,code,open,high,low,close,preclose,volume,amount,pctChg",
121 | start_date=data_start_date, end_date=data_end_date, frequency="d")
122 | status(rs)
123 | data_load(rs).to_csv(data_path+'sh.000300.csv')
124 |
125 | # 登出系统
126 | bs.logout()
127 |
--------------------------------------------------------------------------------
/data/hs300_stocks.csv:
--------------------------------------------------------------------------------
1 | ,updateDate,code,code_name
2 | 0,2021-05-31,sh.600000,浦发银行
3 | 1,2021-05-31,sh.600004,白云机场
4 | 2,2021-05-31,sh.600009,上海机场
5 | 3,2021-05-31,sh.600010,包钢股份
6 | 4,2021-05-31,sh.600011,华能国际
7 | 5,2021-05-31,sh.600015,华夏银行
8 | 6,2021-05-31,sh.600016,民生银行
9 | 7,2021-05-31,sh.600018,上港集团
10 | 8,2021-05-31,sh.600019,宝钢股份
11 | 9,2021-05-31,sh.600025,华能水电
12 | 10,2021-05-31,sh.600027,华电国际
13 | 11,2021-05-31,sh.600028,中国石化
14 | 12,2021-05-31,sh.600029,南方航空
15 | 13,2021-05-31,sh.600030,中信证券
16 | 14,2021-05-31,sh.600031,三一重工
17 | 15,2021-05-31,sh.600036,招商银行
18 | 16,2021-05-31,sh.600048,保利地产
19 | 17,2021-05-31,sh.600050,中国联通
20 | 18,2021-05-31,sh.600061,国投资本
21 | 19,2021-05-31,sh.600066,宇通客车
22 | 20,2021-05-31,sh.600068,葛洲坝
23 | 21,2021-05-31,sh.600085,同仁堂
24 | 22,2021-05-31,sh.600104,上汽集团
25 | 23,2021-05-31,sh.600109,国金证券
26 | 24,2021-05-31,sh.600111,北方稀土
27 | 25,2021-05-31,sh.600115,东方航空
28 | 26,2021-05-31,sh.600118,中国卫星
29 | 27,2021-05-31,sh.600150,中国船舶
30 | 28,2021-05-31,sh.600161,天坛生物
31 | 29,2021-05-31,sh.600176,中国巨石
32 | 30,2021-05-31,sh.600177,雅戈尔
33 | 31,2021-05-31,sh.600183,生益科技
34 | 32,2021-05-31,sh.600196,复星医药
35 | 33,2021-05-31,sh.600208,新湖中宝
36 | 34,2021-05-31,sh.600233,圆通速递
37 | 35,2021-05-31,sh.600271,航天信息
38 | 36,2021-05-31,sh.600276,恒瑞医药
39 | 37,2021-05-31,sh.600297,广汇汽车
40 | 38,2021-05-31,sh.600299,安迪苏
41 | 39,2021-05-31,sh.600309,万华化学
42 | 40,2021-05-31,sh.600332,白云山
43 | 41,2021-05-31,sh.600340,华夏幸福
44 | 42,2021-05-31,sh.600346,恒力石化
45 | 43,2021-05-31,sh.600352,浙江龙盛
46 | 44,2021-05-31,sh.600362,江西铜业
47 | 45,2021-05-31,sh.600369,西南证券
48 | 46,2021-05-31,sh.600383,金地集团
49 | 47,2021-05-31,sh.600390,五矿资本
50 | 48,2021-05-31,sh.600406,国电南瑞
51 | 49,2021-05-31,sh.600436,片仔癀
52 | 50,2021-05-31,sh.600438,通威股份
53 | 51,2021-05-31,sh.600482,中国动力
54 | 52,2021-05-31,sh.600487,亨通光电
55 | 53,2021-05-31,sh.600489,中金黄金
56 | 54,2021-05-31,sh.600498,烽火通信
57 | 55,2021-05-31,sh.600519,贵州茅台
58 | 56,2021-05-31,sh.600522,中天科技
59 | 57,2021-05-31,sh.600547,山东黄金
60 | 58,2021-05-31,sh.600570,恒生电子
61 | 59,2021-05-31,sh.600584,长电科技
62 | 60,2021-05-31,sh.600585,海螺水泥
63 | 61,2021-05-31,sh.600588,用友网络
64 | 62,2021-05-31,sh.600600,青岛啤酒
65 | 63,2021-05-31,sh.600606,绿地控股
66 | 64,2021-05-31,sh.600637,东方明珠
67 | 65,2021-05-31,sh.600655,豫园股份
68 | 66,2021-05-31,sh.600660,福耀玻璃
69 | 67,2021-05-31,sh.600690,海尔智家
70 | 68,2021-05-31,sh.600703,三安光电
71 | 69,2021-05-31,sh.600705,中航资本
72 | 70,2021-05-31,sh.600741,华域汽车
73 | 71,2021-05-31,sh.600745,闻泰科技
74 | 72,2021-05-31,sh.600760,中航沈飞
75 | 73,2021-05-31,sh.600763,通策医疗
76 | 74,2021-05-31,sh.600795,国电电力
77 | 75,2021-05-31,sh.600809,山西汾酒
78 | 76,2021-05-31,sh.600837,海通证券
79 | 77,2021-05-31,sh.600845,宝信软件
80 | 78,2021-05-31,sh.600848,上海临港
81 | 79,2021-05-31,sh.600872,中炬高新
82 | 80,2021-05-31,sh.600886,国投电力
83 | 81,2021-05-31,sh.600887,伊利股份
84 | 82,2021-05-31,sh.600893,航发动力
85 | 83,2021-05-31,sh.600900,长江电力
86 | 84,2021-05-31,sh.600918,中泰证券
87 | 85,2021-05-31,sh.600919,江苏银行
88 | 86,2021-05-31,sh.600926,杭州银行
89 | 87,2021-05-31,sh.600958,东方证券
90 | 88,2021-05-31,sh.600989,宝丰能源
91 | 89,2021-05-31,sh.600998,九州通
92 | 90,2021-05-31,sh.600999,招商证券
93 | 91,2021-05-31,sh.601006,大秦铁路
94 | 92,2021-05-31,sh.601009,南京银行
95 | 93,2021-05-31,sh.601012,隆基股份
96 | 94,2021-05-31,sh.601021,春秋航空
97 | 95,2021-05-31,sh.601066,中信建投
98 | 96,2021-05-31,sh.601077,渝农商行
99 | 97,2021-05-31,sh.601088,中国神华
100 | 98,2021-05-31,sh.601100,恒立液压
101 | 99,2021-05-31,sh.601108,财通证券
102 | 100,2021-05-31,sh.601111,中国国航
103 | 101,2021-05-31,sh.601117,中国化学
104 | 102,2021-05-31,sh.601138,工业富联
105 | 103,2021-05-31,sh.601155,新城控股
106 | 104,2021-05-31,sh.601162,天风证券
107 | 105,2021-05-31,sh.601166,兴业银行
108 | 106,2021-05-31,sh.601169,北京银行
109 | 107,2021-05-31,sh.601186,中国铁建
110 | 108,2021-05-31,sh.601198,东兴证券
111 | 109,2021-05-31,sh.601211,国泰君安
112 | 110,2021-05-31,sh.601216,君正集团
113 | 111,2021-05-31,sh.601225,陕西煤业
114 | 112,2021-05-31,sh.601229,上海银行
115 | 113,2021-05-31,sh.601231,环旭电子
116 | 114,2021-05-31,sh.601236,红塔证券
117 | 115,2021-05-31,sh.601238,广汽集团
118 | 116,2021-05-31,sh.601288,农业银行
119 | 117,2021-05-31,sh.601318,中国平安
120 | 118,2021-05-31,sh.601319,中国人保
121 | 119,2021-05-31,sh.601328,交通银行
122 | 120,2021-05-31,sh.601336,新华保险
123 | 121,2021-05-31,sh.601360,三六零
124 | 122,2021-05-31,sh.601377,兴业证券
125 | 123,2021-05-31,sh.601390,中国中铁
126 | 124,2021-05-31,sh.601398,工商银行
127 | 125,2021-05-31,sh.601555,东吴证券
128 | 126,2021-05-31,sh.601577,长沙银行
129 | 127,2021-05-31,sh.601600,中国铝业
130 | 128,2021-05-31,sh.601601,中国太保
131 | 129,2021-05-31,sh.601607,上海医药
132 | 130,2021-05-31,sh.601618,中国中冶
133 | 131,2021-05-31,sh.601628,中国人寿
134 | 132,2021-05-31,sh.601633,长城汽车
135 | 133,2021-05-31,sh.601658,邮储银行
136 | 134,2021-05-31,sh.601668,中国建筑
137 | 135,2021-05-31,sh.601669,中国电建
138 | 136,2021-05-31,sh.601688,华泰证券
139 | 137,2021-05-31,sh.601696,中银证券
140 | 138,2021-05-31,sh.601698,中国卫通
141 | 139,2021-05-31,sh.601727,上海电气
142 | 140,2021-05-31,sh.601766,中国中车
143 | 141,2021-05-31,sh.601788,光大证券
144 | 142,2021-05-31,sh.601800,中国交建
145 | 143,2021-05-31,sh.601808,中海油服
146 | 144,2021-05-31,sh.601816,京沪高铁
147 | 145,2021-05-31,sh.601818,光大银行
148 | 146,2021-05-31,sh.601838,成都银行
149 | 147,2021-05-31,sh.601857,中国石油
150 | 148,2021-05-31,sh.601872,招商轮船
151 | 149,2021-05-31,sh.601877,正泰电器
152 | 150,2021-05-31,sh.601878,浙商证券
153 | 151,2021-05-31,sh.601881,中国银河
154 | 152,2021-05-31,sh.601888,中国中免
155 | 153,2021-05-31,sh.601899,紫金矿业
156 | 154,2021-05-31,sh.601901,方正证券
157 | 155,2021-05-31,sh.601916,浙商银行
158 | 156,2021-05-31,sh.601919,中远海控
159 | 157,2021-05-31,sh.601933,永辉超市
160 | 158,2021-05-31,sh.601939,建设银行
161 | 159,2021-05-31,sh.601985,中国核电
162 | 160,2021-05-31,sh.601988,中国银行
163 | 161,2021-05-31,sh.601989,中国重工
164 | 162,2021-05-31,sh.601990,南京证券
165 | 163,2021-05-31,sh.601998,中信银行
166 | 164,2021-05-31,sh.603019,中科曙光
167 | 165,2021-05-31,sh.603087,甘李药业
168 | 166,2021-05-31,sh.603156,养元饮品
169 | 167,2021-05-31,sh.603160,汇顶科技
170 | 168,2021-05-31,sh.603195,公牛集团
171 | 169,2021-05-31,sh.603259,药明康德
172 | 170,2021-05-31,sh.603288,海天味业
173 | 171,2021-05-31,sh.603369,今世缘
174 | 172,2021-05-31,sh.603392,万泰生物
175 | 173,2021-05-31,sh.603501,韦尔股份
176 | 174,2021-05-31,sh.603658,安图生物
177 | 175,2021-05-31,sh.603799,华友钴业
178 | 176,2021-05-31,sh.603833,欧派家居
179 | 177,2021-05-31,sh.603899,晨光文具
180 | 178,2021-05-31,sh.603986,兆易创新
181 | 179,2021-05-31,sh.603993,洛阳钼业
182 | 180,2021-05-31,sh.688008,澜起科技
183 | 181,2021-05-31,sh.688009,中国通号
184 | 182,2021-05-31,sh.688012,中微公司
185 | 183,2021-05-31,sh.688036,传音控股
186 | 184,2021-05-31,sz.000001,平安银行
187 | 185,2021-05-31,sz.000002,万科A
188 | 186,2021-05-31,sz.000063,中兴通讯
189 | 187,2021-05-31,sz.000066,中国长城
190 | 188,2021-05-31,sz.000069,华侨城A
191 | 189,2021-05-31,sz.000100,TCL科技
192 | 190,2021-05-31,sz.000157,中联重科
193 | 191,2021-05-31,sz.000166,申万宏源
194 | 192,2021-05-31,sz.000333,美的集团
195 | 193,2021-05-31,sz.000338,潍柴动力
196 | 194,2021-05-31,sz.000425,徐工机械
197 | 195,2021-05-31,sz.000538,云南白药
198 | 196,2021-05-31,sz.000568,泸州老窖
199 | 197,2021-05-31,sz.000596,古井贡酒
200 | 198,2021-05-31,sz.000625,长安汽车
201 | 199,2021-05-31,sz.000627,天茂集团
202 | 200,2021-05-31,sz.000651,格力电器
203 | 201,2021-05-31,sz.000656,金科股份
204 | 202,2021-05-31,sz.000661,长春高新
205 | 203,2021-05-31,sz.000671,阳光城
206 | 204,2021-05-31,sz.000703,恒逸石化
207 | 205,2021-05-31,sz.000708,中信特钢
208 | 206,2021-05-31,sz.000723,美锦能源
209 | 207,2021-05-31,sz.000725,京东方A
210 | 208,2021-05-31,sz.000728,国元证券
211 | 209,2021-05-31,sz.000768,中航西飞
212 | 210,2021-05-31,sz.000776,广发证券
213 | 211,2021-05-31,sz.000783,长江证券
214 | 212,2021-05-31,sz.000786,北新建材
215 | 213,2021-05-31,sz.000858,五粮液
216 | 214,2021-05-31,sz.000860,顺鑫农业
217 | 215,2021-05-31,sz.000876,新希望
218 | 216,2021-05-31,sz.000895,双汇发展
219 | 217,2021-05-31,sz.000938,紫光股份
220 | 218,2021-05-31,sz.000961,中南建设
221 | 219,2021-05-31,sz.000963,华东医药
222 | 220,2021-05-31,sz.000977,浪潮信息
223 | 221,2021-05-31,sz.001979,招商蛇口
224 | 222,2021-05-31,sz.002001,新和成
225 | 223,2021-05-31,sz.002007,华兰生物
226 | 224,2021-05-31,sz.002008,大族激光
227 | 225,2021-05-31,sz.002024,苏宁易购
228 | 226,2021-05-31,sz.002027,分众传媒
229 | 227,2021-05-31,sz.002032,苏泊尔
230 | 228,2021-05-31,sz.002044,美年健康
231 | 229,2021-05-31,sz.002049,紫光国微
232 | 230,2021-05-31,sz.002050,三花智控
233 | 231,2021-05-31,sz.002120,韵达股份
234 | 232,2021-05-31,sz.002129,中环股份
235 | 233,2021-05-31,sz.002142,宁波银行
236 | 234,2021-05-31,sz.002146,荣盛发展
237 | 235,2021-05-31,sz.002153,石基信息
238 | 236,2021-05-31,sz.002157,正邦科技
239 | 237,2021-05-31,sz.002179,中航光电
240 | 238,2021-05-31,sz.002202,金风科技
241 | 239,2021-05-31,sz.002230,科大讯飞
242 | 240,2021-05-31,sz.002236,大华股份
243 | 241,2021-05-31,sz.002241,歌尔股份
244 | 242,2021-05-31,sz.002252,上海莱士
245 | 243,2021-05-31,sz.002271,东方雨虹
246 | 244,2021-05-31,sz.002304,洋河股份
247 | 245,2021-05-31,sz.002311,海大集团
248 | 246,2021-05-31,sz.002352,顺丰控股
249 | 247,2021-05-31,sz.002371,北方华创
250 | 248,2021-05-31,sz.002384,东山精密
251 | 249,2021-05-31,sz.002410,广联达
252 | 250,2021-05-31,sz.002414,高德红外
253 | 251,2021-05-31,sz.002415,海康威视
254 | 252,2021-05-31,sz.002422,科伦药业
255 | 253,2021-05-31,sz.002456,欧菲光
256 | 254,2021-05-31,sz.002460,赣锋锂业
257 | 255,2021-05-31,sz.002463,沪电股份
258 | 256,2021-05-31,sz.002475,立讯精密
259 | 257,2021-05-31,sz.002493,荣盛石化
260 | 258,2021-05-31,sz.002508,老板电器
261 | 259,2021-05-31,sz.002555,三七互娱
262 | 260,2021-05-31,sz.002558,巨人网络
263 | 261,2021-05-31,sz.002594,比亚迪
264 | 262,2021-05-31,sz.002600,领益智造
265 | 263,2021-05-31,sz.002601,龙蟒佰利
266 | 264,2021-05-31,sz.002602,世纪华通
267 | 265,2021-05-31,sz.002607,中公教育
268 | 266,2021-05-31,sz.002624,完美世界
269 | 267,2021-05-31,sz.002673,西部证券
270 | 268,2021-05-31,sz.002714,牧原股份
271 | 269,2021-05-31,sz.002736,国信证券
272 | 270,2021-05-31,sz.002739,万达电影
273 | 271,2021-05-31,sz.002773,康弘药业
274 | 272,2021-05-31,sz.002812,恩捷股份
275 | 273,2021-05-31,sz.002821,凯莱英
276 | 274,2021-05-31,sz.002841,视源股份
277 | 275,2021-05-31,sz.002916,深南电路
278 | 276,2021-05-31,sz.002938,鹏鼎控股
279 | 277,2021-05-31,sz.002939,长城证券
280 | 278,2021-05-31,sz.002945,华林证券
281 | 279,2021-05-31,sz.002958,青农商行
282 | 280,2021-05-31,sz.003816,中国广核
283 | 281,2021-05-31,sz.300003,乐普医疗
284 | 282,2021-05-31,sz.300014,亿纬锂能
285 | 283,2021-05-31,sz.300015,爱尔眼科
286 | 284,2021-05-31,sz.300033,同花顺
287 | 285,2021-05-31,sz.300059,东方财富
288 | 286,2021-05-31,sz.300122,智飞生物
289 | 287,2021-05-31,sz.300124,汇川技术
290 | 288,2021-05-31,sz.300136,信维通信
291 | 289,2021-05-31,sz.300142,沃森生物
292 | 290,2021-05-31,sz.300144,宋城演艺
293 | 291,2021-05-31,sz.300347,泰格医药
294 | 292,2021-05-31,sz.300408,三环集团
295 | 293,2021-05-31,sz.300413,芒果超媒
296 | 294,2021-05-31,sz.300433,蓝思科技
297 | 295,2021-05-31,sz.300498,温氏股份
298 | 296,2021-05-31,sz.300529,健帆生物
299 | 297,2021-05-31,sz.300601,康泰生物
300 | 298,2021-05-31,sz.300628,亿联网络
301 | 299,2021-05-31,sz.300676,华大基因
302 |
--------------------------------------------------------------------------------
/strategy.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | @version: 3.8.3
4 | @time: 21/4/29 9:30
5 | @author: Yamisora
6 | @file: strategy.py
7 | """
8 | from prediction import *
9 |
10 |
11 | class Strategy:
12 | def __init__(self, data_days=10):
13 | """
14 | 选股策略
15 | @data_days: 回测选择数据日期
16 | """
17 | # 策略所需数据天数
18 | self.data_days = data_days
19 | # index选择指数组合
20 | self.index_name = 'hs300'
21 | self.index_code = 'sh.000300'
22 | # 存储路径
23 | self.base_data_path = './data/'
24 | self.data_path = './data/stocks/'
25 | self.train_data_path = './data/train_data/'
26 | # 指数组合内股票名称,代码数据
27 | self.stocks = pd.read_csv('{}{}_stocks.csv'.format(self.base_data_path, self.index_name))
28 | self.stocks_codes = self.stocks['code']
29 | # 指数日线数据
30 | self.index = pd.read_csv('{}{}.csv'.format(self.data_path, self.index_code))
31 | # 交易日str序列
32 | self.trading_dates = self.index['date']
33 | # 训练CNN模型
34 | self.dataset = StockDataset(data_days=data_days)
35 | self.prediction = Prediction(data_days=data_days, batch_size=50)
36 | self.prediction.train_cnn(self.dataset, retrain=False, epochs=2)
37 | self.prediction.train_lstm(self.dataset, retrain=False, epochs=2)
38 | # self.prediction.train_gru(self.dataset, retrain=False, epochs=2)
39 | # self.prediction.train_rnn_tanh(self.dataset, retrain=False, epochs=2)
40 | self.prediction.train_rnn_relu(self.dataset, retrain=False, epochs=2)
41 | self.prediction.train_resnet18(self.dataset, retrain=False, epochs=2)
42 | self.prediction.train_resnet34(self.dataset, retrain=False, epochs=2)
43 | self.prediction.train_resnet50(self.dataset, retrain=False, epochs=2)
44 | self.prediction.train_resnet101(self.dataset, retrain=False, epochs=2)
45 | self.prediction.train_resnet152(self.dataset, retrain=False, epochs=2)
46 | self.prediction.train_densenet(self.dataset, retrain=False, epochs=2)
47 |
48 | def choose_by_bm(self, today: tuple, number: int):
49 | """
50 | 选择最近data_days中平均账面市值比(BM)最高的number只股票
51 | """
52 | # 第一次买入策略应大于策略所需数据天数
53 | if today[1] < self.data_days:
54 | return pd.Series(None)
55 | # 建立用于计算平均BM的DF
56 | stocks_data = pd.DataFrame(self.stocks_codes)
57 | stocks_data['aver_BM'] = 0
58 | stocks_data = stocks_data.set_index('code')
59 | # 到交易日前一日为止共data_days日期序号
60 | days = range(today[1] - self.data_days, today[1])
61 | for stock_code in self.stocks_codes:
62 | sum_BM = 0
63 | valid_days = self.data_days
64 | stock_data = pd.read_csv('{}{}.csv'.format(self.data_path, stock_code), index_col='date')
65 | for day in days:
66 | if self.trading_dates[day] in stock_data.index:
67 | # 加入每日市净率倒数
68 | pb = stock_data.loc[self.trading_dates[day], 'pbMRQ']
69 | if pb != 0:
70 | sum_BM += 1.0 / pb
71 | else:
72 | sum_BM += 0
73 | else:
74 | valid_days -= 1
75 | if valid_days != 0:
76 | aver_BM = sum_BM / valid_days
77 | else:
78 | aver_BM = 0
79 | if aver_BM > 0:
80 | stocks_data.loc[stock_code, 'aver_BM'] = aver_BM
81 | # print(stocks_data)
82 | stocks_data.sort_values(by='aver_BM', ascending=False, inplace=True)
83 | # print(stocks_data.index)
84 | if len(stocks_data.index) > number:
85 | # 取0到number-1共number只股票
86 | return stocks_data.index[0:number]
87 | else:
88 | # 取全部股票
89 | return stocks_data.index[:]
90 |
91 | def choose_by_mf(self, today: tuple, number: int):
92 | """
93 | 选择最近data_days中动量因子(Momentum Factor)最高的number只股票
94 | """
95 | # 第一次买入策略应大于策略所需数据天数
96 | if today[1] < self.data_days:
97 | return pd.Series(None)
98 | # 建立用于计算平均MF的DF
99 | stocks_data = pd.DataFrame(self.stocks_codes)
100 | stocks_data['aver_MF'] = 0
101 | stocks_data = stocks_data.set_index('code')
102 | # 到交易日前一日为止共data_days日期序号
103 | days = range(today[1] - self.data_days, today[1])
104 | for stock_code in self.stocks_codes:
105 | sum_MF = 0
106 | valid_days = self.data_days
107 | stock_data = pd.read_csv('{}{}.csv'.format(self.data_path, stock_code), index_col='date')
108 | for day in days:
109 | if self.trading_dates[day] in stock_data.index:
110 | # 加入收益率
111 | pc = stock_data.loc[self.trading_dates[day], 'preclose']
112 | close = stock_data.loc[self.trading_dates[day], 'close']
113 | sum_MF += close / pc
114 | else:
115 | valid_days -= 1
116 | if valid_days != 0:
117 | aver_MF = sum_MF / valid_days
118 | else:
119 | aver_MF = 0
120 | if aver_MF > 0:
121 | stocks_data.loc[stock_code, 'aver_MF'] = aver_MF
122 | # print(stocks_data)
123 | stocks_data.sort_values(by='aver_MF', ascending=False, inplace=True)
124 | # print(stocks_data.index)
125 | if len(stocks_data.index) > number:
126 | # 取0到number-1共number只股票
127 | return stocks_data.index[0:number]
128 | else:
129 | # 取全部股票
130 | return stocks_data.index[:]
131 |
132 | def choose_by_tr(self, today: tuple, number: int):
133 | """
134 | 选择最近data_days中换手率因子(Unusual Turnover Rate, 异常换手率)最高的number只股票
135 | """
136 | # 第一次买入策略应大于策略所需数据天数
137 | if today[1] < self.data_days:
138 | return pd.Series(None)
139 | # 建立用于计算平均TR的DF
140 | stocks_data = pd.DataFrame(self.stocks_codes)
141 | stocks_data['aver_TR'] = 0
142 | stocks_data = stocks_data.set_index('code')
143 | # 到交易日前一日为止共data_days日期序号
144 | days = range(today[1] - self.data_days, today[1])
145 | for stock_code in self.stocks_codes:
146 | sum_TR = 0
147 | valid_days = self.data_days
148 | stock_data = pd.read_csv('{}{}.csv'.format(self.data_path, stock_code), index_col='date')
149 | for day in days:
150 | if self.trading_dates[day] in stock_data.index:
151 | # 加入换手率
152 | tr = stock_data.loc[self.trading_dates[day], 'turn']
153 | sum_TR += tr
154 | else:
155 | valid_days -= 1
156 | if valid_days > 2:
157 | aver_TR = sum_TR / valid_days
158 | tr1 = stock_data.loc[self.trading_dates[days[-1]], 'turn']
159 | tr2 = stock_data.loc[self.trading_dates[days[-1] - 1], 'turn']
160 | ratio = (tr1 + tr2) / (aver_TR * 2)
161 | else:
162 | ratio = 0
163 | if ratio > 0:
164 | stocks_data.loc[stock_code, 'ratio'] = ratio
165 |
166 | # print(stocks_data)
167 | stocks_data.sort_values(by='ratio', ascending=False, inplace=True)
168 | # print(stocks_data.index)
169 | if len(stocks_data.index) > number:
170 | # 取0到number-1共number只股票
171 | return stocks_data.index[0:number]
172 | else:
173 | # 取全部股票
174 | return stocks_data.index[:]
175 |
176 | def __nn_choose(self, model_type: str, today: tuple, number: int):
177 | """
178 | 选择指定NN预测未来data_days天涨幅最高的number只股票
179 | """
180 | # 第一次买入策略应大于策略所需数据天数
181 | if today[1] < self.data_days:
182 | return pd.Series(None)
183 | # 建立用于计算预测涨跌幅的DF
184 | stocks_data = pd.DataFrame(self.stocks_codes)
185 | stocks_data['change'] = 0
186 | stocks_data = stocks_data.set_index('code')
187 | avail_num = 0
188 | # 预测每只股票未来data_days天涨跌幅
189 | for stock_code in self.stocks_codes:
190 | change = getattr(self.prediction, 'predict_' + model_type)(stock_code, today)
191 | if type(change) != int:
192 | # tensor直接取值
193 | change = change[0, 0].item()
194 | if change > 0:
195 | # 去除小于0的预测值
196 | stocks_data.loc[stock_code, 'change'] = change
197 | avail_num += 1
198 | # 排序
199 | stocks_data.sort_values(by='change', ascending=False, inplace=True)
200 | if avail_num > number:
201 | # 取0到number-1共number只股票
202 | return stocks_data.index[0:number]
203 | else:
204 | # 取全部有效股票
205 | return stocks_data.index[:avail_num]
206 |
207 | def choose_by_cnn(self, today: tuple, number: int):
208 | return self.__nn_choose('cnn', today, number)
209 |
210 | def choose_by_lstm(self, today: tuple, number: int):
211 | return self.__nn_choose('lstm', today, number)
212 |
213 | def choose_by_gru(self, today: tuple, number: int):
214 | return self.__nn_choose('gru', today, number)
215 |
216 | def choose_by_rnn_tanh(self, today: tuple, number: int):
217 | return self.__nn_choose('rnn_tanh', today, number)
218 |
219 | def choose_by_rnn_relu(self, today: tuple, number: int):
220 | return self.__nn_choose('rnn_relu', today, number)
221 |
222 | def choose_by_resnet18(self, today: tuple, number: int):
223 | return self.__nn_choose('resnet18', today, number)
224 |
225 | def choose_by_resnet34(self, today: tuple, number: int):
226 | return self.__nn_choose('resnet34', today, number)
227 |
228 | def choose_by_resnet50(self, today: tuple, number: int):
229 | return self.__nn_choose('resnet50', today, number)
230 |
231 | def choose_by_resnet101(self, today: tuple, number: int):
232 | return self.__nn_choose('resnet101', today, number)
233 |
234 | def choose_by_resnet152(self, today: tuple, number: int):
235 | return self.__nn_choose('resnet152', today, number)
236 |
237 | def choose_by_densenet(self, today: tuple, number: int):
238 | return self.__nn_choose('densenet', today, number)
239 |
240 | def choose_by_ensemble(self, today: tuple):
241 | chosen_num = pd.DataFrame()
242 | chosen_num['code'] = self.stocks_codes
243 | chosen_num['num'] = 0
244 | chosen_num.set_index('code', inplace=True)
245 | number = 300
246 | for chosen in (self.__nn_choose('cnn', today, number),
247 | self.__nn_choose('lstm', today, number),
248 | self.__nn_choose('rnn_relu', today, number),
249 | self.__nn_choose('resnet18', today, number),
250 | self.__nn_choose('resnet34', today, number),
251 | self.__nn_choose('resnet50', today, number),
252 | self.__nn_choose('densenet', today, number)):
253 | for stock_code in self.stocks_codes:
254 | if stock_code in chosen:
255 | chosen_num.loc[stock_code, 'num'] += 1
256 | return chosen_num[chosen_num['num'] >= 3].index
257 |
--------------------------------------------------------------------------------
/backtest.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | @version: 3.8.3
4 | @time: 21/4/26 10:52
5 | @author: Yamisora
6 | @file: backtest.py
7 | """
8 | # import matplotlib.pyplot as plt
9 | # import pandas as pd
10 | import time
11 |
12 | from strategy import *
13 |
14 |
15 | class Backtest:
16 | def __init__(self, start_cash=300000, fee=0.0003):
17 | """
18 | 回测
19 | @start_cash: 初始资金
20 | @fee: 手续费比例
21 | """
22 | # index选择指数组合
23 | self.index_name = 'hs300'
24 | self.index_code = 'sh.000300'
25 | # 存储路径
26 | self.base_data_path = './data/'
27 | self.data_path = './data/stocks/'
28 | # 默认万三手续费
29 | self.fee = fee
30 | # 指数组合内股票名称,代码数据
31 | self.stocks = pd.read_csv('{}{}_stocks.csv'.format(self.base_data_path, self.index_name))
32 | self.stocks_codes = self.stocks['code']
33 | # 指数日线数据
34 | self.index = pd.read_csv('{}{}.csv'.format(self.data_path, self.index_code))
35 | # 交易日str序列
36 | self.trading_dates = self.index['date']
37 | # 今日名称str与序列序号int
38 | self.today = (self.trading_dates[0], 0)
39 | # 初始资金
40 | self.start_cash = start_cash
41 | # 每日可用资金
42 | self.cash = pd.DataFrame(self.trading_dates)
43 | self.cash['cash'] = start_cash
44 | self.cash = self.cash.set_index('date')
45 | # 每日持股
46 | self.position = pd.DataFrame()
47 | self.position['date'] = self.trading_dates
48 | for stock_code in self.stocks_codes:
49 | self.position[stock_code] = 0
50 | self.position = self.position.set_index('date')
51 |
52 | def stocks_data(self, stock_codes, trading_date: str) -> pd.DataFrame():
53 | """
54 | 读取指定交易日内,一系列股票日线数据
55 | """
56 | # 空输入情况
57 | if stock_codes.empty:
58 | return pd.DataFrame(None)
59 | stocks = pd.DataFrame()
60 | for stock_code in stock_codes:
61 | # 读取每只股票数据
62 | data = pd.read_csv('{}{}.csv'.format(self.data_path, stock_code), index_col='date')
63 | if trading_date in data.index:
64 | # 读入指定日期数据
65 | stocks = stocks.append(data.loc[trading_date], ignore_index=True)
66 | stocks = stocks.set_index('code')
67 | return stocks
68 |
69 | def buy(self, stocks_codes) -> bool:
70 | """
71 | 全仓买入trading date的所有stock codes股票
72 | """
73 | trading_date = self.today[0]
74 | # 读入当前交易日内所有待购买股票日线数据
75 | stocks = self.stocks_data(stocks_codes, trading_date)
76 | # 空输入情况
77 | if stocks.empty:
78 | return False
79 | # 预计购买股票数
80 | n = len(stocks_codes)
81 | # 每只股票可用购买资金
82 | single = self.cash.loc[trading_date, 'cash'] // n
83 | for stock_code in stocks_codes:
84 | # 每只股票开盘价作为买入价
85 | open_price = stocks.loc[stock_code, 'open']
86 | # 计算除去手续费后可购买份额(整百)
87 | quantity = ((single / (1+self.fee)) / open_price) // 100
88 | # 买入并修改当日现金余额
89 | self.position.loc[trading_date, stock_code] += quantity * 100
90 | self.cash.loc[trading_date, 'cash'] -= open_price * quantity * 100
91 | del stocks
92 | return True
93 |
94 | def sell(self, stocks_codes):
95 | """
96 | 空仓trading date的除去stock codes外股票
97 | """
98 | trading_date = self.today[0]
99 | # 读入当前交易日内所有股票日线数据
100 | stocks = self.stocks_data(self.stocks_codes, trading_date)
101 | # 初始化卖出金额
102 | cash = 0
103 | # 卖出股票数量
104 | sell_num = 0
105 | # 卖出所有不继续持仓的股票并删除欲购买列表中已持仓的股票
106 | for stock_code in self.stocks_codes:
107 | position = self.position.loc[trading_date, stock_code]
108 | if position != 0:
109 | if stock_code not in stocks_codes:
110 | # 卖出
111 | cash += position * stocks.loc[stock_code, 'open'] * (1-self.fee)
112 | self.position.loc[trading_date, stock_code] = 0
113 | sell_num += 1
114 | else:
115 | # 去除已选股票中已持仓股票
116 | stocks_codes = stocks_codes.drop(stock_code)
117 | # 当日现金余额增加卖出金额
118 | self.cash.loc[trading_date, 'cash'] += cash
119 | del stocks
120 | return stocks_codes, sell_num
121 |
122 | def next_day(self) -> str:
123 | """
124 | 返回下一个交易日str
125 | 延续前一天cash数量
126 | """
127 | # 获取当日现金余额、持仓、日期序号
128 | cash = self.cash.loc[self.today[0], 'cash']
129 | position = self.position.loc[self.today[0]]
130 | today = self.today[1]
131 | if today < len(self.trading_dates) - 1:
132 | # 更新下一日现金余额、持仓、日期元组
133 | self.today = (self.trading_dates[today+1], today+1)
134 | self.cash.loc[self.today[0], 'cash'] = cash
135 | self.position.loc[self.today[0]] = position
136 | return self.today[0]
137 |
138 | def calculate(self):
139 | """
140 | 计算收益折线
141 | """
142 | # 总收益百分比
143 | basic_position = self.start_cash
144 | position = []
145 | for i, trading_date in enumerate(self.trading_dates):
146 | # 每隔5交易日计算持仓
147 | if i % 5 != 0:
148 | continue
149 | print('当前计算交易日: '+trading_date, end='\r')
150 | # 读入当前交易日内所有股票日线信息
151 | stock_data = self.stocks_data(self.stocks_codes, trading_date)
152 | # 初始化当前拥有总金额为现金金额
153 | daily_position = self.cash.loc[trading_date, 'cash']
154 | for stock_code in self.stocks_codes:
155 | # 确认每只股票持股数
156 | quantity = self.position.loc[trading_date, stock_code]
157 | if quantity != 0:
158 | daily_position += quantity * stock_data.loc[stock_code, 'close']
159 | position.append(daily_position)
160 | position = pd.Series(position)
161 | position /= basic_position
162 | return position
163 |
164 |
165 | if __name__ == '__main__':
166 | start_time = time.time()
167 | bt1 = Backtest(start_cash=10000000, fee=0.0003)
168 | bt2 = Backtest(start_cash=10000000, fee=0.0003)
169 | bt3 = Backtest(start_cash=10000000, fee=0.0003)
170 | bt4 = Backtest(start_cash=10000000, fee=0.0003)
171 | bt5 = Backtest(start_cash=10000000, fee=0.0003)
172 | # bt6 = Backtest(start_cash=10000000, fee=0.0003)
173 | # bt7 = Backtest(start_cash=10000000, fee=0.0003)
174 | bt8 = Backtest(start_cash=10000000, fee=0.0003)
175 | bt9 = Backtest(start_cash=10000000, fee=0.0003)
176 | bt10 = Backtest(start_cash=10000000, fee=0.0003)
177 | bt11 = Backtest(start_cash=10000000, fee=0.0003)
178 | # bt12 = Backtest(start_cash=10000000, fee=0.0003)
179 | # bt13 = Backtest(start_cash=10000000, fee=0.0003)
180 | bt14 = Backtest(start_cash=10000000, fee=0.0003)
181 | bt15 = Backtest(start_cash=10000000, fee=0.0003)
182 | strategy = Strategy(data_days=10)
183 | for date_key, date in bt1.trading_dates.items():
184 | # 每10交易日调仓一次
185 | if date_key % 10 == 0:
186 | print('当前交易日: '+date)
187 | print('因子模型选股中...')
188 | chosen1 = strategy.choose_by_bm(bt1.today, 90)
189 | chosen3 = strategy.choose_by_mf(bt3.today, 90)
190 | chosen4 = strategy.choose_by_tr(bt4.today, 90)
191 | print('神经网络模型选股中...')
192 | chosen2 = strategy.choose_by_cnn(bt2.today, 90)
193 | chosen5 = strategy.choose_by_lstm(bt5.today, 90)
194 | # chosen6 = strategy.choose_by_gru(bt6.today, 90)
195 | # chosen7 = strategy.choose_by_rnn_tanh(bt7.today, 90)
196 | chosen8 = strategy.choose_by_rnn_relu(bt8.today, 90)
197 | chosen9 = strategy.choose_by_resnet18(bt9.today, 90)
198 | chosen10 = strategy.choose_by_resnet34(bt10.today, 90)
199 | chosen11 = strategy.choose_by_resnet50(bt11.today, 90)
200 | # chosen12 = strategy.choose_by_resnet101(bt12.today, 90)
201 | # chosen13 = strategy.choose_by_resnet152(bt13.today, 90)
202 | chosen14 = strategy.choose_by_densenet(bt14.today, 90)
203 | print('集成学习模型选股中...')
204 | chosen15 = strategy.choose_by_ensemble(bt15.today)
205 |
206 | to_buy1, sell1 = bt1.sell(chosen1)
207 | print('价值因子(BM)选股模型卖出', sell1, '只股票')
208 | to_buy2, sell2 = bt2.sell(chosen2)
209 | print('CNN选股模型卖出', sell2, '只股票')
210 | to_buy3, sell3 = bt3.sell(chosen3)
211 | print('动量因子(MF)选股模型卖出', sell3, '只股票')
212 | to_buy4, sell4 = bt4.sell(chosen4)
213 | print('换手率因子(TR)选股模型卖出', sell4, '只股票')
214 | to_buy5, sell5 = bt5.sell(chosen5)
215 | print('LSTM选股模型卖出', sell5, '只股票')
216 | # to_buy6, sell6 = bt6.sell(chosen6)
217 | # print('GRU选股模型卖出', sell6, '只股票')
218 | # to_buy7, sell7 = bt7.sell(chosen7)
219 | # print('RNN_tanh选股模型卖出', sell7, '只股票')
220 | to_buy8, sell8 = bt8.sell(chosen8)
221 | print('RNN_relu选股模型卖出', sell8, '只股票')
222 | to_buy9, sell9 = bt9.sell(chosen9)
223 | print('ResNet18选股模型卖出', sell9, '只股票')
224 | to_buy10, sell10 = bt10.sell(chosen10)
225 | print('ResNet34选股模型卖出', sell10, '只股票')
226 | to_buy11, sell11 = bt11.sell(chosen11)
227 | print('ResNet50选股模型卖出', sell11, '只股票')
228 | # to_buy12, sell12 = bt12.sell(chosen12)
229 | # print('ResNet101选股模型卖出', sell12, '只股票')
230 | # to_buy13, sell13 = bt13.sell(chosen13)
231 | # print('ResNet152选股模型卖出', sell13, '只股票')
232 | to_buy14, sell14 = bt14.sell(chosen14)
233 | print('DenseNet选股模型卖出', sell14, '只股票')
234 | to_buy15, sell15 = bt15.sell(chosen15)
235 | print('集成学习选股模型卖出', sell15, '只股票')
236 | bt1.buy(to_buy1)
237 | print('价值因子(BM)选股模型买入', len(to_buy1), '只股票')
238 | bt2.buy(to_buy2)
239 | print('CNN选股模型买入', len(to_buy2), '只股票')
240 | bt3.buy(to_buy3)
241 | print('动量因子(MF)选股模型买入', len(to_buy3), '只股票')
242 | bt4.buy(to_buy4)
243 | print('换手率因子(TR)选股模型买入', len(to_buy4), '只股票')
244 | bt5.buy(to_buy5)
245 | print('LSTM选股模型买入', len(to_buy5), '只股票')
246 | # bt6.buy(to_buy6)
247 | # print('GRU选股模型买入', len(to_buy6), '只股票')
248 | # bt7.buy(to_buy7)
249 | # print('RNN_tanh选股模型买入', len(to_buy7), '只股票')
250 | bt8.buy(to_buy8)
251 | print('RNN_relu选股模型买入', len(to_buy8), '只股票')
252 | bt9.buy(to_buy9)
253 | print('ResNet18选股模型买入', len(to_buy9), '只股票')
254 | bt10.buy(to_buy10)
255 | print('ResNet34选股模型买入', len(to_buy10), '只股票')
256 | bt11.buy(to_buy11)
257 | print('ResNet50选股模型买入', len(to_buy11), '只股票')
258 | # bt12.buy(to_buy12)
259 | # print('ResNet101选股模型买入', len(to_buy12), '只股票')
260 | # bt13.buy(to_buy13)
261 | # print('ResNet152选股模型买入', len(to_buy13), '只股票')
262 | bt14.buy(to_buy14)
263 | print('DenseNet选股模型买入', len(to_buy14), '只股票')
264 | bt15.buy(to_buy15)
265 | print('集成学习选股模型买入', len(to_buy15), '只股票')
266 | bt1.next_day()
267 | bt2.next_day()
268 | bt3.next_day()
269 | bt4.next_day()
270 | bt5.next_day()
271 | # bt6.next_day()
272 | # bt7.next_day()
273 | bt8.next_day()
274 | bt9.next_day()
275 | bt10.next_day()
276 | bt11.next_day()
277 | # bt12.next_day()
278 | # bt13.next_day()
279 | bt14.next_day()
280 | bt15.next_day()
281 | mid_time = time.time()
282 | span = mid_time - start_time
283 | print('回测模拟交易用时 {} 分 {} 秒'.format(int(span // 60), span % 60))
284 | print('\n计算价值因子(BM)选股模型收益中')
285 | bm_position = bt1.calculate()
286 | print('\n计算CNN选股模型收益中')
287 | cnn_position = bt2.calculate()
288 | print('\n计算动量因子(MF)选股模型收益中')
289 | mf_position = bt3.calculate()
290 | print('\n计算换手率因子(TR)选股模型收益中')
291 | tr_position = bt4.calculate()
292 | print('\n计算LSTM选股模型收益中')
293 | lstm_position = bt5.calculate()
294 | # print('\n计算GRU选股模型收益中')
295 | # gru_position = bt6.calculate()
296 | # print('\n计算RNN_tanh选股模型收益中')
297 | # rnn_tanh_position = bt7.calculate()
298 | print('\n计算RNN_relu选股模型收益中')
299 | rnn_relu_position = bt8.calculate()
300 | print('\n计算ResNet18选股模型收益中')
301 | resnet18_position = bt9.calculate()
302 | print('\n计算ResNet34选股模型收益中')
303 | resnet34_position = bt10.calculate()
304 | print('\n计算ResNet50选股模型收益中')
305 | resnet50_position = bt11.calculate()
306 | # print('\n计算ResNet101选股模型收益中')
307 | # resnet101_position = bt12.calculate()
308 | # print('\n计算ResNet152选股模型收益中')
309 | # resnet152_position = bt13.calculate()
310 | print('\n计算DenseNet选股模型收益中')
311 | densenet_position = bt14.calculate()
312 | print('\n计算集成学习选股模型收益中')
313 | ensemble_position = bt15.calculate()
314 | # 指数收益百分比
315 | basic_index_price = bt1.index['close'][0]
316 | index_price = bt1.index['close'][::5] / basic_index_price
317 | x = range(0, len(bt1.trading_dates), 5)
318 | plt.rcParams['font.sans-serif'] = ['SimHei']
319 | plt.rcParams['axes.unicode_minus'] = False
320 | plt.figure(figsize=[20, 15], dpi=160)
321 | plt.subplot(211)
322 | plt.plot(x, index_price, 'k:', label='沪深300指数收益率')
323 | plt.plot(x, bm_position, 'r:', label='价值因子(BM)选股模型持仓收益率')
324 | plt.plot(x, cnn_position, label='CNN选股模型持仓收益率')
325 | plt.plot(x, mf_position, 'g:', label='动量因子(MF)选股模型持仓收益率')
326 | plt.plot(x, tr_position, 'b:', label='换手率因子(TR)选股模型持仓收益率')
327 | plt.plot(x, lstm_position, label='LSTM选股模型持仓收益率')
328 | # plt.plot(x, gru_position, label='GRU选股模型持仓收益率')
329 | # plt.plot(x, rnn_tanh_position, label='RNN_tanh选股模型持仓收益率')
330 | plt.plot(x, rnn_relu_position, label='RNN_relu选股模型持仓收益率')
331 | plt.plot(x, resnet18_position, label='ResNet18选股模型持仓收益率')
332 | plt.plot(x, resnet34_position, label='ResNet34选股模型持仓收益率')
333 | plt.plot(x, resnet50_position, label='ResNet50选股模型持仓收益率')
334 | # plt.plot(x, resnet101_position, label='ResNet101选股模型持仓收益率')
335 | # plt.plot(x, resnet152_position, label='ResNet152选股模型持仓收益率')
336 | plt.plot(x, densenet_position, label='DenseNet选股模型持仓收益率')
337 | plt.plot(x, ensemble_position, label='集成学习选股模型持仓收益率')
338 | plt.ylabel('收益率/%')
339 | x_ticks = list(x[::len(x)//9])
340 | x_ticks.append(x[-1])
341 | x_labels = [bt1.trading_dates[i] for i in x_ticks]
342 | plt.xticks(x_ticks, x_labels)
343 | plt.legend()
344 | plt.subplot(212)
345 | plt.plot(x, [0]*len(x), 'k:', label='基准市场收益率(沪深300)', )
346 | plt.plot(x, bm_position.values-index_price.values, 'r:', label='价值因子(BM)选股模型持仓超额收益率')
347 | plt.plot(x, cnn_position.values-index_price.values, label='CNN选股模型持仓超额收益率')
348 | plt.plot(x, mf_position.values-index_price.values, 'g:', label='动量因子(MF)选股模型持仓超额收益率')
349 | plt.plot(x, tr_position.values-index_price.values, 'b:', label='换手率因子(TR)选股模型持仓超额收益率')
350 | plt.plot(x, lstm_position.values-index_price.values, label='LSTM选股模型持仓超额收益率')
351 | # plt.plot(x, gru_position.values-index_price.values, label='GRU选股模型持仓超额收益率')
352 | # plt.plot(x, rnn_tanh_position.values-index_price.values, label='RNN_tanh选股模型持仓超额收益率')
353 | plt.plot(x, rnn_relu_position.values-index_price.values, label='RNN_relu选股模型持仓超额收益率')
354 | plt.plot(x, resnet18_position.values-index_price.values, label='ResNet18选股模型持仓超额收益率')
355 | plt.plot(x, resnet34_position.values-index_price.values, label='ResNet34选股模型持仓超额收益率')
356 | plt.plot(x, resnet50_position.values-index_price.values, label='ResNet50选股模型持仓超额收益率')
357 | # plt.plot(x, resnet101_position.values-index_price.values, label='ResNet101选股模型持仓超额收益率')
358 | # plt.plot(x, resnet152_position.values-index_price.values, label='ResNet152选股模型持仓超额收益率')
359 | plt.plot(x, densenet_position.values-index_price.values, label='DenseNet选股模型持仓超额收益率')
360 | plt.plot(x, ensemble_position.values-index_price.values, label='集成学习选股模型持仓超额收益率')
361 | plt.ylabel('超额收益率/%')
362 | plt.xticks(x_ticks, x_labels)
363 | plt.legend()
364 | plt.savefig('result.jpg')
365 | end_time = time.time()
366 | span = end_time - mid_time
367 | print('计算持仓收益用时 {} 分 {} 秒'.format(int(span // 60), span % 60))
368 | span = end_time - start_time
369 | print('总计用时 {} 分 {:.2f} 秒'.format(int(span // 60), span % 60))
370 |
--------------------------------------------------------------------------------
/prediction.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | @version: 3.8.3
4 | @time: 21/5/11 8:33
5 | @author: Yamisora
6 | @file: prediction.py
7 | """
8 | import torch
9 | import torch.nn as nn
10 | from torch.utils.data.dataset import Dataset
11 | from torch.utils.data.dataloader import DataLoader
12 | import torch.nn.functional as F
13 | import pandas as pd
14 | import numpy as np
15 | from tqdm import tqdm
16 | import os
17 | import matplotlib.pyplot as plt
18 | from collections import OrderedDict
19 |
20 | # 运行设备
21 | device = 'cuda' if torch.cuda.is_available() else 'cpu'
22 |
23 |
24 | def return_rate_transform(return_rate):
25 | """按收益率分布转换为数值分类模型"""
26 | if return_rate < -0.093:
27 | return -1.0
28 | elif return_rate < -0.053:
29 | return -0.8
30 | elif return_rate < -0.030:
31 | return -0.6
32 | elif return_rate < -0.014:
33 | return -0.4
34 | elif return_rate < 0.000:
35 | return -0.2
36 | elif return_rate < 0.016:
37 | return 0.2
38 | elif return_rate < 0.034:
39 | return 0.4
40 | elif return_rate < 0.058:
41 | return 0.6
42 | elif return_rate < 0.100:
43 | return 0.8
44 | elif return_rate >= 0.100:
45 | return 1.0
46 |
47 |
48 | class StockDataset(Dataset):
49 | """沪深300股票训练数据集"""
50 | def __init__(self, data_days=10, remake_data=False):
51 | super(StockDataset, self).__init__()
52 | # 存储路径
53 | self.base_data_path = './data/'
54 | self.data_path = './data/stocks/'
55 | self.train_data_path = './data/train_data/'
56 | # 策略所需数据天数
57 | self.data_days = data_days
58 | # 指数组合
59 | self.index_name = 'hs300'
60 | self.index_code = 'sh.000300'
61 | # 指数组合内股票名称,代码数据
62 | self.stocks = pd.read_csv('{}{}_stocks.csv'.format(self.base_data_path, self.index_name))
63 | self.stocks_codes = self.stocks['code']
64 | # 输入列
65 | self.input_columns = ('open', 'high', 'low', 'close', 'preclose',
66 | 'turn', 'peTTM', 'psTTM', 'pcfNcfTTM', 'pbMRQ',)
67 | # 数据集
68 | if not os.path.exists('{}{}.pkl'.format(self.base_data_path, self.index_name)):
69 | remake_data = True
70 | if remake_data:
71 | data = []
72 | for stock_code in tqdm(self.stocks_codes):
73 | # 读取数据
74 | stock_data = pd.read_csv('{}{}.csv'.format(self.train_data_path, stock_code))
75 | # 选择指定列
76 | stock_data = pd.DataFrame(stock_data, columns=self.input_columns)
77 |
78 | batches = len(stock_data.index) - 2 * self.data_days
79 | if batches <= 0:
80 | continue
81 | # 数据集存入个股训练数据
82 | for i in range(batches):
83 | # 清除无效数据(0)
84 | if 0 in stock_data[i:i + self.data_days].values:
85 | continue
86 | # 当前日期为data_days + i
87 | # data_days后收盘价
88 | next_price = stock_data.loc[2 * data_days + i, 'close']
89 | # 当前日期收盘价
90 | this_price = stock_data.loc[data_days + i, 'close']
91 | # high_change = stock_data.loc[data_days + i, 'high'] / stock_data.loc[data_days + i - 1, 'high']-1
92 | # low_change = stock_data.loc[data_days + i, 'low'] / stock_data.loc[data_days + i - 1, 'low'] - 1
93 | close_change = this_price / stock_data.loc[data_days + i - 1, 'close'] - 1
94 | predict_change = (next_price / this_price - 1)
95 | # 当前日期前一天到前data_days天 共data_days天数据
96 | data.append({'data': stock_data[i:i + self.data_days].values,
97 | 'label': [predict_change, close_change]})
98 | # 'label': [predict_change, low_change, high_change, close_change]})
99 | self.data = pd.DataFrame(data)
100 | self.data.to_pickle('{}{}.pkl'.format(self.base_data_path, self.index_name))
101 | else:
102 | self.data = pd.read_pickle('{}{}.pkl'.format(self.base_data_path, self.index_name))
103 |
104 | def __len__(self):
105 | """返回整个数据集的大小"""
106 | return len(self.data)
107 |
108 | def __getitem__(self, idx):
109 | """根据索引index返回dataset[index]"""
110 | data = torch.tensor(self.data.loc[idx, 'data'], dtype=torch.float32, device=device)
111 | label = torch.tensor(self.data.loc[idx, 'label'], dtype=torch.float32, device=device)
112 | return data, label
113 |
114 |
115 | class CNNModel(nn.Module):
116 | """类LeNet结构CNN模型"""
117 | def __init__(self, input_size, data_days=10):
118 | super(CNNModel, self).__init__()
119 | self.conv1 = nn.Conv2d(1, 6, 3) # 输入通道数为1,输出通道数为6
120 | self.conv2 = nn.Conv2d(6, 16, 3) # 输入通道数为6,输出通道数为16
121 | self.fc1 = nn.Linear((data_days - 4) * (input_size - 4) * 16, 120)
122 | self.fc2 = nn.Linear(120, 84)
123 | self.fc3 = nn.Linear(84, 2)
124 |
125 | def forward(self, x):
126 | x = x.view(x.size()[0], 1, x.size()[1], x.size()[2])
127 | # 输入x (50, 1, 10, 10) -> conv1 (50, 6, 8, 8) -> relu
128 | x = self.conv1(x)
129 | x = F.relu(x)
130 | # 输入x (50, 6, 8, 8) -> conv2 (50, 16, 6, 6) -> relu
131 | x = self.conv2(x)
132 | x = F.relu(x)
133 | # view函数将张量x变形成一维向量形式,总特征数不变,为全连接层做准备
134 | x = x.view(x.size()[0], -1)
135 | x = F.relu(self.fc1(x))
136 | x = F.relu(self.fc2(x))
137 | x = self.fc3(x)
138 | return x
139 |
140 |
141 | class RNNModel(nn.Module):
142 | """LSTM,GRU,使用tanh与relu激活的RNN四种结构模型"""
143 | def __init__(self, rnn_type, input_size, hidden_size, n_layers):
144 | super(RNNModel, self).__init__()
145 | if rnn_type in ['LSTM', 'GRU']:
146 | self.rnn = getattr(nn, rnn_type)(input_size, hidden_size, n_layers, batch_first=True)
147 | else:
148 | try:
149 | non_linearity = {'RNN_TANH': 'tanh', 'RNN_RELU': 'relu'}[rnn_type]
150 | except KeyError:
151 | raise ValueError("""非可选RNN类型,可选参数:['LSTM', 'GRU', 'RNN_TANH', 'RNN_RELU']""")
152 | self.rnn = nn.RNN(input_size, hidden_size, n_layers, nonlinearity=non_linearity, batch_first=True)
153 | self.fc1 = nn.Linear(hidden_size, 120)
154 | self.fc2 = nn.Linear(120, 84)
155 | self.fc3 = nn.Linear(84, 2)
156 | # self.norm = nn.BatchNorm1d(10)
157 | # self.fc = nn.Linear(hidden_size, 3)
158 |
159 | self.rnn_type = rnn_type
160 | self.hidden_size = hidden_size
161 | self.n_layers = n_layers
162 |
163 | def forward(self, x):
164 | # x = self.norm(x)
165 | x, _ = self.rnn(x)
166 | x = F.relu(self.fc1(x[:, -1, :]))
167 | x = F.relu(self.fc2(x))
168 | x = self.fc3(x)
169 | # print(x)
170 | # x = F.relu(x[:, -1, :])
171 | # print(x)
172 | # x = self.fc(x)
173 | return x
174 |
175 |
176 | class BasicBlock(nn.Module):
177 | """用于ResNet18和34的残差块,用的是2个3x3的卷积"""
178 | expansion = 1
179 |
180 | def __init__(self, in_planes, planes, stride=1):
181 | super(BasicBlock, self).__init__()
182 | self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=3,
183 | stride=stride, padding=1, bias=False)
184 | self.bn1 = nn.BatchNorm2d(planes)
185 | self.conv2 = nn.Conv2d(planes, planes, kernel_size=3,
186 | stride=1, padding=1, bias=False)
187 | self.bn2 = nn.BatchNorm2d(planes)
188 | self.shortcut = nn.Sequential()
189 | # 经过处理后的x要与x的维度相同(尺寸和深度)
190 | # 如果不相同,需要添加卷积+BN来变换为同一维度
191 | if stride != 1 or in_planes != self.expansion * planes:
192 | self.shortcut = nn.Sequential(
193 | nn.Conv2d(in_planes, self.expansion * planes,
194 | kernel_size=1, stride=stride, bias=False),
195 | nn.BatchNorm2d(self.expansion * planes)
196 | )
197 |
198 | def forward(self, x):
199 | out = F.relu(self.bn1(self.conv1(x)))
200 | out = self.bn2(self.conv2(out))
201 | out += self.shortcut(x)
202 | out = F.relu(out)
203 | return out
204 |
205 |
206 | class Bottleneck(nn.Module):
207 | """用于ResNet50,101和152的残差块,用的是1x1+3x3+1x1的卷积"""
208 | # 前面1x1和3x3卷积的filter个数相等,最后1x1卷积是其expansion倍
209 | expansion = 4
210 |
211 | def __init__(self, in_planes, planes, stride=1):
212 | super(Bottleneck, self).__init__()
213 | self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=1, bias=False)
214 | self.bn1 = nn.BatchNorm2d(planes)
215 | self.conv2 = nn.Conv2d(planes, planes, kernel_size=3,
216 | stride=stride, padding=1, bias=False)
217 | self.bn2 = nn.BatchNorm2d(planes)
218 | self.conv3 = nn.Conv2d(planes, self.expansion * planes,
219 | kernel_size=1, bias=False)
220 | self.bn3 = nn.BatchNorm2d(self.expansion * planes)
221 |
222 | self.shortcut = nn.Sequential()
223 | if stride != 1 or in_planes != self.expansion * planes:
224 | self.shortcut = nn.Sequential(
225 | nn.Conv2d(in_planes, self.expansion * planes,
226 | kernel_size=1, stride=stride, bias=False),
227 | nn.BatchNorm2d(self.expansion * planes)
228 | )
229 |
230 | def forward(self, x):
231 | out = F.relu(self.bn1(self.conv1(x)))
232 | out = F.relu(self.bn2(self.conv2(out)))
233 | out = self.bn3(self.conv3(out))
234 | out += self.shortcut(x)
235 | out = F.relu(out)
236 | return out
237 |
238 |
239 | class ResNet(nn.Module):
240 | """实现将ResNet迁移应用于股票预测"""
241 | def __init__(self, block, num_blocks, num_classes=2):
242 | super(ResNet, self).__init__()
243 | self.in_planes = 64
244 |
245 | self.conv1 = nn.Conv2d(1, 64, kernel_size=3,
246 | stride=1, padding=1, bias=False)
247 | self.bn1 = nn.BatchNorm2d(64)
248 |
249 | self.layer1 = self._make_layer(block, 64, num_blocks[0], stride=1)
250 | self.layer2 = self._make_layer(block, 128, num_blocks[1], stride=2)
251 | self.layer3 = self._make_layer(block, 256, num_blocks[2], stride=2)
252 | self.layer4 = self._make_layer(block, 512, num_blocks[3], stride=2)
253 | self.linear = nn.Linear(4 * 512 * block.expansion, num_classes)
254 |
255 | def _make_layer(self, block, planes, num_blocks, stride):
256 | strides = [stride] + [1] * (num_blocks - 1)
257 | layers = []
258 | for stride in strides:
259 | layers.append(block(self.in_planes, planes, stride))
260 | self.in_planes = planes * block.expansion
261 | return nn.Sequential(*layers)
262 |
263 | def forward(self, x):
264 | x = x.view(x.size()[0], 1, x.size()[1], x.size()[2])
265 | out = F.relu(self.bn1(self.conv1(x)))
266 | out = self.layer1(out)
267 | out = self.layer2(out)
268 | out = self.layer3(out)
269 | out = self.layer4(out)
270 | # out = F.avg_pool2d(out, 4)
271 | out = out.view(out.size(0), -1)
272 | # print(out.size())
273 | out = self.linear(out)
274 | return out
275 |
276 |
277 | def ResNet18():
278 | return ResNet(BasicBlock, [2, 2, 2, 2])
279 |
280 |
281 | def ResNet34():
282 | return ResNet(BasicBlock, [3, 4, 6, 3])
283 |
284 |
285 | def ResNet50():
286 | return ResNet(Bottleneck, [3, 4, 6, 3])
287 |
288 |
289 | def ResNet101():
290 | return ResNet(Bottleneck, [3, 4, 23, 3])
291 |
292 |
293 | def ResNet152():
294 | return ResNet(Bottleneck, [3, 8, 36, 3])
295 |
296 |
297 | class DenseLayer(nn.Sequential):
298 | def __init__(self, in_channels, growth_rate, bn_size):
299 | super(DenseLayer, self).__init__()
300 | self.add_module('norm1', nn.BatchNorm2d(in_channels))
301 | self.add_module('relu1', nn.ReLU(inplace=True))
302 | self.add_module('conv1', nn.Conv2d(in_channels, bn_size * growth_rate,
303 | kernel_size=1,
304 | stride=1, bias=False))
305 | self.add_module('norm2', nn.BatchNorm2d(bn_size*growth_rate))
306 | self.add_module('relu2', nn.ReLU(inplace=True))
307 | self.add_module('conv2', nn.Conv2d(bn_size*growth_rate, growth_rate,
308 | kernel_size=3,
309 | stride=1, padding=1, bias=False))
310 |
311 | # 重载forward函数
312 | def forward(self, x):
313 | new_features = super(DenseLayer, self).forward(x)
314 | return torch.cat([x, new_features], 1)
315 |
316 |
317 | class DenseBlock(nn.Sequential):
318 | def __init__(self, num_layers, in_channels, bn_size, growth_rate):
319 | super(DenseBlock, self).__init__()
320 | for i in range(num_layers):
321 | self.add_module('denselayer%d' % (i+1),
322 | DenseLayer(in_channels + growth_rate * i,
323 | growth_rate, bn_size))
324 |
325 |
326 | class Transition(nn.Sequential):
327 | def __init__(self, in_channels, out_channels):
328 | super(Transition, self).__init__()
329 | self.add_module('norm', nn.BatchNorm2d(in_channels))
330 | self.add_module('relu', nn.ReLU(inplace=True))
331 | self.add_module('conv', nn.Conv2d(in_channels, out_channels,
332 | kernel_size=1,
333 | stride=1, bias=False))
334 | self.add_module('pool', nn.AvgPool2d(kernel_size=2, stride=2))
335 |
336 |
337 | class DenseNetBC(nn.Module):
338 | def __init__(self, growth_rate=12, block_config=(6, 12, 24, 16),
339 | bn_size=4, theta=0.5, num_classes=2):
340 | super(DenseNetBC, self).__init__()
341 |
342 | # 初始的卷积为filter:2倍的growth_rate
343 | num_init_feature = 2 * growth_rate
344 |
345 | # 原DenseNet对cifar-10与ImageNet的分别初始化
346 | # if num_classes == 10:
347 | # self.features = nn.Sequential(OrderedDict([
348 | # ('conv0', nn.Conv2d(3, num_init_feature,
349 | # kernel_size=3, stride=1,
350 | # padding=1, bias=False)),
351 | # ]))
352 | # else:
353 | # self.features = nn.Sequential(OrderedDict([
354 | # ('conv0', nn.Conv2d(3, num_init_feature,
355 | # kernel_size=7, stride=2,
356 | # padding=3, bias=False)),
357 | # ('norm0', nn.BatchNorm2d(num_init_feature)),
358 | # ('relu0', nn.ReLU(inplace=True)),
359 | # ('pool0', nn.MaxPool2d(kernel_size=3, stride=2, padding=1))
360 | # ]))
361 | self.features = nn.Sequential(OrderedDict([
362 | ('conv0', nn.Conv2d(1, num_init_feature,
363 | kernel_size=3, stride=1,
364 | padding=1, bias=False)),
365 | ]))
366 |
367 | num_feature = num_init_feature
368 | for i, num_layers in enumerate(block_config):
369 | self.features.add_module('denseblock%d' % (i+1),
370 | DenseBlock(num_layers, num_feature,
371 | bn_size, growth_rate))
372 | num_feature = num_feature + growth_rate * num_layers
373 | if i != len(block_config)-1:
374 | self.features.add_module('transition%d' % (i + 1),
375 | Transition(num_feature,
376 | int(num_feature * theta)))
377 | num_feature = int(num_feature * theta)
378 |
379 | self.features.add_module('norm5', nn.BatchNorm2d(num_feature))
380 | self.features.add_module('relu5', nn.ReLU(inplace=True))
381 | self.features.add_module('avg_pool', nn.AdaptiveAvgPool2d((1, 1)))
382 |
383 | self.linear = nn.Linear(num_feature, num_classes)
384 |
385 | for m in self.modules():
386 | if isinstance(m, nn.Conv2d):
387 | nn.init.kaiming_normal_(m.weight)
388 | elif isinstance(m, nn.BatchNorm2d):
389 | nn.init.constant_(m.weight, 1)
390 | nn.init.constant_(m.bias, 0)
391 | elif isinstance(m, nn.Linear):
392 | nn.init.constant_(m.bias, 0)
393 |
394 | def forward(self, x):
395 | # 增加一个1的维度(图像处理中为RGB维度)
396 | x = x.view(x.size()[0], 1, x.size()[1], x.size()[2])
397 | features = self.features(x)
398 | out = features.view(features.size(0), -1)
399 | out = self.linear(out)
400 | return out
401 |
402 |
403 | def dense_net_BC_100():
404 | return DenseNetBC(growth_rate=12, block_config=(16, 16, 16))
405 |
406 |
407 | class Prediction:
408 | def __init__(self, data_days=10, batch_size=50):
409 | # 策略所需数据天数
410 | self.data_days = data_days
411 | # 指数组合
412 | self.index_name = 'hs300'
413 | self.index_code = 'sh.000300'
414 | # 存储路径
415 | self.base_data_path = './data/'
416 | self.data_path = './data/stocks/'
417 | # 指数组合内股票名称,代码数据
418 | self.stocks = pd.read_csv('{}{}_stocks.csv'.format(self.base_data_path, self.index_name))
419 | self.stocks_codes = self.stocks['code']
420 | # 指数日线数据
421 | self.index = pd.read_csv('{}{}.csv'.format(self.data_path, self.index_code))
422 | # 交易日str序列
423 | self.trading_dates = self.index['date']
424 | # 一次喂入数据批次
425 | self.batch_size = batch_size
426 | # 输入列
427 | self.input_columns = ('open', 'high', 'low', 'close', 'preclose',
428 | 'turn', 'peTTM', 'psTTM', 'pcfNcfTTM', 'pbMRQ',)
429 | input_size = len(self.input_columns)
430 |
431 | # cnn模型
432 | self.cnn = CNNModel(data_days, input_size).to(device)
433 |
434 | # RNN类型 输入大小 隐层大小 隐层数
435 | # rnn_types = 'LSTM', 'GRU', 'RNN_TANH', 'RNN_RELU'
436 | hidden_size = 20
437 | n_layers = 2
438 | # 初始化模型
439 | self.lstm = RNNModel('LSTM', input_size, hidden_size, n_layers).to(device)
440 | self.gru = RNNModel('GRU', input_size, hidden_size, n_layers).to(device)
441 | self.rnn_tanh = RNNModel('RNN_TANH', input_size, hidden_size, n_layers).to(device)
442 | self.rnn_relu = RNNModel('RNN_RELU', input_size, hidden_size, n_layers).to(device)
443 |
444 | # ResNet模型
445 | self.resnet18 = ResNet18().to(device)
446 | self.resnet34 = ResNet34().to(device)
447 | self.resnet50 = ResNet50().to(device)
448 | self.resnet101 = ResNet101().to(device)
449 | self.resnet152 = ResNet152().to(device)
450 |
451 | # DenseNet模型
452 | self.densenet = dense_net_BC_100().to(device)
453 |
454 | # 使用MSE误差
455 | self.criterion = nn.MSELoss()
456 | # 使用AdamW优化器 默认参数
457 | self.cnn_optimizer = torch.optim.AdamW(self.cnn.parameters())
458 | self.lstm_optimizer = torch.optim.AdamW(self.lstm.parameters())
459 | self.gru_optimizer = torch.optim.AdamW(self.gru.parameters())
460 | self.rnn_tanh_optimizer = torch.optim.AdamW(self.rnn_tanh.parameters())
461 | self.rnn_relu_optimizer = torch.optim.AdamW(self.rnn_relu.parameters())
462 | self.rn18_optimizer = torch.optim.AdamW(self.resnet18.parameters())
463 | self.rn34_optimizer = torch.optim.AdamW(self.resnet34.parameters())
464 | self.rn50_optimizer = torch.optim.AdamW(self.resnet50.parameters())
465 | self.rn101_optimizer = torch.optim.AdamW(self.resnet101.parameters())
466 | self.rn152_optimizer = torch.optim.AdamW(self.resnet152.parameters())
467 | self.densenet_optimizer = torch.optim.AdamW(self.densenet.parameters())
468 |
469 | def __train(self, model_name, model, optim, train_dataset, epochs=2):
470 | # 生成训练数据
471 | train_data = DataLoader(train_dataset, batch_size=self.batch_size, shuffle=True)
472 | # 设置为训练模式
473 | model.train()
474 | print('*' * 20, '\n', model_name, '模型训练中')
475 | for epoch in range(epochs):
476 | for data, label in train_data:
477 | # 前向传播 计算结果
478 | output = model.forward(data)
479 | # label = label.view(label.size()[0], 1)
480 | # 计算误差
481 | loss = self.criterion(output, label)
482 | # 清除梯度记录
483 | optim.zero_grad()
484 | # 误差反向传播
485 | loss.backward()
486 | # 优化器更新参数
487 | optim.step()
488 | print('Train_loss:', loss.item(), end='\r')
489 | if loss.item() < 1e-3:
490 | break
491 | # 保存训练好的模型
492 | torch.save(model, '{}{}.pt'.format(self.base_data_path, model_name))
493 | print('\n', model_name, '模型训练完成')
494 |
495 | def train_cnn(self, train_dataset, epochs=2, retrain=False):
496 | if not os.path.exists('{}CNN.pt'.format(self.base_data_path)):
497 | retrain = True
498 | if not retrain:
499 | # 读取训练好的模型
500 | self.cnn = torch.load('{}CNN.pt'.format(self.base_data_path, self.index_name))
501 | return
502 | self.__train('CNN', self.cnn, self.cnn_optimizer, train_dataset, epochs)
503 |
504 | def train_lstm(self, train_dataset, epochs=2, retrain=False):
505 | if not os.path.exists('{}LSTM.pt'.format(self.base_data_path)):
506 | retrain = True
507 | if not retrain:
508 | # 读取训练好的模型
509 | self.lstm = torch.load('{}LSTM.pt'.format(self.base_data_path))
510 | return
511 | self.__train('LSTM', self.lstm, self.lstm_optimizer, train_dataset, epochs)
512 |
513 | def train_gru(self, train_dataset, epochs=2, retrain=False):
514 | if not os.path.exists('{}GRU.pt'.format(self.base_data_path)):
515 | retrain = True
516 | if not retrain:
517 | # 读取训练好的模型
518 | self.rnn_relu = torch.load('{}GRU.pt'.format(self.base_data_path))
519 | return
520 | self.__train('GRU', self.gru, self.gru_optimizer, train_dataset, epochs)
521 |
522 | def train_rnn_tanh(self, train_dataset, epochs=2, retrain=False):
523 | if not os.path.exists('{}RNN_tanh.pt'.format(self.base_data_path)):
524 | retrain = True
525 | if not retrain:
526 | # 读取训练好的模型
527 | self.rnn_relu = torch.load('{}RNN_tanh.pt'.format(self.base_data_path))
528 | return
529 | self.__train('RNN_tanh', self.rnn_tanh, self.rnn_tanh_optimizer, train_dataset, epochs)
530 |
531 | def train_rnn_relu(self, train_dataset, epochs=2, retrain=False):
532 | if not os.path.exists('{}RNN_relu.pt'.format(self.base_data_path)):
533 | retrain = True
534 | if not retrain:
535 | # 读取训练好的模型
536 | self.rnn_relu = torch.load('{}RNN_relu.pt'.format(self.base_data_path))
537 | return
538 | self.__train('RNN_relu', self.rnn_relu, self.rnn_relu_optimizer, train_dataset, epochs)
539 |
540 | def train_resnet18(self, train_dataset, epochs=2, retrain=False):
541 | if not os.path.exists('{}resnet18.pt'.format(self.base_data_path)):
542 | retrain = True
543 | if not retrain:
544 | # 读取训练好的模型
545 | self.resnet18 = torch.load('{}resnet18.pt'.format(self.base_data_path))
546 | return
547 | self.__train('resnet18', self.resnet18, self.rn18_optimizer, train_dataset, epochs)
548 |
549 | def train_resnet34(self, train_dataset, epochs=2, retrain=False):
550 | if not os.path.exists('{}resnet34.pt'.format(self.base_data_path)):
551 | retrain = True
552 | if not retrain:
553 | # 读取训练好的模型
554 | self.resnet34 = torch.load('{}resnet34.pt'.format(self.base_data_path))
555 | return
556 | self.__train('resnet34', self.resnet34, self.rn34_optimizer, train_dataset, epochs)
557 |
558 | def train_resnet50(self, train_dataset, epochs=2, retrain=False):
559 | if not os.path.exists('{}resnet50.pt'.format(self.base_data_path)):
560 | retrain = True
561 | if not retrain:
562 | # 读取训练好的模型
563 | self.resnet50 = torch.load('{}resnet50.pt'.format(self.base_data_path))
564 | return
565 | self.__train('resnet50', self.resnet50, self.rn50_optimizer, train_dataset, epochs)
566 |
567 | def train_resnet101(self, train_dataset, epochs=2, retrain=False):
568 | if not os.path.exists('{}resnet101.pt'.format(self.base_data_path)):
569 | retrain = True
570 | if not retrain:
571 | # 读取训练好的模型
572 | self.resnet101 = torch.load('{}resnet101.pt'.format(self.base_data_path))
573 | return
574 | self.__train('resnet101', self.resnet101, self.rn101_optimizer, train_dataset, epochs)
575 |
576 | def train_resnet152(self, train_dataset, epochs=2, retrain=False):
577 | if not os.path.exists('{}resnet152.pt'.format(self.base_data_path)):
578 | retrain = True
579 | if not retrain:
580 | # 读取训练好的模型
581 | self.resnet152 = torch.load('{}resnet152.pt'.format(self.base_data_path))
582 | return
583 | self.__train('resnet152', self.resnet152, self.rn152_optimizer, train_dataset, epochs)
584 |
585 | def train_densenet(self, train_dataset, epochs=2, retrain=False):
586 | if not os.path.exists('{}densenet.pt'.format(self.base_data_path)):
587 | retrain = True
588 | if not retrain:
589 | # 读取训练好的模型
590 | self.densenet = torch.load('{}densenet.pt'.format(self.base_data_path))
591 | return
592 | self.__train('densenet', self.densenet, self.densenet_optimizer, train_dataset, epochs)
593 |
594 | def __predict_data(self, stock_code: str, today: tuple, abs_date=False):
595 | stock_data = pd.read_csv('{}{}.csv'.format(self.data_path, stock_code))
596 | # 当前日期在数据集中序号
597 | date_index = today[1] if abs_date else len(stock_data) - len(self.trading_dates) + today[1]
598 | # 数据不足时返回0
599 | if date_index < self.data_days:
600 | return 0
601 | # 生成预测数据
602 | stock_data = pd.DataFrame(stock_data, columns=self.input_columns)
603 | # 将0替换为上一行数据
604 | stock_data = stock_data.replace(0, None)
605 | stock_data = stock_data[date_index - self.data_days:date_index]
606 | stock_data = np.reshape(stock_data.values, (1, self.data_days, len(self.input_columns)))
607 | stock_data = torch.tensor(stock_data, dtype=torch.float32, device=device)
608 | return stock_data
609 |
610 | def __predict(self, model, stock_code: str, today: tuple):
611 | # 设置为预测模式
612 | model.eval()
613 | stock_data = self.__predict_data(stock_code, today)
614 | if type(stock_data) == int:
615 | return 0
616 | with torch.no_grad():
617 | # 前向传播 输出结果
618 | output = model.forward(stock_data)
619 | return output
620 |
621 | def predict_cnn(self, stock_code: str, today: tuple):
622 | return self.__predict(self.cnn, stock_code, today)
623 |
624 | def predict_lstm(self, stock_code: str, today: tuple):
625 | return self.__predict(self.lstm, stock_code, today)
626 |
627 | def predict_gru(self, stock_code: str, today: tuple):
628 | return self.__predict(self.gru, stock_code, today)
629 |
630 | def predict_rnn_tanh(self, stock_code: str, today: tuple):
631 | return self.__predict(self.rnn_tanh, stock_code, today)
632 |
633 | def predict_rnn_relu(self, stock_code: str, today: tuple):
634 | return self.__predict(self.rnn_relu, stock_code, today)
635 |
636 | def predict_resnet18(self, stock_code: str, today: tuple):
637 | return self.__predict(self.resnet18, stock_code, today)
638 |
639 | def predict_resnet34(self, stock_code: str, today: tuple):
640 | return self.__predict(self.resnet34, stock_code, today)
641 |
642 | def predict_resnet50(self, stock_code: str, today: tuple):
643 | return self.__predict(self.resnet50, stock_code, today)
644 |
645 | def predict_resnet101(self, stock_code: str, today: tuple):
646 | return self.__predict(self.resnet101, stock_code, today)
647 |
648 | def predict_resnet152(self, stock_code: str, today: tuple):
649 | return self.__predict(self.resnet152, stock_code, today)
650 |
651 | def predict_densenet(self, stock_code: str, today: tuple):
652 | return self.__predict(self.densenet, stock_code, today)
653 |
654 |
655 | if __name__ == '__main__':
656 | dataset = StockDataset(data_days=10, remake_data=False)
657 | print('训练集大小:', len(dataset))
658 |
659 | prediction = Prediction(data_days=10, batch_size=200)
660 |
661 | # p2 = t_data.loc[trading_day1[1], 'high'] / t_data.loc[trading_day1[1] - 1, 'high'] - 1
662 | # p3 = t_data.loc[trading_day1[1], 'low'] / t_data.loc[trading_day1[1] - 1, 'low'] - 1
663 | # p4 = t_data.loc[trading_day1[1], 'close'] / t_data.loc[trading_day1[1] - 1, 'close'] - 1
664 | # print(return_rate_transform(p1), p2, p3, p4)
665 |
666 | prediction.train_cnn(dataset, retrain=False, epochs=1)
667 | prediction.train_lstm(dataset, retrain=False, epochs=1)
668 | # GRU与tanhRNN效果不佳 抛弃
669 | # prediction.train_gru(dataset, retrain=False, epochs=1)
670 | # prediction.train_rnn_tanh(dataset, retrain=False, epochs=1)
671 | prediction.train_rnn_relu(dataset, retrain=False, epochs=1)
672 | prediction.train_resnet18(dataset, retrain=False, epochs=1)
673 | prediction.train_resnet34(dataset, retrain=False, epochs=1)
674 | prediction.train_resnet50(dataset, retrain=False, epochs=1)
675 | prediction.train_resnet101(dataset, retrain=False, epochs=1)
676 | prediction.train_resnet152(dataset, retrain=False, epochs=1)
677 | prediction.train_densenet(dataset, retrain=False, epochs=1)
678 |
679 | plt.rcParams['font.sans-serif'] = ['SimHei']
680 | plt.rcParams['axes.unicode_minus'] = False
681 | plt.figure(figsize=[30, 15], dpi=160)
682 | for code in dataset.stocks_codes[:5]:
683 | print('正在绘制'+code+'预测图像')
684 | plt.clf()
685 | df = pd.read_csv('./data/stocks/' + code + '.csv')
686 | trading_dates = df['date']
687 | x_r = range(0, len(trading_dates))
688 | x_ticks = list(x_r[::100])
689 | x_ticks.append(x_r[-1])
690 | x_labels = [trading_dates[i] for i in x_ticks]
691 | true_close = df['close'].values
692 |
693 | def close_p(x):
694 | if type(x) == int:
695 | return x
696 | x = x[0, 1].item()
697 | return x if 0.2 > x > -0.2 else 0.0
698 |
699 | print('计算CNN')
700 | cnn_close = [true_close[j]*(1+close_p(prediction.predict_cnn(code, (0, j))))
701 | for j in range(len(trading_dates))]
702 | print('计算LSTM')
703 | lstm_close = [true_close[j]*(1+close_p(prediction.predict_lstm(code, (0, j))))
704 | for j in range(len(trading_dates))]
705 | # print('计算GRU')
706 | # gru_close = [true_close[j]*(1+close_p(prediction.predict_gru(code, (0, j))))
707 | # for j in range(len(trading_dates))]
708 | # print('计算RNN_tanh')
709 | # rnn_tanh_close = [true_close[j] * (1 + close_p(prediction.predict_rnn_tanh(code, (0, j))))
710 | # for j in range(len(trading_dates))]
711 | print('计算RNN_relu')
712 | rnn_relu_close = [true_close[j] * (1 + close_p(prediction.predict_rnn_relu(code, (0, j))))
713 | for j in range(len(trading_dates))]
714 | print('计算ResNet18')
715 | rn18_close = [true_close[j]*(1+close_p(prediction.predict_resnet18(code, (0, j))))
716 | for j in range(len(trading_dates))]
717 | print('计算ResNet34')
718 | rn34_close = [true_close[j]*(1+close_p(prediction.predict_resnet34(code, (0, j))))
719 | for j in range(len(trading_dates))]
720 | print('计算ResNet50')
721 | rn50_close = [true_close[j]*(1+close_p(prediction.predict_resnet50(code, (0, j))))
722 | for j in range(len(trading_dates))]
723 | print('计算ResNet101')
724 | rn101_close = [true_close[j]*(1+close_p(prediction.predict_resnet101(code, (0, j))))
725 | for j in range(len(trading_dates))]
726 | print('计算ResNet152')
727 | rn152_close = [true_close[j]*(1+close_p(prediction.predict_resnet152(code, (0, j))))
728 | for j in range(len(trading_dates))]
729 | print('计算DenseNet')
730 | densenet_close = [true_close[j]*(1+close_p(prediction.predict_densenet(code, (0, j))))
731 | for j in range(len(trading_dates))]
732 |
733 | def sp(i, predict_close, label_name):
734 | plt.subplot(3, 3, i)
735 | plt.plot(x_r, true_close, label='真实值')
736 | plt.plot(x_r, predict_close, label=label_name)
737 | plt.ylabel('收盘价')
738 | plt.xticks(x_ticks, x_labels)
739 | plt.legend()
740 |
741 | sp(1, cnn_close, 'CNN模型预测值')
742 | sp(2, lstm_close, 'LSTM模型预测值')
743 | # sp(3, gru_close, 'GRU模型预测值')
744 | # sp(4, rnn_tanh_close, 'RNN_tanh模型预测值')
745 | sp(3, rnn_relu_close, 'RNN_relu模型预测值')
746 | sp(4, rn18_close, 'ResNet18模型预测值')
747 | sp(5, rn34_close, 'ResNet34模型预测值')
748 | sp(6, rn34_close, 'ResNet50模型预测值')
749 | sp(7, rn101_close, 'ResNet101模型预测值')
750 | sp(8, rn101_close, 'ResNet152模型预测值')
751 | sp(9, densenet_close, 'DenseNet模型预测值')
752 |
753 | plt.savefig(code+'_predict.jpg')
754 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/stock_indicator.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | @version: 3.8.3
4 | @author: Yamisora
5 | @file: stock_indicator.py
6 | 股票技术指标接口
7 | Created on 2018/07/26
8 | @original author: Wangzili
9 | @contact: 446406177@qq.com
10 | """
11 | import pandas as pd
12 | import numpy as np
13 | import itertools
14 |
15 |
16 | def ma(df, n=10):
17 | """
18 | 移动平均线 Moving Average
19 | MA(N)=(第1日收盘价+第2日收盘价—+……+第N日收盘价)/N
20 | """
21 | pv = pd.DataFrame()
22 | pv['date'] = df['date']
23 | pv['ma'] = df.close.rolling(n).mean()
24 | return pv
25 |
26 |
27 | def _ma(series, n):
28 | """
29 | 移动平均
30 | """
31 | return series.rolling(n).mean()
32 |
33 |
34 | def md(df, n=10):
35 | """
36 | 移动标准差
37 | STD=S(CLOSE,N)=[∑(CLOSE-MA(CLOSE,N))^2/N]^0.5
38 | """
39 | _md = pd.DataFrame()
40 | _md['date'] = df.date
41 | _md["md"] = df.close.rolling(n).std(ddof=0)
42 | return _md
43 |
44 |
45 | def _md(series, n):
46 | """
47 | 标准差MD
48 | """
49 | return series.rolling(n).std(ddof=0) # 有时候会用ddof=1
50 |
51 |
52 | def ema(df, n=12):
53 | """
54 | 指数平均数指标 Exponential Moving Average
55 | 今日EMA(N)=2/(N+1)×今日收盘价+(N-1)/(N+1)×昨日EMA(N)
56 | EMA(X,N)=[2×X+(N-1)×EMA(ref(X),N]/(N+1)
57 | """
58 | _ema = pd.DataFrame()
59 | _ema['date'] = df['date']
60 | _ema['ema'] = df.close.ewm(ignore_na=False, span=n, min_periods=0, adjust=False).mean()
61 | return _ema
62 |
63 |
64 | def _ema(series, n):
65 | """
66 | 指数平均数
67 | """
68 | return series.ewm(ignore_na=False, span=n, min_periods=0, adjust=False).mean()
69 |
70 |
71 | def dma(df, n=10, m=50, k=10):
72 | """
73 | 平均线差 DMA(10,50,10)
74 | DDD=MA(N1)-MA(N2)
75 | AMA= MA(DDD,M)
76 | 其中N1表示短期天数,N2表示长期天数,M表示AMA的天数
77 | """
78 | _dma = pd.DataFrame()
79 | _dma['date'] = df['date']
80 | _dma['ddd'] = _ma(df.close, n) - _ma(df.close, m)
81 | _dma['ama'] = _ma(_dma.ddd, k)
82 | del _dma['ddd']
83 | return _dma
84 |
85 |
86 | def dmi(df, n=14, m=6):
87 | """
88 | # 通达信计算方法
89 | TRZ: = EMA(MAX(MAX(HIGH - LOW, ABS(HIGH - REF(CLOSE, 1))), ABS(REF(CLOSE, 1) - LOW)), 7);
90 | HD: = HIGH - REF(HIGH, 1);
91 | LD: = REF(LOW, 1) - LOW;
92 | DMP: = EMA(IF(HD > 0 AND HD > LD, HD, 0), 7);
93 | DMM: = EMA(IF(LD > 0 AND LD > HD, LD, 0), 7);
94 | PDI: DMP * 100 / TRZ;
95 | MDI: DMM * 100 / TRZ;
96 | ADX: EMA(ABS(MDI - PDI) / (MDI + PDI) * 100, 7);
97 | ADXR: EMA(ADX, 7);
98 | tr = pd.Series(np.vstack([df.high - df.low, (df.high - df.close.shift()).abs(), (df.low - df.close.shift()).abs()]).max(axis=0))
99 | trz = _ema(tr, n)
100 | _m = pd.DataFrame()
101 | _m['hd'] = df.high - df.high.shift()
102 | _m['ld'] = df.low.shift() - df.low
103 | _m['mp'] = _m.apply(lambda x: x.hd if x.hd > 0 and x.hd > x.ld else 0, axis=1)
104 | _m['mm'] = _m.apply(lambda x: x.ld if x.ld > 0 and x.hd < x.ld else 0, axis=1)
105 | _m['dmp'] = _ema(_m.mp, n)
106 | _m['dmm'] = _ema(_m.mm, n)
107 | _dmi = pd.DataFrame()
108 | _dmi['date'] = df.date
109 | _dmi['pdi'] = _m.dmp * 100 / trz
110 | _dmi['mdi'] = _m.dmm * 100 / trz
111 | _dmi['adx'] = _ema((_dmi.mdi - _dmi.pdi).abs() / (_dmi.mdi + _dmi.pdi) * 100, m)
112 | _dmi['adxr'] = _ema(_dmi.adx, m)
113 | return _dmi
114 | """
115 | """
116 | # 同花顺计算方式
117 | TR := SUM(MAX(MAX(HIGH-LOW,ABS(HIGH-REF(CLOSE,1))),ABS(LOW-REF(CLOSE,1))),N);
118 | HD: = HIGH - REF(HIGH, 1);
119 | LD: = REF(LOW, 1) - LOW;
120 | DMP:= SUM(IF(HD>0 AND HD>LD,HD,0),N);
121 | DMM:= SUM(IF(LD>0 AND LD>HD,LD,0),N);
122 | +DI: DMP*100/TR;
123 | -DI: DMM*100/TR;
124 | ADX: MA(ABS(-DI-+DI)/(-DI++DI)*100,M);
125 | ADXR:(ADX+REF(ADX,M))/2;
126 | """
127 | tr = pd.Series(np.vstack([df.high - df.low, (df.high - df.close.shift()).abs(), (df.low - df.close.shift()).abs()]).max(axis=0))
128 | trz = tr.rolling(n).sum()
129 | _m = pd.DataFrame()
130 | _m['hd'] = df.high - df.high.shift()
131 | _m['ld'] = df.low.shift() - df.low
132 | _m['mp'] = _m.apply(lambda x: x.hd if x.hd > 0 and x.hd > x.ld else 0, axis=1)
133 | _m['mm'] = _m.apply(lambda x: x.ld if x.ld > 0 and x.hd < x.ld else 0, axis=1)
134 | _m['dmp'] = _m.mp.rolling(n).sum()
135 | _m['dmm'] = _m.mm.rolling(n).sum()
136 | _dmi = pd.DataFrame()
137 | _dmi['date'] = df.date
138 | _dmi['pdi'] = _m.dmp * 100 / trz
139 | _dmi['mdi'] = _m.dmm * 100 / trz
140 | _dmi['adx'] = _ma((_dmi.mdi - _dmi.pdi).abs() / (_dmi.mdi + _dmi.pdi) * 100, m)
141 | _dmi['adxr'] = (_dmi.adx + _dmi.adx.shift(m)) / 2
142 | return _dmi
143 |
144 |
145 | def macd(df, n=12, m=26, k=9):
146 | """
147 | 平滑异同移动平均线(Moving Average Convergence Divergence)
148 | 今日EMA(N)=2/(N+1)×今日收盘价+(N-1)/(N+1)×昨日EMA(N)
149 | DIFF= EMA(N1)- EMA(N2)
150 | DEA(DIF,M)= 2/(M+1)×DIF +[1-2/(M+1)]×DEA(REF(DIF,1),M)
151 | MACD(BAR)=2×(DIF-DEA)
152 | return:
153 | osc: MACD bar / OSC 差值柱形图 DIFF - DEM
154 | diff: 差离值
155 | dea: 讯号线
156 | """
157 | _macd = pd.DataFrame()
158 | _macd['date'] = df['date']
159 | _macd['diff'] = _ema(df.close, n) - _ema(df.close, m)
160 | _macd['dea'] = _ema(_macd['diff'], k)
161 | _macd['macd'] = _macd['diff'] - _macd['dea']
162 | del _macd['diff'], _macd['dea']
163 | return _macd
164 |
165 |
166 | def kdj(df, n=9):
167 | """
168 | 随机指标KDJ
169 | N日RSV=(第N日收盘价-N日内最低价)/(N日内最高价-N日内最低价)×100%
170 | 当日K值=2/3前1日K值+1/3×当日RSV=SMA(RSV,M1)
171 | 当日D值=2/3前1日D值+1/3×当日K= SMA(K,M2)
172 | 当日J值=3 ×当日K值-2×当日D值
173 | """
174 | _kdj = pd.DataFrame()
175 | _kdj['date'] = df['date']
176 | rsv = (df.close - df.low.rolling(n).min()) / (df.high.rolling(n).max() - df.low.rolling(n).min()) * 100
177 | _kdj['k'] = sma(rsv, 3)
178 | _kdj['d'] = sma(_kdj.k, 3)
179 | _kdj['j'] = 3 * _kdj.k - 2 * _kdj.d
180 | return _kdj
181 |
182 |
183 | def rsi(df, n=6):
184 | """
185 | 相对强弱指标(Relative Strength Index,简称RSI n=6、12和24
186 | LC= REF(CLOSE,1)
187 | RSI=SMA(MAX(CLOSE-LC,0),N,1)/SMA(ABS(CLOSE-LC),N1,1)×100
188 | SMA(C,N,M)=M/N×今日收盘价+(N-M)/N×昨日SMA(N)
189 | """
190 | # pd.set_option('display.max_rows', 1000)
191 | _rsi = pd.DataFrame()
192 | _rsi['date'] = df['date']
193 | px = df.close - df.close.shift()
194 | px[px < 0] = 0
195 | _rsi['rsi'] = sma(px, n) / sma((df['close'] - df['close'].shift()).abs(), n) * 100
196 | # def tmax(x):
197 | # if x < 0:
198 | # x = 0
199 | # return x
200 | # _rsi['rsi'] = sma((df['close'] - df['close'].shift(1)).apply(tmax), n) / sma((df['close'] - df['close'].shift(1)).abs(), n) * 100
201 | return _rsi
202 |
203 |
204 | def stochrsi(df, n=12):
205 | """
206 | 随机强弱指标(Relative Strength Index,简称RSI n=6、12和24
207 | Stochastic Relative Strength Index(Stoch RSI)
208 | https://zhuanlan.zhihu.com/p/55070261
209 | """
210 | _stochrsi = pd.DataFrame()
211 | _stochrsi['date'] = df.date
212 | px = df.close - df.close.shift()
213 | px[px < 0] = 0
214 | rsi = sma(px, n) / sma((df.close - df.close.shift()).abs(), n) * 100
215 | lrsi = rsi.rolling(n).min()
216 | _stochrsi['stochrsi'] = (rsi - lrsi) / (rsi.rolling(n).max() - lrsi) * 100
217 | _stochrsi['fastk'] = sma(_stochrsi.stochrsi, 3) # or _ma ??????
218 | _stochrsi['fastd'] = sma(_stochrsi.fastk, 3) # or _ma ??????
219 | return _stochrsi
220 |
221 |
222 | def vrsi(df, n=6):
223 | """
224 | 量相对强弱指标
225 | VRSI=SMA(最大值(成交量-REF(成交量,1),0),N,1)/SMA(ABS((成交量-REF(成交量,1),N,1)×100%
226 | """
227 | _vrsi = pd.DataFrame()
228 | _vrsi['date'] = df['date']
229 | px = df['volume'] - df['volume'].shift(1)
230 | px[px < 0] = 0
231 | _vrsi['vrsi'] = sma(px, n) / sma((df['volume'] - df['volume'].shift(1)).abs(), n) * 100
232 | return _vrsi
233 |
234 |
235 | def boll(df, n=26, k=2):
236 | """
237 | 布林线指标BOLL boll(26,2) MID=MA(N)
238 | 标准差MD=根号[∑(CLOSE-MA(CLOSE,N))^2/N]
239 | UPPER=MID+k×MD
240 | LOWER=MID-k×MD
241 | """
242 | _boll = pd.DataFrame()
243 | _boll['date'] = df.date
244 | _boll['boll_mid'] = _ma(df.close, n)
245 | _mdd = _md(df.close, n)
246 | _boll['boll_up'] = _boll.boll_mid + k * _mdd
247 | _boll['boll_low'] = _boll.boll_mid - k * _mdd
248 | return _boll
249 |
250 |
251 | def bbiboll(df, n=10, k=3):
252 | """
253 | BBI多空布林线 bbiboll(10,3)
254 | BBI={MA(3)+ MA(6)+ MA(12)+ MA(24)}/4
255 | 标准差MD=根号[∑(BBI-MA(BBI,N))^2/N]
256 | UPR= BBI+k×MD
257 | DWN= BBI-k×MD
258 | """
259 | # pd.set_option('display.max_rows', 1000)
260 | _bbiboll = pd.DataFrame()
261 | _bbiboll['date'] = df.date
262 | _bbiboll['bbi'] = (_ma(df.close, 3) + _ma(df.close, 6) + _ma(df.close, 12) + _ma(df.close, 24)) / 4
263 | _bbiboll['md'] = _md(_bbiboll.bbi, n)
264 | _bbiboll['upr'] = _bbiboll.bbi + k * _bbiboll.md
265 | _bbiboll['dwn'] = _bbiboll.bbi - k * _bbiboll.md
266 | del _bbiboll['md']
267 | return _bbiboll
268 |
269 |
270 | def wr(df, n=14):
271 | """
272 | 威廉指标 w&r
273 | WR=[最高值(最高价,N)-收盘价]/[最高值(最高价,N)-最低值(最低价,N)]×100%
274 | """
275 |
276 | _wr = pd.DataFrame()
277 | _wr['date'] = df['date']
278 | higest = df.high.rolling(n).max()
279 | _wr['w_r'] = (higest - df.close) / (higest - df.low.rolling(n).min()) * 100
280 | return _wr
281 |
282 |
283 | def bias(df, n=12):
284 | """
285 | 乖离率 bias
286 | bias=[(当日收盘价-12日平均价)/12日平均价]×100%
287 | """
288 | _bias = pd.DataFrame()
289 | _bias['date'] = df.date
290 | _mav = df.close.rolling(n).mean()
291 | _bias['bias'] = (np.true_divide((df.close - _mav), _mav)) * 100
292 | # _bias["bias"] = np.vectorize(lambda x: round(Decimal(x), 4))(BIAS)
293 | return _bias
294 |
295 |
296 | def asi(df, n=5):
297 | """
298 | 振动升降指标(累计震动升降因子) ASI # 同花顺给出的公式不完整就不贴出来了
299 | """
300 | _asi = pd.DataFrame()
301 | _asi['date'] = df.date
302 | _m = pd.DataFrame()
303 | _m['a'] = (df.high - df.close.shift()).abs()
304 | _m['b'] = (df.low - df.close.shift()).abs()
305 | _m['c'] = (df.high - df.low.shift()).abs()
306 | _m['d'] = (df.close.shift() - df.open.shift()).abs()
307 | _m['r'] = _m.apply(lambda x: x.a + 0.5 * x.b + 0.25 * x.d if max(x.a, x.b, x.c) == x.a else (
308 | x.b + 0.5 * x.a + 0.25 * x.d if max(x.a, x.b, x.c) == x.b else x.c + 0.25 * x.d
309 | ), axis=1)
310 | _m['x'] = df.close - df.close.shift() + 0.5 * (df.close - df.open) + df.close.shift() - df.open.shift()
311 | _m['k'] = np.maximum(_m.a, _m.b)
312 | _asi['si'] = 16 * (_m.x / _m.r) * _m.k
313 | _asi["asi"] = _ma(_asi.si, n)
314 | return _asi
315 |
316 |
317 | def vr_rate(df, n=26):
318 | """
319 | 成交量变异率 vr or vr_rate
320 | VR=(AVS+1/2CVS)/(BVS+1/2CVS)×100
321 | 其中:
322 | AVS:表示N日内股价上涨成交量之和
323 | BVS:表示N日内股价下跌成交量之和
324 | CVS:表示N日内股价不涨不跌成交量之和
325 | """
326 | _vr = pd.DataFrame()
327 | _vr['date'] = df['date']
328 | _m = pd.DataFrame()
329 | _m['volume'] = df.volume
330 | _m['cs'] = df.close - df.close.shift(1)
331 | _m['avs'] = _m.apply(lambda x: x.volume if x.cs > 0 else 0, axis=1)
332 | _m['bvs'] = _m.apply(lambda x: x.volume if x.cs < 0 else 0, axis=1)
333 | _m['cvs'] = _m.apply(lambda x: x.volume if x.cs == 0 else 0, axis=1)
334 | _vr['vr_rate'] = (_m.avs.rolling(n).sum() + 1 / 2 * _m.cvs.rolling(n).sum()
335 | ) / (_m.bvs.rolling(n).sum() + 1 / 2 * _m.cvs.rolling(n).sum()) * 100
336 | return _vr
337 |
338 |
339 | def vr(df, n=5):
340 | """
341 | 开市后平均每分钟的成交量与过去5个交易日平均每分钟成交量之比
342 | 量比:=V/REF(MA(V,5),1);
343 | 涨幅:=(C-REF(C,1))/REF(C,1)*100;
344 | 1)量比大于1.8,涨幅小于2%,现价涨幅在0—2%之间,在盘中选股的
345 | 选股:量比>1.8 AND 涨幅>0 AND 涨幅<2;
346 | """
347 | _vr = pd.DataFrame()
348 | _vr['date'] = df.date
349 | _vr['vr'] = df.volume / _ma(df.volume, n).shift(1)
350 | _vr['rr'] = (df.close - df.close.shift(1)) / df.close.shift(1) * 100
351 | return _vr
352 |
353 |
354 | def arbr(df, n=26):
355 | """
356 | 人气意愿指标 arbr(26)
357 | N日AR=N日内(H-O)之和除以N日内(O-L)之和
358 | 其中,H为当日最高价,L为当日最低价,O为当日开盘价,N为设定的时间参数,一般原始参数日设定为26日
359 | N日BR=N日内(H-CY)之和除以N日内(CY-L)之和
360 | 其中,H为当日最高价,L为当日最低价,CY为前一交易日的收盘价,N为设定的时间参数,一般原始参数日设定为26日。
361 | """
362 | _arbr = pd.DataFrame()
363 | _arbr['date'] = df.date
364 | _arbr['ar'] = (df.high - df.open).rolling(n).sum() / (df.open - df.low).rolling(n).sum() * 100
365 | _arbr['br'] = (df.high - df.close.shift(1)).rolling(n).sum() / (df.close.shift() - df.low).rolling(n).sum() * 100
366 | return _arbr
367 |
368 |
369 | def dpo(df, n=20, m=6):
370 | """
371 | 区间震荡线指标 dpo(20,6)
372 | DPO=CLOSE-MA(CLOSE, N/2+1)
373 | MADPO=MA(DPO,M)
374 | """
375 | _dpo = pd.DataFrame()
376 | _dpo['date'] = df['date']
377 | _dpo['dpo'] = df.close - _ma(df.close, int(n / 2 + 1))
378 | _dpo['dopma'] = _ma(_dpo.dpo, m)
379 | return _dpo
380 |
381 |
382 | def tema(df, n=20):
383 | """
384 | h 一般取20或60
385 | TEMA三重指数移动平均线是帕特里克马洛于1994年开发的一个更平滑更快速的移动均线
386 | """
387 | _tema = pd.DataFrame()
388 | _tema['date'] = df.date
389 | a1 = _ema(df.close, n)
390 | a2 = _ema(a1, n)
391 | a3 = _ema(a2, n)
392 | _tema['tema'] = (3 * a1 - 3 * a2 + a3) / _ma(df.close, n)
393 | return _tema
394 |
395 |
396 | def trix(df, n=12, m=20):
397 | """
398 | 三重指数平滑平均 TRIX(12)
399 | TR= EMA(EMA(EMA(CLOSE,N),N),N),即进行三次平滑处理
400 | TRIX=(TR-昨日TR)/ 昨日TR×100
401 | TRMA=MA(TRIX,M)
402 | """
403 | _trix = pd.DataFrame()
404 | _trix['date'] = df.date
405 | tr = _ema(_ema(_ema(df.close, n), n), n)
406 | _trix['trix'] = (tr - tr.shift()) / tr.shift() * 100
407 | _trix['trma'] = _ma(_trix.trix, m)
408 | return _trix
409 |
410 |
411 | def bbi(df):
412 | """
413 | 多空指数 BBI(3,6,12,24)
414 | BBI=(3日均价+6日均价+12日均价+24日均价)/4
415 | """
416 | _bbi = pd.DataFrame()
417 | _bbi['date'] = df['date']
418 | _bbi['bbi'] = (_ma(df.close, 3) + _ma(df.close, 6) + _ma(df.close, 12) + _ma(df.close, 24)) / 4
419 | return _bbi
420 |
421 |
422 | def mtm(df, n=6, m=5):
423 | """
424 | 动力指标 MTM(6,5)
425 | MTM(N日)=C-REF(C,N)式中,C=当日的收盘价,REF(C,N)=N日前的收盘价;N日是只计算交易日期,剔除掉节假日。
426 | MTMMA(MTM,N1)= MA(MTM,N1)
427 | N表示间隔天数,N1表示天数
428 | """
429 | _mtm = pd.DataFrame()
430 | _mtm['date'] = df.date
431 | _mtm['mtm'] = df.close - df.close.shift(n)
432 | _mtm['mtmma'] = _ma(_mtm.mtm, m)
433 | return _mtm
434 |
435 |
436 | def obv(df):
437 | """
438 | 能量潮 On Balance Volume
439 | 多空比率净额= [(收盘价-最低价)-(最高价-收盘价)] ÷( 最高价-最低价)×V # 同花顺貌似用的下面公式
440 | 主公式:当日OBV=前一日OBV+今日成交量
441 | 1.基期OBV值为0,即该股上市的第一天,OBV值为0
442 | 2.若当日收盘价>上日收盘价,则当日OBV=前一日OBV+今日成交量
443 | 3.若当日收盘价<上日收盘价,则当日OBV=前一日OBV-今日成交量
444 | 4.若当日收盘价=上日收盘价,则当日OBV=前一日OBV
445 | """
446 | _obv = pd.DataFrame()
447 | _obv["date"] = df['date']
448 | # tmp = np.true_divide(((df.close - df.low) - (df.high - df.close)), (df.high - df.low))
449 | # _obv['obvv'] = tmp * df.volume
450 | # _obv["obv"] = _obv.obvv.expanding(1).sum() / 100
451 | _m = pd.DataFrame()
452 | _m['date'] = df.date
453 | _m['cs'] = df.close - df.close.shift()
454 | _m['v'] = df.volume
455 | _m['vv'] = _m.apply(lambda x: x.v if x.cs > 0 else (-x.v if x.cs < 0 else 0), axis=1)
456 | _obv['obv'] = _m.vv.expanding(1).sum()
457 | return _obv
458 |
459 |
460 | def cci(df, n=14):
461 | """
462 | 顺势指标
463 | TYP:=(HIGH+LOW+CLOSE)/3
464 | CCI:=(TYP-MA(TYP,N))/(0.015×AVEDEV(TYP,N))
465 | """
466 | _cci = pd.DataFrame()
467 | _cci["date"] = df['date']
468 | typ = (df.high + df.low + df.close) / 3
469 | _cci['cci'] = ((typ - typ.rolling(n).mean()) /
470 | (0.015 * typ.rolling(min_periods=1, center=False, window=n).apply(
471 | lambda x: np.fabs(x - x.mean()).mean())))
472 | return _cci
473 |
474 |
475 | def priceosc(df, n=12, m=26):
476 | """
477 | 价格振动指数
478 | PRICEOSC=(MA(C,12)-MA(C,26))/MA(C,12) * 100
479 | """
480 | _c = pd.DataFrame()
481 | _c['date'] = df['date']
482 | man = _ma(df.close, n)
483 | _c['osc'] = (man - _ma(df.close, m)) / man * 100
484 | return _c
485 |
486 |
487 | def sma(a, n, m=1):
488 | """
489 | 平滑移动指标 Smooth Moving Average
490 | """
491 | ''' # 方法一,此方法有缺陷
492 | _sma = []
493 | for index, value in enumerate(a):
494 | if index == 0 or pd.isna(value) or np.isnan(value):
495 | tsma = 0
496 | else:
497 | # Y=(M*X+(N-M)*Y')/N
498 | tsma = (m * value + (n - m) * tsma) / n
499 | _sma.append(tsma)
500 | return pd.Series(_sma)
501 | '''
502 | ''' # 方法二
503 |
504 | results = np.nan_to_num(a).copy()
505 | # FIXME this is very slow
506 | for i in range(1, len(a)):
507 | results[i] = (m * results[i] + (n - m) * results[i - 1]) / n
508 | # results[i] = ((n - 1) * results[i - 1] + results[i]) / n
509 | # return results
510 | '''
511 | # b = np.nan_to_num(a).copy()
512 | # return ((n - m) * a.shift(1) + m * a) / n
513 |
514 | a = a.fillna(0)
515 | b = a.ewm(min_periods=0, ignore_na=False, adjust=False, alpha=m/n).mean()
516 | return b
517 |
518 |
519 | def dbcd(df, n=5, m=16, t=76):
520 | """
521 | 异同离差乖离率 dbcd(5,16,76)
522 | BIAS=(C-MA(C,N))/MA(C,N)
523 | DIF=(BIAS-REF(BIAS,M))
524 | DBCD=SMA(DIF,T,1) =(1-1/T)×SMA(REF(DIF,1),T,1)+ 1/T×DIF
525 | MM=MA(DBCD,5)
526 | """
527 | _dbcd = pd.DataFrame()
528 | _dbcd['date'] = df.date
529 | man = _ma(df.close, n)
530 | _bias = (df.close - man) / man
531 | _dif = _bias - _bias.shift(m)
532 | _dbcd['dbcd'] = sma(_dif, t)
533 | _dbcd['mm'] = _ma(_dbcd.dbcd, n)
534 | return _dbcd
535 |
536 |
537 | def roc(df, n=12, m=6):
538 | """
539 | 变动速率 roc(12,6)
540 | ROC=(今日收盘价-N日前的收盘价)/ N日前的收盘价×100%
541 | ROCMA=MA(ROC,M)
542 | ROC:(CLOSE-REF(CLOSE,N))/REF(CLOSE,N)×100
543 | ROCMA:MA(ROC,M)
544 | """
545 | _roc = pd.DataFrame()
546 | _roc['date'] = df['date']
547 | _roc['roc'] = (df.close - df.close.shift(n))/df.close.shift(n) * 100
548 | _roc['rocma'] = _ma(_roc.roc, m)
549 | return _roc
550 |
551 |
552 | def vroc(df, n=12):
553 | """
554 | 量变动速率
555 | VROC=(当日成交量-N日前的成交量)/ N日前的成交量×100%
556 | """
557 | _vroc = pd.DataFrame()
558 | _vroc['date'] = df['date']
559 | _vroc['vroc'] = (df.volume - df.volume.shift(n)) / df.volume.shift(n) * 100
560 | return _vroc
561 |
562 |
563 | def cr(df, n=26):
564 | """ 能量指标
565 | CR=∑(H-PM)/∑(PM-L)×100
566 | PM:上一交易日中价((最高、最低、收盘价的均值)
567 | H:当天最高价
568 | L:当天最低价
569 | """
570 | _cr = pd.DataFrame()
571 | _cr['date'] = df.date
572 | # pm = ((df['high'] + df['low'] + df['close']) / 3).shift(1)
573 | pm = (df[['high', 'low', 'close']]).mean(axis=1).shift(1)
574 | _cr['cr'] = (df.high - pm).rolling(n).sum()/(pm - df.low).rolling(n).sum() * 100
575 | return _cr
576 |
577 |
578 | def psy(df, n=12):
579 | """
580 | 心理指标 PSY(12)
581 | PSY=N日内上涨天数/N×100
582 | PSY:COUNT(CLOSE>REF(CLOSE,1),N)/N×100
583 | MAPSY=PSY的M日简单移动平均
584 | """
585 | _psy = pd.DataFrame()
586 | _psy['date'] = df.date
587 | p = df.close - df.close.shift()
588 | p[p <= 0] = np.nan
589 | _psy['psy'] = p.rolling(n).count() / n * 100
590 | return _psy
591 |
592 |
593 | def wad(df, n=30):
594 | """
595 | 威廉聚散指标 WAD(30)
596 | TRL=昨日收盘价与今日最低价中价格最低者;TRH=昨日收盘价与今日最高价中价格最高者
597 | 如果今日的收盘价>昨日的收盘价,则今日的A/D=今日的收盘价-今日的TRL
598 | 如果今日的收盘价<昨日的收盘价,则今日的A/D=今日的收盘价-今日的TRH
599 | 如果今日的收盘价=昨日的收盘价,则今日的A/D=0
600 | WAD=今日的A/D+昨日的WAD;MAWAD=WAD的M日简单移动平均
601 | """
602 | def dmd(x):
603 | if x.c > 0:
604 | y = x.close - x.trl
605 | elif x.c < 0:
606 | y = x.close - x.trh
607 | else:
608 | y = 0
609 | return y
610 |
611 | _wad = pd.DataFrame()
612 | _wad['date'] = df['date']
613 | _ad = pd.DataFrame()
614 | _ad['trl'] = np.minimum(df.low, df.close.shift(1))
615 | _ad['trh'] = np.maximum(df.high, df.close.shift(1))
616 | _ad['c'] = df.close - df.close.shift()
617 | _ad['close'] = df.close
618 | _ad['ad'] = _ad.apply(dmd, axis=1)
619 | _wad['wad'] = _ad.ad.expanding(1).sum()
620 | _wad['mawad'] = _ma(_wad.wad, n)
621 | return _wad
622 |
623 |
624 | def mfi(df, n=14):
625 | """
626 | 资金流向指标 mfi(14)
627 | MF=TYP×成交量;TYP:当日中价((最高、最低、收盘价的均值)
628 | 如果当日TYP>昨日TYP,则将当日的MF值视为当日PMF值。而当日NMF值=0
629 | 如果当日TYP<=昨日TYP,则将当日的MF值视为当日NMF值。而当日PMF值=0
630 | MR=∑PMF/∑NMF
631 | MFI=100-(100÷(1+MR))
632 | """
633 | _mfi = pd.DataFrame()
634 | _mfi['date'] = df.date
635 | _m = pd.DataFrame()
636 | _m['typ'] = df[['high', 'low', 'close']].mean(axis=1)
637 | _m['mf'] = _m.typ * df.volume
638 | _m['typ_shift'] = _m.typ - _m.typ.shift(1)
639 | _m['pmf'] = _m.apply(lambda x: x.mf if x.typ_shift > 0 else 0, axis=1)
640 | _m['nmf'] = _m.apply(lambda x: x.mf if x.typ_shift <= 0 else 0, axis=1)
641 | # _mfi['mfi'] = 100 - (100 / (1 + _m.pmf.rolling(n).sum() / _m.nmf.rolling(n).sum()))
642 | _m['mr'] = _m.pmf.rolling(n).sum() / _m.nmf.rolling(n).sum()
643 | _mfi['mfi'] = 100 * _m.mr / (1 + _m.mr) # 同花顺自己给出的公式和实际用的公式不一样,真操蛋,浪费两个小时时间
644 | return _mfi
645 |
646 |
647 | def pvt(df):
648 | """
649 | pvt 量价趋势指标 pvt
650 | 如果设x=(今日收盘价—昨日收盘价)/昨日收盘价×当日成交量,
651 | 那么当日PVT指标值则为从第一个交易日起每日X值的累加。
652 | """
653 | _pvt = pd.DataFrame()
654 | _pvt['date'] = df.date
655 |
656 | x = (df.close - df.close.shift(1)) / df.close.shift(1) * df.volume
657 | _pvt['pvt'] = x.expanding(1).sum()
658 | return _pvt
659 |
660 |
661 | def wvad(df, n=24, m=6):
662 | """ # 算法是对的,同花顺计算wvad用的n=6
663 | 威廉变异离散量 wvad(24,6)
664 | WVAD=N1日的∑ {(当日收盘价-当日开盘价)/(当日最高价-当日最低价)×成交量}
665 | MAWVAD=MA(WVAD,N2)
666 | """
667 | _wvad = pd.DataFrame()
668 | _wvad['date'] = df.date
669 | # _wvad['wvad'] = (np.true_divide((df.close - df.open), (df.high - df.low)) * df.volume).rolling(n).sum()
670 | _wvad['wvad'] = (np.true_divide((df.close - df.open), (df.high - df.low)) * df.volume).rolling(n).sum()
671 | _wvad['mawvad'] = _ma(_wvad.wvad, m)
672 | return _wvad
673 |
674 |
675 | def cdp(df):
676 | """
677 | 逆势操作 cdp
678 | CDP=(最高价+最低价+收盘价)/3 # 同花顺实际用的(H+L+2*c)/4
679 | AH=CDP+(前日最高价-前日最低价)
680 | NH=CDP×2-最低价
681 | NL=CDP×2-最高价
682 | AL=CDP-(前日最高价-前日最低价)
683 | """
684 | _cdp = pd.DataFrame()
685 | _cdp['date'] = df.date
686 | # _cdp['cdp'] = (df.high + df.low + df.close * 2).shift(1) / 4
687 | _cdp['cdp'] = df[['high', 'low', 'close', 'close']].shift().mean(axis=1)
688 | _cdp['ah'] = _cdp.cdp + (df.high.shift(1) - df.low.shift())
689 | _cdp['al'] = _cdp.cdp - (df.high.shift(1) - df.low.shift())
690 | _cdp['nh'] = _cdp.cdp * 2 - df.low.shift(1)
691 | _cdp['nl'] = _cdp.cdp * 2 - df.high.shift(1)
692 | return _cdp
693 |
694 |
695 | def env(df, n=14):
696 | """
697 | ENV指标 ENV(14)
698 | Upper=MA(CLOSE,N)×1.06
699 | LOWER= MA(CLOSE,N)×0.94
700 | """
701 | _env = pd.DataFrame()
702 | _env['date'] = df.date
703 | _env['env_up'] = df.close.rolling(n).mean() * 1.06
704 | _env['env_low'] = df.close.rolling(n).mean() * 0.94
705 | return _env
706 |
707 |
708 | def mike(df, n=12):
709 | """
710 | 麦克指标 mike(12)
711 | 初始价(TYP)=(当日最高价+当日最低价+当日收盘价)/3
712 | HV=N日内区间最高价
713 | LV=N日内区间最低价
714 | 初级压力线(WR)=TYP×2-LV
715 | 中级压力线(MR)=TYP+HV-LV
716 | 强力压力线(SR)=2×HV-LV
717 | 初级支撑线(WS)=TYP×2-HV
718 | 中级支撑线(MS)=TYP-HV+LV
719 | 强力支撑线(SS)=2×LV-HV
720 | """
721 | _mike = pd.DataFrame()
722 | _mike['date'] = df.date
723 | typ = df[['high', 'low', 'close']].mean(axis=1)
724 | hv = df.high.rolling(n).max()
725 | lv = df.low.rolling(n).min()
726 | _mike['wr'] = typ * 2 - lv
727 | _mike['mr'] = typ + hv - lv
728 | _mike['sr'] = 2 * hv - lv
729 | _mike['ws'] = typ * 2 - hv
730 | _mike['ms'] = typ - hv + lv
731 | _mike['ss'] = 2 * lv - hv
732 | return _mike
733 |
734 |
735 | def vma(df, n=5):
736 | """
737 | 量简单移动平均 VMA(5) VMA=MA(volume,N)
738 | VOLUME表示成交量;N表示天数
739 | """
740 | _vma = pd.DataFrame()
741 | _vma['date'] = df.date
742 | _vma['vma'] = _ma(df.volume, n)
743 | return _vma
744 |
745 |
746 | def vmacd(df, qn=12, sn=26, m=9):
747 | """
748 | 量指数平滑异同平均 vmacd(12,26,9)
749 | 今日EMA(N)=2/(N+1)×今日成交量+(N-1)/(N+1)×昨日EMA(N)
750 | DIFF= EMA(N1)- EMA(N2)
751 | DEA(DIF,M)= 2/(M+1)×DIF +[1-2/(M+1)]×DEA(REF(DIF,1),M)
752 | MACD(BAR)=2×(DIF-DEA)
753 | """
754 | _vmacd = pd.DataFrame()
755 | _vmacd['date'] = df.date
756 | _vmacd['diff'] = _ema(df.volume, qn) - _ema(df.volume, sn)
757 | _vmacd['dea'] = _ema(_vmacd['diff'], m) # TODO: 不能用_vmacd.diff, 不知道为什么
758 | _vmacd['vmacd'] = (_vmacd['diff'] - _vmacd['dea'])
759 | del _vmacd['diff'], _vmacd['dea']
760 | return _vmacd
761 |
762 |
763 | def vosc(df, n=12, m=26):
764 | """
765 | 成交量震荡 vosc(12,26)
766 | VOSC=(MA(VOLUME,SHORT)- MA(VOLUME,LONG))/MA(VOLUME,SHORT)×100
767 | """
768 | _c = pd.DataFrame()
769 | _c['date'] = df['date']
770 | _c['vosc'] = (_ma(df.volume, n) - _ma(df.volume, m)) / _ma(df.volume, n) * 100
771 | return _c
772 |
773 |
774 | def tapi(df, n=6):
775 | """
776 | 加权指数成交值 tapi(6)
777 | TAPI=每日成交总值/当日加权指数=a/PI;A表示每日的成交金额,PI表示当天的股价指数即指收盘价
778 | """
779 | _tapi = pd.DataFrame()
780 | _tapi['date'] = df.date
781 | _tapi['tapi'] = df.amount / df.close
782 | _tapi['matapi'] = _ma(_tapi.tapi, n)
783 | return _tapi
784 |
785 |
786 | def vstd(df, n=10):
787 | """
788 | 成交量标准差 vstd(10)
789 | VSTD=STD(Volume,N)=[∑(Volume-MA(Volume,N))^2/N]^0.5
790 | """
791 | _vstd = pd.DataFrame()
792 | _vstd['date'] = df.date
793 | _vstd['vstd'] = df.volume.rolling(n).std(ddof=1)
794 | return _vstd
795 |
796 |
797 | def adtm(df, n=23, m=8):
798 | """
799 | 动态买卖气指标 adtm(23,8)
800 | 如果开盘价≤昨日开盘价,DTM=0
801 | 如果开盘价>昨日开盘价,DTM=(最高价-开盘价)和(开盘价-昨日开盘价)的较大值
802 | 如果开盘价≥昨日开盘价,DBM=0
803 | 如果开盘价<昨日开盘价,DBM=(开盘价-最低价)
804 | STM=DTM在N日内的和
805 | SBM=DBM在N日内的和
806 | 如果STM > SBM,ADTM=(STM-SBM)/STM
807 | 如果STM < SBM , ADTM = (STM-SBM)/SBM
808 | 如果STM = SBM,ADTM=0
809 | ADTMMA=MA(ADTM,M)
810 | """
811 | _adtm = pd.DataFrame()
812 | _adtm['date'] = df.date
813 | _m = pd.DataFrame()
814 | _m['cc'] = df.open - df.open.shift(1)
815 | _m['ho'] = df.high - df.open
816 | _m['ol'] = df.open - df.low
817 | _m['dtm'] = _m.apply(lambda x: max(x.ho, x.cc) if x.cc > 0 else 0, axis=1)
818 | _m['dbm'] = _m.apply(lambda x: x.ol if x.cc < 0 else 0, axis=1)
819 | _m['stm'] = _m.dtm.rolling(n).sum()
820 | _m['sbm'] = _m.dbm.rolling(n).sum()
821 | _m['ss'] = _m.stm - _m.sbm
822 | _adtm['adtm'] = _m.apply(lambda x: x.ss / x.stm if x.ss > 0 else (x.ss / x.sbm if x.ss < 0 else 0), axis=1)
823 | _adtm['adtmma'] = _ma(_adtm.adtm, m)
824 | return _adtm
825 |
826 |
827 | def mi(df, n=12):
828 | """
829 | 动量指标 mi(12)
830 | A=CLOSE-REF(CLOSE,N)
831 | MI=SMA(A,N,1)
832 | """
833 | _mi = pd.DataFrame()
834 | _mi['date'] = df.date
835 | _mi['mi'] = sma(df.close - df.close.shift(n), n)
836 | return _mi
837 |
838 |
839 | def micd(df, n=3, m=10, k=20):
840 | """
841 | 异同离差动力指数 micd(3,10,20)
842 | MI=CLOSE-ref(CLOSE,1)AMI=SMA(MI,N1,1)
843 | DIF=MA(ref(AMI,1),N2)-MA(ref(AMI,1),N3)
844 | MICD=SMA(DIF,10,1)
845 | """
846 | _micd = pd.DataFrame()
847 | _micd['date'] = df.date
848 | mi = df.close - df.close.shift(1)
849 | ami = sma(mi, n)
850 | dif = _ma(ami.shift(1), m) - _ma(ami.shift(1), k)
851 | _micd['micd'] = sma(dif, m)
852 | return _micd
853 |
854 |
855 | def rc(df, n=50):
856 | """
857 | 变化率指数 rc(50)
858 | RC=收盘价/REF(收盘价,N)×100
859 | ARC=EMA(REF(RC,1),N,1)
860 | """
861 | _rc = pd.DataFrame()
862 | _rc['date'] = df.date
863 | _rc['rc'] = df.close / df.close.shift(n) * 100
864 | _rc['arc'] = sma(_rc.rc.shift(), n)
865 | return _rc
866 |
867 |
868 | def rccd(df, n=59, m=21, k=28):
869 | """ # TODO: 计算结果错误和同花顺不同,检查不出来为什么
870 | 异同离差变化率指数 rate of change convergence divergence rccd(59,21,28)
871 | RC=收盘价/REF(收盘价,N)×100%
872 | ARC=EMA(REF(RC,1),N,1)
873 | DIF=MA(ref(ARC,1),N1)-MA MA(ref(ARC,1),N2)
874 | RCCD=SMA(DIF,N,1)
875 | """
876 | _rccd = pd.DataFrame()
877 | _rccd['date'] = df.date
878 | rc = df.close / df.close.shift(n) * 100
879 | arc = sma(rc.shift(), n)
880 | dif = _ma(arc.shift(), m) - _ma(arc.shift(), k)
881 | _rccd['rccd'] = sma(dif, n)
882 | return _rccd
883 |
884 |
885 | def srmi(df, n=9):
886 | """
887 | SRMIMI修正指标 srmi(9)
888 | 如果收盘价>N日前的收盘价,SRMI就等于(收盘价-N日前的收盘价)/收盘价
889 | 如果收盘价 0 else (x.cs/x.cp if x.cs < 0 else 0), axis=1)
899 | return _srmi
900 |
901 |
902 | # def dptb(df, n=7):
903 | # """
904 | # 大盘同步指标 dptb(7)
905 | # DPTB=(统计N天中个股收盘价>开盘价,且指数收盘价>开盘价的天数或者个股收盘价<开盘价,且指数收盘价<开盘价)/N
906 | # """
907 | # ind = ts.get_k_data("sh000001", start=df.date.iloc[0], end=df.date.iloc[-1])
908 | # sd = df.copy()
909 | # sd.set_index('date', inplace=True) # 可能出现停盘等情况,所以将date设为index
910 | # ind.set_index('date', inplace=True)
911 | # _dptb = pd.DataFrame(index=df.date)
912 | # q = ind.close - ind.open
913 | # _dptb['p'] = sd.close - sd.open
914 | # _dptb['q'] = q
915 | # _dptb['m'] = _dptb.apply(lambda x: 1 if (x.p > 0 and x.q > 0) or (x.p < 0 and x.q < 0) else np.nan, axis=1)
916 | # _dptb['jdrs'] = _dptb.m.rolling(n).count() / n
917 | # _dptb.drop(columns=['p', 'q', 'm'], inplace=True)
918 | # _dptb.reset_index(inplace=True)
919 | # return _dptb
920 |
921 |
922 | # def jdqs(df, n=20):
923 | # """
924 | # 阶段强势指标 jdqs(20)
925 | # JDQS=(统计N天中个股收盘价>开盘价,且指数收盘价<开盘价的天数)/(统计N天中指数收盘价<开盘价的天数)
926 | # """
927 | # ind = ts.get_k_data("sh000001", start=df.date.iloc[0], end=df.date.iloc[-1])
928 | # sd = df.copy()
929 | # sd.set_index('date', inplace=True) # 可能出现停盘等情况,所以将date设为index
930 | # ind.set_index('date', inplace=True)
931 | # _jdrs = pd.DataFrame(index=df.date)
932 | # q = ind.close - ind.open
933 | # _jdrs['p'] = sd.close - sd.open
934 | # _jdrs['q'] = q
935 | # _jdrs['m'] = _jdrs.apply(lambda x: 1 if (x.p > 0 and x.q < 0) else np.nan, axis=1)
936 | # q[q > 0] = np.nan
937 | # _jdrs['t'] = q
938 | # _jdrs['jdrs'] = _jdrs.m.rolling(n).count() / _jdrs.t.rolling(n).count()
939 | # _jdrs.drop(columns=['p', 'q', 'm', 't'], inplace=True)
940 | # _jdrs.reset_index(inplace=True)
941 | # return _jdrs
942 |
943 |
944 | # def jdrs(df, n=20):
945 | # """
946 | # 阶段弱势指标 jdrs(20)
947 | # JDRS=(统计N天中个股收盘价<开盘价,且指数收盘价>开盘价的天数)/(统计N天中指数收盘价>开盘价的天数)
948 | # """
949 | # ind = ts.get_k_data("sh000001", start=df.date.iloc[0], end=df.date.iloc[-1])
950 | # sd = df.copy()
951 | # sd.set_index('date', inplace=True)
952 | # ind.set_index('date', inplace=True)
953 | # _jdrs = pd.DataFrame(index=df.date)
954 | # q = ind.close - ind.open
955 | # _jdrs['p'] = sd.close - sd.open
956 | # _jdrs['q'] = q
957 | # _jdrs['m'] = _jdrs.apply(lambda x: 1 if (x.p < 0 and x.q > 0) else np.nan, axis=1)
958 | # q[q < 0] = np.nan
959 | # _jdrs['t'] = q
960 | # _jdrs['jdrs'] = _jdrs.m.rolling(n).count() / _jdrs.t.rolling(n).count()
961 | # _jdrs.drop(columns=['p', 'q', 'm', 't'], inplace=True)
962 | # _jdrs.reset_index(inplace=True)
963 | # return _jdrs
964 |
965 |
966 | def zdzb(df, n=125, m=5, k=20):
967 | """
968 | 筑底指标 zdzb(125,5,20)
969 | A=(统计N1日内收盘价>=前收盘价的天数)/(统计N1日内收盘价<前收盘价的天数)
970 | B=MA(A,N2)
971 | D=MA(A,N3)
972 | """
973 | _zdzb = pd.DataFrame()
974 | _zdzb['date'] = df.date
975 | p = df.close - df.close.shift(1)
976 | q = p.copy()
977 | p[p < 0] = np.nan
978 | q[q >= 0] = np.nan
979 | _zdzb['zdzb_a'] = p.rolling(n).count() / q.rolling(n).count()
980 | _zdzb['zdzb_b'] = _zdzb.zdzb_a.rolling(m).mean()
981 | _zdzb['zdzb_d'] = _zdzb.zdzb_a.rolling(k).mean()
982 | return _zdzb
983 |
984 |
985 | def atr(df, n=14):
986 | """
987 | 真实波幅 atr(14)
988 | TR:MAX(MAX((HIGH-LOW),ABS(REF(CLOSE,1)-HIGH)),ABS(REF(CLOSE,1)-LOW))
989 | ATR:MA(TR,N)
990 | """
991 | _atr = pd.DataFrame()
992 | _atr['date'] = df.date
993 | # _atr['tr'] = np.maximum(df.high - df.low, (df.close.shift(1) - df.low).abs())
994 | # _atr['tr'] = np.maximum.reduce([df.high - df.low, (df.close.shift(1) - df.high).abs(), (df.close.shift(1) - df.low).abs()])
995 | _atr['tr'] = np.vstack([df.high - df.low, (df.close.shift(1) - df.high).abs(), (df.close.shift(1) - df.low).abs()]).max(axis=0)
996 | _atr['atr'] = _atr.tr.rolling(n).mean()
997 | return _atr
998 |
999 |
1000 | def mass(df, n=9, m=25):
1001 | """
1002 | 梅丝线 mass(9,25)
1003 | AHL=MA((H-L),N1)
1004 | BHL= MA(AHL,N1)
1005 | MASS=SUM(AHL/BHL,N2)
1006 | H:表示最高价;L:表示最低价
1007 | """
1008 | _mass = pd.DataFrame()
1009 | _mass['date'] = df.date
1010 | ahl = _ma((df.high - df.low), n)
1011 | bhl = _ma(ahl, n)
1012 | _mass['mass'] = (ahl / bhl).rolling(m).sum()
1013 | return _mass
1014 |
1015 |
1016 | def vhf(df, n=28):
1017 | """
1018 | 纵横指标 vhf(28)
1019 | VHF=(N日内最大收盘价与N日内最小收盘价之前的差)/(N日收盘价与前收盘价差的绝对值之和)
1020 | """
1021 | _vhf = pd.DataFrame()
1022 | _vhf['date'] = df.date
1023 | _vhf['vhf'] = (df.close.rolling(n).max() - df.close.rolling(n).min()) / (df.close - df.close.shift(1)).abs().rolling(n).sum()
1024 | return _vhf
1025 |
1026 |
1027 | def cvlt(df, n=10):
1028 | """
1029 | 佳庆离散指标 cvlt(10)
1030 | cvlt=(最高价与最低价的差的指数移动平均-前N日的最高价与最低价的差的指数移动平均)/前N日的最高价与最低价的差的指数移动平均
1031 | """
1032 | _cvlt = pd.DataFrame()
1033 | _cvlt['date'] = df.date
1034 | p = _ema(df.high.shift(n) - df.low.shift(n), n)
1035 | _cvlt['cvlt'] = (_ema(df.high - df.low, n) - p) / p * 100
1036 | return _cvlt
1037 |
1038 |
1039 | def up_n(df):
1040 | """
1041 | 连涨天数 up_n 连续上涨天数,当天收盘价大于开盘价即为上涨一天 # 同花顺实际结果用收盘价-前一天收盘价
1042 | """
1043 | _up = pd.DataFrame()
1044 | _up['date'] = df.date
1045 | p = df.close - df.close.shift()
1046 | p[p > 0] = 1
1047 | p[p < 0] = 0
1048 | m = []
1049 | for k, g in itertools.groupby(p):
1050 | t = 0
1051 | for i in g:
1052 | if k == 0:
1053 | m.append(0)
1054 | else:
1055 | t += 1
1056 | m.append(t)
1057 | # _up['p'] = p
1058 | _up['up'] = m
1059 | return _up
1060 |
1061 |
1062 | def down_n(df):
1063 | """
1064 | 连跌天数 down_n 连续下跌天数,当天收盘价小于开盘价即为下跌一天
1065 | """
1066 | _down = pd.DataFrame()
1067 | _down['date'] = df.date
1068 | p = df.close - df.close.shift()
1069 | p[p > 0] = 0
1070 | p[p < 0] = 1
1071 | m = []
1072 | for k, g in itertools.groupby(p):
1073 | t = 0
1074 | for i in g:
1075 | if k == 0:
1076 | m.append(0)
1077 | else:
1078 | t += 1
1079 | m.append(t)
1080 | _down['down'] = m
1081 | return _down
1082 |
1083 |
1084 | def elder(df, n=20):
1085 | """
1086 | 艾达透视因子 观察多控指标
1087 | A = H - EMA(C, N)
1088 | B = L - EMA(C, N)
1089 | Elder = (A-B)/C
1090 | """
1091 | _elder = pd.DataFrame()
1092 | _elder['date'] = df.date
1093 | a = df.high - _ema(df.close, n)
1094 | b = df.low - _ema(df.close, n)
1095 | _elder['elder'] = (a - b) / df.close
1096 | return _elder
1097 |
1098 |
1099 | """ --------------------------------------- 趋势性因子 -------------------------------------------"""
1100 |
1101 |
1102 | def acd(df, n=6):
1103 | """
1104 | 收集派发因子 n=6或20 累积/派发线(Accumulation/Distribution Line,A/D或AC)
1105 | ACD指标将市场分为两股收集(买入)及派发(估出)的力量
1106 | """
1107 | _acd = pd.DataFrame()
1108 | _acd['date'] = df.date
1109 | _m = pd.DataFrame()
1110 | _m['dif'] = df.close - df.close.shift()
1111 | _m['close'] = df.close
1112 | _m['low'] = np.minimum(df.low, df.low.shift())
1113 | _m['high'] = np.maximum(df.high, df.high.shift())
1114 | _m['cd'] = _m.apply(lambda x: x.close - x.low if x.dif > 0 else (x.close - x.high if x.dif < 0 else 0), axis=1)
1115 | _acd['acd'] = _m.cd.rolling(n).sum()
1116 | return _acd
1117 |
1118 |
1119 | def cop(df, n=11, m=14, h=10):
1120 | """
1121 | 估波指标(Coppock
1122 | Curve)又称“估波曲线”,通过计算月度价格的变化速率的加权平均值来测量市场的动量,属于长线指标。
1123 |
1124 | 估波指标由Edwin
1125 | Sedgwick
1126 | Coppock于1962年提出,主要用于判断牛市的到来。该指标只能产生买进讯号。依估波指标买进股票后,应另外寻求其他指标来辅助卖出讯号。
1127 | """
1128 | _cop = pd.DataFrame()
1129 | _cop['date'] = df.date
1130 | rc = (df.close - df.close.shift(n)) / df.close.shift(n) * 100 + (df.close - df.close.shift(m)) / df.close.shift(m) * 100
1131 | _cop['cop'] = _ema(rc, h)
1132 | return _cop
1133 |
1134 |
1135 | def join_frame(d1, d2, column='date'):
1136 | # 将两个DataFrame 按照datetime合并
1137 | return d1.join(d2.set_index(column), on=column)
1138 |
1139 |
1140 | # if __name__ == "__main__":
1141 | # import tushare as ts
1142 | # data = ts.get_k_data("000063", start="2017-05-01")
1143 | # data = ts.get_k_data("002264", start="2017-05-01")
1144 | # 使用tushare数据api
1145 | # apikey = ''
1146 | # if os.path.exists('tushare_apikey.txt'):
1147 | # with open('tushare_apikey.txt', 'r') as f:
1148 | # apikey = f.read()
1149 | # pro = ts.pro_api(apikey)
1150 | # data = pro.daily(ts_code='000001.SZ', start_date='20211101', end_date='20211128')
1151 | # data.rename(columns={'trade_date': 'date'}, inplace=True)
1152 | # print(data)
1153 | # maf = ma(data, n=10)
1154 | # 将均线合并到data中
1155 | # print(join_frame(data, maf))
1156 |
1157 | # data = pd.DataFrame({"close": [1,2,3,4,5,6,7,8,9,0]})
1158 | # print(ma(data))
1159 | # mdf = md(data)
1160 | # print(md(data, n=26))
1161 | # print(join_frame(data, mdf))
1162 | # emaf = ema(data)
1163 | # print(ema(data, 5))
1164 | # print(join_frame(data, emaf))
1165 | # print(dma(data))
1166 | # print(dmi(data))
1167 | # print(macd(data))
1168 | # print(kdj(data))
1169 | # print(vrsi(data, 6))
1170 | # print(boll(data))
1171 | # print(bbiboll(data))
1172 | # print(wr(data))
1173 | # print(bias(data))
1174 | # print(rsi(data))
1175 | # print(asi(data))
1176 | # print(vr_rate(data))
1177 | # print(vr(data))
1178 | # print(arbr(data))
1179 | # print(dpo(data))
1180 | # print(trix(data))
1181 | # print(bbi(data))
1182 | # print(ts.top_list(date="2019-01-17"))
1183 | # print(mtm(data))
1184 | # print(obv(data))
1185 | # print(cci(data))
1186 | # print(priceosc(data))
1187 | # print(dbcd(data))
1188 | # print(roc(data))
1189 | # print(vroc(data))
1190 | # print(cr(data))
1191 | # print(psy(data))
1192 | # print(wad(data))
1193 | # print(mfi(data))
1194 | # print(pvt(data))
1195 | # print(wvad(data))
1196 | # print(cdp(data))
1197 | # print(env(data))
1198 | # print(mike(data))
1199 | # print(vr(data))
1200 | # print(vma(data))
1201 | # print(vmacd(data))
1202 | # print(vosc(data))
1203 | # print(tapi(data))
1204 | # print(vstd(data))
1205 | # print(adtm(data))
1206 | # print(mi(data))
1207 | # print(micd(data))
1208 | # print(rc(data))
1209 | # print(rccd(data))
1210 | # print(srmi(data))
1211 | # print(dptb(data))
1212 | # print(jdqs(data))
1213 | # pd.set_option('display.max_rows', 1000)
1214 | # print(jdrs(data))
1215 | # print(join_frame(data, jdrs(data)))
1216 | # print(data)
1217 | # print(zdzb(data))
1218 | # print(atr(data))
1219 | # print(mass(data))
1220 | # print(vhf(data))
1221 | # print(cvlt(data))
1222 | # print(up_n(data))
1223 | # print(down_n(data))
1224 | # --------------------------------- 以下函数没有同花顺验证,慎重使用 --------------------------------
1225 | # print(elder(data))
1226 | # print(acd(data))
1227 | # print(cop(data))
1228 | # print(tema(data, n=20))
1229 | # print(stochrsi(data))
1230 | # print(rsi(data))
1231 |
--------------------------------------------------------------------------------
/data/stocks/sh.000300.csv:
--------------------------------------------------------------------------------
1 | ,date,code,open,high,low,close,preclose,volume,amount,pctChg
2 | 0,2019-01-02,sh.000300,3017.0670,3018.7750,2958.4880,2969.5350,3010.6530,6866302208,76105572352.0000,-1.365800
3 | 1,2019-01-03,sh.000300,2963.0180,3000.4410,2953.2540,2964.8420,2969.5350,7086710272,76664799232.0000,-0.158000
4 | 2,2019-01-04,sh.000300,2940.1910,3036.8140,2935.8290,3035.8740,2964.8420,10331897088,107141038080.0000,2.395800
5 | 3,2019-01-07,sh.000300,3055.1530,3061.7490,3035.9120,3054.3030,3035.8740,10116435968,105703940096.0000,0.607000
6 | 4,2019-01-08,sh.000300,3049.8740,3055.5100,3038.5330,3047.7030,3054.3030,8617058560,79628881920.0000,-0.216100
7 | 5,2019-01-09,sh.000300,3065.2300,3117.9610,3062.8470,3078.4750,3047.7030,10736434944,117129678848.0000,1.009700
8 | 6,2019-01-10,sh.000300,3077.4810,3092.5410,3062.5720,3072.6860,3078.4750,8527175680,90206871552.0000,-0.188000
9 | 7,2019-01-11,sh.000300,3082.2610,3102.8330,3071.0260,3094.7780,3072.6860,7178642432,77420240896.0000,0.719000
10 | 8,2019-01-14,sh.000300,3092.4980,3097.4060,3064.3820,3067.7840,3094.7780,6612170240,68115969024.0000,-0.872200
11 | 9,2019-01-15,sh.000300,3071.5180,3129.3700,3064.6700,3127.9900,3067.7840,8877296128,99976892416.0000,1.962500
12 | 10,2019-01-16,sh.000300,3126.1340,3135.0110,3117.2920,3128.6510,3127.9900,8021434112,85781590016.0000,0.021100
13 | 11,2019-01-17,sh.000300,3132.6280,3141.7090,3110.0600,3111.4160,3128.6510,8017487104,82888208384.0000,-0.550900
14 | 12,2019-01-18,sh.000300,3124.5020,3171.6860,3120.3450,3168.1730,3111.4160,10396383488,106780659712.0000,1.824200
15 | 13,2019-01-21,sh.000300,3170.8770,3199.2130,3170.8770,3185.6360,3168.1730,9391502336,105536987136.0000,0.551200
16 | 14,2019-01-22,sh.000300,3181.9490,3181.9490,3135.3370,3143.3170,3185.6360,7299052800,78150877184.0000,-1.328400
17 | 15,2019-01-23,sh.000300,3136.0960,3157.6260,3131.8670,3141.0530,3143.3170,5987047936,62669651968.0000,-0.072000
18 | 16,2019-01-24,sh.000300,3146.6040,3165.6290,3125.3000,3158.7810,3141.0530,7293463552,80963878912.0000,0.564400
19 | 17,2019-01-25,sh.000300,3165.1810,3203.1740,3164.4080,3184.4690,3158.7810,8396772864,93207953408.0000,0.813200
20 | 18,2019-01-28,sh.000300,3203.1180,3228.8670,3174.7240,3183.7770,3184.4690,8262243072,97371496448.0000,-0.021700
21 | 19,2019-01-29,sh.000300,3177.2610,3200.9890,3148.2340,3193.9690,3183.7770,7765833472,85943910400.0000,0.320100
22 | 20,2019-01-30,sh.000300,3181.6550,3202.8960,3167.8930,3168.4820,3193.9690,6374651648,73005121536.0000,-0.798000
23 | 21,2019-01-31,sh.000300,3182.6980,3216.0670,3178.0100,3201.6330,3168.4820,8624783872,97509924864.0000,1.046300
24 | 22,2019-02-01,sh.000300,3225.7330,3247.4950,3207.7160,3247.3970,3201.6330,8201964032,94766411776.0000,1.429400
25 | 23,2019-02-11,sh.000300,3239.8070,3307.0630,3239.8070,3306.4720,3247.3970,9881843456,114752356352.0000,1.819100
26 | 24,2019-02-12,sh.000300,3306.3520,3335.3600,3298.6330,3330.3350,3306.4720,12223246336,122834100224.0000,0.721700
27 | 25,2019-02-13,sh.000300,3337.7790,3405.5770,3329.1430,3397.0270,3330.3350,16382833152,168866263040.0000,2.002600
28 | 26,2019-02-14,sh.000300,3392.8540,3415.3990,3381.9820,3402.1400,3397.0270,15112729088,138649288704.0000,0.150500
29 | 27,2019-02-15,sh.000300,3391.2420,3395.0290,3335.8700,3338.7040,3402.1400,14366860288,141555060736.0000,-1.864600
30 | 28,2019-02-18,sh.000300,3366.4230,3445.7440,3366.4230,3445.7440,3338.7040,18288609024,180449742848.0000,3.206000
31 | 29,2019-02-19,sh.000300,3454.7210,3480.7930,3419.0730,3439.6070,3445.7440,17908378624,185762746368.0000,-0.178100
32 | 30,2019-02-20,sh.000300,3449.9320,3463.7730,3421.5050,3451.9270,3439.6070,14739031040,145570263040.0000,0.358200
33 | 31,2019-02-21,sh.000300,3450.1410,3500.2510,3431.6310,3442.7050,3451.9270,18014328832,185197154304.0000,-0.267200
34 | 32,2019-02-22,sh.000300,3439.3780,3520.1180,3417.9780,3520.1180,3442.7050,18723797504,202869288960.0000,2.248600
35 | 33,2019-02-25,sh.000300,3575.8520,3729.4830,3574.6880,3729.4830,3520.1180,34255712256,376382394368.0000,5.947700
36 | 34,2019-02-26,sh.000300,3734.7050,3762.1120,3679.2700,3684.6930,3729.4830,35803869696,387632861184.0000,-1.201000
37 | 35,2019-02-27,sh.000300,3682.8110,3737.6310,3638.3330,3678.3920,3684.6930,28623600640,307306147840.0000,-0.171000
38 | 36,2019-02-28,sh.000300,3675.2640,3695.4640,3650.0530,3669.3700,3678.3920,18481021952,206010957824.0000,-0.245300
39 | 37,2019-03-01,sh.000300,3699.2150,3749.7140,3668.7650,3749.7140,3669.3700,20471100416,235620622336.0000,2.189600
40 | 38,2019-03-04,sh.000300,3783.0360,3886.5790,3764.7760,3794.1040,3749.7140,32349012736,376397283328.0000,1.183800
41 | 39,2019-03-05,sh.000300,3785.3760,3816.1620,3770.7850,3816.0130,3794.1040,23085316608,261464121344.0000,0.577400
42 | 40,2019-03-06,sh.000300,3822.8580,3855.1550,3787.5220,3848.0900,3816.0130,31807737088,331155615744.0000,0.840600
43 | 41,2019-03-07,sh.000300,3841.1450,3845.1820,3778.8000,3808.8490,3848.0900,32984654848,359339151360.0000,-1.019800
44 | 42,2019-03-08,sh.000300,3721.4010,3774.5430,3656.1910,3657.5790,3808.8490,31799007744,349296693248.0000,-3.971500
45 | 43,2019-03-11,sh.000300,3663.9770,3731.9090,3650.8120,3729.9540,3657.5790,23091286528,268718460928.0000,1.978800
46 | 44,2019-03-12,sh.000300,3758.3150,3804.7200,3723.6780,3755.3510,3729.9540,27492638208,325180620800.0000,0.680900
47 | 45,2019-03-13,sh.000300,3758.7130,3763.0920,3708.8140,3724.1940,3755.3510,23368224768,286171049984.0000,-0.829700
48 | 46,2019-03-14,sh.000300,3710.2930,3747.8190,3673.8500,3698.4850,3724.1940,19081723648,231820148736.0000,-0.690300
49 | 47,2019-03-15,sh.000300,3713.9360,3782.2360,3713.9360,3745.0050,3698.4850,17517454336,224194363392.0000,1.257800
50 | 48,2019-03-18,sh.000300,3753.6430,3851.7470,3733.6780,3851.7470,3745.0050,21692805888,276473450496.0000,2.850300
51 | 49,2019-03-19,sh.000300,3856.5880,3868.3350,3815.2180,3833.9620,3851.7470,18172710912,224096890880.0000,-0.461700
52 | 50,2019-03-20,sh.000300,3825.3350,3855.1460,3790.5110,3835.4390,3833.9620,17563208960,215406993408.0000,0.038500
53 | 51,2019-03-21,sh.000300,3840.2780,3864.0690,3823.4660,3836.8910,3835.4390,19631031040,231993446400.0000,0.037900
54 | 52,2019-03-22,sh.000300,3838.1250,3845.5800,3786.5910,3833.8010,3836.8910,17135699200,198518386688.0000,-0.080500
55 | 53,2019-03-25,sh.000300,3776.4420,3807.1790,3741.6060,3742.8250,3833.8010,19858632960,223396564992.0000,-2.373000
56 | 54,2019-03-26,sh.000300,3766.5280,3770.8430,3687.5470,3700.4380,3742.8250,17304657920,196547809280.0000,-1.132500
57 | 55,2019-03-27,sh.000300,3724.4050,3750.2640,3703.4500,3743.3870,3700.4380,13875845376,177507528704.0000,1.160600
58 | 56,2019-03-28,sh.000300,3731.0610,3755.7160,3710.0810,3728.3950,3743.3870,13327212800,172604391424.0000,-0.400500
59 | 57,2019-03-29,sh.000300,3739.7730,3876.3790,3739.7730,3872.3410,3728.3950,21563910400,283022299136.0000,3.860800
60 | 58,2019-04-01,sh.000300,3901.1690,3982.9090,3901.1690,3973.9280,3872.3410,27138270464,340799401984.0000,2.623400
61 | 59,2019-04-02,sh.000300,3986.3440,3988.0970,3956.5050,3971.2850,3973.9280,22600034048,281892057088.0000,-0.066500
62 | 60,2019-04-03,sh.000300,3947.8690,4026.4970,3939.7830,4022.1560,3971.2850,23191736832,284826497024.0000,1.281000
63 | 61,2019-04-04,sh.000300,4039.7410,4072.1130,4021.7050,4062.2300,4022.1560,26041093888,313539432448.0000,0.996300
64 | 62,2019-04-08,sh.000300,4097.1020,4122.6030,4017.4880,4057.2280,4062.2300,26750557696,324670451712.0000,-0.123100
65 | 63,2019-04-09,sh.000300,4063.8130,4084.2430,4038.2820,4075.4300,4057.2280,18295680768,243187912704.0000,0.448600
66 | 64,2019-04-10,sh.000300,4062.4420,4115.3780,4035.4740,4085.8470,4075.4300,19468761344,278282027008.0000,0.255600
67 | 65,2019-04-11,sh.000300,4083.4610,4097.1240,3990.2390,3997.5770,4085.8470,16904964096,236259155968.0000,-2.160400
68 | 66,2019-04-12,sh.000300,3986.7820,4006.9330,3961.4640,3988.6160,3997.5770,13586211840,178795937792.0000,-0.224200
69 | 67,2019-04-15,sh.000300,4056.4910,4085.3880,3974.2260,3975.5240,3988.6160,18264557056,236298723328.0000,-0.328200
70 | 68,2019-04-16,sh.000300,3958.0960,4085.7890,3943.4870,4085.7890,3975.5240,20204196608,250569207808.0000,2.773600
71 | 69,2019-04-17,sh.000300,4080.7170,4106.6150,4057.5030,4087.2390,4085.7890,18036711680,228824428544.0000,0.035500
72 | 70,2019-04-18,sh.000300,4085.1140,4094.0530,4056.2350,4072.0750,4087.2390,14656212224,187812687872.0000,-0.371000
73 | 71,2019-04-19,sh.000300,4076.2950,4120.6350,4046.2040,4120.6070,4072.0750,15079491072,194701692928.0000,1.191800
74 | 72,2019-04-22,sh.000300,4125.9710,4126.0900,4015.4740,4025.6100,4120.6070,18935374592,244380549120.0000,-2.305400
75 | 73,2019-04-23,sh.000300,4021.6270,4061.0850,4005.2830,4019.0050,4025.6100,15561165056,204121505792.0000,-0.164100
76 | 74,2019-04-24,sh.000300,4033.6290,4044.3370,3967.8050,4030.0880,4019.0050,14549869568,186497961984.0000,0.275800
77 | 75,2019-04-25,sh.000300,4013.6020,4022.5630,3938.3250,3941.8160,4030.0880,15972207104,197530996736.0000,-2.190300
78 | 76,2019-04-26,sh.000300,3921.8900,3943.8330,3887.2520,3889.2740,3941.8160,14200806912,186572136448.0000,-1.332900
79 | 77,2019-04-29,sh.000300,3896.5820,3953.2280,3875.4520,3900.3330,3889.2740,15387092736,203946553344.0000,0.284300
80 | 78,2019-04-30,sh.000300,3887.1790,3923.1080,3885.1470,3913.2110,3900.3330,11623337728,161665925120.0000,0.330200
81 | 79,2019-05-06,sh.000300,3775.0760,3791.6110,3647.1400,3684.6160,3913.2110,19747288320,254115401728.0000,-5.841600
82 | 80,2019-05-07,sh.000300,3702.2650,3738.1760,3671.8340,3720.6680,3684.6160,13284765440,183659159552.0000,0.978400
83 | 81,2019-05-08,sh.000300,3648.5480,3722.9320,3642.4980,3667.4570,3720.6680,11286735616,145058488320.0000,-1.430100
84 | 82,2019-05-09,sh.000300,3637.3460,3656.8960,3584.8220,3599.7000,3667.4570,10103739392,141829095424.0000,-1.847500
85 | 83,2019-05-10,sh.000300,3643.0550,3732.9230,3589.2900,3730.4510,3599.7000,14800384768,195067170816.0000,3.632300
86 | 84,2019-05-13,sh.000300,3675.7590,3702.9010,3658.0000,3668.7250,3730.4510,10339185920,135053926400.0000,-1.654600
87 | 85,2019-05-14,sh.000300,3630.4380,3683.2610,3630.4380,3645.1500,3668.7250,10231345920,135262867456.0000,-0.642600
88 | 86,2019-05-15,sh.000300,3674.9930,3741.0400,3674.9930,3727.0920,3645.1500,11016176896,152534548480.0000,2.248000
89 | 87,2019-05-16,sh.000300,3720.0390,3745.1400,3707.9030,3743.9630,3727.0920,11625827328,139851939840.0000,0.452700
90 | 88,2019-05-17,sh.000300,3744.8750,3745.3550,3637.5820,3648.7600,3743.9630,12845324544,154092351488.0000,-2.542800
91 | 89,2019-05-20,sh.000300,3635.7350,3644.5000,3583.8320,3617.7920,3648.7600,10896347648,134194262016.0000,-0.848700
92 | 90,2019-05-21,sh.000300,3619.4360,3690.0880,3610.6810,3666.7760,3617.7920,11102291968,133071380480.0000,1.354000
93 | 91,2019-05-22,sh.000300,3663.1530,3679.2720,3634.7470,3649.3790,3666.7760,9834612736,121775243264.0000,-0.474400
94 | 92,2019-05-23,sh.000300,3629.5280,3631.4740,3578.1120,3583.9640,3649.3790,9989778176,125611970560.0000,-1.792500
95 | 93,2019-05-24,sh.000300,3584.9010,3623.3900,3580.7850,3593.9130,3583.9640,8093404928,101337497600.0000,0.277600
96 | 94,2019-05-27,sh.000300,3592.6020,3648.0260,3556.2560,3637.1970,3593.9130,10883087104,133399052288.0000,1.204400
97 | 95,2019-05-28,sh.000300,3633.0180,3683.2300,3627.7870,3672.2600,3637.1970,11788624128,148966334464.0000,0.964000
98 | 96,2019-05-29,sh.000300,3642.5410,3693.2270,3637.3480,3663.9090,3672.2600,9335544064,120002035712.0000,-0.227400
99 | 97,2019-05-30,sh.000300,3648.8490,3650.9710,3612.6240,3641.1830,3663.9090,9420256000,112864079872.0000,-0.620300
100 | 98,2019-05-31,sh.000300,3640.9960,3668.1790,3627.5440,3629.7890,3641.1830,8922226688,108264202240.0000,-0.312900
101 | 99,2019-06-03,sh.000300,3640.6120,3672.8130,3613.1270,3632.0120,3629.7890,10072317952,123902447616.0000,0.061200
102 | 100,2019-06-04,sh.000300,3632.5600,3636.1280,3584.4610,3598.4660,3632.0120,8709709312,109467238400.0000,-0.923600
103 | 101,2019-06-05,sh.000300,3627.7940,3634.4530,3593.9510,3597.1050,3598.4660,8864201984,114634227712.0000,-0.037800
104 | 102,2019-06-06,sh.000300,3601.0350,3601.0350,3557.0160,3564.6770,3597.1050,8553440256,104367267840.0000,-0.901500
105 | 103,2019-06-10,sh.000300,3578.0080,3623.7300,3568.2780,3610.7430,3564.6770,9237506048,117346607104.0000,1.292300
106 | 104,2019-06-11,sh.000300,3617.5230,3723.1410,3617.5230,3719.2750,3610.7430,14348280576,180899074048.0000,3.005800
107 | 105,2019-06-12,sh.000300,3706.8630,3711.8790,3683.9390,3691.0950,3719.2750,11917885184,132296097792.0000,-0.757700
108 | 106,2019-06-13,sh.000300,3689.5830,3697.5910,3654.2740,3685.3930,3691.0950,9633171712,110459904000.0000,-0.154500
109 | 107,2019-06-14,sh.000300,3690.4760,3709.6520,3650.9090,3654.8790,3685.3930,10181700352,116584259584.0000,-0.828000
110 | 108,2019-06-17,sh.000300,3654.4430,3683.7740,3645.4980,3654.8240,3654.8790,7297667840,93092581376.0000,-0.001500
111 | 109,2019-06-18,sh.000300,3661.1290,3675.6450,3638.7800,3667.6180,3654.8240,7069226496,89472839680.0000,0.350100
112 | 110,2019-06-19,sh.000300,3761.3380,3771.3470,3715.1330,3715.9380,3667.6180,12559571456,172574179328.0000,1.317500
113 | 111,2019-06-20,sh.000300,3718.9410,3845.7910,3717.1850,3828.5180,3715.9380,16887207424,227726983168.0000,3.029700
114 | 112,2019-06-21,sh.000300,3832.7320,3856.0850,3817.3060,3833.9380,3828.5180,15363515392,199961616384.0000,0.141600
115 | 113,2019-06-24,sh.000300,3836.3050,3853.5450,3819.7690,3841.2650,3833.9380,10008462080,143644733440.0000,0.191100
116 | 114,2019-06-25,sh.000300,3837.4250,3838.0570,3755.0090,3801.3090,3841.2650,12407591168,169358794752.0000,-1.040200
117 | 115,2019-06-26,sh.000300,3779.5120,3809.7580,3771.7160,3794.3310,3801.3090,8182028288,112106860544.0000,-0.183600
118 | 116,2019-06-27,sh.000300,3807.5370,3854.0800,3805.8320,3834.8170,3794.3310,10531635712,156483420160.0000,1.067000
119 | 117,2019-06-28,sh.000300,3832.0590,3835.2320,3803.0540,3825.5870,3834.8170,8476613888,116512051200.0000,-0.240700
120 | 118,2019-07-01,sh.000300,3899.3310,3936.6680,3886.9090,3935.8110,3825.5870,15837033984,217470251008.0000,2.881200
121 | 119,2019-07-02,sh.000300,3931.0480,3942.4250,3918.9370,3937.1690,3935.8110,13186349568,173997043712.0000,0.034500
122 | 120,2019-07-03,sh.000300,3927.4360,3927.4360,3878.8400,3893.5340,3937.1690,11199260416,163145732096.0000,-1.108300
123 | 121,2019-07-04,sh.000300,3895.1970,3906.8890,3854.6930,3873.1010,3893.5340,9934225664,142669254656.0000,-0.524800
124 | 122,2019-07-05,sh.000300,3875.3730,3900.3090,3857.9280,3893.2020,3873.1010,7400652800,116236521472.0000,0.519000
125 | 123,2019-07-08,sh.000300,3875.7540,3875.7540,3775.0250,3802.7890,3893.2020,10953908736,147198418944.0000,-2.322300
126 | 124,2019-07-09,sh.000300,3798.0950,3811.0990,3774.7640,3793.1290,3802.7890,7484273152,113147604992.0000,-0.254000
127 | 125,2019-07-10,sh.000300,3807.9490,3810.3960,3774.2300,3786.7390,3793.1290,7283394816,101355479040.0000,-0.168500
128 | 126,2019-07-11,sh.000300,3806.1850,3830.7380,3774.4130,3785.2210,3786.7390,7531196416,113674616832.0000,-0.040100
129 | 127,2019-07-12,sh.000300,3783.0730,3820.2350,3774.5220,3808.7310,3785.2210,7546596608,107007922176.0000,0.621100
130 | 128,2019-07-15,sh.000300,3792.6400,3844.8680,3745.8540,3824.1870,3808.7310,10120522240,142493044736.0000,0.405800
131 | 129,2019-07-16,sh.000300,3819.2470,3828.3250,3799.8660,3806.8440,3824.1870,8073095168,108449681408.0000,-0.453500
132 | 130,2019-07-17,sh.000300,3800.1060,3820.2710,3787.8970,3804.6380,3806.8440,9518388480,116766781440.0000,-0.057900
133 | 131,2019-07-18,sh.000300,3793.1890,3793.3910,3767.9950,3768.4010,3804.6380,8749644544,111669366784.0000,-0.952400
134 | 132,2019-07-19,sh.000300,3787.5070,3828.1510,3787.5070,3807.9550,3768.4010,8808614912,117797527552.0000,1.049600
135 | 133,2019-07-22,sh.000300,3813.5020,3816.5380,3765.4420,3781.6830,3807.9550,9210137600,117810446336.0000,-0.689900
136 | 134,2019-07-23,sh.000300,3783.5410,3792.9640,3768.7610,3789.9130,3781.6830,7131334656,103866609664.0000,0.217600
137 | 135,2019-07-24,sh.000300,3803.5860,3840.0570,3803.5730,3819.8320,3789.9130,9094068480,129940586496.0000,0.789400
138 | 136,2019-07-25,sh.000300,3821.3890,3851.0660,3812.9530,3851.0660,3819.8320,9374041600,125899501568.0000,0.817700
139 | 137,2019-07-26,sh.000300,3835.2280,3863.5870,3832.5220,3858.5680,3851.0660,8325929984,110929727488.0000,0.194800
140 | 138,2019-07-29,sh.000300,3857.9390,3862.7460,3842.4260,3854.2700,3858.5680,8481436928,111679107072.0000,-0.111400
141 | 139,2019-07-30,sh.000300,3861.5690,3890.7290,3861.5690,3870.3170,3854.2700,9412395520,120480280576.0000,0.416300
142 | 140,2019-07-31,sh.000300,3856.7450,3856.7450,3830.0910,3835.3580,3870.3170,8215115520,111083892736.0000,-0.903300
143 | 141,2019-08-01,sh.000300,3819.3240,3831.2640,3791.5460,3803.4690,3835.3580,8411418112,117649162240.0000,-0.831400
144 | 142,2019-08-02,sh.000300,3729.1300,3754.5320,3720.0580,3747.4370,3803.4690,10833589760,141874786304.0000,-1.473200
145 | 143,2019-08-05,sh.000300,3724.4090,3739.5030,3675.6880,3675.6880,3747.4370,10132598016,133061099520.0000,-1.914600
146 | 144,2019-08-06,sh.000300,3609.1110,3649.8950,3575.8620,3636.3280,3675.6880,12983387136,167267479552.0000,-1.070800
147 | 145,2019-08-07,sh.000300,3654.6320,3659.0770,3621.4310,3621.4310,3636.3280,8423871488,108667666432.0000,-0.409700
148 | 146,2019-08-08,sh.000300,3651.3570,3675.4600,3646.9380,3669.2930,3621.4310,8845770752,114981617664.0000,1.321600
149 | 147,2019-08-09,sh.000300,3686.7490,3689.1770,3628.1160,3633.5290,3669.2930,8529558016,116355690496.0000,-0.974700
150 | 148,2019-08-12,sh.000300,3647.8660,3699.1040,3643.3160,3699.1040,3633.5290,8208305664,121129345024.0000,1.804700
151 | 149,2019-08-13,sh.000300,3675.5860,3686.4300,3658.0120,3665.7510,3699.1040,7650030336,103764320256.0000,-0.901700
152 | 150,2019-08-14,sh.000300,3712.0650,3717.5570,3680.6080,3682.4010,3665.7510,9120259072,128301670400.0000,0.454200
153 | 151,2019-08-15,sh.000300,3618.0090,3694.2980,3612.1100,3694.0000,3682.4010,8859883264,119241080832.0000,0.315000
154 | 152,2019-08-16,sh.000300,3697.9400,3738.0960,3687.0750,3710.5380,3694.0000,8831916800,132696911872.0000,0.447700
155 | 153,2019-08-19,sh.000300,3736.0340,3791.0940,3720.6890,3791.0940,3710.5380,13932701184,195448938496.0000,2.171000
156 | 154,2019-08-20,sh.000300,3786.0260,3799.8970,3778.7300,3787.7320,3791.0940,10860208896,149115342848.0000,-0.088700
157 | 155,2019-08-21,sh.000300,3778.3090,3792.5950,3775.4470,3781.7570,3787.7320,8229988096,121688506368.0000,-0.157700
158 | 156,2019-08-22,sh.000300,3793.8550,3797.3290,3771.2040,3793.5060,3781.7570,8580779264,120708136960.0000,0.310700
159 | 157,2019-08-23,sh.000300,3796.8820,3829.3600,3788.0340,3820.8630,3793.5060,8795458304,137802153984.0000,0.721200
160 | 158,2019-08-26,sh.000300,3756.3610,3778.8660,3753.1640,3765.9100,3820.8630,9385926912,142350987264.0000,-1.438200
161 | 159,2019-08-27,sh.000300,3791.4580,3848.2350,3790.8730,3816.9450,3765.9100,12473147904,181748785152.0000,1.355200
162 | 160,2019-08-28,sh.000300,3818.8120,3822.5880,3790.1380,3802.5840,3816.9450,8875081216,137667276800.0000,-0.376200
163 | 161,2019-08-29,sh.000300,3805.4940,3808.5950,3774.3960,3790.1860,3802.5840,8408338688,126475677696.0000,-0.326000
164 | 162,2019-08-30,sh.000300,3816.6780,3828.9690,3778.9180,3799.5860,3790.1860,9669515008,152408670208.0000,0.248000
165 | 163,2019-09-02,sh.000300,3803.6890,3855.7760,3799.8160,3848.3190,3799.5860,11028934912,164994457600.0000,1.282600
166 | 164,2019-09-03,sh.000300,3852.5790,3856.6810,3833.7570,3853.6100,3848.3190,9771463168,146270633984.0000,0.137500
167 | 165,2019-09-04,sh.000300,3848.6480,3886.0010,3846.4210,3886.0010,3853.6100,12662861568,176839745536.0000,0.840500
168 | 166,2019-09-05,sh.000300,3909.2080,3970.0030,3909.2080,3925.3230,3886.0010,18165623040,244681224192.0000,1.011900
169 | 167,2019-09-06,sh.000300,3946.6850,3948.5390,3922.3360,3948.5070,3925.3230,12188237568,181718269952.0000,0.590600
170 | 168,2019-09-09,sh.000300,3980.9570,3985.2390,3954.8750,3972.9480,3948.5070,14680975360,209545388032.0000,0.619000
171 | 169,2019-09-10,sh.000300,3976.8690,3976.9220,3938.7440,3959.2650,3972.9480,13088938496,184494350336.0000,-0.344400
172 | 170,2019-09-11,sh.000300,3969.6750,3971.2230,3922.9530,3930.0990,3959.2650,13159487488,190165008384.0000,-0.736600
173 | 171,2019-09-12,sh.000300,3944.6910,3975.9310,3933.4360,3972.3790,3930.0990,11024127232,156750651392.0000,1.075800
174 | 172,2019-09-16,sh.000300,3981.3610,3982.2040,3943.3730,3957.7150,3972.3790,11025980416,154736553984.0000,-0.369100
175 | 173,2019-09-17,sh.000300,3947.1570,3947.1570,3879.4850,3891.2200,3957.7150,11369431808,154899300352.0000,-1.680100
176 | 174,2019-09-18,sh.000300,3902.9940,3923.1460,3902.5100,3910.0830,3891.2200,8205615104,130159558656.0000,0.484800
177 | 175,2019-09-19,sh.000300,3923.9630,3924.3820,3897.0660,3924.3820,3910.0830,8598423808,127421792256.0000,0.365700
178 | 176,2019-09-20,sh.000300,3933.4590,3942.2240,3921.4120,3935.6510,3924.3820,10345595392,153162588160.0000,0.287100
179 | 177,2019-09-23,sh.000300,3925.1850,3925.1850,3868.2140,3890.6610,3935.6510,9403622400,139223506944.0000,-1.143100
180 | 178,2019-09-24,sh.000300,3895.8660,3927.0110,3886.1400,3901.0750,3890.6610,8778322944,142341398528.0000,0.267700
181 | 179,2019-09-25,sh.000300,3887.5540,3889.8390,3867.2270,3870.9830,3901.0750,8952083456,133224464384.0000,-0.771400
182 | 180,2019-09-26,sh.000300,3884.7020,3890.7450,3840.2470,3841.1380,3870.9830,10269830144,150806749184.0000,-0.771000
183 | 181,2019-09-27,sh.000300,3843.4580,3859.5000,3832.2460,3852.6530,3841.1380,7400394752,109130485760.0000,0.299800
184 | 182,2019-09-30,sh.000300,3842.0740,3857.2310,3813.5490,3814.5280,3852.6530,6593131264,100487270400.0000,-0.989600
185 | 183,2019-10-08,sh.000300,3818.5890,3861.6420,3818.5890,3837.6790,3814.5280,7665786112,118365683712.0000,0.606900
186 | 184,2019-10-09,sh.000300,3822.6060,3845.3400,3805.0670,3843.2390,3837.6790,7585451264,112406208512.0000,0.144900
187 | 185,2019-10-10,sh.000300,3838.4860,3877.1420,3829.4320,3874.6390,3843.2390,7922269440,127474044928.0000,0.817000
188 | 186,2019-10-11,sh.000300,3885.5190,3922.3690,3868.8410,3911.7250,3874.6390,9341257728,139817299968.0000,0.957200
189 | 187,2019-10-14,sh.000300,3944.8590,3983.8110,3934.7320,3953.2410,3911.7250,12239361024,167857131520.0000,1.061300
190 | 188,2019-10-15,sh.000300,3953.1640,3953.1640,3928.1510,3936.2490,3953.2410,8527394816,125117108224.0000,-0.429800
191 | 189,2019-10-16,sh.000300,3939.2760,3964.0450,3919.0160,3922.6850,3936.2490,8322970624,128558534656.0000,-0.344600
192 | 190,2019-10-17,sh.000300,3929.3860,3935.8120,3913.9170,3925.2210,3922.6850,6486374400,99991851008.0000,0.064600
193 | 191,2019-10-18,sh.000300,3935.4190,3940.5400,3864.9650,3869.3770,3925.2210,8232113920,122186928128.0000,-1.422700
194 | 192,2019-10-21,sh.000300,3865.3430,3884.7440,3856.0370,3880.8390,3869.3770,7418291712,110858235904.0000,0.296200
195 | 193,2019-10-22,sh.000300,3896.3140,3897.4350,3870.5480,3895.8800,3880.8390,6891856640,102843371520.0000,0.387600
196 | 194,2019-10-23,sh.000300,3892.6760,3901.4240,3862.1960,3871.0840,3895.8800,7019862528,99733598208.0000,-0.636500
197 | 195,2019-10-24,sh.000300,3877.9230,3890.1950,3852.5820,3870.6670,3871.0840,7133457408,105096949760.0000,-0.010800
198 | 196,2019-10-25,sh.000300,3871.7680,3899.7220,3849.0330,3896.7920,3870.6670,7745361920,126677483520.0000,0.674900
199 | 197,2019-10-28,sh.000300,3904.9820,3927.7950,3897.8170,3926.5850,3896.7920,9740602112,150762201088.0000,0.764600
200 | 198,2019-10-29,sh.000300,3929.7070,3932.3740,3910.2260,3910.2260,3926.5850,8225707520,139611418624.0000,-0.416600
201 | 199,2019-10-30,sh.000300,3904.7170,3908.0990,3883.4460,3891.2250,3910.2260,7787292416,122610503680.0000,-0.485900
202 | 200,2019-10-31,sh.000300,3906.8590,3907.1500,3878.8750,3886.7510,3891.2250,8671453952,135012425728.0000,-0.115000
203 | 201,2019-11-01,sh.000300,3883.8080,3956.0790,3876.4160,3952.3870,3886.7510,10068961280,151471063040.0000,1.688711
204 | 202,2019-11-04,sh.000300,3964.0050,3985.3570,3964.0050,3978.1210,3952.3870,10419385600,154485362688.0000,0.651100
205 | 203,2019-11-05,sh.000300,3982.1150,4030.6380,3970.8660,4002.8120,3978.1210,11291187968,163317854208.0000,0.620670
206 | 204,2019-11-06,sh.000300,4006.3270,4007.5010,3973.7760,3984.8810,4002.8120,9731295232,139859763200.0000,-0.447960
207 | 205,2019-11-07,sh.000300,3984.5520,4005.3820,3975.5470,3991.8740,3984.8810,8725489920,117751554048.0000,0.175488
208 | 206,2019-11-08,sh.000300,4017.6740,4022.0360,3971.5720,3973.0100,3991.8740,9710694912,139026673664.0000,-0.472560
209 | 207,2019-11-11,sh.000300,3948.6180,3948.6180,3897.5500,3902.9780,3973.0100,9415561984,130330083328.0000,-1.762694
210 | 208,2019-11-12,sh.000300,3905.9580,3914.8820,3877.7390,3903.6880,3902.9780,7654306816,108828237824.0000,0.018191
211 | 209,2019-11-13,sh.000300,3905.2830,3908.4190,3882.4310,3899.9810,3903.6880,7674907904,112057147392.0000,-0.094961
212 | 210,2019-11-14,sh.000300,3905.9280,3916.9450,3895.1410,3905.8570,3899.9810,8700844544,119791566848.0000,0.150667
213 | 211,2019-11-15,sh.000300,3908.4890,3915.1040,3877.0890,3877.0890,3905.8570,8373091584,115423019008.0000,-0.736535
214 | 212,2019-11-18,sh.000300,3874.4400,3913.1020,3868.3160,3907.9290,3877.0890,7664599296,107085819904.0000,0.795442
215 | 213,2019-11-19,sh.000300,3904.0990,3947.0390,3902.3770,3947.0390,3907.9290,8216102400,123227172864.0000,1.000786
216 | 214,2019-11-20,sh.000300,3940.1340,3943.2270,3901.9860,3907.8640,3947.0390,7681533184,118003064832.0000,-0.992516
217 | 215,2019-11-21,sh.000300,3894.5390,3901.8260,3875.9680,3889.5980,3907.8640,6913053696,104147771392.0000,-0.467416
218 | 216,2019-11-22,sh.000300,3894.1740,3918.8380,3833.5030,3849.9940,3889.5980,9104263936,146981163008.0000,-1.018203
219 | 217,2019-11-25,sh.000300,3850.9660,3878.2500,3839.4200,3878.2060,3849.9940,10606628864,140851077120.0000,0.732780
220 | 218,2019-11-26,sh.000300,3893.4340,3899.1090,3869.5940,3891.6530,3878.2060,11151353600,140213633024.0000,0.346732
221 | 219,2019-11-27,sh.000300,3883.4290,3889.9780,3862.7010,3875.6180,3891.6530,7643730432,107238821888.0000,-0.412036
222 | 220,2019-11-28,sh.000300,3877.9010,3887.6900,3852.0100,3862.3020,3875.6180,6523011840,87081787392.0000,-0.343584
223 | 221,2019-11-29,sh.000300,3857.1880,3861.6580,3804.8290,3828.6700,3862.3020,7414433024,116200558592.0000,-0.870776
224 | 222,2019-12-02,sh.000300,3835.5120,3854.7500,3829.3120,3836.0580,3828.6700,7741217280,109992591360.0000,0.192965
225 | 223,2019-12-03,sh.000300,3829.2120,3851.1200,3811.6280,3851.0870,3836.0580,7361124096,108703715328.0000,0.391782
226 | 224,2019-12-04,sh.000300,3841.6620,3852.9920,3831.0740,3849.8190,3851.0870,7968338432,109646344192.0000,-0.032926
227 | 225,2019-12-05,sh.000300,3863.6080,3883.4030,3859.8220,3879.3630,3849.8190,8905119232,129357594624.0000,0.767413
228 | 226,2019-12-06,sh.000300,3885.0580,3902.3850,3878.7000,3902.3850,3879.3630,7864888832,116424777728.0000,0.593448
229 | 227,2019-12-09,sh.000300,3909.5290,3911.9680,3885.2500,3895.4460,3902.3850,9535380736,130873098240.0000,-0.177814
230 | 228,2019-12-10,sh.000300,3886.4440,3900.9590,3882.0870,3900.3840,3895.4460,8626292736,121118412800.0000,0.126763
231 | 229,2019-12-11,sh.000300,3907.1590,3909.3850,3890.3410,3902.7490,3900.3840,9976548096,127690403840.0000,0.060635
232 | 230,2019-12-12,sh.000300,3908.4530,3908.4530,3886.1180,3891.0240,3902.7490,8470832896,117874315264.0000,-0.300429
233 | 231,2019-12-13,sh.000300,3928.0040,3969.4560,3925.2750,3968.2210,3891.0240,14857134848,201018884096.0000,1.983976
234 | 232,2019-12-16,sh.000300,3970.7090,3987.5860,3953.5120,3987.5460,3968.2210,14848667136,202154897408.0000,0.486994
235 | 233,2019-12-17,sh.000300,3987.7420,4067.1350,3984.5190,4041.7990,3987.5460,20116293632,251637866496.0000,1.360561
236 | 234,2019-12-18,sh.000300,4039.7240,4057.6400,4025.3430,4032.7820,4041.7990,15135176448,197620207616.0000,-0.223094
237 | 235,2019-12-19,sh.000300,4034.6150,4038.5430,4014.8950,4027.1490,4032.7820,11790055936,152553807872.0000,-0.139680
238 | 236,2019-12-20,sh.000300,4032.1510,4046.7260,4014.9290,4017.2520,4027.1490,12126766336,158460231680.0000,-0.245757
239 | 237,2019-12-23,sh.000300,4014.6920,4032.1720,3964.3790,3967.0960,4017.2520,12281624576,162048262144.0000,-1.248515
240 | 238,2019-12-24,sh.000300,3971.5600,3994.5090,3963.6650,3992.9580,3967.0960,9598904576,122499162112.0000,0.651913
241 | 239,2019-12-25,sh.000300,3988.6570,4000.5550,3976.3550,3990.8670,3992.9580,9493889024,131896467456.0000,-0.052367
242 | 240,2019-12-26,sh.000300,3993.6680,4025.9870,3993.5410,4025.9870,3990.8670,10886064128,140814966784.0000,0.880009
243 | 241,2019-12-27,sh.000300,4029.2450,4066.7960,4019.7220,4022.0270,4025.9870,15092641024,195090415616.0000,-0.098361
244 | 242,2019-12-30,sh.000300,4015.5190,4083.6900,4001.4950,4081.6330,4022.0270,15597148928,216814661632.0000,1.481989
245 | 243,2019-12-31,sh.000300,4077.7510,4098.1440,4069.0080,4096.5820,4081.6330,12326425856,173119348736.0000,0.366250
246 | 244,2020-01-02,sh.000300,4121.3480,4172.6550,4121.3480,4152.2400,4096.5820,18211677184,270105530368.0000,1.358645
247 | 245,2020-01-03,sh.000300,4161.2180,4164.2980,4131.8640,4144.9640,4152.2400,14282624512,215216287744.0000,-0.175231
248 | 246,2020-01-06,sh.000300,4120.5210,4170.6380,4102.3790,4129.2950,4144.9640,17530995200,250182070272.0000,-0.378025
249 | 247,2020-01-07,sh.000300,4137.4010,4161.2500,4135.0970,4160.2270,4129.2950,13948903168,196389060608.0000,0.749087
250 | 248,2020-01-08,sh.000300,4139.6310,4149.8130,4101.9800,4112.3170,4160.2270,16758585088,212406263808.0000,-1.151620
251 | 249,2020-01-09,sh.000300,4145.5340,4165.6570,4143.5920,4164.3690,4112.3170,13688632320,200150351872.0000,1.265758
252 | 250,2020-01-10,sh.000300,4177.5770,4180.9770,4148.4810,4163.1840,4164.3690,11303171840,177827414016.0000,-0.028456
253 | 251,2020-01-13,sh.000300,4166.9250,4203.9880,4148.6000,4203.9880,4163.1840,11969198336,199795490816.0000,0.980115
254 | 252,2020-01-14,sh.000300,4215.1570,4223.5070,4188.0800,4189.8860,4203.9880,12932078336,196221263872.0000,-0.335443
255 | 253,2020-01-15,sh.000300,4186.8810,4193.8680,4150.8790,4166.7340,4189.8860,10463313664,163081932800.0000,-0.552569
256 | 254,2020-01-16,sh.000300,4174.8170,4175.2930,4142.1790,4149.0430,4166.7340,10026764288,156242505728.0000,-0.424577
257 | 255,2020-01-17,sh.000300,4162.1930,4177.0280,4141.6440,4154.8530,4149.0430,9872568320,166591590400.0000,0.140032
258 | 256,2020-01-20,sh.000300,4170.7360,4185.9620,4149.4870,4185.8300,4154.8530,12240914688,202692288512.0000,0.745562
259 | 257,2020-01-21,sh.000300,4165.0200,4165.0200,4113.3250,4114.3080,4185.8300,13052750592,204586881024.0000,-1.708669
260 | 258,2020-01-22,sh.000300,4093.8000,4141.1770,4046.4860,4131.9310,4114.3080,12675876352,208136151040.0000,0.428334
261 | 259,2020-01-23,sh.000300,4093.3220,4103.5240,3972.3930,4003.9010,4131.9310,16035760384,250409357312.0000,-3.098551
262 | 260,2020-02-03,sh.000300,3639.9080,3732.1570,3639.9080,3688.3570,4003.9010,15755964672,243303104512.0000,-7.880914
263 | 261,2020-02-04,sh.000300,3652.0030,3786.8620,3652.0030,3785.6370,3688.3570,21393332736,298165768192.0000,2.637489
264 | 262,2020-02-05,sh.000300,3801.0990,3866.0100,3781.6130,3828.5270,3785.6370,17492552448,264042921984.0000,1.132967
265 | 263,2020-02-06,sh.000300,3841.7530,3914.9150,3806.9600,3899.7750,3828.5270,17646223616,262820089856.0000,1.860977
266 | 264,2020-02-07,sh.000300,3879.5530,3899.8830,3849.7120,3899.8690,3899.7750,15173175808,237508816896.0000,0.002410
267 | 265,2020-02-10,sh.000300,3872.3730,3920.1660,3861.0060,3916.0050,3899.8690,14840696832,229625442304.0000,0.413757
268 | 266,2020-02-11,sh.000300,3926.4200,3970.5220,3915.7070,3952.4640,3916.0050,14344167424,219307118592.0000,0.931025
269 | 267,2020-02-12,sh.000300,3945.6660,3984.4320,3940.6660,3984.4320,3952.4640,12671032064,200776708096.0000,0.808812
270 | 268,2020-02-13,sh.000300,3985.8750,3999.5490,3950.1420,3959.9180,3984.4320,14500184320,228605964288.0000,-0.615245
271 | 269,2020-02-14,sh.000300,3954.2340,4001.5620,3954.0230,3987.7340,3959.9180,14323980288,222895075328.0000,0.702439
272 | 270,2020-02-17,sh.000300,3999.6510,4077.4460,3999.6510,4077.4240,3987.7340,18277896960,273067819008.0000,2.249147
273 | 271,2020-02-18,sh.000300,4069.8310,4076.3880,4027.7850,4057.5100,4077.4240,16323621888,242552516608.0000,-0.488397
274 | 272,2020-02-19,sh.000300,4049.5860,4085.1700,4042.8450,4051.3100,4057.5100,16904644096,257554534400.0000,-0.152803
275 | 273,2020-02-20,sh.000300,4062.8960,4148.5280,4055.8100,4144.6560,4051.3100,21223262464,310835589120.0000,2.304094
276 | 274,2020-02-21,sh.000300,4134.8740,4184.4370,4130.1670,4149.4900,4144.6560,21721360384,326564003840.0000,0.116632
277 | 275,2020-02-24,sh.000300,4131.8360,4149.0100,4097.1750,4132.8380,4149.4900,21286930432,326387802112.0000,-0.401302
278 | 276,2020-02-25,sh.000300,4066.3020,4126.7070,4020.9070,4123.8540,4132.8380,24416783104,372213719040.0000,-0.217381
279 | 277,2020-02-26,sh.000300,4070.0990,4132.7810,4061.1250,4073.0150,4123.8540,26109406208,366022418432.0000,-1.232803
280 | 278,2020-02-27,sh.000300,4084.0780,4110.5270,4067.4400,4084.8750,4073.0150,18129097984,282050207744.0000,0.291185
281 | 279,2020-02-28,sh.000300,3988.7270,4031.1450,3928.0660,3940.0480,4084.8750,23027509248,330358906880.0000,-3.545445
282 | 280,2020-03-02,sh.000300,3968.8430,4092.5390,3968.8430,4069.6660,3940.0480,21931355904,317426204672.0000,3.289757
283 | 281,2020-03-03,sh.000300,4125.1350,4147.6520,4067.9090,4091.3610,4069.6660,21936977664,330802585600.0000,0.533090
284 | 282,2020-03-04,sh.000300,4078.4990,4115.2610,4060.7290,4115.0520,4091.3610,18242472960,281784864768.0000,0.579049
285 | 283,2020-03-05,sh.000300,4150.2100,4215.8510,4127.0380,4206.7250,4115.0520,23182311424,362838831104.0000,2.227748
286 | 284,2020-03-06,sh.000300,4158.2020,4181.3100,4135.3900,4138.5070,4206.7250,17247571712,253168631808.0000,-1.621642
287 | 285,2020-03-09,sh.000300,4063.0760,4063.0760,3995.1313,3997.1325,4138.5072,20810203500,305428730303.8000,-3.416080
288 | 286,2020-03-10,sh.000300,3975.2288,4093.0024,3954.7506,4082.7315,3997.1325,19741640200,296184435851.3000,2.141510
289 | 287,2020-03-11,sh.000300,4090.9348,4091.2704,4028.3964,4028.4289,4082.7315,16165611100,244990872685.9000,-1.330056
290 | 288,2020-03-12,sh.000300,3976.1139,3987.4336,3926.2704,3950.9111,4028.4289,15706045800,233152848759.1000,-1.924269
291 | 289,2020-03-13,sh.000300,3771.0139,3937.1806,3765.1479,3895.3128,3950.9111,18829672200,280213453213.7000,-1.407227
292 | 290,2020-03-16,sh.000300,3899.8598,3899.8598,3720.5127,3727.8398,3895.3128,18596826000,282836238271.2000,-4.299347
293 | 291,2020-03-17,sh.000300,3739.7833,3786.8908,3618.3070,3709.6822,3727.8398,16624612900,250824025696.9000,-0.487081
294 | 292,2020-03-18,sh.000300,3729.6853,3775.8506,3636.2565,3636.2565,3709.6822,15503754700,244127161535.3000,-1.979299
295 | 293,2020-03-19,sh.000300,3623.7890,3647.9874,3503.1866,3589.0926,3636.2565,18080740700,271827467961.6000,-1.297045
296 | 294,2020-03-20,sh.000300,3629.5126,3663.9517,3588.7766,3653.2239,3589.0926,13960300000,211223073323.1000,1.786839
297 | 295,2020-03-23,sh.000300,3542.6837,3585.8014,3523.7877,3530.3058,3653.2239,13710879000,197669624970.1000,-3.364647
298 | 296,2020-03-24,sh.000300,3598.6548,3627.7592,3545.4524,3625.1146,3530.3058,14310302100,208553840688.5000,2.685569
299 | 297,2020-03-25,sh.000300,3711.4753,3732.6536,3685.9942,3722.5181,3625.1146,15349595800,231561518761.2000,2.686908
300 | 298,2020-03-26,sh.000300,3692.6083,3736.2536,3681.2668,3698.0472,3722.5181,11231066500,169336311861.4000,-0.657375
301 | 299,2020-03-27,sh.000300,3746.3914,3758.7827,3709.9213,3710.0605,3698.0472,12406099500,186103426334.7000,0.324855
302 | 300,2020-03-30,sh.000300,3657.4624,3690.6388,3637.5853,3674.1108,3710.0605,12687667300,180640799409.3000,-0.968979
303 | 301,2020-03-31,sh.000300,3708.1404,3716.0707,3676.2024,3686.1551,3674.1108,11145302500,161595510008.2000,0.327815
304 | 302,2020-04-01,sh.000300,3682.2966,3731.7799,3670.9653,3675.0758,3686.1551,11935262000,170422568804.4000,-0.300565
305 | 303,2020-04-02,sh.000300,3656.3225,3734.5306,3652.3167,3734.5306,3675.0758,11516820900,168893255656.6000,1.617784
306 | 304,2020-04-03,sh.000300,3721.4815,3738.8323,3698.9822,3713.2183,3734.5306,9982508300,150132815028.5000,-0.570682
307 | 305,2020-04-07,sh.000300,3779.9076,3803.6286,3772.2054,3798.0214,3713.2183,14277803000,207642820316.9000,2.283817
308 | 306,2020-04-08,sh.000300,3776.4171,3793.0023,3767.2924,3780.3445,3798.0214,11138951300,161576772320.2000,-0.465424
309 | 307,2020-04-09,sh.000300,3798.4879,3801.7245,3785.3116,3792.8105,3780.3445,10048503200,154595318812.8000,0.329758
310 | 308,2020-04-10,sh.000300,3794.8429,3824.7441,3758.9599,3769.1782,3792.8105,10244495600,162251233800.7000,-0.623081
311 | 309,2020-04-13,sh.000300,3751.7093,3769.8764,3740.1936,3753.2566,3769.1782,7905334300,119874303204.6000,-0.422416
312 | 310,2020-04-14,sh.000300,3777.8343,3825.7599,3764.9838,3825.6991,3753.2566,11063758500,170612579792.4000,1.930124
313 | 311,2020-04-15,sh.000300,3820.8506,3829.8009,3793.4402,3797.3623,3825.6991,10846198400,169700216633.0000,-0.740696
314 | 312,2020-04-16,sh.000300,3777.7986,3807.3569,3774.5585,3802.3806,3797.3623,9594796500,147164302056.9000,0.132152
315 | 313,2020-04-17,sh.000300,3831.9232,3863.4521,3821.4201,3839.4871,3802.3806,13200430100,203595267033.5000,0.975875
316 | 314,2020-04-20,sh.000300,3845.4598,3853.7984,3831.5530,3853.4551,3839.4871,10001311500,151924090117.0000,0.363799
317 | 315,2020-04-21,sh.000300,3838.2314,3838.2314,3779.9967,3808.0474,3853.4551,10292188800,155077454132.0000,-1.178363
318 | 316,2020-04-22,sh.000300,3789.1297,3839.3834,3782.2149,3839.3834,3808.0474,8589946400,135547280790.0000,0.822889
319 | 317,2020-04-23,sh.000300,3851.9132,3857.4709,3826.5565,3829.7525,3839.3834,9550845000,142122548831.8000,-0.250845
320 | 318,2020-04-24,sh.000300,3826.3116,3827.2120,3787.0714,3796.9721,3829.7525,9484413500,138961200282.7000,-0.855940
321 | 319,2020-04-27,sh.000300,3808.0171,3842.8706,3793.7655,3822.7690,3796.9721,9546273500,145301151875.0000,0.679407
322 | 320,2020-04-28,sh.000300,3835.3480,3859.6754,3768.2000,3849.1465,3822.7690,12209347600,184179759240.3000,0.690010
323 | 321,2020-04-29,sh.000300,3837.5135,3880.7444,3833.7164,3867.0320,3849.1465,9585459000,151282103744.2000,0.464661
324 | 322,2020-04-30,sh.000300,3880.4094,3921.7004,3880.4094,3912.5772,3867.0320,13291712500,202268288802.3000,1.177782
325 | 323,2020-05-06,sh.000300,3867.2587,3937.6909,3865.9875,3936.2539,3912.5772,13985567500,214935962364.4000,0.605143
326 | 324,2020-05-07,sh.000300,3937.5918,3941.4833,3915.9048,3924.8946,3936.2539,10551464600,167207801840.2000,-0.288581
327 | 325,2020-05-08,sh.000300,3942.9972,3979.6627,3935.9805,3963.6217,3924.8946,11694334100,190299584716.9000,0.986704
328 | 326,2020-05-11,sh.000300,3974.7605,3998.0972,3944.5037,3960.1803,3963.6217,12267380300,193758093899.8000,-0.086825
329 | 327,2020-05-12,sh.000300,3961.3427,3970.1115,3930.2108,3960.2378,3960.1803,9825055400,157465780059.9000,0.001452
330 | 328,2020-05-13,sh.000300,3946.6428,3972.5254,3932.5711,3968.2529,3960.2378,8819066900,145563383275.8000,0.202389
331 | 329,2020-05-14,sh.000300,3952.1986,3952.1986,3924.0452,3925.2177,3968.2529,8853000400,143499177719.8000,-1.084487
332 | 330,2020-05-15,sh.000300,3941.1250,3945.1956,3907.4021,3912.8159,3925.2177,9261838200,153301505149.4000,-0.315952
333 | 331,2020-05-18,sh.000300,3914.6602,3946.4312,3898.4041,3922.9117,3912.8159,11280176200,188528121367.6000,0.258019
334 | 332,2020-05-19,sh.000300,3963.7754,3966.8518,3944.0715,3956.2495,3922.9117,9401529100,159886222402.2000,0.849823
335 | 333,2020-05-20,sh.000300,3955.7145,3955.7145,3923.9213,3935.2220,3956.2495,10079115000,157102533276.1000,-0.531501
336 | 334,2020-05-21,sh.000300,3950.5981,3951.7430,3907.5788,3913.7949,3935.2220,9486103300,149154142257.8000,-0.544495
337 | 335,2020-05-22,sh.000300,3907.5761,3907.5761,3818.1488,3824.0640,3913.7949,10337836000,157286504986.3000,-2.292683
338 | 336,2020-05-25,sh.000300,3828.3206,3835.6333,3800.1796,3829.3245,3824.0640,7903332600,127011917716.3000,0.137563
339 | 337,2020-05-26,sh.000300,3850.0009,3874.7484,3844.4776,3872.7701,3829.3245,7744807600,125445619316.8000,1.134550
340 | 338,2020-05-27,sh.000300,3873.6984,3873.6984,3838.4247,3845.6135,3872.7701,8371183100,123737501165.0000,-0.701219
341 | 339,2020-05-28,sh.000300,3848.4892,3885.4211,3818.4318,3856.6324,3845.6135,9306405400,139108407792.0000,0.286532
342 | 340,2020-05-29,sh.000300,3838.3769,3872.3031,3830.4185,3867.0232,3856.6324,9381383200,135658136028.2000,0.269427
343 | 341,2020-06-01,sh.000300,3901.7263,3976.3151,3901.7263,3971.3402,3867.0232,13645665200,208436512945.1000,2.697605
344 | 342,2020-06-02,sh.000300,3969.9521,3991.7761,3958.9774,3983.5677,3971.3402,14430306000,195563304256.3000,0.307894
345 | 343,2020-06-03,sh.000300,4001.1708,4018.6759,3982.9299,3983.6477,3983.5677,13659748300,200882767676.9000,0.002008
346 | 344,2020-06-04,sh.000300,3998.1636,3999.8051,3968.5723,3982.1851,3983.6477,10427773700,149057855837.5000,-0.036715
347 | 345,2020-06-05,sh.000300,3988.2239,4001.2509,3967.9260,4001.2509,3982.1851,10244394200,154311342981.8000,0.478777
348 | 346,2020-06-08,sh.000300,4023.6060,4050.2213,4016.1015,4021.9549,4001.2509,13792581300,193047518687.6000,0.517438
349 | 347,2020-06-09,sh.000300,4027.5613,4052.1557,4016.3387,4047.0293,4021.9549,11530447900,166533966010.0000,0.623438
350 | 348,2020-06-10,sh.000300,4046.2317,4046.2317,4024.4185,4039.7051,4047.0293,11226572800,166778642366.2000,-0.180977
351 | 349,2020-06-11,sh.000300,4031.7396,4043.0123,3979.7522,3995.8846,4039.7051,12730894100,197079441861.1000,-1.084745
352 | 350,2020-06-12,sh.000300,3931.6236,4011.0591,3927.2491,4003.0829,3995.8846,13416664900,193504046742.3000,0.180143
353 | 351,2020-06-15,sh.000300,3982.9672,4007.1396,3954.9883,3954.9883,4003.0829,13129786000,211125336143.8000,-1.201439
354 | 352,2020-06-16,sh.000300,3995.5786,4014.5702,3987.8637,4014.5702,3954.9883,11105153900,185104029158.9000,1.506500
355 | 353,2020-06-17,sh.000300,4018.6094,4018.6094,3992.1339,4017.5941,4014.5702,10560579900,176977503611.2000,0.075323
356 | 354,2020-06-18,sh.000300,4009.7831,4047.5566,4000.9008,4044.3842,4017.5941,13814876100,210192918146.2000,0.666819
357 | 355,2020-06-19,sh.000300,4047.0483,4109.3602,4043.4925,4098.7095,4044.3842,15294699000,255549797299.6000,1.343228
358 | 356,2020-06-22,sh.000300,4097.5071,4126.9421,4088.7822,4102.0459,4098.7095,15582946500,259200520725.7000,0.081401
359 | 357,2020-06-23,sh.000300,4098.0373,4124.7250,4080.7533,4121.7944,4102.0459,12922951000,234806510834.5000,0.481430
360 | 358,2020-06-24,sh.000300,4128.1003,4144.6782,4123.3582,4138.9895,4121.7944,12171246500,224551430008.0000,0.417175
361 | 359,2020-06-29,sh.000300,4127.9348,4137.3696,4092.5352,4109.7164,4138.9895,13086585400,226522059762.9000,-0.707252
362 | 360,2020-06-30,sh.000300,4130.0028,4174.4236,4129.7754,4163.9637,4109.7164,12593352100,227935704488.9000,1.319977
363 | 361,2020-07-01,sh.000300,4172.6425,4247.7835,4163.4954,4247.7835,4163.9637,16999045600,305711799762.0000,2.012981
364 | 362,2020-07-02,sh.000300,4239.4080,4340.1039,4238.1164,4335.8445,4247.7835,25293936800,399571526695.3000,2.073105
365 | 363,2020-07-03,sh.000300,4353.1937,4419.5955,4348.4535,4419.5955,4335.8445,29048553900,442335024266.1000,1.931596
366 | 364,2020-07-06,sh.000300,4465.8081,4678.1121,4465.8081,4670.0949,4419.5955,40582102500,597438217716.0000,5.667926
367 | 365,2020-07-07,sh.000300,4739.6104,4796.3155,4688.0574,4698.1264,4670.0949,40600855300,635254742706.0000,0.600234
368 | 366,2020-07-08,sh.000300,4692.8621,4803.3643,4670.6501,4774.0042,4698.1264,34807484700,532849825964.5000,1.615065
369 | 367,2020-07-09,sh.000300,4770.0769,4854.1201,4757.2943,4840.7712,4774.0042,35104689300,556718732098.9000,1.398553
370 | 368,2020-07-10,sh.000300,4796.0873,4821.3745,4734.4725,4753.1333,4840.7712,31694965100,510472055095.9000,-1.810412
371 | 369,2020-07-13,sh.000300,4742.3738,4878.0773,4741.8743,4852.9612,4753.1333,32164544600,541105098721.0000,2.100255
372 | 370,2020-07-14,sh.000300,4836.1655,4860.4404,4729.9258,4806.6902,4852.9612,29724198500,511211048184.9000,-0.953459
373 | 371,2020-07-15,sh.000300,4821.5155,4837.4757,4723.3608,4744.4687,4806.6902,27238900600,486748347680.4000,-1.294477
374 | 372,2020-07-16,sh.000300,4741.5295,4772.5638,4513.6537,4516.2532,4744.4687,28465713300,511237962884.2000,-4.810138
375 | 373,2020-07-17,sh.000300,4524.7717,4601.3733,4485.8214,4544.7007,4516.2532,20737556300,372973887046.0000,0.629892
376 | 374,2020-07-20,sh.000300,4597.2038,4681.9431,4534.2305,4680.3046,4544.7007,24606891400,416714222275.7000,2.983781
377 | 375,2020-07-21,sh.000300,4697.5026,4714.2925,4661.4440,4691.0425,4680.3046,20041565900,356069805762.6000,0.229427
378 | 376,2020-07-22,sh.000300,4682.6575,4790.4491,4675.3488,4714.4454,4691.0425,22419921100,386470859914.3000,0.498885
379 | 377,2020-07-23,sh.000300,4668.7401,4731.4004,4607.6585,4712.4357,4714.4454,23431456900,405175268660.9000,-0.042629
380 | 378,2020-07-24,sh.000300,4679.0273,4691.6980,4479.3928,4505.5906,4712.4357,24390520300,437726712279.7000,-4.389346
381 | 379,2020-07-27,sh.000300,4535.0053,4558.1189,4482.4408,4528.4500,4505.5906,17142055100,301893370163.2000,0.507356
382 | 380,2020-07-28,sh.000300,4567.6691,4590.2496,4537.6849,4568.2576,4528.4500,16276849800,292835785345.2000,0.879056
383 | 381,2020-07-29,sh.000300,4559.1634,4680.5580,4548.8535,4679.0080,4568.2576,18669530500,350432649160.5000,2.424347
384 | 382,2020-07-30,sh.000300,4689.7632,4704.6305,4649.7677,4656.1506,4679.0080,16696756600,324009242692.4000,-0.488510
385 | 383,2020-07-31,sh.000300,4652.1824,4741.8084,4621.9635,4695.0462,4656.1506,18483902600,351119312415.0000,0.835360
386 | 384,2020-08-03,sh.000300,4735.8985,4771.3694,4720.0250,4771.3108,4695.0462,21477623900,401914824928.3000,1.624363
387 | 385,2020-08-04,sh.000300,4778.4866,4807.0782,4747.7748,4775.8024,4771.3108,23997498500,426411345935.8000,0.094138
388 | 386,2020-08-05,sh.000300,4761.7637,4786.7031,4711.2723,4777.1089,4775.8024,19670054800,347407839399.1000,0.027357
389 | 387,2020-08-06,sh.000300,4779.2377,4791.8565,4691.1569,4762.7642,4777.1089,22785440600,404323404006.9000,-0.300280
390 | 388,2020-08-07,sh.000300,4742.2939,4749.0217,4637.8427,4707.9262,4762.7642,21351821600,397041212825.0000,-1.151390
391 | 389,2020-08-10,sh.000300,4681.7553,4757.6634,4646.2885,4724.8697,4707.9262,20378883200,371297560017.6000,0.359893
392 | 390,2020-08-11,sh.000300,4730.3748,4791.5337,4674.8642,4681.7837,4724.8697,20554651100,350828586241.1000,-0.911898
393 | 391,2020-08-12,sh.000300,4668.8899,4681.6206,4566.2736,4647.6446,4681.7837,20288723900,347298673202.0000,-0.729190
394 | 392,2020-08-13,sh.000300,4666.4901,4671.7689,4626.1033,4635.7126,4647.6446,15255009200,250945872578.9000,-0.256732
395 | 393,2020-08-14,sh.000300,4627.6100,4708.0709,4617.6320,4704.6288,4635.7126,14729292100,254343934256.2000,1.486637
396 | 394,2020-08-17,sh.000300,4727.1204,4838.0864,4721.3589,4815.2261,4704.6288,26800155600,416469154934.0000,2.350819
397 | 395,2020-08-18,sh.000300,4816.5703,4825.3861,4788.8293,4812.7564,4815.2261,18913985400,314395904535.5000,-0.051289
398 | 396,2020-08-19,sh.000300,4804.6655,4809.0499,4738.0086,4740.6784,4812.7564,19244294800,319403284708.3000,-1.497645
399 | 397,2020-08-20,sh.000300,4708.1253,4721.4357,4662.8032,4679.1544,4740.6784,15836863900,260486563515.0000,-1.297789
400 | 398,2020-08-21,sh.000300,4717.7874,4739.4836,4684.8101,4718.8431,4679.1544,14265786400,251775160233.8000,0.848202
401 | 399,2020-08-24,sh.000300,4746.4035,4769.4673,4716.6054,4755.8491,4718.8431,15114351200,272428686418.6000,0.784218
402 | 400,2020-08-25,sh.000300,4769.2107,4802.4122,4746.3130,4761.9507,4755.8491,14170135100,262308788275.0000,0.128297
403 | 401,2020-08-26,sh.000300,4761.7186,4786.4249,4689.8810,4706.1302,4761.9507,15130518000,277456360643.0000,-1.172219
404 | 402,2020-08-27,sh.000300,4718.0620,4731.9351,4679.3623,4731.3451,4706.1302,11904285000,223631511405.6000,0.535788
405 | 403,2020-08-28,sh.000300,4727.2920,4850.4884,4719.3526,4844.2652,4731.3451,15939976500,305047882508.6000,2.386638
406 | 404,2020-08-31,sh.000300,4870.9337,4901.2115,4816.2123,4816.2153,4844.2652,20256702900,357005064604.8000,-0.579033
407 | 405,2020-09-01,sh.000300,4803.3922,4842.1350,4791.7829,4842.1223,4816.2153,13839540200,262018070577.3000,0.537912
408 | 406,2020-09-02,sh.000300,4859.0754,4863.5509,4797.5204,4843.8870,4842.1223,15798952400,280778613751.4000,0.036445
409 | 407,2020-09-03,sh.000300,4841.5020,4877.0117,4800.0577,4817.0952,4843.8870,14567120100,279411988792.3000,-0.553105
410 | 408,2020-09-04,sh.000300,4737.2368,4778.2030,4726.5559,4770.2190,4817.0952,12003279600,238463337878.7000,-0.973122
411 | 409,2020-09-07,sh.000300,4759.5213,4789.3031,4655.5600,4669.3677,4770.2190,14860779100,282316394067.8000,-2.114186
412 | 410,2020-09-08,sh.000300,4683.8256,4707.8966,4639.0531,4694.3894,4669.3677,13919922700,249198138076.0000,0.535869
413 | 411,2020-09-09,sh.000300,4634.2470,4645.1972,4558.0304,4584.5887,4694.3894,16227710700,244905191934.1000,-2.338977
414 | 412,2020-09-10,sh.000300,4632.0994,4647.7505,4572.2058,4581.9775,4584.5887,15065287800,226146354804.6000,-0.056956
415 | 413,2020-09-11,sh.000300,4572.2572,4630.8842,4563.1061,4627.2826,4581.9775,11530242400,198240927301.5000,0.988767
416 | 414,2020-09-14,sh.000300,4652.0539,4666.9862,4625.9877,4651.0507,4627.2826,10723517900,211653411810.9000,0.513651
417 | 415,2020-09-15,sh.000300,4649.4472,4691.4997,4630.5374,4688.4826,4651.0507,10191592500,194573684119.3000,0.804805
418 | 416,2020-09-16,sh.000300,4683.0060,4690.6815,4638.4586,4657.3584,4688.4826,10875364100,196120184850.9000,-0.663844
419 | 417,2020-09-17,sh.000300,4642.0542,4664.9491,4601.6390,4632.7142,4657.3584,10598363100,214146647269.6000,-0.529145
420 | 418,2020-09-18,sh.000300,4636.6422,4737.8039,4631.7045,4737.0887,4632.7142,16042647500,281885944229.0000,2.252988
421 | 419,2020-09-21,sh.000300,4750.7481,4752.9799,4688.7199,4691.4281,4737.0887,12453582700,224137912695.2000,-0.963896
422 | 420,2020-09-22,sh.000300,4654.2179,4706.2096,4622.1111,4635.7608,4691.4281,11967294700,202909215534.6000,-1.186575
423 | 421,2020-09-23,sh.000300,4639.6592,4665.9600,4623.5528,4652.3273,4635.7608,9582652800,190393472276.3000,0.357363
424 | 422,2020-09-24,sh.000300,4623.9535,4631.9482,4562.2086,4563.0657,4652.3273,11259368300,193515873700.2000,-1.918644
425 | 423,2020-09-25,sh.000300,4582.4820,4599.5387,4554.7199,4570.0216,4563.0657,9301515500,167457376964.0000,0.152439
426 | 424,2020-09-28,sh.000300,4582.6471,4613.6324,4571.1507,4581.9085,4570.0216,8504838900,159314675407.1000,0.260106
427 | 425,2020-09-29,sh.000300,4608.2926,4616.6767,4586.3537,4591.7993,4581.9085,8599385800,159937888502.2000,0.215866
428 | 426,2020-09-30,sh.000300,4607.5753,4634.7239,4563.4108,4587.3953,4591.7993,8908120000,165532220885.2000,-0.095910
429 | 427,2020-10-09,sh.000300,4663.6100,4695.4041,4655.0851,4681.1412,4587.3953,11133751200,229926731489.9000,2.043554
430 | 428,2020-10-12,sh.000300,4705.1883,4823.2666,4704.1554,4823.1578,4681.1412,15578455800,307848558046.0000,3.033803
431 | 429,2020-10-13,sh.000300,4812.8989,4845.9191,4795.3730,4839.2010,4823.1578,11651633800,242172567248.5000,0.332629
432 | 430,2020-10-14,sh.000300,4830.4575,4830.4575,4795.9069,4807.1021,4839.2010,11190692300,229836207247.8000,-0.663310
433 | 431,2020-10-15,sh.000300,4810.7821,4833.8925,4796.2647,4798.7361,4807.1021,10996496200,213878285047.0000,-0.174034
434 | 432,2020-10-16,sh.000300,4798.9162,4825.5518,4765.9670,4791.6760,4798.7361,11671610200,204175130717.5000,-0.147124
435 | 433,2020-10-19,sh.000300,4823.4944,4849.6050,4747.3356,4755.4879,4791.6760,12924636100,225392198225.0000,-0.755228
436 | 434,2020-10-20,sh.000300,4751.3694,4793.4672,4739.4583,4793.4672,4755.4879,9804815600,185849198017.6000,0.798642
437 | 435,2020-10-21,sh.000300,4801.6313,4801.6313,4758.8552,4792.8284,4793.4672,10380570300,189978697043.6000,-0.013326
438 | 436,2020-10-22,sh.000300,4780.5954,4791.8078,4725.4993,4777.9845,4792.8284,10135089100,194614971169.8000,-0.309711
439 | 437,2020-10-23,sh.000300,4775.4665,4802.4560,4717.0984,4718.4881,4777.9845,10682518400,200985821991.5000,-1.245220
440 | 438,2020-10-26,sh.000300,4684.0465,4713.3945,4639.3019,4691.2359,4718.4881,10834327500,205518988284.4000,-0.577562
441 | 439,2020-10-27,sh.000300,4680.1371,4708.4623,4671.8536,4699.2792,4691.2359,9265630400,186675545690.4000,0.171454
442 | 440,2020-10-28,sh.000300,4703.0036,4753.3125,4685.6012,4737.2718,4699.2792,10846340200,226754264067.0000,0.808477
443 | 441,2020-10-29,sh.000300,4683.6070,4803.0317,4679.2529,4772.9198,4737.2718,11711725000,252303504993.0000,0.752501
444 | 442,2020-10-30,sh.000300,4776.4726,4778.5089,4683.4719,4695.3338,4772.9198,13980230300,280783321713.1000,-1.625546
445 | 443,2020-11-02,sh.000300,4702.7457,4738.0239,4695.4436,4720.8313,4695.3338,14286769300,279027685157.1000,0.543039
446 | 444,2020-11-03,sh.000300,4743.1742,4793.3963,4734.1748,4777.5608,4720.8313,13605540800,252390556313.5000,1.201685
447 | 445,2020-11-04,sh.000300,4781.4480,4825.4638,4770.5582,4813.6564,4777.5608,11466180600,230513773046.3000,0.755524
448 | 446,2020-11-05,sh.000300,4861.3377,4885.1118,4837.9996,4885.1118,4813.6564,13924459400,281951932371.0000,1.484431
449 | 447,2020-11-06,sh.000300,4897.6295,4897.6295,4845.4293,4885.7178,4885.1118,15363903400,305365103652.9000,0.012405
450 | 448,2020-11-09,sh.000300,4918.8609,4997.8017,4918.8609,4981.3497,4885.7178,19713198400,371923282063.4000,1.957377
451 | 449,2020-11-10,sh.000300,4995.4126,4995.4126,4928.9319,4953.8756,4981.3497,17626721400,334271459964.0000,-0.551539
452 | 450,2020-11-11,sh.000300,4937.7582,4957.5846,4901.7067,4904.8981,4953.8756,16447051500,303858557977.1000,-0.988670
453 | 451,2020-11-12,sh.000300,4916.7736,4926.3422,4891.5100,4908.4630,4904.8981,11811461900,227645907147.2000,0.072680
454 | 452,2020-11-13,sh.000300,4886.9778,4886.9778,4825.7578,4856.8513,4908.4630,13369307900,255353111737.8000,-1.051484
455 | 453,2020-11-16,sh.000300,4880.9580,4904.1716,4848.6239,4904.1716,4856.8513,14877098000,266705031671.5000,0.974300
456 | 454,2020-11-17,sh.000300,4903.1200,4909.2902,4865.3942,4894.7860,4904.1716,15148746400,288911408551.0000,-0.191380
457 | 455,2020-11-18,sh.000300,4889.6749,4911.0876,4870.7162,4891.6716,4894.7860,16421661600,290727223227.2000,-0.063627
458 | 456,2020-11-19,sh.000300,4880.9224,4939.7911,4870.2005,4927.9891,4891.6716,13368137800,247727135000.5000,0.742435
459 | 457,2020-11-20,sh.000300,4928.2223,4947.4297,4922.5895,4943.2882,4927.9891,12940034100,229053679195.4000,0.310453
460 | 458,2020-11-23,sh.000300,4954.5987,5029.6515,4940.4494,5005.0273,4943.2882,20591518700,333633826416.7000,1.248948
461 | 459,2020-11-24,sh.000300,4997.0485,5001.0614,4960.9817,4974.2855,5005.0273,15663791100,264804443317.7000,-0.614218
462 | 460,2020-11-25,sh.000300,4992.7466,5004.7732,4910.7000,4910.7000,4974.2855,17034052700,277070642970.7000,-1.278284
463 | 461,2020-11-26,sh.000300,4908.3208,4925.2857,4867.8153,4919.5912,4910.7000,13720233800,239748145475.7000,0.181058
464 | 462,2020-11-27,sh.000300,4930.5928,4980.7650,4917.3479,4980.7650,4919.5912,16295292200,253178971224.0000,1.243473
465 | 463,2020-11-30,sh.000300,4994.1063,5055.1920,4960.2519,4960.2519,4980.7650,26263895000,396495834420.8000,-0.411846
466 | 464,2020-12-01,sh.000300,4963.1302,5072.5494,4963.1302,5067.0983,4960.2519,20406563800,328451014444.2000,2.154052
467 | 465,2020-12-02,sh.000300,5072.9755,5090.6084,5043.3091,5067.1447,5067.0983,19543547600,310609728842.5000,0.000916
468 | 466,2020-12-03,sh.000300,5065.4531,5072.3046,5033.7887,5057.0603,5067.1447,17786574800,275335207429.1000,-0.199015
469 | 467,2020-12-04,sh.000300,5049.5231,5072.3865,5017.8506,5065.9163,5057.0603,14434716700,257798820735.0000,0.175122
470 | 468,2020-12-07,sh.000300,5065.7285,5067.8698,5014.6090,5022.2351,5065.9163,13989621700,264657773932.9000,-0.862257
471 | 469,2020-12-08,sh.000300,5029.1063,5043.0605,4998.9218,5009.8786,5022.2351,12307302900,234880648439.1000,-0.246036
472 | 470,2020-12-09,sh.000300,5022.3846,5033.6417,4942.5195,4942.6986,5009.8786,13891696500,260772774152.9000,-1.340951
473 | 471,2020-12-10,sh.000300,4931.2933,4962.7433,4919.7696,4940.5249,4942.6986,12591427000,229651278357.4000,-0.043978
474 | 472,2020-12-11,sh.000300,4957.8236,4957.8236,4849.3547,4889.6292,4940.5249,15935769700,275212730069.9000,-1.030168
475 | 473,2020-12-14,sh.000300,4903.6270,4937.2601,4887.6599,4934.8352,4889.6292,12080155200,247878279711.0000,0.924528
476 | 474,2020-12-15,sh.000300,4931.6019,4954.1885,4904.7926,4945.1000,4934.8352,11834263300,248093390249.2000,0.208007
477 | 475,2020-12-16,sh.000300,4957.2971,4968.8558,4938.1932,4953.8670,4945.1000,10677896800,229696035696.9000,0.177287
478 | 476,2020-12-17,sh.000300,4960.7290,5021.6171,4950.3713,5017.4784,4953.8670,13338547900,270180356109.3000,1.284076
479 | 477,2020-12-18,sh.000300,5014.3211,5027.4446,4979.0051,4999.9678,5017.4784,12804961800,258938551535.8000,-0.348992
480 | 478,2020-12-21,sh.000300,4995.7622,5048.5074,4969.9990,5046.8396,4999.9678,14081178200,298204296843.3000,0.937442
481 | 479,2020-12-22,sh.000300,5034.9831,5055.1348,4960.9457,4964.7727,5046.8396,16234497000,326758817663.3000,-1.626105
482 | 480,2020-12-23,sh.000300,4977.2994,5028.4506,4968.1509,5007.1235,4964.7727,14029281900,308729037473.7000,0.853026
483 | 481,2020-12-24,sh.000300,5006.0051,5033.0380,4979.2371,5000.0154,5007.1235,11441866700,246674476188.8000,-0.141960
484 | 482,2020-12-25,sh.000300,4985.7695,5042.0978,4973.6812,5042.0137,5000.0154,12100697900,243992268243.3000,0.839963
485 | 483,2020-12-28,sh.000300,5042.9432,5089.3447,5037.8582,5064.4147,5042.0137,13691440700,281019254170.5000,0.444287
486 | 484,2020-12-29,sh.000300,5071.4490,5077.4167,5034.3078,5042.9361,5064.4147,14119866200,279035233253.8000,-0.424108
487 | 485,2020-12-30,sh.000300,5037.9848,5113.7105,5036.6288,5113.7105,5042.9361,14862644800,296577812603.0000,1.403436
488 | 486,2020-12-31,sh.000300,5122.4799,5215.6178,5122.4799,5211.2885,5113.7105,17160250900,358731371834.7000,1.908164
489 | 487,2021-01-04,sh.000300,5212.9313,5284.4343,5190.9372,5267.7181,5211.2885,21171138200,452796175554.0000,1.082834
490 | 488,2021-01-05,sh.000300,5245.8355,5368.5049,5234.3775,5368.5049,5267.7181,22493115900,498041939761.0000,1.913291
491 | 489,2021-01-06,sh.000300,5386.5144,5433.4694,5341.4304,5417.6677,5368.5049,19377344400,444434377137.3000,0.915763
492 | 490,2021-01-07,sh.000300,5428.3944,5513.6568,5413.3526,5513.6568,5417.6677,21987208000,473385353695.8000,1.771779
493 | 491,2021-01-08,sh.000300,5526.2876,5547.4733,5442.6939,5495.4306,5513.6568,20432495600,473567653978.6000,-0.330565
494 | 492,2021-01-11,sh.000300,5504.2358,5555.6916,5412.5046,5441.1583,5495.4306,23183598300,522298482544.3000,-0.987590
495 | 493,2021-01-12,sh.000300,5419.4996,5596.3525,5417.6272,5596.3525,5441.1583,22422018600,486233760739.8000,2.852227
496 | 494,2021-01-13,sh.000300,5609.2637,5644.7195,5535.1435,5577.9711,5596.3525,26156988600,546959736365.5000,-0.328453
497 | 495,2021-01-14,sh.000300,5556.2125,5568.0179,5458.6818,5470.4563,5577.9711,24368338000,501890111879.0000,-1.927489
498 | 496,2021-01-15,sh.000300,5471.3910,5500.6348,5390.2737,5458.0812,5470.4563,23863743500,475709920372.3000,-0.226217
499 | 497,2021-01-18,sh.000300,5438.1618,5541.4613,5410.7750,5518.5205,5458.0812,20705186900,422717209153.0000,1.107336
500 | 498,2021-01-19,sh.000300,5525.9690,5532.4793,5415.7166,5437.5234,5518.5205,21104342500,433205176449.9000,-1.467732
501 | 499,2021-01-20,sh.000300,5439.9111,5496.0493,5426.5357,5476.4336,5437.5234,17091326000,373770384496.4000,0.715587
502 | 500,2021-01-21,sh.000300,5492.9587,5593.1058,5490.5626,5564.9693,5476.4336,20995019700,453183684478.9000,1.616667
503 | 501,2021-01-22,sh.000300,5562.3790,5573.6594,5513.8769,5569.7760,5564.9693,19930002000,456622193435.6000,0.086374
504 | 502,2021-01-25,sh.000300,5564.1237,5655.4795,5543.2663,5625.9232,5569.7760,19704701900,508166980802.0000,1.008069
505 | 503,2021-01-26,sh.000300,5600.9017,5600.9017,5505.9962,5512.9678,5625.9232,17190459000,415008069865.0000,-2.007766
506 | 504,2021-01-27,sh.000300,5505.7708,5534.9928,5449.6385,5528.0034,5512.9678,16019084100,376892605839.1000,0.272732
507 | 505,2021-01-28,sh.000300,5450.3695,5462.2352,5360.3766,5377.1427,5528.0034,17048558500,376166523177.5000,-2.729027
508 | 506,2021-01-29,sh.000300,5413.9684,5430.2015,5288.0955,5351.9646,5377.1427,18217878400,390287690019.0000,-0.468243
509 | 507,2021-02-01,sh.000300,5356.8535,5422.2990,5342.0458,5417.6484,5351.9646,16631370600,346859083730.0000,1.227284
510 | 508,2021-02-02,sh.000300,5429.7032,5503.2145,5411.5173,5501.0915,5417.6484,16521056500,380016716111.9000,1.540209
511 | 509,2021-02-03,sh.000300,5499.2961,5532.8864,5473.1237,5485.2008,5501.0915,18805431700,404343602637.7000,-0.288864
512 | 510,2021-02-04,sh.000300,5453.9764,5510.0535,5411.5749,5473.9475,5485.2008,18057565400,397995205379.9000,-0.205157
513 | 511,2021-02-05,sh.000300,5494.7011,5550.7714,5477.6517,5483.4140,5473.9475,18969959800,395400134490.0000,0.172937
514 | 512,2021-02-08,sh.000300,5506.1423,5576.4908,5479.8529,5564.5618,5483.4140,16403377500,367582771658.8000,1.479877
515 | 513,2021-02-09,sh.000300,5584.1650,5686.2502,5555.0537,5686.2502,5564.5618,16488726000,378769121171.9000,2.186846
516 | 514,2021-02-10,sh.000300,5709.6840,5823.4219,5707.3295,5807.7191,5686.2502,17016978600,417056463360.9000,2.136186
517 | 515,2021-02-18,sh.000300,5922.0714,5930.9122,5747.6631,5768.3814,5807.7191,21884868600,507481235977.7000,-0.677335
518 | 516,2021-02-19,sh.000300,5734.0193,5787.8871,5667.3209,5778.8420,5768.3814,21447578000,456433793702.1000,0.181344
519 | 517,2021-02-22,sh.000300,5785.5097,5785.5097,5597.3327,5597.3327,5778.8420,28212438200,543633153216.5000,-3.140929
520 | 518,2021-02-23,sh.000300,5542.6841,5644.7551,5541.1092,5579.6681,5597.3327,23380772700,424904470814.2000,-0.315590
521 | 519,2021-02-24,sh.000300,5591.4795,5598.8284,5379.7278,5437.5683,5579.6681,22542861000,472369211004.2000,-2.546743
522 | 520,2021-02-25,sh.000300,5494.4706,5527.6296,5444.1646,5469.5584,5437.5683,23073602800,412206157140.7000,0.588316
523 | 521,2021-02-26,sh.000300,5343.9041,5416.3197,5318.8579,5336.7609,5469.5584,21226454300,405717700127.9000,-2.427938
524 | 522,2021-03-01,sh.000300,5389.2499,5421.5550,5345.9449,5418.7837,5336.7609,17746352300,358146545967.0000,1.536940
525 | 523,2021-03-02,sh.000300,5453.2847,5454.9687,5305.0545,5349.6301,5418.7837,19651111500,376444604695.3000,-1.276183
526 | 524,2021-03-03,sh.000300,5327.3467,5452.3960,5316.4809,5452.2125,5349.6301,19470905400,337610313596.0000,1.917561
527 | 525,2021-03-04,sh.000300,5388.4785,5392.3725,5254.7771,5280.7058,5452.2125,21277521100,384382456961.0000,-3.145635
528 | 526,2021-03-05,sh.000300,5191.9699,5307.8203,5174.2458,5262.7958,5280.7058,20262795600,352539774294.9000,-0.339159
529 | 527,2021-03-08,sh.000300,5299.7907,5326.2602,5079.7984,5080.0246,5262.7958,23023163500,407133802141.7000,-3.472892
530 | 528,2021-03-09,sh.000300,5066.1546,5094.3110,4917.9090,4970.9994,5080.0246,23071100400,414415213806.0000,-2.146155
531 | 529,2021-03-10,sh.000300,5047.0589,5055.2785,4981.6161,5003.6121,4970.9994,16992849000,309577408714.9000,0.656059
532 | 530,2021-03-11,sh.000300,5024.5586,5138.4146,5020.5784,5128.2156,5003.6121,18960076600,333859199678.6000,2.490271
533 | 531,2021-03-12,sh.000300,5153.6740,5153.6740,5086.8234,5146.3786,5128.2156,20102058900,323237751413.4000,0.354178
534 | 532,2021-03-15,sh.000300,5116.1228,5120.8757,4992.3989,5035.5441,5146.3786,20415308400,330740513807.9000,-2.153641
535 | 533,2021-03-16,sh.000300,5054.4089,5084.3085,5009.9510,5079.3624,5035.5441,16139005400,271755048563.6000,0.870180
536 | 534,2021-03-17,sh.000300,5062.7706,5123.5452,5020.1255,5100.8581,5079.3624,14916237600,263492417709.0000,0.423197
537 | 535,2021-03-18,sh.000300,5114.5872,5160.4566,5111.1294,5141.7681,5100.8581,14290151800,260930046844.7000,0.802022
538 | 536,2021-03-19,sh.000300,5068.5319,5089.9175,4980.7609,5007.0907,5141.7681,16417484900,282974489237.2000,-2.619282
539 | 537,2021-03-22,sh.000300,5008.3953,5071.3378,4996.5410,5057.1520,5007.0907,16740263200,264209098943.0000,0.999808
540 | 538,2021-03-23,sh.000300,5057.0632,5064.0200,4966.5340,5009.2459,5057.1520,15801396700,255755377659.6000,-0.947294
541 | 539,2021-03-24,sh.000300,4985.4013,5024.3274,4919.8932,4928.6853,5009.2459,15938598200,265970020152.0000,-1.608238
542 | 540,2021-03-25,sh.000300,4904.0683,4950.7608,4883.6615,4926.3469,4928.6853,13294518900,219782049461.7000,-0.047445
543 | 541,2021-03-26,sh.000300,4953.9453,5050.8292,4953.9453,5037.9899,4926.3469,14592669700,273901922431.0000,2.266243
544 | 542,2021-03-29,sh.000300,5052.2634,5086.6543,5010.3902,5046.8773,5037.9899,14338821500,266176599970.5000,0.176408
545 | 543,2021-03-30,sh.000300,5043.0952,5106.0365,5032.7950,5094.7291,5046.8773,13861856000,254928014461.3000,0.948147
546 | 544,2021-03-31,sh.000300,5085.9497,5085.9497,5015.6070,5048.3607,5094.7291,14133574300,241058485554.4000,-0.910125
547 | 545,2021-04-01,sh.000300,5059.9359,5115.4286,5056.8718,5110.7768,5048.3607,12032489000,211493324391.1000,1.236364
548 | 546,2021-04-02,sh.000300,5129.8545,5169.8312,5116.3472,5161.5569,5110.7768,12700225400,248060376224.1000,0.993589
549 | 547,2021-04-06,sh.000300,5178.6401,5181.1490,5125.3301,5140.3418,5161.5569,10983421000,213852444065.4000,-0.411021
550 | 548,2021-04-07,sh.000300,5141.6556,5141.6556,5065.1932,5103.7428,5140.3418,14576374800,246271190296.5000,-0.711995
551 | 549,2021-04-08,sh.000300,5078.2627,5129.1318,5062.0725,5112.2086,5103.7428,14177104700,228422004674.7000,0.165874
552 | 550,2021-04-09,sh.000300,5100.0422,5100.0422,5022.0926,5035.3374,5112.2086,12841650900,221519791677.6000,-1.503679
553 | 551,2021-04-12,sh.000300,5026.9791,5045.6018,4933.0126,4947.7459,5035.3374,15264431400,267218195772.7000,-1.739536
554 | 552,2021-04-13,sh.000300,4949.8074,4994.5404,4924.1979,4939.6438,4947.7459,13291935800,225753230649.0000,-0.163753
555 | 553,2021-04-14,sh.000300,4945.6857,4987.1191,4940.2686,4980.6279,4939.6438,12086083800,221036276090.0000,0.829697
556 | 554,2021-04-15,sh.000300,4969.9099,4969.9099,4900.3033,4948.9741,4980.6279,10882938400,213820884103.5000,-0.635538
557 | 555,2021-04-16,sh.000300,4966.8999,4979.1731,4917.9596,4966.1811,4948.9741,11123992400,213389173713.5000,0.347688
558 | 556,2021-04-19,sh.000300,4966.4090,5088.2106,4940.7473,5087.0165,4966.1811,15476982400,307899776737.5000,2.433165
559 | 557,2021-04-20,sh.000300,5065.7757,5119.8586,5058.9247,5083.3654,5087.0165,13654170000,276640588159.1000,-0.071773
560 | 558,2021-04-21,sh.000300,5055.2398,5110.5623,5047.9916,5098.7449,5083.3654,12463727700,242574995256.0000,0.302546
561 | 559,2021-04-22,sh.000300,5114.2799,5119.2246,5067.1382,5089.2435,5098.7449,12116764500,241488845756.1000,-0.186348
562 | 560,2021-04-23,sh.000300,5088.8263,5149.9825,5086.4914,5135.4534,5089.2435,12205699100,264345183118.9000,0.907992
563 | 561,2021-04-26,sh.000300,5156.5941,5181.1066,5072.9585,5077.2372,5135.4534,15138196700,325760384278.3000,-1.133614
564 | 562,2021-04-27,sh.000300,5076.6415,5095.9842,5042.6099,5090.5195,5077.2372,12396183700,254738009833.6000,0.261605
565 | 563,2021-04-28,sh.000300,5073.9728,5119.4455,5059.2628,5119.2421,5090.5195,12062031800,272182521893.2000,0.564237
566 | 564,2021-04-29,sh.000300,5128.2795,5170.5852,5113.6484,5164.1692,5119.2421,14009248000,294112454366.3000,0.877612
567 | 565,2021-04-30,sh.000300,5156.3557,5163.2517,5094.9285,5123.4890,5164.1692,16012162100,315075102884.9000,-0.787739
568 | 566,2021-05-06,sh.000300,5098.8006,5132.8986,5037.4083,5061.1244,5123.4890,15882263000,323258264641.5000,-1.217229
569 | 567,2021-05-07,sh.000300,5073.4554,5093.7471,4996.0370,4996.0527,5061.1244,17225832100,304638402155.0000,-1.285716
570 | 568,2021-05-10,sh.000300,5001.4371,5019.3927,4953.6965,4992.4220,4996.0527,17082058500,282656808853.4000,-0.072671
571 | 569,2021-05-11,sh.000300,4956.0794,5033.4938,4925.9152,5023.0595,4992.4220,15152649700,270931616512.9000,0.613680
572 | 570,2021-05-12,sh.000300,5003.8171,5051.1682,4995.4048,5044.5481,5023.0595,12661908600,228344006493.0000,0.427799
573 | 571,2021-05-13,sh.000300,4992.3519,5022.0836,4975.4462,4992.9738,5044.5481,13227940600,237821404345.3000,-1.022377
574 | 572,2021-05-14,sh.000300,5007.6286,5112.9838,4981.2948,5110.5901,4992.9738,15942618000,318802786822.9000,2.355636
575 | 573,2021-05-17,sh.000300,5115.3063,5206.6947,5115.3063,5184.9853,5110.5901,15388963400,335439913424.1000,1.455707
576 | 574,2021-05-18,sh.000300,5190.9345,5201.6721,5156.7924,5187.6013,5184.9853,11840426100,238182265921.9000,0.050453
577 | 575,2021-05-19,sh.000300,5173.1666,5193.5574,5151.6392,5172.2720,5187.6013,11872998300,250736278155.8000,-0.295499
578 | 576,2021-05-20,sh.000300,5167.0546,5201.5935,5152.0358,5186.4120,5172.2720,13845477500,277088462047.3000,0.273381
579 | 577,2021-05-21,sh.000300,5199.1285,5216.1615,5123.1171,5134.1483,5186.4120,12476848500,268053627530.6000,-1.007704
580 | 578,2021-05-24,sh.000300,5138.8149,5155.5875,5092.3894,5155.5875,5134.1483,12674233600,278513133226.0000,0.417580
581 | 579,2021-05-25,sh.000300,5165.0361,5324.3609,5161.5238,5318.4780,5155.5875,18299683900,404683305641.1000,3.159494
582 | 580,2021-05-26,sh.000300,5326.1169,5344.2837,5308.7389,5320.5927,5318.4780,16960709600,346444644792.8000,0.039761
583 | 581,2021-05-27,sh.000300,5311.3726,5378.4764,5286.0500,5338.2329,5320.5927,14846285500,311893705935.1000,0.331546
584 | 582,2021-05-28,sh.000300,5338.7278,5360.2774,5288.6515,5321.0886,5338.2329,16460580600,330711896344.2000,-0.321161
585 | 583,2021-05-31,sh.000300,5318.0825,5331.6294,5281.6851,5331.5696,5321.0886,14460326900,321450798233.5000,0.196971
586 | 584,2021-06-01,sh.000300,5320.4745,5343.7529,5269.2590,5341.6798,5331.5696,14383147400,321845842153.4000,0.189629
587 | 585,2021-06-02,sh.000300,5348.3440,5352.6404,5266.7852,5289.9736,5341.6798,13775431900,296176177153.5000,-0.967976
588 |
--------------------------------------------------------------------------------