在CAPM模型的基础上,再向大家讲述Fama-French的三因子模型,并构建策略,实际应用于A股市场。
import pandas as pd
import numpy as np
from sklearn import linear_model
# 初始化函数,全局只运行一次
def init(context):
g.bstk = '399006.SZ' #设置指数
set_benchmark(g.bstk)#设置基准指数
g.day = 0 #记录运行天数
g.tradeday = 20 #调仓频率
g.stock = [] #储存上期的股票池
g.trade = False #是否调仓的开关
g.longday = 252 #样本长度
g.stocknum = 20 #持仓数量
pass
#每日开盘前9:00被调用一次,用于储存自定义参数、全局变量,执行盘前选股等
def before_trading(context):
#判断是否调仓
if g.day%g.tradeday==0:
g.trade=True
else:
g.trade=False
g.day=g.day+1
## 开盘时运行函数
def handle_bar(context, bar_dict):
if g.trade==True:
#获取选股结果
needstock_list = alpha_FF()
#获取上期持仓个股
holdstock_list = list(g.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)
#操作完毕,将选股结果放到上期股票池储存变量中,以备下次使用。
g.stock = frozenset(needstock_list)
else:
pass
#=================获取股票池==================================
def stock(yestoday,today): #要的是过去交易日的股票池,但换仓日不应该停牌
stk2=list(get_index_stocks(g.bstk,yestoday))#过去的
stk=list(get_index_stocks(g.bstk,today))#换仓日的
#获取换仓日的股票再换仓日的ST和停牌情况
price=get_price(stk, None, today, '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))#符合不停牌非ST和过去交易日的沪深300成分股
return tradestk
#==========================获取当天交易日的前N个交易日的日期
def tradeday(today,n):
daylist=list(get_all_trade_days().strftime('%Y%m%d'))
calnum = daylist.index(today)#获取今日日期在整个月历中的序
lasttrade=daylist[calnum-n]#去前N个序的交易日
return lasttrade
#==========================alpha计算函数=========================
def alpha_FF():
today=get_last_datetime().strftime('%Y%m%d')#获取当天日期 格式YMD
#获取前N个交易日的日期
ldate=tradeday(today,g.longday)
stock_list = stock(ldate,today) #获取交易股票列表
stock_num = int(len(stock_list)*0.2)
#查询市值、所有者权益数据
q = query(valuation.symbol,valuation.market_cap,balance.total_equity).filter(valuation.symbol.in_(stock_list),)
basic = get_fundamentals(q, date = ldate)
basic['B/M']= basic['balance_total_equity']/basic[&#