因为每天复盘工作需要做一些数据统计,手工统计实在太麻烦,干脆在研究里实现,省了不少时间。
主要实现了以下三个功能:
其中SAR指标的yes/no信号源自于股社区的鱼盆模型,SAR指标的计算使用了talib库,与同花顺、通达信等软件的计算结果有所差别,暂时还没有好的解决方案。其中1、2项的复盘结果会输出一个文本文档,3项则直接在研究里输出。因为聚宽的数据是每天下午四点更新,建议在四点以后运行,可获得当日的复盘统计。供大家参考。
每日复盘
import talib as ta
import numpy as np
import pandas as pd
import jqdata as jq
import re
import requests
'''定义公共变量和函数'''
# 获取交易日数据
today = datetime.date.today()
trade_days = jq.get_trade_days(end_date=today, count=21)
today = trade_days[-1] # 当天
yesterday = trade_days[-2] # 上一个交易日
previous_day_20 = trade_days[-21] # 前20个交易日
# 获取涨跌幅函数
def get_stock_rise(stock_list, start_date, end_date):
# 获取当日未停牌股票
panel = get_price(stock_list, start_date=end_date, end_date=end_date, fields=['paused'])
df = panel['paused'].T
df = df[df[end_date] == 0]
stock_list = list(df.index)
# 获取收盘价数据
panel = get_price(stock_list, start_date=start_date, end_date=end_date, fields=['close'])
df = panel['close'].T
# 计算涨跌幅
df['rise'] = (df[end_date] - df[start_date]) / df[start_date]
df = df.sort_index(by='rise', ascending=False)
return df
# 匹配行业和概念名称
def match_text(industry_name):
r = requests.get(r'https://www.joinquant.com/data/dict/plateData')
tmp = r.content.decode('utf-8')
matches = re.findall(r"<h[\d]{1,} id=\"" + industry_name + "\">.*?" + industry_name + ".*?</h[\d]{1,}>.*?<table>(.*?)</table>", tmp, re.S)
content = matches[0]
tr_matches = re.findall(r"<tr>.*?<td>(.*?)</td>.*?<td>(.*?)</td>.*?<td>(.*?)</td>.*?</tr>", content, re.S)
for code, name, start_date in tr_matches:
yield code, name, start_date
# 获取板块和概念数据
def get_block_list(textlist):
df = map(lambda x:pd.DataFrame([[code, name, start_date] for code, name, start_date in match_text(x)], columns=['code','name','start_date']), textlist)
df_block = pd.concat(df,axis=0).reset_index(drop=1)
# 增加涨跌幅列
df_block['rise'] = 0
return df_block
'''统计盘面数据'''
# 获取涨跌幅数据
stock_list = list(get_all_securities(['stock']).index)
df = get_stock_rise(stock_list, yesterday, today)
# 涨跌幅统计
df_positive = df[df['rise'] > 0]
df_negative = df[df['rise'] < 0]
df_zero = df[df['rise'] == 0]
df_positive_5 = df[df['rise'] >= 0.05]
df_negative_5 = df[df['rise'] <= -0.05]
rise_median = df['rise'].median()
# 获取首日上市新股
# 因首日上市新股涨幅统计为nan,需在涨幅统计时加上新股的数量
df_new = np.isnan(df.rise)
df_new = df_new[df_new == True]
# 获取两市成交额
index_sh = '000001.XSHG' #上证综指
index_sz = '399106.XSHE' #深证综指
panel = get_price([index_sh,index_sz], start_date=yesterday, end_date=today, fields=['money'])
df = panel['money'].T
# 成交额统计
money_today = df[today].sum() / 1e+8
money_rise = (df[today].sum() - df[yesterday].sum()) / 1e+8
# 复盘总结
review = '(%s)\n复盘:\n' % today
review += '今日两市上涨%s家、下跌%s家、平盘%s家,涨幅在5%%以上%s家、跌幅在5%%以上%s家,涨幅中位数%.2f%%。\n' % (
(len(df_positive) + len(df_new)),
len(df_negative),
len(df_zero),
(len(df_positive_5) + len(df_new)),
len(df_negative_5),
rise_median*100)
review += '两市成交额%.2f亿,较上一交易日%s%.2f亿。\n' % (
money_today,
('增加' if money_rise > 0 else '减少'),
abs(money_rise))
print(review)
write_file('复盘统计/review.txt', review)
'''统计SAR指标'''
# 初始化参数
n = 10
index_list = ('000001.XSHG', #上证指数
'399001.XSHE', #深证成数
'399005.XSHE', #中小板指
'399006.XSHE', #创业板指
'000016.XSHG', #上证50
'000300.XSHG', #沪深300
'000905.XSHG', #中证500
'399678.XSHE', #深次新股
)
df_sar = pd.DataFrame(index=index_list,
columns=('name','signal','critical_value','critical_rise','previous_20_rise','annual_rise'))
review = '\nSAR指标:\n'
# 统计yes/no信号
for index in index_list:
# 获取指数名称
df_sar.name[index] = get_security_info(index).display_name
# 计算SAR值
df = get_price(index, end_date=today, fields=('open','high','low','close'), count=n)
sar = ta.SAR(df.high.values, df.low.values, acceleration=0.02, maximum=0.2)
# 判断yes/no信号
df_sar.signal[index] = 'yes' if df.close[-1] > sar[-1] else 'no'
# 临界值
df_sar.critical_value[index] = sar[-1]
# 临界幅度,达到临界值需要的涨跌幅度
df_sar.critical_rise[index] = (sar[-1] - df.close[-1]) / df.close[-1]
# 计算20天涨幅
df_20 = get_price(index, end_date=previous_day_20, fields='close', count=1)
df_sar.previous_20_rise[index] = (df.close[-1] - df_20.close[-1]) / df_20.close[-1]
# 计算年度涨幅
last_year = datetime.date.today().year - 1
last_end_date = datetime.date(last_year, 12, 31)
df_last = get_price(index, end_date=last_end_date, fields='close', count=1)
df_sar.annual_rise[index] = (df.close[-1] - df_last.close[-1]) / df_last.close[-1]
# 输出
review += '%s:%s,临界值 %.2f,临界幅度 %.2f%%,20天涨幅 %.2f%%,年度涨幅 %.2f%%\n' % (
df_sar.name[index],
df_sar.signal[index],
df_sar.critical_value[index],
df_sar.critical_rise[index]*100,
df_sar.previous_20_rise[index]*100,
df_sar.annual_rise[index]*100)
print(review)
write_file('复盘统计/review.txt', review, append=True)
'''统计行业板块涨跌幅'''
#获取行业数据
textlist = ["申万一级行业"]
df_block = get_block_list(textlist)
df_block['rise_20'] = 0
# 获取板块涨跌幅数据
for index in df_block.index:
# 获取板块成份股
stock_list = list(get_industry_stocks(df_block.code[index], today))
# 获取板块今日涨跌幅数据
df = get_stock_rise(stock_list, yesterday, today)
df_block.loc[index,'rise'] = df.rise.mean()
# 获取板块20天涨跌幅数据
df_20 = get_stock_rise(stock_list, previous_day_20, today)
df_block.loc[index,'rise_20'] = df_20.rise.mean()
print('申万一级行业涨跌幅')
df_block.sort(["rise_20"], ascending=False)
'''统计概念板块涨跌幅'''
#获取行业数据
textlist = ["概念板块"]
df_block = get_block_list(textlist)
df_block['rise_20'] = 0
# 获取板块涨跌幅数据
for index in df_block.index:
# 获取板块成份股
stock_list = list(get_concept_stocks(df_block.code[index], today))
# 获取板块今日涨跌幅数据
df = get_stock_rise(stock_list, yesterday, today)
df_block.loc[index,'rise'] = df.rise.mean()
# 获取板块20天涨跌幅数据
df_20 = get_stock_rise(stock_list, previous_day_20, today)
df_block.loc[index,'rise_20'] = df_20.rise.mean()
print('概念板块涨跌幅')
df_block.sort(["rise_20"], ascending=False)
本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...
移动端课程