策略分享

综合风控:如何通过条件止损+补仓+精炼买入/卖出信号

由xyz142创建,最终由xyz142 被浏览 25 用户

策略介绍

本策略主要讲解如何在策略中加入个股风控与大盘风控逻辑。

  • 个股风控:个股价格低于某一价格时,但是不影响其他股票的买卖信号,也被称为止盈止损逻辑。
  • 大盘风控:大盘上证指数最近表现比较差时,将仓内股票全部清空,当日不再交易。

本策略就是在平台的默认可视化线性模板策略的基础上进行修改的,就是一个简单的小市值策略

  • 剔除上市小于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%的话,就出发大盘风控的实现


\

  1. 首先我们要新建一个输入特征模块,这个模块读取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
  1. 接着我们链接一个新的数据抽取模块,它的起始和结束时间和策略数据一样
  2. 接着我们将新的数据抽取模块连接到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

\

{link}