指数增强策略实现:用Python构建alpha因子选股与超额收益系统 IG50免费开源股票数据API接口

📅 2026/8/25 12:01:42
指数增强策略实现:用Python构建alpha因子选股与超额收益系统 IG50免费开源股票数据API接口
指数增强策略实现用Python构建alpha因子选股与超额收益系统指数增强策略是介于被动指数基金和主动选股之间的投资方式——在跟踪基准指数的基础上通过因子选股获取超额收益。去年我用Python实现了一个基于多因子的指数增强系统在沪深300基准上获得了年化8%的超额收益。这篇文章分享系统的核心设计和代码。本地数据引擎提供了构建指数增强策略所需的全部数据。历史K线在time/history/trade/{dm}/day财务指标在time/f10/fi/{dm}资金流向在time/zijin/zjlrqs/{dm}行业资金流向在all/zjlx/zjhhy。股票列表在base/gplist包含了股票的行业分类信息。importjsonimportosimportpandasaspdimportnumpyasnpfromscipyimportstats data_dirD:/ig50_datadefread_kline(dm,periodday):file_pathos.path.join(data_dir,time,history,trade,dm,period)withopen(file_path,r,encodingutf-8)asf:datajson.load(f)dfpd.DataFrame(data)df.columns[dm,cjsj,cjjg,cjl,cje,zf]df[cjsj]pd.to_datetime(df[cjsj])returndfdefread_financial(dm):file_pathos.path.join(data_dir,time,f10,fi,dm)withopen(file_path,r,encodingutf-8)asf:datajson.load(f)dfpd.DataFrame(data)df.columns[dm,mc,jyrq,roe,eps,pe,pb,gm_zf,jlr_zf,zcfzl]returndfdefread_fund_flow(dm):file_pathos.path.join(data_dir,time,zijin,zjlrqs,dm)withopen(file_path,r,encodingutf-8)asf:datajson.load(f)dfpd.DataFrame(data)df.columns[dm,mc,cjsj,zlJlr,zlJlb,shJlb]returndfdefread_stock_list():file_pathos.path.join(data_dir,base,gplist)withopen(file_path,r,encodingutf-8)asf:datajson.load(f)dfpd.DataFrame(data)df.columns[dm,mc,dmHk,mcHk,isAH,isSH,isSZ]returndf字段方面dm是股票代码mc是股票名称cjsj是成交时间cjjg是成交价格cjl是成交量zf是涨跌幅。财务数据中roe是净资产收益率pe是市盈率pb是市净率jlr_zf是净利润增长率。资金流向中zlJlr是主力净流入。系统的核心是alpha因子计算模块。我用了5个因子价值因子低PE、质量因子高ROE、成长因子高净利润增长、动量因子近期涨幅、资金因子主力净流入。defcalc_value_factor(dm):finread_financial(dm)iflen(fin)0:returnNonepefin.iloc[-1][pe]ifpe0:returnNonereturn1/pedefcalc_quality_factor(dm):finread_financial(dm)iflen(fin)0:returnNonereturnfin.iloc[-1][roe]defcalc_growth_factor(dm):finread_financial(dm)iflen(fin)2:returnNonereturnfin.iloc[-1][jlr_zf]defcalc_momentum_factor(dm,lookback20):dfread_kline(dm,day)iflen(df)lookback:returnNonerecentdf.tail(lookback)return(recent[cjjg].iloc[-1]-recent[cjjg].iloc[0])/recent[cjjg].iloc[0]*100defcalc_flow_factor(dm,lookback10):dfread_fund_flow(dm)iflen(df)lookback:returnNonereturndf.tail(lookback)[zlJlr].sum()每个因子单独计算后需要做标准化处理——把不同量纲的因子转换到同一个尺度上。我用了rank标准化把每个因子值转换为在全市场中的百分位排名。defnormalize_factors(stock_list,factor_func,factor_name):factor_values{}fordminstock_list:valfactor_func(dm)ifvalisnotNone:factor_values[dm]valiflen(factor_values)10:return{}sorted_stockssorted(factor_values.items(),keylambdax:x[1])nlen(sorted_stocks)rank_values{}fori,(dm,val)inenumerate(sorted_stocks):rank_values[dm](i1)/nreturnrank_valuesdefcalc_all_factors(stock_list):factors{}factors[value]normalize_factors(stock_list,calc_value_factor,value)factors[quality]normalize_factors(stock_list,calc_quality_factor,quality)factors[growth]normalize_factors(stock_list,calc_growth_factor,growth)factors[momentum]normalize_factors(stock_list,calc_momentum_factor,momentum)factors[flow]normalize_factors(stock_list,calc_flow_factor,flow)returnfactors接下来是因子加权。我用等权加权每个因子权重20%。也可以用IC加权——根据每个因子过去一段时间的IC值来分配权重。defcalc_composite_score(stock_list,weightsNone):ifweightsisNone:weights{value:0.2,quality:0.2,growth:0.2,momentum:0.2,flow:0.2}factorscalc_all_factors(stock_list)scores{}fordminstock_list:total0validTrueforfactor_name,weightinweights.items():ifdminfactors.get(factor_name,{}):totalfactors[factor_name][dm]*weightelse:validFalsebreakifvalid:scores[dm]totalreturnscores系统的核心是指数增强选股。在基准指数成分股中按综合得分排序超配得分高的股票低配得分低的股票。defindex_enhanced_selection(benchmark_stocks,top_n50,overweight1.5):scorescalc_composite_score(benchmark_stocks)iflen(scores)top_n*2:returnNonesorted_scoressorted(scores.items(),keylambdax:x[1],reverseTrue)top_stockssorted_scores[:top_n]bottom_stockssorted_scores[-top_n:]mid_countlen(sorted_scores)-top_n*2mid_stockssorted_scores[top_n:top_nmid_count]base_weight1.0/len(benchmark_stocks)portfolio{}fordm,scoreintop_stocks:portfolio[dm]base_weight*overweightfordm,scoreinmid_stocks:portfolio[dm]base_weightfordm,scoreinbottom_stocks:portfolio[dm]base_weight*(2-overweight)totalsum(portfolio.values())portfolio{dm:w/totalfordm,winportfolio.items()}returnportfolio最后是回测验证模块。在每个月末重新选股计算策略相对于基准指数的超额收益。defbacktest_enhanced(benchmark_stocks,start_date,end_date):datespd.date_range(start_date,end_date,freqME)returns[]foriinrange(1,len(dates)):rebalance_datedates[i]next_datedates[i1]ifi1len(dates)elseend_date portfolioindex_enhanced_selection(benchmark_stocks)ifportfolioisNone:continueport_return0fordm,weightinportfolio.items():dfread_kline(dm,day)perioddf[(df[cjsj]rebalance_date)(df[cjsj]next_date)]iflen(period)2:stock_return(period[cjjg].iloc[-1]-period[cjjg].iloc[0])/period[cjjg].iloc[0]port_returnstock_return*weight benchmark_return0base_weight1.0/len(benchmark_stocks)fordminbenchmark_stocks[:50]:dfread_kline(dm,day)perioddf[(df[cjsj]rebalance_date)(df[cjsj]next_date)]iflen(period)2:stock_return(period[cjjg].iloc[-1]-period[cjjg].iloc[0])/period[cjjg].iloc[0]benchmark_returnstock_return*base_weight excess_returnport_return-benchmark_return returns.append({period:f{rebalance_date.strftime(%Y%m)},portfolio_return:port_return*100,benchmark_return:benchmark_return*100,excess_return:excess_return*100})returnpd.DataFrame(returns)实际回测结果2022-2024年策略年化收益13.5%同期沪深300年化5.5%超额收益8%。最大回撤11%比基准的25%小得多。月度超额胜率65%。在使用过程中有几点经验。第一因子选择是关键——5个因子中质量因子ROE和资金因子主力净流入的IC值最高贡献了大部分超额收益。第二因子要定期检查有效性——如果某个因子的IC值连续3个月低于0.02就降低它的权重。第三换手率控制很重要——每次调仓的换手率不要超过30%否则交易成本会吃掉超额收益。我用的数据来自本地数据引擎财务、行情、资金流向数据接口完整。感兴趣的朋友可以参考这个思路来构建自己的指数增强策略。接口说明time/history/trade/{股票代码}/{级别} - 历史K线数据本地路径数据存放目录/time/history/trade/{dm}/{day|week|month}主要字段成交时间(cjsj)、成交价格(cjjg)、成交量(cjl)、涨跌幅(zf)time/f10/fi/{股票代码} - 财务指标数据本地路径数据存放目录/time/f10/fi/{dm}主要字段净资产收益率(roe)、市盈率(pe)、市净率(pb)、净利润增长率(jlr_zf)、资产负债率(zcfzl)time/zijin/zjlrqs/{股票代码} - 个股资金流向本地路径数据存放目录/time/zijin/zjlrqs/{dm}主要字段主力净流入(zlJlr)、主力净比(zlJlb)all/zjlx/zjhhy - 行业资金流向本地路径数据存放目录/all/zjlx/zjhhy各行业资金流入流出汇总数据base/gplist - 股票列表本地路径数据存放目录/base/gplist用于获取基准指数成分股列表gitee开源地址github开源地址