作为策略集锦压轴篇,向大家介绍完整的多因子选股策略,结合了光大证券多因子选股研报,希望能在多因子研究模块,给大家打好坚实基础。
import pandas as pd
import numpy as np
# 初始化函数,全局只运行一次
def init(context):
g.n = 20 #设置最大持仓数量为20只股票
run_monthly(handle_bar,date_rule=1)
#将trade交易函数设置为定时运行:每个月第一个交易日
context.stock = []#储存上期的股票池
g.stock='000300.SH'#设置指数获取其成分股
g.kc=False #因子择时结果是够为空仓
## 开盘时运行函数
def handle_bar(context, bar_dict):
date=get_last_datetime().strftime('%Y%m%d')
#执行选股函数:alphastock(date),并将结果导入,该股票列表是需要买入的个股。
needstock_list = alphastock(date)
if g.kc ==True:
context.stock=[]
for i in list(context.portfolio.positions):
order_target(i,0)
pass
else:
#获取上期持仓个股
holdstock_list = list(context.stock)
#确定本期需要卖出的个股
sell_list = list(set(holdstock_list)-set(needstock_list))
#执行卖出操作,运用for循环,逐个操作。
for s in sell_list:
order_target(s,0)
#确定本期需要买入的个股,其余即为继续持仓的个股
buy_list=[]
for i in needstock_list:
if i in holdstock_list:
pass
else:
buy_list.append(i)
#确定可用资金,平分分配至需买入的个股
n=len(buy_list)
cash=context.portfolio.available_cash/n
#执行买入操作
for s in range(0,n,1):
stock=list(buy_list)[s]
order_value(stock,cash)
#操作完毕,将选股结果放到上期股票池储存变量中,以备下次使用。
context.stock = frozenset(needstock_list)
#===============以沪深300为股票池,除去ST和停牌=====
def stock(date):
stk=list(get_index_stocks(g.stock,date))
#2015年前上市的
stk2=list(get_all_securities('stock','20150105').index)
price=get_price(stk, None, date, '1d', ['is_paused', 'is_st'], False, None, 1, is_panel=1)
stopstk=price['is_paused'].iloc[-1]
ststk=price['is_st'].iloc[-1]
startstk=(stopstk[stopstk==0].index)
okstk=(ststk[ststk==0].index)
tradestk=list(set(startstk)&set(okstk)&set(stk2))
return tradestk
def alphastock(date):
stock_list=stock(date)
quote_rate_all=get_price(stock_list, None, date, '1d', ['quote_rate'], False, 'pre', 273, is_panel=1)['quote_rate']
nowmonth=quote_rate_all.iloc[-21:]
quote_rate=quote_rate_all.iloc[:-21]
PM_1M=quote_rate.iloc[-21:].sum()
PM_3M=quote_rate.iloc[-63:].sum()
PM_6M=quote_rate.iloc[-126:].sum()
PM_9M=quote_rate.iloc[-189:].sum()
PM_12M=quote_rate.iloc[:].sum()
PM_12MC6M=quote_rate.iloc[:].sum()-quote_rate.iloc[-126:].sum()
PM_12MC1M=quote_rate.iloc[:].sum()-quote_rate.iloc[-21:].sum()
PM_6MC1M=quote_rate.iloc[-126:].sum()-quote_rate.iloc[-21:].sum()
quote_rate=quote_rate.T
quote_rate['PM_1M']=PM_1M
quote_rate['PM_3M']=PM_3M
quote_rate['PM_6M']=PM_6M
quote_rate['PM_9M']=PM_9M
quote_rate['PM_12M']=PM_12M
quote_rate['PM_12MC6M']=PM_12MC6M
quote_rate['PM_12MC1M']=PM_12MC1M
quote_rate['PM_6MC1M']=PM_6MC1M
yinzi_list=['PM_1M','PM_3M','PM_6M','PM_9M','PM_12M','PM_12MC6M','PM_12MC1M','PM_6MC1M']
for i in quote_rate.columns:
if i in yinzi_list:
pass
else:
del quote_rate[i]
nowmonth=nowmonth.sum()
quote_rate['nowmonth']=nowmonth
stocknum=int(len(quote_rate.index)*0.1)
yinzi_IClist=[]
zeshi=0
for i in quote_rate.columns:
if i in yinzi_list:
quote_rate = pd.DataFrame(quote_rate).sort_values(by =i, ascending=False)
d=quote_rate['nowmonth'].iloc[:stocknum].mean()-quote_rate['nowmonth'].iloc[-stocknum:].mean()
if d <0:
zeshi=zeshi+1
yinzi_IClist.append(d)
else:
yinzi_IClist.append(d)
if zeshi > 4:
g.kc = True
else:
g.kc = False
quote_rate_all=quote_rate_all.iloc[-252:]
PM_1M=quote_rate_all.iloc[-21:].sum()
PM_3M=quote_rate_all.iloc[-63:].sum()
PM_6M=quote_rate_all.iloc[-126:].sum()
PM_9M=quote_rate_all.iloc[-189:].sum()
PM_12M=quote_rate_all.iloc[:].sum()
PM_12MC6M=quote_rate_all.iloc[:].sum()-quote_rate_all.iloc[-126:].sum()
PM_12MC1M=quote_rate_all.iloc[:].sum()-quote_rate_all.iloc[-21:].sum()
PM_6MC1M=quote_rate_all.iloc[-126:].sum()-quote_rate_all.iloc[-21:].sum()
df=pd.DataFrame(columns=yinzi_list)
df['PM_1M']=PM_1M
df['PM_3M']=PM_3M
df['PM_6M']=PM_6M
df['PM_9M']=PM_9M
df['PM_12M']=PM_12M
df['PM_12MC6M']=PM_12MC6M
df['PM_12MC1M']=PM_12MC1M
df['PM_6MC1M']=PM_6MC1M
for i in yinzi_list:
df[i] = (df[i] - df[i].mean())/df[i].std()
df=df.T
df['IC']=yinzi_IClist
df=df[df['IC']>0]
for i in df.columns:
if i =='IC':
pass
else:
df[i]=df[i]*df['IC']
del df['IC']
alpha=df.sum()
df=df.T
df['alpha']=alpha
df['syboml']=df.index
df=pd.DataFrame(df).sort_values(by ='alpha', ascending=False)
#获取前20只股票的代码
needstock_list=[]
for s in range(0,g.n,1):
needstock_list.append(df.iloc[s]['syboml'])
#完成函数,输入即为10只股票代码,作为策略的股票池
return needstock_list