请 [注册] 或 [登录]  | 返回主站

量化交易吧 /  数理科学 帖子:3364712 新帖:0

[自编指数研究]上证指数一直涨, 创业板指数一直跌, 小市值择时该何去何从?——别担心,自编指数为你指路!

爱德华发表于:5 月 25 日 00:00回复(1)
"""
title:自编指数研究 v1.1 by 小宽(QQ:1026070)
description: 根据给定的股池, 按深交所指数编制算法, 计算出该股池的每日指数myindex, 再推算出ROC(20)值和是否清仓标识
    也可通过编写 getter 函数, 动态获取符合条件的股池
lastModified: 2016-12-09 12:50:00
"""
from jqdata import * # get_trade_days
import pandas as pd
import datetime as dt
#start_date = dt.datetime.strptime('2016-05-01', '%Y-%m-%d').date()
#trdays = get_all_trade_days() # 全部交易日
trdays = get_trade_days(count=365) #取最近365个交易日
#print trdays
ORIGIN_DATE = trdays[0] #起点交易日

#print '全部交易日总数: %d' % len(trdays)

# 获取多日成分股的流通市值累计值
def get_sumcaps(stock_list=None, periods=50, startdate=None, getter=None):
    #import datetime
    # 用 stock_list 传入静态成分股池, 或用 getter 函数动态获取, 两者必须有一
    if (stock_list is None or len(stock_list) == 0) and getter is None:
        print '[Error]get_mcaps: getter function or stock_list is required'
        return None
    else:
        stocks = stock_list
    result = pd.DataFrame(columns=['date','sumcap'])#, index=['date'])
    #daterange = pd.date_range(start_date, periods=100)
    #for dt in reversed(daterange):
    if startdate is None:
        #print '[Warning] param "startdate" not specified, using today\'s date instead.'
        startdate = dt.date.today()
    i = 0
    adate = startdate
    # 从当前日期开始, 逐日倒退, 获取每日累计流通市值
    while i < periods and adate >= ORIGIN_DATE: #必须有个最小日期作为限制,否则可能陷入死循环
        adate = adate + dt.timedelta(-1) # 时间倒退一日
        if adate not in trdays: #忽略非交易日
            #print '*date: %s is not a trading day, skipped' % adate
            continue
        #TODO: 动态获取成分股列表
        if getter is not None:
            stocks = getter(adate, i, periods) # 可根据 date 获取该日符合条件的成分股
        
        df = get_fundamentals(query(
                valuation.code, valuation.circulating_market_cap.label('cmcap') #获取该日流通市值
            ).filter(valuation.code.in_(stocks)), date=adate)
        
        sumcap = df['cmcap'].sum() #所有成分股的流通市值累计
        stock_count = len(df['code']) # 成分股数量, 用于归一化
        if sumcap == 0: break # 没数据了, 说明到头了, 退出循环
        result = result.append({'date': adate, 'sumcap': sumcap, 'count': stock_count}, ignore_index=True)
        i += 1
        
    return result

#startdate = dt.datetime.strptime('2016-12-01', '%Y-%m-%d').date()
#startdate = dt.date.today()
#DEMO成分股池, 也可以用 getter 函数动态获取成分股
stock_list = ['300434.XSHE', '300483.XSHE', '002743.XSHE'] 
TOTAL = 50 #至少为 ROC 周期数 2 倍, 但数据越多并不影响每日ROC涨跌幅
df = get_sumcaps(stock_list, periods=TOTAL)

# 计算指数, 附加到新的 myindex 列
def calc_myindex(df, basis=1000.0):
    df['myindex'] = basis #初始化,全置1, 也可用1000作为起始点位
    df_sumcap = df['sumcap']
    df_count = df['count']
    # 自定义指数的算法参考深交所指数算法: 当日指数=前日指数*Σ(当日成分股流通市值)/Σ(前日成分股流通市值)
    for i in reversed(range(len(df)-1)): # 从倒数第2个开始滚动计算
        prev = i + 1
        v = df['myindex'][prev]*(df_sumcap[i]/df_count[i])/(df_sumcap[prev]/df_count[prev])
        df.ix[i, 'myindex']= v # df 修改某个单元值的正确方式!

    return df

df = calc_myindex(df)
#print '---------自编指数:myindex:-----------\n', df

roc20 = df['myindex'][0] / df['myindex'][20] - 1 # 计算ROC(20)
print '自编指数:myindex 结论: 当前 roc20=%f, 清仓=%s' % (roc20, roc20<=0)

# 计算指数的ROC值和是否清仓标识clear, 附加到新的列
def calc_myindex_roc(df, days=20):
    len_df = len(df)
    df['roc'] = numpy.nan
    df['clear'] = numpy.nan
    for i in range(len_df):
        if i + days >= len_df: # 超出最大范围就跳出循环
            break
        v = df['myindex'][i] / df['myindex'][i+days] - 1
        df.ix[i, 'roc'] = v # df 修改某个单元值的正确方式! #ROC值
        df.ix[i, 'clear'] = v <= 0 #是否清仓标识
    return df
    
df = calc_myindex_roc(df, 20) # ROC(20)
print '---------自编指数:myindex with ROC20:-----------\n', df
自编指数:myindex 结论: 当前 roc20=-0.075468, 清仓=True
---------自编指数:myindex with ROC20:-----------
          date  sumcap  count      myindex       roc  clear
0   2016-12-08   48.88      3  1084.775854 -0.075468   True
1   2016-12-07   49.77      3  1104.527297 -0.046186   True
2   2016-12-06   49.07      3  1088.992455 -0.070468   True
3   2016-12-05   48.73      3  1081.446960 -0.066296   True
4   2016-12-02   48.72      3  1081.225033 -0.064336   True
5   2016-12-01   50.59      3  1122.725255 -0.035830   True
6   2016-11-30   50.01      3  1109.853529 -0.028932   True
7   2016-11-29   49.94      3  1108.300044 -0.035162   True
8   2016-11-28   51.16      3  1135.375055  0.016693  False
9   2016-11-25   51.64      3  1146.027519  0.025213  False
10  2016-11-24   51.80      3  1149.578340  0.007194  False
11  2016-11-23   53.46      3  1186.418109  0.043733  False
12  2016-11-22   54.12      3  1201.065246  0.016147  False
13  2016-11-21   53.93      3  1196.848646  0.016397  False
14  2016-11-18   53.19      3  1180.426099  0.012179  False
15  2016-11-17   53.37      3  1184.420772  0.000938  False
16  2016-11-16   54.11      3  1200.843320  0.019021  False
17  2016-11-15   54.51      3  1209.720373  0.027521  False
18  2016-11-14   55.59      3  1233.688415  0.083626  False
19  2016-11-11   54.84      3  1217.043941  0.090692  False
20  2016-11-10   52.87      3  1173.324456  0.090103  False
21  2016-11-09   52.18      3  1158.011540  0.134348  False
22  2016-11-08   52.79      3  1171.549046  0.170250  False
23  2016-11-07   52.19      3  1158.233466  0.168869  False
24  2016-11-04   52.07      3  1155.570351  0.192625  False
25  2016-11-03   52.47      3  1164.447403  0.200961  False
26  2016-11-02   51.50      3  1142.920550  0.182006  False
27  2016-11-01   51.76      3  1148.690635  0.190159  False
28  2016-10-31   50.32      3  1116.733245  0.166435  False
29  2016-10-28   50.37      3  1117.842876  0.117843  False
30  2016-10-27   51.43      3  1141.367066       NaN    NaN
31  2016-10-26   51.22      3  1136.706613       NaN    NaN
32  2016-10-25   53.26      3  1181.979583       NaN    NaN
33  2016-10-24   53.06      3  1177.541056       NaN    NaN
34  2016-10-21   52.55      3  1166.222814       NaN    NaN
35  2016-10-20   53.32      3  1183.311141       NaN    NaN
36  2016-10-19   53.10      3  1178.428762       NaN    NaN
37  2016-10-18   53.05      3  1177.319130       NaN    NaN
38  2016-10-17   51.30      3  1138.482024       NaN    NaN
39  2016-10-14   50.28      3  1115.845539       NaN    NaN
40  2016-10-13   48.50      3  1076.342654       NaN    NaN
41  2016-10-12   46.00      3  1020.861074       NaN    NaN
42  2016-10-11   45.11      3  1001.109632       NaN    NaN
43  2016-10-10   44.65      3   990.901021       NaN    NaN
44  2016-09-30   43.66      3   968.930315       NaN    NaN
45  2016-09-29   43.69      3   969.596094       NaN    NaN
46  2016-09-28   43.57      3   966.932978       NaN    NaN
47  2016-09-27   43.49      3   965.157568       NaN    NaN
48  2016-09-26   43.14      3   957.390146       NaN    NaN
49  2016-09-23   45.06      3  1000.000000       NaN    NaN
 

全部回复

0/140

量化课程

    移动端课程