综合风控:如何通过条件止损+补仓+精炼买入/卖出信号
由xyz142创建,最终由xyz142 被浏览 112 用户
策略介绍
本策略主要讲解如何在策略中加入个股风控与大盘风控逻辑。
- 个股风控:个股价格低于某一价格时,但是不影响其他股票的买卖信号,也被称为止盈止损逻辑。
- 大盘风控:大盘上证指数最近表现比较差时,将仓内股票全部清空,当日不再交易。
本策略就是在平台的默认可视化线性模板策略的基础上进行修改的,就是一个简单的小市值策略
- 剔除上市小于1年的新股、剔除ST股票、按照市值排序
- 等权持股30只、持仓5个交易日
策略实现
1. 止盈止损
止盈止损的逻辑,其实就是判断仓内的每一只股票自买入以来的涨跌,这个涨跌如果大于一个临界值,或者小于一个临界值,我们就将它卖出
止盈止损的判断需要每天判断,并不只在调仓日判断
以下代码展示了涨跌大于30%,或小于-10%,就卖出的逻辑
# 获取当前持有的所有股票
current_hold_instruments = set(context.get_account_positions().keys())
# 对于持仓中的每一只股票来说
for ins in current_hold_instruments:
# 获取它的成本价
stock_cost = context.get_position(ins).cost_price
# 获取它的当前市场价
stock_market_price = context.get_position(ins).last_price
# 计算涨跌幅
if stock_cost != 0:
return_pct = (stock_market_price - stock_cost) / stock_cost
else:
return_pct = 0
# 如果涨幅大于0.3或小于-0.1
if return_pct > 0.3 or return_pct < -0.1:
# 就把这只股票卖出
context.order_target_percent(ins, 0)
我们通过context.get_position(ins).cost_price可以获得股票的成本价,通过context.get_position(ins).last_price可以获得股票的当前市场价,这二者就可以算出股票的涨跌
之后判断涨跌是否符合止盈止损条件,如果满足就卖出
2.大盘风控
大盘风控,也叫指数择时,其实就是判断大盘表现,如果大盘最近表现太差,则将仓内股票全部卖出,今日不再交易
大盘风控的逻辑,同样也要每日判断,不只是调仓日,而且要在止盈止损之前判断
以下展示了上证指数5日内跌超5%的话,就出发大盘风控的实现
\
- 首先我们要新建一个输入特征模块,这个模块读取
cn_stock_index_bar1d
指数日线行情这个表
- 在”表达式过滤条件“中,我们加入
instrument = ‘000001.SH’
表示指数只看上证指数 - 在”表达式特征“中,我们加入
IF(close / m_lag(close, 5) - 1 < -0.05, 1, 0) AS market_risk_indicator
,是设置一个风控信号,如果大盘跌超5%,风控信号就为1,否则就为0 - 在”表达式-其他字段“与”表达式-排序字段“中,只写
date
,因为指数的instrument
我们已经具体到上证指数一个了,就不存在其他instrument
了
- 接着我们链接一个新的数据抽取模块,它的起始和结束时间和策略数据一样
- 接着我们将新的数据抽取模块连接到BigTrader的第二个输入”其他输入数据“上
- 在BigTader的初始化函数中,加入
context.data2 = context.options['data'].read()
,就成功加载刚才的大盘数据了,之后在K线处理函数中调用context.data2
就可以了
\
- 之后在K线处理函数中加入以下代码,表示大盘风控的逻辑
# 获取当前日期数据以及持仓
current_date = data.current_dt.strftime("%Y-%m-%d")
current_day_data = context.data[context.data["date"] == current_date]
current_day_data2 = context.data2[context.data2["date"] == current_date]
current_hold_instruments = set(context.get_account_positions().keys())
# 获取今天是否大盘风控的信号
current_day_market_risk_indicator = current_day_data2['market_risk_indicator'].iloc[0]
# 如果今天大盘风控
if current_day_market_risk_indicator != 0:
# 则卖出仓内所有股票
for ins in current_hold_instruments:
context.order_target_percent(ins, 0)
# 且今天不交易了
return
3. 加入止盈止损与大盘风控后的完整K线处理函数
def bigquant_run(context, data):
import pandas as pd
#--------------------------------------大盘风控模块START--------------------------------------#
# 获取当前日期数据以及持仓
current_date = data.current_dt.strftime("%Y-%m-%d")
current_day_data = context.data[context.data["date"] == current_date]
current_day_data2 = context.data2[context.data2["date"] == current_date]
current_hold_instruments = set(context.get_account_positions().keys())
# 获取今天是否大盘风控的信号
current_day_market_risk_indicator = current_day_data2['market_risk_indicator'].iloc[0]
# 如果今天大盘风控
if current_day_market_risk_indicator != 0:
# 则卖出仓内所有股票
for ins in current_hold_instruments:
context.order_target_percent(ins, 0)
# 且今天不交易了
return
#--------------------------------------大盘风控模块END----------------------------------------#
#----------------------------------------止盈模块START----------------------------------------#
# 获取当前持有的所有股票
current_hold_instruments = set(context.get_account_positions().keys())
# 对于持仓中的每一只股票来说
for ins in current_hold_instruments:
# 获取它的成本价
stock_cost = context.get_position(ins).cost_price
# 获取它的当前市场价
stock_market_price = context.get_position(ins).last_price
# 计算涨跌幅
if stock_cost != 0:
return_pct = (stock_market_price - stock_cost) / stock_cost
else:
return_pct = 0
# 如果涨幅大于0.3或小于-0.1
if return_pct > 0.3 or return_pct < -0.1:
# 就把这只股票卖出
context.order_target_percent(ins, 0)
#----------------------------------------止盈模块END------------------------------------------#
# 下一个交易日不是调仓日,则不生成信号
if not context.rebalance_period.is_signal_date(data.current_dt.date()):
return
# 从传入的数据 context.data 中读取今天的信号数据
today_df = context.data[context.data["date"] == data.current_dt.strftime("%Y-%m-%d")]
# 卖出不在目标持有列表中的股票
for instrument in sorted(set(context.get_account_positions().keys()) - set(today_df["instrument"])):
context.order_target_percent(instrument, 0)
# 买入目标持有列表中的股票
for i, x in today_df.iterrows():
context.order_target_percent(x.instrument, float(x.position))
策略表现
加入止盈止损与大盘风控的回测表现:
不加止盈止损与大盘风控的回测表现:
可以看出,止盈止损与大盘风控让该策略表现更好一些
但是要注意,止盈止损和大盘风控并不保证会提高所有策略的表现,要视情况决定是否加入这两项交易逻辑
策略源码
https://bigquant.com/codesharev2/77dd1240-edc4-4c34-a4a4-1883f271e70a
\