大盘风控和个股风控
由yvan0617创建,最终由iquant 被浏览 450 用户
【旧版提示】此文档不可用,详见新文档:
https://bigquant.com/wiki/doc/114-YCE9b0Z1h3#h-%E7%AD%96%E7%95%A5%E4%BB%8B%E7%BB%8D
一般的大盘风控和个股风控在回测模块的主函数里面处理就可以了。因为回测的主函数可以理解是每日收盘后运行,所以可以获取到当天大盘信息和个股价格信息进行风控,再综合策略的逻辑进行下单。
下面介绍另外一种风控的方法,在盘前函数进行处理,此方法处理可以取消前一日的下单,并新增当日的下单。此方法处理稍微复杂,一般建议使用上面第一种方法。如下样例实现的功能是:
- 大盘风控:大盘上证指数最近10日下跌10%时全部清仓,当日不买入。
- 个股风控:个股价格低于20均线时卖出,但是不影响其他股票的买卖信号。
第一步,我们在回测模块的初始化函数里面进行风控数据的获取
#大盘数据获取
bm_df = DataSource('bar1d_index_CN_STOCK_A').read(instruments=['000001.HIX'])
bm_df["bm_ret"] = bm_df["close"]/bm_df["close"].shift(10)-1
bm_df["bm_ret"] = bm_df["bm_ret"].shift(1) #取昨日的收益情况
context.bm_df = bm_df[['date','bm_ret']]
#个股风控计算
start_date = context.ranker_prediction.date.iloc[0]
start_date = pd.to_datetime(start_date)-timedelta(days=30)
end_date = context.ranker_prediction.date.iloc[-1]
stocks = context.ranker_prediction.instrument.to_list()
data = DataSource("bar1d_CN_STOCK_A").read(instruments=stocks,start_date=start_date.strftime("%Y-%m-%d"),end_date=end_date)
#计算个股风控,小于20日均线
def cal_risk(df):
df = df.sort_values("date")
df["ma"] = df.close.rolling(20).mean()
df["risk"] = np.where(df.close.shift(1)<df.ma.shift(1),1,0)
return df
context.stock_risk_data = data.groupby("instrument").apply(cal_risk).reset_index(drop=True)
第二步,在盘前处理函数里面进行风控逻辑处理
def bigquant_run(context, data):
today=data.current_dt.strftime('%Y-%m-%d')
now_bm = context.bm_df[context.bm_df.date==today]
#个股风控
stock_risk(context,data)
context.bm_risk = 0
#大盘风控判断
if(now_bm.bm_ret.iloc[0]<-0.01):
context.bm_risk = 1
# 得到当前未完成订单
for orders in get_open_orders().values():
# 循环,撤销订单
for _order in orders:
ins=str(_order.sid.symbol)
if data.can_trade(_order.sid) and _order.amount>0:
#大盘风控取消买单
cancel_order(_order)
print(today,'大盘风控取消买单',ins)
if data.can_trade(_order.sid) and _order.amount<0:#卖单由后续统一处理,先取消
#大盘风控取消卖单
cancel_order(_order)
print(today,'大盘风控取消卖单',ins)
#====卖出股票
stock_hold_now = {e.symbol:p.amount for e, p in context.perf_tracker.position_tracker.positions.items()}
print(today,"=======风控卖出所有的股票:",stock_hold_now)
for instr,amount in stock_hold_now.items():
#插入定单
insert_order(context,today,instr,amount)
其实大家可以发现,如上两条风控完全可以在主函数里面进行,而且处理逻辑更简单。在此只是提供一种在盘前进行处理的方法,具体策略请参照:
https://bigquant.com/experimentshare/c67265ce63db42e694fb66877259e732
\