Tushare使用
首先去Tushare社区注册自己的账号并获取token
平台支持包和http协议获取,但本文中使用接口pro_bar是集成接口,SDK层面有逻辑判断,暂时无法使用HTTP调用。
在python环境下安装tushare
pip install tushare
调用Api接口例子:
import tushare as ts
ts.set_token('your token') # 只需要在第一次或者token失效后调用,完成调取tushare数据凭证的设置,正常情况下不需要重复设置。
df = pro.trade_cal(exchange='', start_date='20180901', end_date='20181001', fields='exchange,cal_date,is_open,pretrade_date', is_open='0')
结果:
exchange cal_date is_open pretrade_date
0 SSE 20180901 0 20180831
1 SSE 20180902 0 20180831
2 SSE 20180908 0 20180907
3 SSE 20180909 0 20180907
4 SSE 20180915 0 20180914
5 SSE 20180916 0 20180914
6 SSE 20180922 0 20180921
7 SSE 20180923 0 20180921
8 SSE 20180924 0 20180921
9 SSE 20180929 0 20180928
10 SSE 20180930 0 20180928
11 SSE 20181001 0 20180928
MACD及算法介绍
MACD,又称为指数平滑移动平均线,从双指数移动平均线发展而来,由快的指数移动平均线(EMA12)减去慢的指数移动平均线(EMA26)得到快线DIFF;再用DIFF的9日指数平滑移动得到慢线DEA;再用 2×(快线DIFF-加权移动均线DEA)得到MACD。
当MACD从负数转向正数,是买的信号。当MACD从正数转向负数,是卖的信号。
当MACD以大角度变化,表示快的移动平均线和慢的移动平均线的差距非常迅速的拉开,代表了一个市场大趋势的转变。
计算公式:
EMA(12)= 前一日EMA(12)×11/13+今日收盘价×2/13
EMA(26)= 前一日EMA(26)×25/27+今日收盘价×2/27
DIFF=今日EMA(12)- 今日EMA(26)
DEA(MACD)= 前一日DEA×8/10+今日DIF×2/10
BAR=2×(DIFF-DEA)
根据公式可知MACD相关参数为迭代结果,而股票发售第一日的参数如下
DIFF=0,DEA=0,BAR(MACD)=0
第二日参数如下
EMA(12)=前一日收盘价(即第一日收盘价)+(今日收盘价 - 前一日收盘价)×2/13
EMA(26)=前一日收盘价(即第一日收盘价)+(今日收盘价 - 前一日收盘价)×2/27
DIFF=EMA(12)-EMA(26)
DEA(9)=0(即前一日DEA(9))+今日DIFF×2/10
BAR=2×(DIFF-DEA)
第三日及之后的参数可由标准计算公式算得
这样,我们就可以利用tushare库获取股票历史信息,并根据公式进行计算。
考虑到A股股票众多,需要统一处理,这里的思路是:stock_basic接口获取所有上市状态的股票代码并保存下来 -> 根据获取到的股票代码集合获取每个股票的历史信息并进行公式计算,将结果保存 -> 每日收盘后只需获取当日收盘价计算更新数据库即可。
附上每日更新数据库所用py代码,包括均价计算部分,并附2021.3.30当日数据库文件
import tushare as ts
import datetime
import time
import re
import csv
import requests
import math
import pandas
def get_daily(ts_code='', trade_date='', start_date='', end_date=''):
for _ in range(3):
try:
if trade_date:
df = ts.pro_api().daily(ts_code=ts_code, trade_date=trade_date)
else:
df = ts.pro_api().daily(ts_code=ts_code, start_date=start_date, end_date=end_date)
except():
time.sleep(1)
else:
return df
def upload_data_daily(): # 此函数为当天收盘后的更新数据库操作 读取文件,并在此基础上更新数据 {股票代码,交易日期,当天收盘价
# ,MA{5, 10, 20, 30, 60, 120, 250},Price{5, 10, 20, 30, 60, 120, 250},MACD{EMA12,EMA26}}
arr = [{}]
nowa = datetime.datetime.now()
delta = datetime.timedelta(days=1000)
n_days = nowa - delta
n_days = n_days.strftime('%Y%m%d')
nowa = nowa.strftime('%Y%m%d')
nowa = str(nowa)
n_days = str(n_days)
with open('C:\\data.csv', newline='') as f:
reader = csv.reader(f)
for row in reader:
if row[0] != 'ts_code':
i = row[0]
pri_1 = pri_5 = pri_10 = pri_20 = pri_30 = pri_60 = pri_120 = pri_250 = 0.0
df = get_daily(ts_code=i, start_date=n_days, end_date=nowa).close
now_date = get_daily(ts_code=i, start_date=n_days, end_date=nowa).trade_date
if len(df) >= 1:
pri_1 = float(df[0])
if len(df) >= 5:
for j in range(5):
pri_5 = pri_5 + float(df[j])
if len(df) >= 10:
for j in range(10):
pri_10 = pri_10 + float(df[j])
if len(df) >= 20:
for j in range(20):
pri_20 = pri_20 + float(df[j])
if len(df) >= 30:
for j in range(30):
pri_30 = pri_30 + float(df[j])
if len(df) >= 60:
for j in range(60):
pri_60 = pri_60 + float(df[j])
if len(df) >= 120:
for j in range(120):
pri_120 = pri_120 + float(df[j])
if len(df) >= 250:
for j in range(250):
pri_250 = pri_250 + float(df[j])
pri_5 /= 5
pri_10 /= 10
pri_20 /= 20
pri_30 /= 30
pri_60 /= 60
pri_120 /= 120
pri_250 /= 250
y_EMA_12 = row[14]
y_EMA_26 = row[15]
y_DEA = row[13]
EMA_12 = float(y_EMA_12) * 11.0 / 13 + pri_1 * 2.0 / 13
EMA_26 = float(y_EMA_26) * 25.0 / 27 + pri_1 * 2.0 / 27
DIFF = EMA_12 - EMA_26
DEA = float(y_DEA) * 4.0 / 5 + DIFF / 5.0
BAR = 2 * (DIFF - DEA)
arr.append({"ts_code": i, "now_date": now_date[0], "list_date": row[2]
, "pri_1": str(pri_1), "pri_5": str(pri_5), "pri_10": str(pri_10)
, "pri_20": str(pri_20), "pri_30": str(pri_30), "pri_60": str(pri_60)
, "pri_120": str(pri_120), "pri_250": str(pri_250), "DIFF": DIFF
, "DEA": DEA, "BAR": BAR, "EMA_12": EMA_12
, "EMA_26": EMA_26})
time.sleep(0.1)
with open("C:\\data.csv", 'w', newline='') as k:
fieldnames = ["ts_code", "now_date", "list_date", "pri_1", "pri_5", "pri_10", "pri_20", "pri_30", "pri_60"
, "pri_120", "pri_250", "DIFF", "DEA", "BAR", "EMA_12", "EMA_26"]
writer = csv.DictWriter(k, fieldnames=fieldnames)
writer.writeheader()
for i in range(3041):
writer.writerow(arr[i])
if __name__ == '__main__':
upload_data_daily()
print('Done.')