Warning: file_exists(): open_basedir restriction in effect. File(/www/wwwroot/com.xiximiao.oa/com.cmstop/public/www/wp-content/db.php) is not within the allowed path(s): (/www/wwwroot/com.xiximiao.oa/com.cmstop/public/www/:/tmp/:/proc/:/var/log/nginx/:/www/wwwroot/com.xiximiao.oa/com.cmstop/public/:/www/wwwroot/com.xiximiao.oa/com.cmstop/vendor/:/www/wwwroot/com.xiximiao.oa/com.cmstop/ppk/) in /www/wwwroot/com.xiximiao.oa/com.cmstop/public/www/wp-includes/load.php on line 707
2380 【深度解析一】小市值动态轮动止损策略 深度研究模型 自动化交易策略代码 44300 » 轻知量化 QMT、PTrade、聚宽策略分享交流平台

2380 【深度解析一】小市值动态轮动止损策略 深度研究模型 自动化交易策略代码 44300

本策略为小市值动态轮动止损策略,核心逻辑如下:
  1. 选股机制
  • 股票池构建:选取上证综指 + 深证综指全部成分股
  • 严格过滤:剔除 ST/*ST / 退市 / 涨停 / 跌停 / 停牌股票
  • 市值筛选:每周选取流通市值最小的前 10 只股票
  • 动态轮动:每周一 10:00 调仓,确保持仓始终为最新小市值组合
  1. 仓位管理
  • 初始建仓:等额分配资金买入全部目标股票
  • 定期调仓:卖出非目标股,补入新入选股票
  • 强制止损:持仓个股亏损达 20% 立即清仓
  • 资金分配:每只股票占组合总资产 10%(g.stocknum=10)
  1. 风险控制
  • 滑点缓冲:设置 0.02 固定滑点
  • 交易限制:单笔交易量不超过市场实际成交量 10%
  • 特殊时期:每年 4 月 5 日 - 30 日强制清仓(规避财报风险)
  • 流动性保障:排除当日无法交易的股票
  1. 交易执行
  • 价格模式:使用真实价格避免未来函数
  • 交易时段:选择上午 10:00 流动性充裕时段
  • 成本控制:QMT 佣金万1,最低 5 元 

策略代码

# 回测资金 10000000

# 导入函数库
from jqdata import *


# 初始化函数,设置基准等等
# context 是由系统维护的上下文环境
# 包含买入均价、持仓情况、可用资金等资产组合相关信息
def initialize(context):
    
    # g. 开头的是全局变量
    # 一经声明整个程序都可以使用
    
    # 设置持股数量
    g.stocknum = 10
    
    # 待买入股票列表
    g.buylist = []           
    
    # 设置沪深300股指作为基准
    # 如果不设置,默认的基准也是沪深300股指
    set_benchmark('000300.XSHG')
    
    # 开启动态复权模式(使用真实价格)
    set_option('use_real_price', True)
    
    # 交易量不超过实际成交量的 0.1
    set_option('order_volume_ratio', 0.1)
    
    # 在日志中写入字符串
    # 整个回测过程中,只会在开始阶段写入一次
    log.info('初始函数开始运行且全局只运行一次')
    
    # 过滤掉order系列API产生的比error级别低的log
    # 默认是 'debug' 参数。最低的级别,日志信息最多
    # 系统推荐尽量使用'debug'参数或不显式设置,方便找出所有错误
    log.set_level('order', 'error')
    
    # 设置滑点
    # 0.02 的滑点设置还比较高
    set_slippage(FixedSlippage(0.02))
    
    # 止损函数在每个交易日的 9:45 都被调用一次
    # 主要是为了尽量控制风险
    # 止损函数调用时间在开仓、调仓函数之前
    run_daily(stoploss, '9:45') 


    # 股票类每笔交易时的手续费是:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣 5 元钱
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')


    # 每周只在第一个交易日进行股票筛选、过滤、排序、开仓、调仓等操作
    
    # 开盘时运行 filter_stocks() 函数
    # 筛选、过滤生成待买入股票列表为交易做准备 
    run_weekly(filter_stocks,1,'09:30') 
    
    # 开盘后 10:00 进行开仓、调仓操作
    run_weekly(market_open,1,'10:00') 
    

关键函数解锁后查看:

# 止损函数
# 每天检查是否有股票触发止损条件
# 如有触发则立即卖出平仓
def stoploss(context):
    
    # 使用 for 循环遍历 context.portfolio.positions 当前持仓的每一只股票
    for stock in context.portfolio.positions:
        
        # 读取每只持仓股票的买入均价赋值给 cost 变量
        cost = context.portfolio.positions[stock].avg_cost
        
        # 读取每只持仓股票的当前价格
        price = context.portfolio.positions[stock].price
        
        # 计算每只持仓股票当前的收益率
        ret = price/cost-1
        
        # 如果收益率小于 -0.2 表示浮亏已经突破 -20%
        if ret < -0.2:
            
            # 清仓该只股票
            # order_target() 将该只股票的持仓量调整为 0
            order_target(stock,0)
            
            # 在日志中写入"触发止损"这个字符串
            log.info('触发止损')
                

                
## 开盘时运行函数
def market_open(context):
    
    # 在日志中写入函数运行时间
    log.info(str('函数运行时间(market_open):'+str(context.current_dt.time())))
    
    # 如果待买入股票列表长度为 0,表示没有要操作的股票
    # 则直接返回
    if(len(g.buylist) == 0):
        return
    
    # 待买入股票列表中有要买入的股票
    # 则调用 rebalance() 函数开仓或调仓
    rebalance(context,g.buylist)



# 调仓 rebalance() 函数
# 第一个参数为上下文环境
# 第二个参数为待买入股票列表
def rebalance(context,buylist):
    
    # 根据当前资产组合的价值,计算每只股票应持仓金额
    every_stock = context.portfolio.portfolio_value/len(buylist)
    
    # 如果当前没有持仓就全部买入。等额分配资金
    if len(list(context.portfolio.positions.keys())) == 0 :
        
        # for 循环对待买入列表中的每只股票都进行购买操作
        for stock_to_buy in buylist :
            
            # 根据 every_stock 价值买入股票
            order_target_value(stock_to_buy, every_stock)
            
    # 如果有持仓,先卖出已经持有但不在待买入列表中的股票
    # 卖出已经过时的股票
    else:
        
        # 遍历每一只持仓股票代码
        for stock_to_sell in list(context.portfolio.positions.keys()):
            
            # 如果这只股票代码不在买入列表中,说明已经过时应该清仓
            if stock_to_sell not in buylist:
                
                # 清仓这只股票
                # 股票的持仓价值额度为0
                order_target_value(stock_to_sell, 0)
        
        # 为buylist里的每支股票调整仓位
        # 这句非常重要
        # 一方面会买入当前未持仓的列表中的股票
        # 另一方面也会影响其他持仓股票的仓位
        # 低于资产组合平均价值的股票会加仓
        # 高于资产组合平均价值的股票会减仓
        # 实验证明调仓对于提高收益率很有帮助
        for i in buylist:
            order_target_value(i, every_stock)
            

2025-02-23
⚠️
本站资源大多来自网络,仅供网友学习交流,未经作者或上传书面授权,请勿作他用。
站长 vx: xiangyin615 或者 留言反馈 ,我们将尽快处理。
Notice: When you of the legal rights be violate, please stir to vx: xiangyin615
个人中心
购物车
优惠劵
搜索