🚀 AI 一键生成 joinquant 策略代码
立即体验

如何在聚宽中实现Tiny100小市值选股策略?(附Python源码与回测设置)

joinquant | 发布时间: 2026/8/12
以下内容由 EasyQuant 生成。

问题描述

聚宽Tiny100小市值策略如何编写与回测?
如何在聚宽中实现Tiny100类小市值选股策略,并正确处理股票池过滤、排序和回测调仓?

解决方案

聚宽 Tiny100 小市值策略实现指南

Tiny100 策略是一种经典的量化选股策略,其核心逻辑是在全市场中剔除风险股票(如ST、停牌、退市股)后,选择市值最小的前100只股票构建投资组合,并定期(如每月)进行调仓。在聚宽(JoinQuant)平台上实现该策略,需要正确处理财务数据查询、股票池过滤、动态复权(真实价格)设置以及定时调仓。

以下是完整的策略编写思路与 Python 源码实现:

一、 策略核心设计要点

  1. 开启真实价格模式:在 initialize 中调用 set_option('use_real_price', True)。小市值股票极易受到分红送股影响,使用真实价格能有效避免回测中的未来函数,确保交易股数(100股的整数倍)计算准确。
  2. 股票池过滤
    • 剔除 ST 股、退市股、未上市股(使用 get_current_data()get_extras())。
    • 剔除停牌股(使用 get_current_data().paused)。
  3. 市值排序:使用 get_fundamentals 查询 valuation.market_cap(总市值),并按升序排序,取前100只。
  4. 定时调仓:使用 run_monthly 设置在每月第一个交易日开盘时进行调仓,降低交易频次和滑点损耗。

二、 策略完整源码(Python3)

# 导入聚宽函数库
import pandas as pd
from jqdata import *

def initialize(context):
    # 设定沪深300作为基准
    set_benchmark('000300.XSHG')
    # 开启动态复权模式(真实价格),小市值策略必须开启
    set_option('use_real_price', True)
    
    # 设定滑点与交易税费
    set_slippage(PriceRelatedSlippage(0.00246), type='stock')
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
    
    # 策略参数设置
    g.target_stock_count = 100  # 持股数量
    
    # 每月第一个交易日,09:30 运行调仓函数
    run_monthly(rebalance, monthday=1, time='09:30', reference_security='000300.XSHG')

def rebalance(context):
    # 1. 获取当前全市场股票
    all_stocks = list(get_all_securities(['stock'], date=context.current_dt.date()).index)
    
    # 2. 过滤停牌、ST、科创板等股票
    current_data = get_current_data()
    initial_filter_stocks = []
    for stock in all_stocks:
        # 剔除科创板(688开头)
        if stock.startswith('688'):
            continue
        # 剔除停牌、ST
        if current_data[stock].paused or current_data[stock].is_st:
            continue
        # 剔除退市或名称中带退的股票
        if '退' in current_data[stock].name:
            continue
        initial_filter_stocks.append(stock)
        
    # 3. 查询市值数据并排序
    # 每次最多返回5000行,小市值过滤后的股票数量通常在此范围内
    q = query(
        valuation.code,
        valuation.market_cap
    ).filter(
        valuation.code.in_(initial_filter_stocks)
    ).order_by(
        valuation.market_cap.asc()  # 按市值升序排列
    ).limit(g.target_stock_count)
    
    df_fundamentals = get_fundamentals(q, date=context.previous_date)
    
    # 获取目标买入列表
    target_stocks = list(df_fundamentals['code'])
    
    # 4. 执行调仓交易
    # 卖出不在目标列表中的持仓股票
    current_positions = list(context.portfolio.positions.keys())
    for stock in current_positions:
        if stock not in target_stocks:
            order_target(stock, 0)
            log.info(f"卖出非目标股: {stock}")
            
    # 等权重买入目标股票
    if len(target_stocks) > 0:
        # 计算每只股票分配的资金
        target_value = context.portfolio.total_value / len(target_stocks)
        for stock in target_stocks:
            order_target_value(stock, target_value)
            log.info(f"调仓买入/调整目标股: {stock} 至价值 {target_value:.2f}元")

三、 回测设置与注意事项

  1. 回测频率:建议选择天频率分钟频率。由于调仓在开盘 09:30 执行,天频率回测即可满足基本需求且运行速度更快。
  2. 滑点设置:小市值股票流动性较差,实盘中容易出现冲击成本。建议在回测中适当调高滑点(例如使用 PriceRelatedSlippage(0.005))以更真实地模拟市场。
  3. 幸存者偏差:聚宽的 get_all_securitiesget_fundamentals 已经包含了历史已退市的股票,这能有效避免幸存者偏差,使小市值策略的回测结果更具参考价值。