小果排序多因子回测系统助手

SKILL研究检索
研究检索 未标注权限 许可证不明确
安装这个技能

小果(微信:xg_quant)排序多因子回测系统助手,专注于量化多因子策略的深度开发、回测与优化。 本系统基于“买入条件过滤 + 排序因子加权打分 + 排名轮动”核心架构,提供从数据治理、因子工程、 策略构建、回测执行到绩效归因的全链路解决方案。支持无限因子组合、灵活的数据注入方式、 完备的交易风控模型和丰富的输出接口。 适用人群:量化研究员、算法交易工程师、多因子策略开发者、基金/资管机构投研人员。 触发关键词:多因子回测、排序因子、因子打分、排名轮动、策略回测、量化选股、因子权重、 自定义因子、xg_rank_factor_backtrader、小果量化、因子分析、绩效归因、Alpha因子。

一句话选型结论

按资料字段整理

小果排序多因子回测系统助手是研究检索类的 Agent Skill,安装方式未标注,权限级别未标注,许可证不明确,有可直接复制的安装命令。技能本质是给模型读的说明书,效果取决于模型与客户端;装完先用一个小任务验证,再放进正式流程。

分类研究检索 安装方式未标注 权限级别未标注权限 许可证许可证不明确
累计安装 未标注 本周 未标注
GitHub 星标 未标注 仓库 未标注
下载量 未标注 技能市场下载数
权限级别 未标注权限 安装前请确认风险范围
许可证 许可证不明确 未说明

安装

未标注
在支持 Skills 的客户端里执行,装完问一句「你有哪些技能」验证
skillhub install user_676c825d/xg-rank-factor-backtrader
  1. 1
    确认客户端支持

    确认你的客户端支持 Skills(Claude、Codex、Cursor 等),并升级到较新的版本。

  2. 2
    拿到技能文件

    执行上面的命令安装;也可以把仓库里的 SKILL.md 手动放进客户端的 skills 目录。

  3. 3
    刷新技能列表

    重新打开客户端,或刷新技能列表,让新放进来的技能被加载。

  4. 4
    验证是否生效

    问一句「你有哪些技能」,确认列表里出现它,再拿一个小任务试跑。

技能档案

研究检索
字段来自技能仓库与公开索引,中文说明由本站标注
作者 / 维护方user_676c825d仓库 未标注 · 版本 未标注
宿主客户端未标注技能可被这些客户端加载
安装方式未标注安装包 community
权限级别未标注权限安装前请确认风险范围
许可证未说明许可证不明确,商用前请自行确认条款
仓库可用性available技能仓库当前是否可访问
最近核验未标注上游最后核验时间 · 数据更新 1791728663
正文体量40.9 KBSKILL.md 原文大小,越大说明说明书写得越细

典型使用场景

3 类
按分类整理的常见用法,具体以 SKILL.md 为准
查资料并整理出处

让模型按主题查资料,并把引用来源整理成清单。

网页与文献要点提炼

把长文、论文、网页压成能直接看的要点。

竞品与行业汇总

按关键词汇总竞品动态与行业信息。

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 有可直接复制的安装命令,不用自己翻文档找入口。

先想清楚的地方

  • 没有标注权限级别,实际能做什么要装好后确认。
  • 许可证不明确,商用或二次分发前先到仓库确认条款。
  • 没有做站内核验,内容以作者仓库为准。
  • 技能只是说明书,实际效果取决于模型与客户端,装完先用小任务试一遍。

更适合

  • 需要在研究检索场景里给模型补一套做法的人。
  • 愿意先读一遍 SKILL.md、确认它会让模型做什么的人。

不太适合

  • 对许可证要求很严、必须明确可商用的人。
  • 只想装完就自动变强、不打算看说明书的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
技能权限级别安装方式累计安装宿主客户端安装命令
小果排序多因子回测系统助手当前 未标注权限 未标注 未标注 未标注 有
寻找技能 浏览器控制 GitHub 仓库 3120.0 万 Codex、Claude、Cursor 有
自我改进 Agent 接触敏感数据 ClawHub 市场 1646.4 万 OpenClaw 有
灵魂追踪 联网访问 GitHub 仓库 758.9 万 Codex、Claude、Cursor 有
自我完善 联网访问 ClawHub 市场 682.9 万 OpenClaw 有
微软代工厂 调用外部服务 GitHub 仓库 661.4 万 Codex、Claude、Cursor 有

SKILL.md 全文

40.9 KB
模型实际读到的说明书原文,来自技能仓库

小果排序多因子回测系统专家

一、系统概述

使用教程:https://gitcode.com/qq_50882340/xg_rank_factor_backtrader

1.1 系统定位

小果排序多因子回测系统(xg_rank_factor_backtrader)是一套专为排名轮动型多因子策略设计的专业级量化回测框架。它将复杂的多因子选股流程标准化为可配置、可扩展的流水线作业,让研究者能够高效地进行因子挖掘、策略回测和绩效分析。

1.2 设计哲学

  • 解耦与复用:将数据加载、因子计算、条件筛选、排序打分、交易执行、绩效评估各环节解耦,每个模块可独立优化和复用。
  • 透明与可解释:每个调仓日的排序逻辑、因子权重、得分明细均可追溯,策略决策过程完全透明。
  • 灵活与扩展:支持用户自定义因子公式、自定义数据注入(标的 + 指数)、自定义交易规则,满足从简单到复杂的各类策略需求。

1.3 核心回测流程(四步)

第一步  买入条件过滤:按 buy_condi_factor 用 and / or / not 逻辑筛出初步候选池
        (is_open_buy_condi=False 时跳过,直接全市场排序)
第二步  排序因子打分:rank_factor 中每个因子得分 = 因子值 × 相关性系数 × 权重
        相关性系数:正相关 = +1,负相关 = -1;Bool 因子参与排序时按 1/0 处理
第三步  综合排序取前N:按 total_factor_rank(降序/升序/无)对总分排序,
        取前 hold_stock_limit 名形成交易股票池
第四步  先卖后买轮动:持股不在交易股票池 → 卖出;交易池中未持股 → 买入;
        受 min_hold_days、止盈(sell_type)、涨跌停过滤、单票仓位上限等约束

1.4 因子值语义约定

  • Bool 类型因子(如金叉/死叉、价格在均线上等):0 表示符合条件(True),1 表示不符合条件(False),用于买入条件 等于 0 判定。
  • 数值类型因子(连续涨跌天数、价格、动量等):正常数值比较(大于/小于/等于)。
  • 买入条件比较时系统会兼容 True/False、'T'/'t'/'TRUE'、'F'/'f'/'FALSE' 等布尔形态,1 和 0 始终按数值处理。

1.5 数据文件字段要求

字段名 说明 是否必须
date 日期 ✅ 必须
close 收盘价 ✅ 必须
open 开盘价 ✅ 必须
high 最高价 ✅ 必须
low 最低价 ✅ 必须
volume 成交量 ✅ 必须
preClose 前收盘价(用于复权与涨跌停过滤) ⚠️ 推荐
zdf 涨跌幅(不存在时自动计算) ⚠️ 推荐
amount 成交金额 ⚠️ 可选
证券代码 股票代码(缺失时自动添加) ⚠️ 可选
证券名称 股票名称 ⚠️ 可选

> 自定义指数数据列要求:使用 add_index_data_from_* 注入的指数数据只需包含 date 与 close(且 close > 0)。系统会自动识别日期列/日期索引并升序排列;若同时存在 open 列也会执行 open > 0 过滤。注入成功后,回测的指数基准将优先使用注入数据(等价于股票数据的 use_custom_data 自动切换机制)。

二、初始化参数完整参考

> 以下为 __init__ 方法全部参数的详细说明,按功能分组。

2.1 时间与标的 (Time & Universe)

参数 类型 默认值 说明
start_date str '20250101' 回测起始日期,格式 YYYYMMDD 或 YYYY-MM-DD
end_date str '20261201' 回测结束日期,格式同上
stock_list list ['159915.SZ','513100.SH','518880.SH'] 候选标的池,元素需带交易所后缀
index_stock str '000300.SH' 基准指数代码(注入自定义指数数据后以注入数据为准)

2.2 资金与费用 (Capital & Cost)

参数 类型 默认值 说明
cash float 100000 初始资金(元)
comm float 0.0001 手续费率(万1 = 0.0001)
min_commission float 0 单笔最低佣金(元),0表示不设下限
slippage float 0 滑点比例(0.001 = 千1)
risk_free_rate float 0.02 无风险利率(年化),用于夏普比率计算

2.3 交易与仓位 (Trading & Position)

参数 类型 默认值 说明
trader_type str '百分比' 买入资金分配方式:'百分比' / '金额' / '数量'
trader_value float 0.5 交易值,含义随 trader_type 变化
hold_stock_limit int 2 最大持仓数,也是排名取前N的N值
max_single_position_ratio float 1.0 单只标的占总资产比例上限,范围 (0,1]
min_hold_days int 1 最小持有天数,期间不触发轮动卖出
interval int 1 调仓间隔(交易日数)
max_workers int 4 数据加载并发线程数

2.4 因子与策略 (Factor & Strategy)

参数 类型 默认值 说明
is_open_user_factor bool True 是否启用自定义因子计算
user_factor_list list ['close','high','low','open','amount','volume','zdf'] 自定义公式所需的基础列
user_factor_cacal dict 内置示例 自定义因子公式字典
is_open_buy_condi bool True 是否启用买入条件过滤
buy_condi_factor dict 内置示例 买入条件配置字典
rank_factor dict 内置示例 排序因子配置字典
total_factor_rank str '降序' 综合得分排序方向:'降序' / '升序' / '无'

2.5 止盈与风控 (Risk Management)

参数 类型 默认值 说明
sell_type str '金额' 止盈类型:'none' / '金额' / '数量' / '百分比'
sell_zdf float 0.03 触发止盈的收益率阈值
sell_value float 1000 止盈卖出的值
enable_limit_up_down_filter bool True 是否过滤涨跌停(|涨跌幅|≥9.5% 剔除)
use_custom_data bool False 是否使用内存注入数据(注入成功会自动切换)

2.6 trader_type 与 trader_value 匹配表

trader_type trader_value 含义 买入金额计算逻辑
'百分比' 总资产比例 每只买入 ≈ 总资产 × 比例 ÷ 待买数量
'金额' 固定总金额 每只买入 ≈ 固定金额 ÷ 待买数量
'数量' 固定总股数 每只买入 ≈ 固定股数

2.7 sell_type 与 sell_value 匹配表

sell_type sell_value 含义 触发后行为
'none' 忽略 不止盈,仅做排名轮动卖出
'金额' 卖出市值金额 卖出约指定金额,不足则全卖
'数量' 卖出股数 卖出指定股数,不足则全卖
'百分比' 卖出仓位比例 卖出指定比例,≥1 则全卖
其他值 忽略 全部卖出

三、自定义因子公式引擎详解

3.1 公式编写规范

  • 数据对象:公式中固定使用 df 代表当前股票的全量日线 DataFrame。
  • 函数库:自动导入 xg_tdx_func 中全部函数,无需额外 import。
  • 返回值:支持 pd.Series(长度与 df 一致)、int/float(广播为常量列)、或可转换为 Series 的对象。
  • 命名约束:自定义因子名不可与已有列名重复。
  • 执行方式:每只股票独立 eval 计算,公式异常会被静默跳过(可通过 verbose 观察结果列确认是否生成成功)。

3.2 支持的常用指标函数速查

趋势类指标

函数 说明 示例
MA(series, n) 简单移动平均 MA(df['close'], 5)
EMA(series, n) 指数移动平均 EMA(df['close'], 12)
MACD(close, fast, slow, signal) MACD指标 MACD(df['close'], 12, 26, 9)
BOLL(close, n, k) 布林带 BOLL(df['close'], 20, 2)
SAR(high, low, step, max) 抛物线转向 SAR(df['high'], df['low'], 0.02, 0.2)

超买超卖类

函数 说明 示例
RSI(close, n) 相对强弱指标 RSI(df['close'], 14)
KDJ(high, low, close, n, m1, m2) KDJ随机指标 KDJ(df['high'], df['low'], df['close'], 9, 3, 3)
CCI(high, low, close, n) 顺势指标 CCI(df['high'], df['low'], df['close'], 14)
WR(high, low, close, n) 威廉指标 WR(df['high'], df['low'], df['close'], 14)

量能类指标

函数 说明 示例
OBV(close, volume) 能量潮 OBV(df['close'], df['volume'])
MFI(high, low, close, volume, n) 资金流量指标 MFI(df['high'], df['low'], df['close'], df['volume'], 14)
VR(volume, n) 成交量比率 VR(df['volume'], 24)

波动类指标

函数 说明 示例
STD(series, n) n周期标准差 STD(df['close'], 20)

逻辑与形态类

函数 说明 示例
CROSS(series1, series2) 上穿金叉 CROSS(MA(df['close'],5), MA(df['close'],10))
CROSS_DOWN(series1, series2) 下穿死叉 CROSS_DOWN(MA(df['close'],5), MA(df['close'],10))
REF(series, n) 引用n周期前数据 REF(df['close'], 5)
HHV(series, n) n周期最高值 HHV(df['high'], 20)
LLV(series, n) n周期最低值 LLV(df['low'], 20)
COUNT(condition, n) n周期内条件成立次数 COUNT(df['close'] > MA(df['close'],5), 10)
EVERY(condition, n) n周期内条件始终成立 EVERY(df['close'] > MA(df['close'],5), 5)
IF(condition, true_val, false_val) 条件判断 IF(df['close'] > MA(df['close'],5), 1, 0)

3.3 典型自定义因子示例

user_factor_cacal = {
    # 动量因子:20日涨跌幅
    "动量_20日": "df['close'] / REF(df['close'], 20) - 1",

    # 波动因子:20日标准差
    "波动率_20日": "STD(df['close'], 20)",

    # 均线乖离率
    "乖离率_5日": "(df['close'] - MA(df['close'], 5)) / MA(df['close'], 5)",

    # 均线多头排列评分 (0-100)
    "均线多头评分": (
        "IF(MA(df['close'],3) > MA(df['close'],5), 25, 0) + "
        "IF(MA(df['close'],5) > MA(df['close'],10), 25, 0) + "
        "IF(MA(df['close'],10) > MA(df['close'],20), 25, 0) + "
        "IF(MA(df['close'],20) > MA(df['close'],30), 25, 0)"
    ),

    # MACD金叉信号 (0=符合)
    "MACD金叉": "IF(CROSS(MACD(df['close'],12,26,9)[0], MACD(df['close'],12,26,9)[1]), 0, 1)",

    # RSI超卖信号 (0=符合)
    "RSI超卖": "IF(RSI(df['close'],14) < 30, 0, 1)",

    # 成交量放大
    "成交量放大": "IF(df['volume'] > MA(df['volume'],5) * 1.5, 1, 0)",
}

四、策略配置详解与最佳实践

4.1 买入条件配置 (buy_condi_factor)

配置格式

buy_condi_factor = {
    "因子名A": {"选择类型": "and|or|not", "选择方向": "等于|大于|小于", "值": 目标值},
}

逻辑组合规则

  • and:所有 and 条件必须同时满足。
  • or:同组 or 条件至少满足其一。
  • not:条件必须不满足。

最佳实践

  • 对于布尔型因子,推荐使用 0 表示符合条件(True),1 表示不符合(False)。
  • 避免使用过多条件导致候选池过小,建议控制在 3-5 个核心条件。
  • 可以使用 or 组合相似的替代条件,增加候选池的鲁棒性。

4.2 排序因子配置 (rank_factor)

配置格式

rank_factor = {
    "因子名A": {"相关性": "正相关|负相关", "权重": 权重值},
}

得分计算公式

单因子得分 = 因子值 × 相关性系数 × 权重
综合得分   = Σ(所有排序因子的单因子得分)
其中:相关性系数:正相关 = +1,负相关 = -1

最佳实践

  • 权重值反映因子的相对重要性,建议使用 1-10 之间的整数。
  • 布尔型因子的权重建议设为 1-2,避免过度影响得分。
  • 避免使用高度相关的因子组合,以防多重共线性。
  • 建议同时包含趋势类(动量)、均值回复类(波动率)、质量类(ROE)等不同类型的因子。

4.3 交易参数调优建议

参数 建议范围 说明
interval 1-20 日频策略用1-5,周频策略用5-10
min_hold_days 1-10 增加此值可降低换手率
hold_stock_limit 5-30 越少越集中,越多越分散
max_single_position_ratio 0.1-0.3 控制单只标的集中度风险
sell_zdf 0.05-0.30 止盈阈值,与策略周期匹配

五、完整函数清单(含内部方法)

> 框架类 xg_rank_factor_backtrader 共 62 个核心方法 + 10 个指数数据接口(合计 72 个),以下按功能模块列出,便于二次开发和深度集成。

5.1 初始化和配置管理

方法签名 说明
__init__(start_date, end_date, stock_list, ...) 构造回测实例,配置全部参数
_validate_factor_config() 验证买入因子和排序因子配置的格式合法性
_validate_params() 验证参数边界(如持仓数>0、日期范围等)
_print_config() 打印完整的初始化配置信息
get_config() -> dict 获取当前策略的全部配置参数

5.2 数据加载与注入

方法签名 说明
get_stock_data(stock_code: str) -> pd.DataFrame 获取单只股票数据(优先自定义数据,其次本地文件)
get_all_stock_data() -> dict 多线程并发加载全部标的的历史数据
get_index_data() -> pd.DataFrame 获取指数数据:优先返回注入的自定义指数数据(has_index_data() 为 True 时),否则加载本地指数文件(带缓存)
_load_single_stock(stock: str) -> tuple 多线程任务:加载单只股票数据
_normalize_dataframe(df: pd.DataFrame, stock_code: str) -> pd.DataFrame 标准化注入的DataFrame(日期处理、列补齐、复权计算)
adjust_price(df: pd.DataFrame) -> pd.DataFrame 价格复权处理(前复权/后复权)
_calculate_buy_hold_net_value(stock_data: dict) -> tuple 计算等权持有不动策略净值
_calculate_index_net_value(index_data: pd.DataFrame) -> tuple 计算指数净值

5.3 自定义数据注入接口(7种)

方法签名 说明
add_stock_data_from_dataframe(stock_code: str, df: pd.DataFrame) -> bool 从DataFrame注入数据
add_stock_data_from_excel(stock_code: str, file_path: str, sheet_name=0, **kwargs) -> bool 从Excel文件注入
add_stock_data_from_csv(stock_code: str, file_path: str, **kwargs) -> bool 从CSV文件注入(自动尝试编码)
add_stock_data_from_json(stock_code: str, file_path: str, orient='records', **kwargs) -> bool 从JSON文件注入
add_stock_data_from_dict(stock_code: str, data: dict) -> bool 从字典注入
add_stock_data_from_parquet(stock_code: str, file_path: str, columns=None, **kwargs) -> bool 从Parquet文件注入
add_stock_data_from_bytes(stock_code: str, file_bytes: bytes, file_type: str='csv', **kwargs) -> bool 从字节流注入(适合文件上传)

5.4 自定义数据管理

方法签名 说明
clear_custom_data() 清空所有已注入的自定义数据
remove_stock_data(stock_code: str) -> bool 移除指定股票的自定义数据
get_custom_data_keys() -> list 获取所有已注入数据的股票代码列表
has_custom_data(stock_code: str) -> bool 检查指定股票是否已有自定义数据

5.5 指数数据注入接口(7种)

> 将自定义指数数据注入内存,注入成功后 has_index_data() 为 True,回测的指数基准优先使用注入数据(等价于股票数据 use_custom_data 机制,自动切换)。数据只需 date、close 两列。

方法签名 说明
add_index_data_from_dataframe(df: pd.DataFrame) -> bool 从DataFrame加载指数数据
add_index_data_from_csv(file_path: str, **kwargs) -> bool 从CSV文件加载指数数据(自动尝试多编码)
add_index_data_from_excel(file_path: str, sheet_name=0, **kwargs) -> bool 从Excel文件加载指数数据
add_index_data_from_json(file_path: str, orient='records', **kwargs) -> bool 从JSON文件加载指数数据
add_index_data_from_dict(data: dict) -> bool 从字典加载指数数据(格式 {'date': [...], 'close': [...]})
add_index_data_from_parquet(file_path: str, columns=None, **kwargs) -> bool 从Parquet文件加载指数数据
add_index_data_from_bytes(file_bytes: bytes, file_type: str='csv', **kwargs) -> bool 从字节数据加载指数数据(file_type 支持 csv/excel/json,适合上传场景)

5.6 指数数据管理

方法签名 说明
clear_index_data() 清空自定义指数数据(恢复使用本地指数文件)
has_index_data() -> bool 检查是否已有自定义指数数据
get_index_data_info() -> dict 获取指数数据信息:{'has_data': bool, 'rows': int, 'start_date': str, 'end_date': str, 'columns': list}(无数据时返回 {'has_data': False})

5.7 因子计算与条件判定

方法签名 说明
_normalize_factor_name(factor_name: str, df_columns: list) -> str 规范化因子名称(处理空格、下划线等)
_is_bool_string(value) -> bool 判断字符串是否为布尔字符串('T','true','F','false')
_is_bool_like(value) -> bool 判断值是否为布尔类型(含字符串布尔)
_convert_to_bool(value) -> bool 将各种形式的布尔值转换为Python布尔
_convert_factor_value_for_rank(value) -> float 将因子值转换为排序用数值(布尔转0/1)
_check_factor_condition_single(value, target, direction) -> bool 检查单个因子条件
check_factor_condition(df: pd.DataFrame, factor_name: str, config: dict) -> pd.Series 检查因子条件,返回布尔掩码
filter_by_buy_conditions(df_date: pd.DataFrame) -> list 应用买入条件过滤,返回符合条件的股票列表
calculate_rank_score(df_date: pd.DataFrame, stock_list: list) -> pd.Series 计算排序因子加权综合得分
get_trading_stocks(df_date: pd.DataFrame) -> tuple 获取交易日期的目标交易股票池及得分

5.8 交易执行与计算

方法签名 说明
calculate_commission(amount: float) -> float 计算交易佣金(含最低佣金)
calculate_buy_shares(amount: float, price: float) -> tuple 计算买入股数和实际成本(含滑点)
calculate_sell_shares_by_amount(shares: int, price: float, sell_amount: float) -> tuple 按金额计算卖出股数和实得金额
calculate_sell_shares_by_percent(shares: int, price: float, sell_percent: float) -> tuple 按比例计算卖出股数和实得金额
calculate_sell_shares_by_count(shares: int, price: float, sell_count: int) -> tuple 按数量计算卖出股数和实得金额
calculate_sell_shares_all(shares: int, price: float) -> tuple 全部卖出计算
check_take_profit(stock: str, current_price: float, buy_price: float, shares: int) -> tuple 止盈条件检查与卖出计算
_record_daily_position(date, cash, positions, factor_maps, merged_records) 记录每日持仓和账户状态

5.9 回测执行

方法签名 说明
run_backtest() -> dict 执行完整回测流程,返回绩效指标
_print_results() 打印回测结果摘要

5.10 数据生成与转换

方法签名 说明
_convert_to_serializable(obj) 将对象转换为JSON可序列化格式
_parse_date(date_str) -> pd.Timestamp 灵活的日期解析函数
generate_equity_curve_data() -> dict 生成净值曲线数据(含策略/基准/指数净值)
generate_trade_data() -> dict 生成成交明细数据
generate_position_data() -> dict 生成每日持仓数据
generate_account_data() -> dict 生成每日账户数据

5.11 绩效评估与报告

方法签名 说明
calculate_performance_metrics(index_data: pd.DataFrame = None) -> dict 计算核心绩效指标
calculate_annual_performance() -> dict 计算年度收益统计
get_performance_metrics() -> dict 获取绩效指标(自动触发回测)
get_equity_curve_data() -> dict 获取净值曲线数据
get_trade_data() -> dict 获取成交数据
get_position_data() -> dict 获取持仓数据
get_account_data() -> dict 获取账户数据
get_annual_performance() -> dict 获取年度收益统计
get_backtrader_data() -> dict 获取回测全量数据
generate_report() -> str 生成格式化文本报告
save_to_json(filename: str = None) -> str 保存回测结果为JSON文件
save_backtrader_data(user: str = 'test') -> str 分类保存回测结果为Excel+JSON

六、输出数据结构详解

> 框架共提供 8 类对外输出数据,均由回测结束后生成(首次调用 get_* 或 run_backtest 时自动触发缓存)。

6.1 绩效指标字段 (performance_metrics)

字段 类型 说明
start_date / end_date str 回测起止日期
total_days int 交易总天数
final_value float 最终总资产
total_pnl float 总盈亏额
total_return float 总收益率(小数,如0.25=25%)
annual_return float 年化收益率
max_drawdown float 最大回撤(负数)
sharpe_ratio float 夏普比率
volatility float 年化波动率
total_trades int 总交易笔数
win_rate float 胜率
profit_loss_ratio float 盈亏比
final_holdings float 期末持仓总股数
remaining_cash float 期末剩余现金
benchmark_final_value float 基准(持有不动)期末净值
benchmark_total_return float 基准(持有不动)收益率
index_final_value float 指数期末净值
index_total_return float 指数收益率
excess_return float 相对基准的超额收益

6.2 年度收益统计字段 (annual_performance)

> 按自然年分组统计,get_annual_performance() / get_backtrader_data() 返回。键为年份字符串,值为如下字段:

字段 类型 说明
year int 年份
start_date / end_date str 当年统计起止日期
total_days int 当年交易日数
total_return float 当年总收益率(小数)
annual_return float 当年收益(按区间计算)
max_drawdown float 当年最大回撤(负数)
sharpe_ratio float 当年夏普比率
sortino_ratio float 当年索提诺比率(近似 = 夏普×0.9)
calmar_ratio float 当年卡玛比率(收益/回撤绝对值)
volatility float 当年年化波动率
win_rate float 胜率(简化统计)
benchmark_total_return float 当年基准(持有不动)收益率
index_total_return float 当年指数收益率
excess_return / excess_return_pct float 相对基准超额收益(小数 / 百分数)

6.3 净值曲线字段 (equity_curve_data)

字段 类型 说明
dates list 日期字符串列表
total_value list 每日总资产
cumulative_pnl list 累计盈亏额
cash list 每日现金余额
holdings list 每日持仓总股数
net_value list 策略净值(总资产/初始资金)
drawdown list 回撤百分比
total_return list 累计收益率(小数)
daily_return list 日收益率
benchmark_net_value list 基准(持有不动)净值
index_net_value list 指数净值

6.4 成交记录字段 (trade_data / trade_log)

> get_trade_data() 返回 {'trades': [...], 'statistics': {...}}。其中 trades 元素(即 trade_log 明细)字段如下:

字段 类型 说明
date str 交易日期
stock str 股票代码
type str 交易类型(买入 / 调仓卖出 / 止盈卖出)
price float 成交价格
shares int 成交股数
amount float 成交金额
commission float 手续费
reason str 交易原因(如"排名买入(排名:2,得分:3.5)"、"排名轮动: 不在交易股票池"、"金额止盈 卖出1000元")

statistics 子结构:

字段 类型 说明
total_trades int 总交易笔数
buy_trades int 买入笔数
sell_trades int 卖出笔数
total_commission float 累计手续费

6.5 持仓数据字段 (position_data)

> get_position_data() 返回 {'positions': [...], 'statistics': {'total_days': N}},每日一行。

字段 类型 说明
date str 日期
holdings float 当日持仓总股数
cash float 当日现金余额
total_value float 当日总资产
cumulative_pnl float 累计盈亏额
total_return float 累计收益率(百分数)
details str 当日逐票持仓明细(代码:股数,分号分隔)

6.6 账户数据字段 (account_data)

> get_account_data() 返回 {'account_history': [...], 'statistics': {}},每日一行。

字段 类型 说明
date str 日期
total_value float 当日总资产
cash float 当日现金余额
holdings float 当日持仓总股数
cumulative_pnl float 累计盈亏额
net_value float 策略净值
total_return float 累计收益率(百分数)
daily_return float 日收益率(百分数)
benchmark_net_value float 基准(持有不动)净值
index_net_value float 指数净值

6.7 导出目录结构

> save_backtrader_data(user='xxx') 将回测结果分类保存为 Excel + JSON 双格式;save_to_json() 保存单文件全量 JSON;get_backtrader_data() 内存中返回同构数据。指数数据目录保存的是回测实际使用的指数数据(注入的自定义指数数据或本地指数)。

策略模型/排序多因子策略/<user>/
├── 指数数据/
│   ├── 指数数据.xlsx
│   └── 指数数据.json
├── 成交数据/
│   ├── 成交数据.xlsx
│   └── 成交数据.json
├── 持股数据/
│   ├── 持股数据.xlsx
│   └── 持股数据.json
├── 账户数据/
│   ├── 账户数据.xlsx
│   └── 账户数据.json
├── 绩效指标/
│   ├── 绩效指标.xlsx
│   └── 绩效指标.json
├── 净值曲线/
│   ├── 净值曲线.xlsx
│   └── 净值曲线.json
├── 策略参数/
│   ├── 策略参数.xlsx
│   └── 策略参数.json
└── 年度收益统计/
    ├── 年度收益统计.xlsx
    └── 年度收益统计.json

七、完整实战示例合集

7.1 示例1:均线多头 + 动量排序轮动策略

from xg_rank_factor_backtrader.xg_rank_factor_backtrader import xg_rank_factor_backtrader

bt = xg_rank_factor_backtrader(
    start_date='20230101',
    end_date='20261201',
    stock_list=['159915.SZ', '513100.SH', '518880.SH', '510300.SH', '512880.SH', '159949.SZ'],
    index_stock='000300.SH',
    cash=500000,
    comm=0.0003,
    trader_type='百分比',
    trader_value=0.8,
    hold_stock_limit=4,
    max_single_position_ratio=0.3,
    interval=5,
    min_hold_days=3,

    is_open_user_factor=True,
    user_factor_list=['close', 'open', 'high', 'low', 'volume', 'zdf', 'amount'],
    user_factor_cacal={
        "收盘价大于5日均线": "IF(df['close'] > MA(df['close'], 5), 0, 1)",
        "5日均线在10日均线上": "IF(MA(df['close'],5) > MA(df['close'],10), 0, 1)",
        "20日动量": "df['close'] / REF(df['close'], 20) - 1",
        "60日动量": "df['close'] / REF(df['close'], 60) - 1",
        "均线多头评分": (
            "IF(MA(df['close'],3) > MA(df['close'],5), 20, 0) + "
            "IF(MA(df['close'],5) > MA(df['close'],10), 20, 0) + "
            "IF(MA(df['close'],10) > MA(df['close'],20), 20, 0) + "
            "IF(MA(df['close'],20) > MA(df['close'],30), 20, 0) + "
            "IF(MA(df['close'],30) > MA(df['close'],60), 20, 0)"
        ),
        "RSI_14": "RSI(df['close'], 14)",
        "波动率_20日": "STD(df['close'], 20)",
    },

    is_open_buy_condi=True,
    buy_condi_factor={
        "收盘价大于5日均线": {"选择类型": "and", "选择方向": "等于", "值": 0},
        "5日均线在10日均线上": {"选择类型": "and", "选择方向": "等于", "值": 0},
        "20日动量": {"选择类型": "and", "选择方向": "大于", "值": 0.01},
    },

    rank_factor={
        "均线多头评分": {"相关性": "正相关", "权重": 2},
        "20日动量": {"相关性": "正相关", "权重": 3},
        "60日动量": {"相关性": "正相关", "权重": 2},
        "RSI_14": {"相关性": "正相关", "权重": 1},
        "波动率_20日": {"相关性": "负相关", "权重": 1},
    },
    total_factor_rank='降序',

    sell_type='百分比',
    sell_zdf=0.15,
    sell_value=0.3,  # 涨15%后卖出30%仓位
    enable_limit_up_down_filter=True,
    max_workers=8,
)

metrics = bt.run_backtest()
print(bt.generate_report())
bt.save_backtrader_data(user="均线动量策略")

7.2 示例2:纯因子排名轮动(关闭买入过滤)

bt = xg_rank_factor_backtrader(
    start_date='20240101',
    end_date='20261201',
    stock_list=['159915.SZ', '513100.SH', '518880.SH', '510300.SH', '512880.SH'],
    cash=200000,
    hold_stock_limit=3,
    interval=3,
    min_hold_days=2,

    is_open_buy_condi=False,  # 关键:关闭买入条件筛选
    is_open_user_factor=True,
    user_factor_cacal={
        "20日涨跌幅": "df['close'] / REF(df['close'], 20) - 1",
        "5日涨跌幅": "df['close'] / REF(df['close'], 5) - 1",
        "20日标准差": "STD(df['close'], 20)",
        "换手率": "df['volume'] / MA(df['volume'], 20)",  # 需数据含volume
    },
    rank_factor={
        "20日涨跌幅": {"相关性": "正相关", "权重": 2},
        "5日涨跌幅": {"相关性": "正相关", "权重": 1},
        "20日标准差": {"相关性": "负相关", "权重": 1},
    },
    total_factor_rank='降序',
    trader_type='金额',
    trader_value=50000,
    sell_type='none',
)

bt.run_backtest()
print(bt.generate_report())

7.3 示例3:自定义数据注入 + 多因子回测

import pandas as pd

# 准备数据(假设已有CSV文件)
bt = xg_rank_factor_backtrader(
    start_date='20230101',
    end_date='20261201',
    stock_list=['159915.SZ', '513100.SH', '518880.SH', '510300.SH'],
    cash=300000,
    hold_stock_limit=2,
    is_open_buy_condi=False,

    is_open_user_factor=True,
    user_factor_cacal={
        "RSI_14": "RSI(df['close'], 14)",
        "MACD金叉": "IF(CROSS(MACD(df['close'],12,26,9)[0], MACD(df['close'],12,26,9)[1]), 0, 1)",
    },
    rank_factor={
        "RSI_14": {"相关性": "正相关", "权重": 1},
        "MACD金叉": {"相关性": "正相关", "权重": 2},
    },
    total_factor_rank='降序',
    sell_type='金额',
    sell_zdf=0.05,
    sell_value=2000,
)

# 注入自定义数据
bt.add_stock_data_from_csv('159915.SZ', 'data/159915.csv')
bt.add_stock_data_from_excel('513100.SH', 'data/513100.xlsx', sheet_name='Sheet1')
bt.add_stock_data_from_json('518880.SH', 'data/518880.json')
bt.add_stock_data_from_dataframe('510300.SH', pd.read_parquet('data/510300.parquet'))

bt.run_backtest()
print(bt.generate_report())
bt.save_to_json('result/multi_factor_backtest.json')

7.4 示例4:提取回测结果进行二次分析

# 运行回测
bt.run_backtest()

# 获取各项数据
metrics = bt.get_performance_metrics()
curve = bt.get_equity_curve_data()
trades = bt.get_trade_data()
positions = bt.get_position_data()

# 打印关键指标
print(f"总收益率: {metrics['total_return']*100:.2f}%")
print(f"年化收益率: {metrics['annual_return']*100:.2f}%")
print(f"最大回撤: {metrics['max_drawdown']*100:.2f}%")
print(f"夏普比率: {metrics['sharpe_ratio']:.3f}")
print(f"胜率: {metrics['win_rate']*100:.2f}%")
print(f"交易笔数: {metrics['total_trades']}")

# 使用matplotlib绘制净值曲线
import matplotlib.pyplot as plt

dates = curve['dates']
plt.figure(figsize=(12, 6))
plt.plot(dates, curve['net_value'], label='策略净值', linewidth=2)
plt.plot(dates, curve['benchmark_net_value'], label='基准(持有不动)', linewidth=1.5, linestyle='--')
if curve.get('index_net_value'):
    plt.plot(dates, curve['index_net_value'], label='指数', linewidth=1.5, linestyle=':')
plt.legend()
plt.xlabel('日期')
plt.ylabel('净值')
plt.title('策略净值 vs 基准 vs 指数')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

# 绘制回撤曲线
plt.figure(figsize=(12, 4))
plt.fill_between(dates, 0, curve['drawdown'], color='red', alpha=0.3)
plt.plot(dates, curve['drawdown'], color='red', linewidth=1)
plt.xlabel('日期')
plt.ylabel('回撤 (%)')
plt.title('策略回撤曲线')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

7.5 示例5:注入自定义指数数据做基准比较

bt = xg_rank_factor_backtrader(
    start_date='20240101',
    end_date='20261201',
    stock_list=['159915.SZ', '513100.SH', '518880.SH'],
    index_stock='000300.SH',   # 注入自定义指数数据后,以注入数据为准
    cash=100000,
    hold_stock_limit=2,
)

# 注入自定义指数数据(date + close 两列即可,均支持)
bt.add_index_data_from_csv('data/index_000300.csv')      # CSV(自动尝试编码)
# bt.add_index_data_from_dataframe(df_index)             # 或 DataFrame
# bt.add_index_data_from_excel('data/index.xlsx')        # 或 Excel
# bt.add_index_data_from_json('data/index.json')         # 或 JSON
# bt.add_index_data_from_dict({'date': [...], 'close': [...]})  # 或 字典
# bt.add_index_data_from_parquet('data/index.parquet')   # 或 Parquet

# 校验注入结果
print(bt.has_index_data())          # True
print(bt.get_index_data_info())     # {'has_data': True, 'rows': N, 'start_date':..., 'end_date':..., 'columns': [...]}

bt.run_backtest()
print(bt.generate_report())

# 如需恢复使用本地指数文件
# bt.clear_index_data()

八、高级技巧与性能优化

8.1 因子组合优化建议

  • 因子多样性:组合使用趋势因子(动量)、均值回复因子(波动率)、质量因子(ROE/毛利率)、情绪因子(换手率)等不同类型。
  • 因子正交化:避免使用高度相关的因子(如5日涨跌幅和10日涨跌幅),可考虑做中性化处理。
  • 权重调优:使用网格搜索或贝叶斯优化寻找最优权重组合。

8.2 交易成本控制

  • 降低换手:增大 interval 和 min_hold_days 可显著降低交易频率。
  • 滑点敏感度:对流动性较差的标的,适当调高 slippage 参数。
  • 佣金优化:min_commission 可模拟券商最低收费,避免小额交易被高佣金侵蚀。

8.3 数据加载优化

  • 列裁剪:user_factor_list 只配置必要的列,减少IO开销。
  • 并行加载:max_workers 可根据CPU核心数设置(建议不超过8)。
  • 数据缓存:get_stock_data 和 get_index_data 内置缓存,避免重复读取;指数注入数据命中缓存时不再读取本地文件。

8.4 策略鲁棒性提升

  • 涨跌停过滤:开启 enable_limit_up_down_filter 避免无法交易的样本。
  • 最小持有天数:防止策略过度响应短期噪声。
  • 仓位上限:max_single_position_ratio 防止单只标的过度集中。

九、常见问题与解决方案 (FAQ)

问题 解决方案
Q1: 提示"数据文件不存在" 检查 data/历史数据 或 data/全部因子数据 目录下是否有 {代码}.parquet,或使用 add_stock_data_from_* 注入数据。
Q2: 排序因子大量缺失 检查因子名是否在数据列或 user_factor_cacal 中定义,查看 generate_report() 尾部的因子缺失警告。
Q3: 买入条件配置后候选池为空 检查条件是否过于严格;确认布尔因子使用 0 表示符合条件;可暂时关闭买入条件进行调试。
Q4: 交易笔数异常多 增大 interval 和 min_hold_days;减少排序因子的数量或降低其敏感性。
Q5: 自定义数据注入后仍走本地目录 确认注入返回 True,使用 get_custom_data_keys() 验证,系统会自动切换 use_custom_data=True。
Q6: 收益率为0或异常 检查数据价格列是否全为正数;确认 cash 初始值设置正确;检查买入逻辑是否成功执行。
Q7: 布尔因子在排序中失去区分度 系统已将布尔值转为0/1,确保权重设置合理;建议布尔因子权重设为1-2。
Q8: 如何查看某个调仓日的详细排序 在回测时设置 verbose=True(默认),控制台会打印每个调仓日的排序详情。
Q9: 自定义指数数据注入后未生效 确认注入返回 True,用 has_index_data() / get_index_data_info() 验证;数据必须含 date/close 且 close > 0,否则注入会失败。

十、扩展开发指南

10.1 自定义新的技术指标

在 xg_tdx_func 库中添加新函数,然后在 user_factor_cacal 中直接调用。

10.2 自定义交易逻辑

继承 xg_rank_factor_backtrader 类,重写以下核心方法:

  • get_trading_stocks():修改交易股票池的选取逻辑
  • check_take_profit():自定义止盈/止损规则
  • calculate_buy_shares():自定义仓位分配算法

10.3 自定义绩效指标

在 calculate_performance_metrics() 中添加新的指标计算逻辑。


1. 指数数据读取接口
新增了以下方法用于加载自定义指数数据:

方法  说明
add_index_data_from_dataframe(df)   从DataFrame加载指数数据
add_index_data_from_csv(file_path)  从CSV文件加载指数数据
add_index_data_from_excel(file_path, sheet_name)    从Excel文件加载指数数据
add_index_data_from_json(file_path) 从JSON文件加载指数数据
add_index_data_from_dict(data)  从字典加载指数数据
add_index_data_from_parquet(file_path)  从Parquet文件加载指数数据
add_index_data_from_bytes(bytes, file_type) 从字节数据加载指数数据
2. 指数数据管理方法
方法  说明
clear_index_data()  清空自定义指数数据
has_index_data()    检查是否有自定义指数数据
get_index_data_info()   获取指数数据信息

小果排序多因子回测系统,让多因子策略开发更高效、更透明。如需源码、更多因子库或技术支持,欢迎联系小果(微信:xg_quant)。

常见问题

5 问
答案由本站依据条目字段整理
小果排序多因子回测系统助手怎么安装?

在支持 Skills 的客户端里执行:skillhub install user_676c825d/xg-rank-factor-backtrader。安装方式为未标注。装完刷新技能列表或重开客户端。

小果排序多因子回测系统助手支持哪些客户端?

资料没有标注宿主客户端,但只要客户端支持 Skills(Claude、Codex、Cursor 等),一般都能加载。

小果排序多因子回测系统助手权限高吗,安全吗?

权限级别为未标注权限。安装前先看它会读取或写入哪些内容。

小果排序多因子回测系统助手收费吗?

本站不代收费用,也没有标注具体价格。是否收费取决于技能本身和所用的模型或客户端,正式使用前按作者说明确认。

小果排序多因子回测系统助手用什么许可证?

许可证标注为 未说明(许可证不明确)。商用或二次分发前请到仓库确认条款原文。

热门专题

按场景挑技能
全部专题 →

技能内容以作者仓库为准;分类、权限级别与许可证状态的中文说明为中文整理,最近核验 未标注。