├── .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 | ![GitHub](https://img.shields.io/github/license/AkatsukiYamisora/stock-prediction-with-DL) 4 | ![Python Version](https://img.shields.io/badge/python-3.8+-blue) 5 | ![Pytorch Version](https://img.shields.io/badge/torch-1.7.0+-blue) 6 | ![GitHub watchers](https://img.shields.io/github/watchers/AkatsukiYamisora/stock-prediction-with-DL?style=social) 7 | ![GitHub Repo stars](https://img.shields.io/github/stars/AkatsukiYamisora/stock-prediction-with-DL?style=social) 8 | 9 | 目前新增了100多个技术指标,优化了一部分代码,正在做图神经网络部分内容,预计做一个小论文,等论文见刊再更新仓库^-^ 10 | 11 | ## data_downloader.py 12 | 13 | 通过baostock下载上证50,沪深300,中证500的日线数据 14 | 15 | ## backtest.py 16 | 17 | 回测模块,根据调仓周期,通过模型选股,按开盘价买入卖出(暂定),计算收益,与指数比较并绘图 18 | 19 | 当前回测结果: 20 | 21 | ![result](result.jpg) 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 | ![1](sh.600000_predict.jpg) 60 | 61 | sh.600004,白云机场 62 | 63 | ![2](sh.600004_predict.jpg) 64 | 65 | sh.600009,上海机场 66 | 67 | ![3](sh.600009_predict.jpg) 68 | 69 | sh.600010,包钢股份 70 | 71 | ![4](sh.600010_predict.jpg) 72 | 73 | sh.600011,华能国际 74 | 75 | ![5](sh.600011_predict.jpg) 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 | --------------------------------------------------------------------------------