返回介绍

第一部分 新手入门

第二部分 股票量化相关

第三部分 基金、利率互换、固定收益类

第四部分 衍生品相关

风险因子(离散类)

发布于 2022-02-20 22:26:18 字数 13582 浏览 943 评论 0 收藏 0

本代码用于计算风险因子

  • 先根据DataAPI.ThemeTickersGet得到每个主题相关的个股
  • 计算个股在前7天的每天涨跌幅,从而计算主题的每天涨跌幅(市值加权)
  • 计算个股前7天的涨跌停次数,计算主题涨跌停比例
  • 对每个股票,按照股票市值占主题总市值的比例,计算涨跌幅和涨跌停比例(均为7日),将两个指标进行排名,个股有两个排名得分
  • 再取两个排名得分的平均,对个股再次排名

排名越高,波动越大,风险越大

datetime.today()

datetime.datetime(2015, 2, 4, 22, 18, 57, 402881)

此处定义了几个函数,方便调用

def GetThemeInfo(thm_id_list):
#由于ThemeTickersGet对于数据量有限制,一次调用1000个主题数据
    num = 1000                                           #每一次调取多少个主题的信息
    cnt_num = len(thm_id_list)/num          #一次调取num个主题,要调用num次
    beginDate = '20140601'                            #开始时间
    endDate = '20150123'                               #结束时间
    if cnt_num>0:
        thm_tk_pd = pd.DataFrame({})
        for i in range(cnt_num):
            info_sub = DataAPI.ThemeTickersGet(beginDate=beginDate,endDate=endDate,themeID=thm_id_list[i*num:(i+1)*num])        #获取主题相关的个股
            thm_tk_pd = pd.concat([thm_tk_pd,info_sub])                                                   #将数据连接
        info_sub = DataAPI.ThemeTickersGet(beginDate=beginDate,endDate=endDate,themeID=thm_id_list[(i+1)*num:])
        thm_tk_pd = pd.concat([thm_tk_pd,info_sub]) 
    else:
        thm_tk_pd = DataAPI.ThemeTickersGet(beginDate=beginDate,endDate=endDate,themeID=thm_id_list)
    return thm_tk_pd

def GetMktInfo(tk_list,beginDate,endDate,field_mkt):    #获得个股的日线行情数据
    num = 50
    cnt_num = len(tk_list)/num
    if cnt_num>0:
        tk_mkt_info = pd.DataFrame({})
        for i in range(cnt_num):
            sub_info = DataAPI.MktEqudGet(ticker=tk_list[i*num:(i+1)*num],beginDate=beginDate,endDate=endDate,field=field_mkt)
            tk_mkt_info = pd.concat([tk_mkt_info,sub_info])
        sub_info = DataAPI.MktEqudGet(ticker=tk_list[(i+1)*num:],beginDate=beginDate,endDate=endDate,field=field_mkt)
        tk_mkt_info = pd.concat([tk_mkt_info,sub_info])
    else:
        tk_mkt_info = DataAPI.MktEqudGet(ticker=tk_list,beginDate=beginDate,endDate=endDate,field=field_mkt)
    return tk_mkt_info

def GetDate(n):    #获得最近7个交易日的日期
    cal = Calendar("China.SSE")
    today_cal = Date.todaysDate()
    today_dtime = datetime.today()
    if cal.isBizDay(today_cal):    #如果今天是交易日
        today_ymd = today_dtime.strftime("%Y%m%d")
        hms = " 15:05:00"
        ben_time = datetime.strptime(today_ymd+hms,"%Y%m%d %H:%M:%S")
        if today_dtime>ben_time:    #如果当前时间晚于15:05分,则可以获取到今日行情数据
            end_date = today_ymd
        else:
            cal_wd = cal.advanceDate(today_cal, '-1B', BizDayConvention.Preceding)    #获得前一个工作日Date格式
            end_date = cal_wd.toISO().replace('-','')    #转换成字符串格式‘20140102’
    else:
        cal_wd = cal.advanceDate(today_cal, '-1B', BizDayConvention.Preceding)    #获得前一个工作日Date格式
        end_date = cal_wd.toISO().replace('-','')    #转换成字符串格式‘20140102’

    end_date_cal = Date.parseISO('-'.join([end_date[0:4],end_date[4:6],end_date[6:8]]))    #更改日期格式为“2014-03-02”
    prd = '-'+str(n-1)+'B'    #起始日期和终止日期间隔的天数
    begin_date_cal = cal.advanceDate(end_date_cal, prd , BizDayConvention.Preceding)    #获得6天前的工作日
    begin_date = begin_date_cal.toISO().replace('-','')
    return begin_date,end_date

读取主题id文件,先对个股和主题进行筛选,然后获得个股的行情数据

#Main
import pandas as pd

f1 = read('20140601_20150203theme_list.txt')                   #从这个文档中读取所有的主题id
thm_id_list = f1.split(',')

thm_tk_pd = GetThemeInfo(thm_id_list=thm_id_list)    #获得主题对应个股的信息
thm_tk_pd = thm_tk_pd[(thm_tk_pd['ticker'].str.len()==6) & (thm_tk_pd['ticker'].apply(lambda x:x[0]=='0' or x[0]=='6'))]    #过滤港股和新三板,因为拿不到行情数据

grouped_thmid = thm_tk_pd.groupby('themeID')    #根据主题id分类,得到每个主题对应的个股
###对主题进行过滤如果该主题所包含的个股《5,则舍弃
fld_thmid_list = []
for name,group in grouped_thmid:    
    if len(group)>=5:
        fld_thmid_list.append(name)
thm_tk_pd = thm_tk_pd[thm_tk_pd['themeID'].isin(fld_thmid_list)]   

ThmId_Nm_dic = dict(zip(thm_tk_pd['themeID'],thm_tk_pd['themeName']))    #获得主题id与主题名称的对应
TkId_Nm_dic = dict(zip(thm_tk_pd['ticker'],thm_tk_pd['secShortName']))    #获得个股id与个股名称的对应
thm_tk_pd = thm_tk_pd[['themeID','ticker']]
tk_list = list(set(thm_tk_pd['ticker']))     #获得所有的个股
n_prd =7
beginDate,endDate = GetDate(n_prd)    #获取n_prd个交易日的具体日期
field_mkt = ['ticker','openPrice','closePrice','highestPrice','lowestPrice','marketValue','preClosePrice ']

tk_mktinfo_pd = GetMktInfo(tk_list,beginDate,endDate,field_mkt)    #获得所有个股的行情数据
tk_mktinfo_pd['return'] = (tk_mktinfo_pd['closePrice']-tk_mktinfo_pd['preClosePrice'])/tk_mktinfo_pd['preClosePrice']    #计算所有个股每天的涨跌幅

计算主题的涨跌幅(绝对值)和涨跌停比例

grouped_thmid = thm_tk_pd.groupby('themeID')    #根据主题id分类,得到每个主题对应的个股
grouped_tkid = thm_tk_pd.groupby('ticker')    #根据ticker分类,得到每个个股对应的主题
thm_rtn_dic, thm_gb_dic, thm_mkv_dic = {},{},{}    #主题的日涨幅,主题的日涨跌停比例,主题的市值
#获得主题的日收益的绝对值的平均
for thm,group_thm in grouped_thmid:
    sub_tk_list = list(group_thm['ticker'])
    sub_tk_mkt_pd = tk_mktinfo_pd[tk_mktinfo_pd['ticker'].isin(sub_tk_list)]    #获得该主题下个股的行情数据
    thm_rtn =  (sub_tk_mkt_pd['marketValue']*abs(sub_tk_mkt_pd['return'])).sum()/sub_tk_mkt_pd['marketValue'].sum()    #计算主题在这7天的平均每天绝对收益
    thm_rtn_dic[thm] = thm_rtn
    thm_mkv_dic[thm] = sub_tk_mkt_pd['marketValue'].sum()    #记录每个主题的市值(7天的和)
    num_gb = len(sub_tk_mkt_pd[(abs((sub_tk_mkt_pd['closePrice']-sub_tk_mkt_pd['preClosePrice']))/sub_tk_mkt_pd['preClosePrice']).round(2)==0.1])    #涨跌停的个股数目
    thm_gb_dic[thm] = num_gb/n_prd    #主题涨跌停比例7日均值

由主题涨跌幅和涨跌停比例,计算个股的涨跌幅和涨跌停比例

tk_inc_gb_dic = {}    #由主题计算的个股的涨幅和涨跌停比例
for tk,group_tk in grouped_tkid:
    tk_mkv = tk_mktinfo_pd['marketValue'][tk_mktinfo_pd['ticker']==tk].sum()    #得到个股市值(7天的和)
    thm_list = group_tk['themeID']
    inc,gb_ratio = 0,0
    for thm in thm_list:
        pro = tk_mkv/thm_mkv_dic[thm]    #个股占该主题的比例
        inc += thm_rtn_dic[thm]*pro
        gb_ratio += thm_gb_dic[thm]*pro
    tk_inc_gb_dic[tk] = (inc,gb_ratio)    #记录个股的涨幅和涨跌停比例

根据个股的涨跌幅和涨跌停比例进行排名,再将这两个排名进行平均,再排名

sort1 = sorted(tk_inc_gb_dic.keys(), key = lambda x:tk_inc_gb_dic[x][0], reverse=True)    #根据个股的涨幅排名,涨幅大的排名在前
sort2 = sorted(tk_inc_gb_dic.keys(), key = lambda x:tk_inc_gb_dic[x][1], reverse=True)    #根据个股的涨跌停比例排名,涨跌停比例高的排名在前
rank = lambda x:(sort1.index(x)+sort2.index(x))*1.0/2+1
id2name = lambda x:TkId_Nm_dic[x]
df = pd.DataFrame({'ticker':tk_list})
df['name'] = pd.Series(map(id2name,tk_list))
df['ranking_score'] = pd.Series(map(rank,tk_list))
df_sort = df.sort(columns=['ranking_score'],ascending = True)
df_sort.reset_index(inplace=True,drop=True)
print "最近个股风险因子排名:"
df_sort
datetime.today()

datetime.datetime(2015, 2, 4, 22, 19, 15, 638752)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文