$npx -y skills add lzwme/finance-quant-skills --skill joinquant-docs聚宽(JoinQuant)官网策略开发指南,涵盖回测、模拟交易、数据 API、交易函数、因子与技术指标。当用户编写聚宽策略、回测、模拟盘、查询聚宽 API、get_price/order/run_daily、Alpha 因子、技术指标,或提及 joinquant、聚宽、jqdata 策略时使用。本地数据获取请用 jqdatasdk 技能。
| 1 | # 聚宽策略开发 |
| 2 | |
| 3 | 基于本目录离线文档,为聚宽官网(回测 / 模拟 / 研究)编写 Python 策略。回答 API 问题时**必须先查阅本地文档**,不得凭记忆编造函数签名或参数。 |
| 4 | |
| 5 | > **与 jqdatasdk 的区别**:`jqdata` 在官网策略环境使用;`jqdatasdk` 是本地 Python 库,API 略有不同,且不能在官网回测/模拟/研究中使用。 |
| 6 | |
| 7 | ## 文档查阅流程 |
| 8 | |
| 9 | 1. **确定问题类型**,按 [reference.md](reference.md) 定位文件 |
| 10 | 2. **用 Grep/Read 搜索**目标函数名或中文关键词(如 `get_price`、`order_target`、`市盈率`) |
| 11 | 3. **交叉验证**:API 行为查 `api.md`,字段/表结构查 `data/*.md`,踩坑查 `faq.md` |
| 12 | 4. **给出答案时**引用文档中的调用方法、参数、返回值与示例代码 |
| 13 | |
| 14 | ``` |
| 15 | 需要写策略框架? → api.md「开始写策略」「策略程序架构」 |
| 16 | 需要查数据 API? → api.md「数据获取函数」+ data/ 对应品种文档 |
| 17 | 需要下单/持仓? → api.md「交易函数」「对象」 |
| 18 | 需要财务/估值数据? → data/Stock.md(run_query + valuation/fundamentals 表) |
| 19 | 需要行业/概念选股? → data/plateData.md + api.md get_industry_stocks 等 |
| 20 | 需要技术指标? → data/technicalanalysis.md(from jqlib.technical_analysis import *) |
| 21 | 需要 Alpha 因子? → data/Alpha101.md、data/Alpha191.md |
| 22 | 需要自定义因子? → fator.md(jqfactor.Factor、calc_factors) |
| 23 | 需要因子看板数据? → data/factor_values.md |
| 24 | ``` |
| 25 | |
| 26 | ## 策略骨架 |
| 27 | |
| 28 | 最小可运行结构: |
| 29 | |
| 30 | ```python |
| 31 | # 导入聚宽函数库 |
| 32 | import jqdata |
| 33 | |
| 34 | def initialize(context): |
| 35 | g.security = '000001.XSHE' |
| 36 | set_benchmark('000300.XSHG') |
| 37 | set_option('use_real_price', True) # 开启动态复权(真实价格),建议开启 |
| 38 | run_daily(trade, time='open') # 或 time='every_bar' / '9:30' |
| 39 | |
| 40 | def trade(context): |
| 41 | security = g.security |
| 42 | close_data = attribute_history(security, 5, '1d', ['close']) |
| 43 | MA5 = close_data['close'].mean() |
| 44 | current_price = close_data['close'][-1] |
| 45 | cash = context.portfolio.available_cash |
| 46 | |
| 47 | if current_price > 1.01 * MA5: |
| 48 | order_value(security, cash) |
| 49 | elif current_price < MA5 and context.portfolio.positions[security].closeable_amount > 0: |
| 50 | order_target(security, 0) |
| 51 | ``` |
| 52 | |
| 53 | ### 生命周期函数 |
| 54 | |
| 55 | | 函数 | 说明 | |
| 56 | |------|------| |
| 57 | | `initialize(context)` | 全局初始化,仅运行一次;用 `g` 存全局变量 | |
| 58 | | `run_daily/weekly/monthly(func, ...)` | 定时任务;`func` 必须是**全局函数**,不能是类方法 | |
| 59 | | `handle_data(context, data)` | 按回测频率驱动;**不建议与 run_daily 混用** | |
| 60 | | `before_trading_start` | 开盘前(9:00) | |
| 61 | | `after_trading_end` | 收盘后(15:30) | |
| 62 | |
| 63 | 带 ♠ 标识的 API 仅支持**回测/模拟**,不能在研究模块调用。`jqdata` 模块在研究与回测环境均可使用。 |
| 64 | |
| 65 | ## 证券代码规范 |
| 66 | |
| 67 | | 市场 | 后缀 | 示例 | |
| 68 | |------|------|------| |
| 69 | | 上海证券交易所 | `.XSHG` | `600519.XSHG` | |
| 70 | | 深圳证券交易所 | `.XSHE` | `000001.XSHE` | |
| 71 | | 中金所 | `.CCFX` | `IC9999.CCFX` | |
| 72 | | 大商所 | `.XDCE` | `A9999.XDCE` | |
| 73 | | 上期所 | `.XSGE` | `AU9999.XSGE` | |
| 74 | | 郑商所 | `.XZCE` | `CY8888.XZCE` | |
| 75 | | 场外基金 | `.OF` | `519671.OF` | |
| 76 | |
| 77 | 期货策略需将 `run_daily` 的 `reference_security` 设为对应主力合约(如 `IF9999.CCFX`),以匹配夜盘开盘时间。 |
| 78 | |
| 79 | ## 常用 API 速查 |
| 80 | |
| 81 | ### 行情与历史 |
| 82 | |
| 83 | ```python |
| 84 | get_price(security, start_date, end_date, frequency='daily', fields=None, fq='pre') |
| 85 | attribute_history(security, count, unit, fields) # 回测环境,不含当天 |
| 86 | history(count, unit, field, security_list, df=True) |
| 87 | get_bars(security, count, unit, fields, include_now=True) |
| 88 | ``` |
| 89 | |
| 90 | ### 标的池与板块 |
| 91 | |
| 92 | ```python |
| 93 | get_all_securities(types=['stock'], date=None) # date 防未来函数 |
| 94 | get_index_stocks('000300.XSHG', date=None) |
| 95 | get_industry_stocks('C15', date=None) |
| 96 | get_concept_stocks('GN036', date=None) |
| 97 | set_universe([...]) # 设置后 history 可不传 security_list |
| 98 | ``` |
| 99 | |
| 100 | ### 财务数据(SQL 查询) |
| 101 | |
| 102 | ```python |
| 103 | from jqdata import * |
| 104 | q = query(valuation).filter(valuation.code == '000001.XSHE') |
| 105 | df = get_fundamentals(q, date='2015-10-15') |
| 106 | |
| 107 | # 或 run_query(单次最多 4000 行,不可连表) |
| 108 | df = finance.run_query(query(finance.STK_XXX).filter(...).limit(4000)) |
| 109 | ``` |
| 110 | |
| 111 | ### 交易 |
| 112 | |
| 113 | ```python |
| 114 | order(security, amount) # 按股数,正买负卖 |
| 115 | order_value(security, value) # 按金额 |
| 116 | order_target(security, amount) # 调到目标股数 |
| 117 | order_target_value(security, value) # 调到目标市值 |
| 118 | order_target_percent(security, percent) # 调到目标仓位比例 |
| 119 | ``` |
| 120 | |
| 121 | A 股买入数量须为 100 整数倍(科创板 200 起);卖光持仓时不受限。每日最多 10000 笔订单。 |
| 122 | |
| 123 | ### 技术指标 |
| 124 | |
| 125 | ```python |
| 126 | from jqlib.technical_analysis import * |
| 127 | # check_date 策略中建议用 context.current_dt,避免盘中取当日收盘指标产生未来数据 |
| 128 | result = MACD(security_list, check_date=context.current_dt, SHORT=12, LONG=26, MID=9) |
| 129 | ``` |
| 130 | |
| 131 | ### 自定义因子 |
| 132 | |
| 133 | ```python |
| 134 | from jqfactor import Factor, calc_factors |
| 135 | |
| 136 | class MyFactor(Factor): |
| 137 | name = 'my_factor' |
| 138 | max_window = 5 |
| 139 | dependencies = ['close'] |
| 140 | def calc(self, data): |
| 141 | return data['close'].mean() |
| 142 | |
| 143 | factors = calc_factors(securities, [MyFactor()], start_date, end_date) |
| 144 | ``` |
| 145 | |
| 146 | 详见 `fator.md` 与 `data/Alpha101.md`、`data/Alpha191.md`。 |
| 147 | |
| 148 | ## 关键注意事项 |
| 149 | |
| 150 | ### 防止未来函数 |
| 151 | |
| 152 | - `get_all_securities(date=...)`、`get_index_stocks(..., date=...)` 等必须传入**历史时点**的 `date`,不能用未来日期 |
| 153 | - `history` / `attribute_history` 取天数据时**不包含当天**;要当天数据需取分钟级 |
| 154 | - 技术指标 `check_date` 只精确到日期时返回收盘值,盘中调用当天会产生未来数据 |
| 155 | - 财务数据默认按公告日期处理,注意 `get_fundamentals` 的 `date` 参数含义 |
| 156 | |
| 157 | ### 运行频率 |
| 158 | |
| 159 | - 优先使用 `run_daily`,避免与 `handle_data` 混用 |
| 160 | - `run_daily(func, time='every_bar')` 频率与回测设置一致 |
| 161 | - `run_weekly/monthly` 的 `force=False` 可避免晚注册时的就近执行 |
| 162 | |
| 163 | ### 数据查询限制 |
| 164 | |
| 165 | - `run_query` / `get_fundamentals` 单次最多返回 **4000 行** |
| 166 | - `run_query` **不支持连表查询** |
| 167 | - 默认行情为**前复权**;`fq=None` 为不复权 |
| 168 | |
| 169 | ### 环境与产品区分 |
| 170 | |
| 171 | | 产品 | 使用场景 | |
| 172 | |------|----------| |
| 173 | | `jqdata`(官网) | 回测、模拟、研究 | |
| 174 | | `jqdatasdk`(本地) | 本地量化研究,**不能**在官网策略中 im |