1. 搭空架子
先写 init / before_trading / handle_bar / after_trading 四个函数,跑起来只打日志,确认框架能启动。
RQAlpha 项目研究站 · 策略 API
官方文档把策略 API 分为约定函数、数据查询接口、交易接口三类:约定函数是 RQAlpha 回调你的入口(init、before_trading、handle_bar、after_trading),数据查询负责取历史与合约信息,交易接口负责下单。策略要做的,就是在这几个回调里把「取数 → 算信号 → 下单」串起来。
依据官方 API 文档整理的策略回调顺序示意;非官方流程图。
「约定函数」是策略与 RQAlpha 的接口:不实现就无法正确运行。
| 函数 | 触发时机 | 典型用途 | 注意点 |
|---|---|---|---|
init(context) | 程序启动时执行一次 | 把标的、参数(如长短均线周期)挂到 context 上 | 不要在 init 里下单;参数用 context.XXX 保存以便调优 |
before_trading(context) | 每个交易日开盘前一次 | 盘前筛选股票池、准备当日要用的数据 | 此时当日 Bar 还没有,取不到当日行情 |
handle_bar(context, bar_dict) | 所订阅标的的 Bar 数据更新时 | 策略主体:读取历史数据、计算信号、调用下单接口 | 日频策略每天触发一次;分钟频由频率配置决定 |
after_trading(context) | 每个交易日收盘后一次 | 盘后统计、记录当日状态 | 不要在此下当日单(交易日已结束) |
sys_scheduler 提供定时器能力(按周期执行指定逻辑);Mod 还可以通过 Hook 挂到框架的其它阶段(见 Mod 扩展页)。官方示例策略用 rqalpha examples -d ./ 生成,建议先跑通 buy_and_hold.py 与 golden_cross.py 再写自己的。RQAlpha 官方 tutorial 列出的常用接口;财务与更细的市场数据在 extend_api 中说明。
| 接口 | 作用 | 用法要点 |
|---|---|---|
history_bars() | 取某合约的历史行情(含 close 等字段) | 示例:history_bars(标的, 长度, '1d', 'close');长度要足够算你需要的均线窗口 |
all_instruments() / instruments() | 获取全部或指定合约的基础信息、详细数据 | 用于按类型筛选股票池(如只看股票或期货) |
current_snapshot() | 当前快照数据 | 需要更高频细节时使用;日频策略通常用 bar_dict 即可 |
get_future_contracts() | 获取期货可交易合约列表 | 期货策略选合约必用;要注意主力合约切换 |
get_trading_dates()、get_previous_trading_date()、get_next_trading_date() | 交易日历相关查询 | 做 T+N 逻辑、调仓日计算时用,避免自己造日历 |
is_suspended()、is_st_stock() | 判断停牌、判断 ST | 选股与下单前过滤,可显著减少无效订单 |
get_yield_curve() | 获取收益率曲线 | 债券/利率相关研究使用 |
bar_dict[标的] | 在 handle_bar 中取当前 Bar 数据 | 字典式访问,可拿 close、volume 等字段 |
RQAlpha 的股票与期货下单接口分开设计,命名上就能区分:股票用 order_*,期货用 buy_open/sell_close 等。
| 接口 | 适用 | 说明 |
|---|---|---|
order_shares() | 股票 | 按股数下单(教程中用它按现金可买数量建仓) |
order_lots() | 股票 | 按手数下单(A 股一手 100 股的场景更直观) |
order_value() / order_percent() | 股票 | 按金额或按组合比例下单 |
order_target_value() / order_target_percent() | 股票 | 按目标金额/目标比例调仓(order_target_value(标的, 0) 即清仓) |
buy_open() / sell_close() | 期货 | 买开仓、平买仓 |
sell_open() / buy_close() | 期货 | 卖开仓、平卖仓 |
cancel_order() / get_open_orders() | 通用 | 撤单与查询未成交订单 |
get_position()、context.portfolio | 通用 | 查询持仓与组合(现金、市值等),是仓位控制的基础 |
is_suspended)、是否 ST(is_st_stock)、资金是否够(context.portfolio.cash)——RQAlpha 官方教程里的 shares = 现金 / 收盘价 就是这个思路的简化版。RQAlpha 官方 tutorial 用「金叉策略」演示完整链路,步骤可直接照搬。
先写 init / before_trading / handle_bar / after_trading 四个函数,跑起来只打日志,确认框架能启动。
在 handle_bar 里用 history_bars 取足够长的收盘价序列,交给 talib 等库算指标。
比较相邻两根 Bar 的均线关系:下穿且持仓则 order_target_value(标的, 0) 清仓;上穿则建仓。
用 plot() 把指标写进结果文件,跑完回测看曲线与 summary 指标,再决定要不要调参。
rqalpha run -s 2014-01-01 -e 2016-01-01 -f rqalpha/examples/golden_cross.py --account stock 100000 -p -bm 000001.XSHE(官方 tutorial 给出的写法)。示例策略可通过 rqalpha examples -d ./ 生成到本地目录再改。
多数来自 RQAlpha 的「回调时机」与「数据长度」两类问题。
| 坑 | 为什么发生 | 怎么避免 |
|---|---|---|
| 指标前几十根为 NaN | 均线窗口没有足够历史数据 | history_bars 的长度取「窗口 + 1」;回测起始日不要贴着数据起点 |
| bar_dict 取不到某标的 | 该标的当日停牌 / 未订阅 | 用 is_suspended 过滤;在 init 里 subscribe 或 update_universe 声明关注标的 |
| 同一根 Bar 反复触发下单 | 信号条件在多个 Bar 上持续成立 | 用「前一根/当前根」的交叉判断,或在 context 里记录已触发标记 |
| 回测很快但没有交易 | 日期区间没有数据、账户类型写错、资金为 0 | 核对 -s/-e、--account 与 bundle 覆盖范围 |
| talib 相关导入失败 | 本地未安装 TA-Lib | 按官方示例安装 TA-Lib;不想装就用 numpy/pandas 自己实现均线 |
| plot 的数据取不到 | 没有调用 plot,或输出文件里 keys 名称记错 | 在 handle_bar 里显式 plot("名称", 值);结果读取见回测指标页 |
本页前面按「约定函数 / 数据 / 交易」分组列了接口,这一段换成按「你要做的事」来选——接口名与约束均照官方 API 文档原文。
| 回调 / 定时器 | 触发时机 | 什么时候用 | 注意点 |
|---|---|---|---|
init(context) | 程序启动时一次 | 声明标的、把参数挂到 context | 不要在 init 里下单;定时器只能在 init 内注册 |
before_trading(context) | 每个交易日开盘前 | 盘前筛股票池、准备当日要用的变量 | 官方明确:不能发单;订阅含夜盘期货时,触发时间可能在前一日 20:00 |
open_auction(context, bar_dict) | 盘前集合竞价 | 需要以当日开盘价参与竞价撮合 | 官方说明:该回调里发出的订单以当日开盘价撮合;此时 bar 不完整,只有 open、limit_up、limit_down 等字段;tick 级回测不触发集合竞价 |
handle_bar(context, bar_dict) | 所订阅标的的 Bar 更新时 | 策略主体:取数、算信号、下单 | 日频策略每天触发一次;多合约分别触发 |
handle_tick(context, tick) | 快照更新时 | 需要 tick 级细节的研究 | 集合竞价与连续交易时段都会触发,多合约分别触发 |
after_trading(context) | 每个交易日收盘后 | 盘后统计、记录当日状态 | 官方明确:不能发单;模拟交易中 15:30 触发 |
scheduler.run_daily(函数, time_rule=…) | 指定的时间点 | 定时调仓,不必自己在 handle_bar 里算时点 | 只能在 init 内使用;被调用函数必须且只能有 context, bar_dict 两个入参 |
scheduler.run_weekly / run_monthly | 每周 / 每月指定日 | 周频、月频调仓策略 | weekday 与 tradingday 不能同时使用(tradingday 为负数表示倒数);run_monthly 的 tradingday 取值范围是 [-23,1]∪[1,23] |
time_rule:market_open / market_close / physical_time 等 | 决定定时器在一天里的哪个时点执行 | 分钟级回测与模拟交易中控制下单时点 | 官方说明:time_rule 只对分钟级回测与模拟交易有效,日回测仍按当天执行;不指定默认 09:31;不支持 09:30 交易;A 股交易时间 09:31–15:00 共 240 分钟 |
| 下单写法 | 官方示例 | 什么时候用 | 注意点 |
|---|---|---|---|
MarketOrder() | order_shares("000001.XSHE", amount=100, price_or_style=MarketOrder()) | 不关心价格,只想成交 | 成交价取决于撮合引擎的设定(见运行策略页的 -me) |
LimitOrder(价格) | LimitOrder(10) | 必须限定成交价 | 价格不合适就不会成交,回测里能检验挂单假设 |
TWAPOrder(931, 945) / VWAPOrder(931, 945) | 与上面同一个 price_or_style 位置 | 把一笔单摊到一段时间内执行 | 时间参数用 HHMM 形式的整数 |
submit_order / order / order_to | 通用下单族 | 需要显式指定方向与开平仓时 | 配合 SIDE(BUY/SELL)与 POSITION_EFFECT(OPEN/CLOSE/CLOSE_TODAY/EXERCISE/MATCH)使用 |
order_shares / order_lots | 按股数 / 按手数 | 股票建仓、加减仓 | A 股一手的股数看 Instrument 的 round_lot(通常 100) |
order_value / order_percent | 按金额 / 按组合比例 | 等金额、等权重建仓 | 比例基于组合总权益,注意现金不足时的行为 |
order_target_value / order_target_percent | 按目标金额 / 目标比例 | 调仓到目标仓位(order_target_value(标的, 0) 即清仓) | 按「目标」而不是「差额」下单,回测中会据此拆成买或卖 |
order_target_portfolio / order_target_portfolio_smart | 按目标组合 | 多标的组合级调仓 | 先定义目标权重再交给 RQAlpha 换算成订单,减少逐标的计算 |
buy_open / sell_close / sell_open / buy_close | 期货开平仓四个接口 | 期货策略 | 股票与期货的下单接口分开设计,别把两者混用 |
cancel_order / get_open_orders / get_position / get_positions | 撤单、查未成交、查持仓 | 按订单状态做风控、判断是否需要重下单 | 订单状态用 ORDER_STATUS 判断:PENDING_NEW / ACTIVE / FILLED / CANCELLED / REJECTED |
handle_bar 之前执行,所以同一天里定时下单会先于 Bar 逻辑;②before_trading / after_trading 不能发单,需要「开盘价成交」时要写 open_auction 而不是这两个回调。同一个 from rqalpha.api import * 里既有随框架自带的数据接口,也有需要 RQDatac 权限才能生效的扩展接口——先分清再做取数设计。
| 分组 | 代表接口 | 能拿到什么 | 前置条件与注意点 |
|---|---|---|---|
| 基础行情 | history_bars / current_snapshot / history_ticks / bar_dict | 历史 Bar、当前快照、历史 tick | 范围取决于数据包(免费版为 A 股日线,见安装与数据页) |
| 合约信息 | instruments / all_instruments / instrument_history / active_instruments | 合约基础信息与历史信息 | 配合 Instrument 字段与方法使用(round_lot、tick_size()、days_to_expire()) |
| 日历与状态 | get_trading_dates / get_previous_trading_date / get_next_trading_date / is_suspended / is_st_stock | 交易日历、停牌与 ST 判断 | T+N 逻辑与调仓日计算必用;下单前过滤能减少无效订单 |
| 持仓与资金 | get_position / get_positions / context.portfolio / deposit / withdraw | 持仓、现金与组合权益 | 期货保证金场景还会用到 finance / repay |
| 订阅与事件 | subscribe / unsubscribe / update_universe / subscribe_event | 控制策略关注的标的与自定义事件 | 先订阅再取数,避免动态股票池取不到数据 |
| 扩展行情 | get_price / get_price_change_rate | 更细的行情序列与涨跌幅 | 需要 RQDatac 权限(见下方三步) |
| 扩展股票与基本面 | get_factor / get_pit_financials_ex / get_industry / get_turnover_rate / concept / get_margin_stocks / get_stock_connect / current_performance / get_split / get_shares / get_securities_margin | 因子、PIT 财务、行业分类、换手率、概念、融资融券、互联互通、拆股 | 需要 RQDatac 权限;接口范围以官方 extend_api 文档为准 |
| 扩展指数 / 期货 / 宏观 | index_components / index_weights;futures.get_dominant / get_member_rank / get_warehouse_stocks / get_dominant_price;econ.get_reserve_ratio / econ.get_money_supply | 指数成分与权重、期货主力与会员排名/仓单、宏观货币指标 | 需要 RQDatac 权限;期货批量数据建议先取主力合约再逐合约取数 |
| 绘图与自定义输出 | plot | 把你关心的指标写进结果文件 | 不显式调用就不会出现在结果里;读取方式见回测指标页 |
| 现象 | 原因 | 处理 |
|---|---|---|
报 NameError: history_bars is not defined | 没有按官方约定导入 API | 先按官方示例 from rqalpha.api import *;工程化项目可显式导入具体函数 |
在 before_trading / after_trading 里下单没有效果 | 官方明确这两个回调不能发单 | 把下单逻辑移到 handle_bar,需要开盘价成交时用 open_auction |
| 限价单一直不成交 | 价格没到,或撮合口径与你的假设不同 | 用 -me 核对是 current_bar 还是 next_bar 撮合(见运行策略页),再决定是否放宽价格 |
用 order_shares 给期货合约下单失败 | RQAlpha 把股票与期货的下单接口分开设计 | 期货改用 buy_open / sell_close / sell_open / buy_close |
取 Instrument 字段抛 KeyError | 官方说明:基金专用字段(如 fund_type)在 ETF 数据里可能不存在 | 先判断 type 再取该字段,或对字段做兜底 |
| 定时器不生效 | 不在 init 内注册、被调用函数签名不是 (context, bar_dict),或日回测下 time_rule 本来就不生效 | 按官方约束改:注册位置、函数签名、改用分钟级回测 |
| 选出来的标的当天下不了单 | 停牌、ST(special_type 为 ST / StarST / PT)、或触及涨跌停 | 下单前用 is_suspended、is_st_stock 过滤,并检查 bar_dict 里的 limit_up / limit_down |
1. 申请 RQDatac 试用并获取官方文档 —— 确认你要用的接口在权限范围内(预期输出:拿到账号与接口文档入口);
2. pip install rqdatac —— 装上扩展数据包(预期输出:import rqdatac 成功);
3. 执行米筐提供的配置脚本把 license 写入环境变量,或在运行策略时传 --rqdatac license:xxx —— 让 RQAlpha 能调用扩展接口(预期输出:策略里的 get_price / get_factor 不再报未授权)。官方另注:在米筐在线量化平台运行策略,可以免费调用扩展 API。
不必。官方说约定函数是「用户必须实现对应的约定函数才可以正确使用」,其中 init 与 handle_bar 是核心;before_trading / after_trading 按需实现(官方教程里的空实现 pass 也能跑)。
官方示例与教程都使用 from rqalpha.api import * 的写法(logger、history_bars、order_shares 等都来自这里)。工程化项目可以改为显式导入以提高可读性,但需逐一对照 API 文档,避免漏掉函数。
基础数据查询 API 之外,财务与更丰富的市场数据在 Ricequant 的扩展数据接口中(extend_api),部分需要 RQData 权限;也可以实现自有数据源接口把这些数据接进来。
可以,策略里维护一个标的列表(写在 context 中)并逐个取数、下单即可;官方示例也演示了通过 update_universe 声明关注标的的写法。
重点检查两点:handle_bar 里只能用到当前 Bar 及之前的数据(不要用全量 DataFrame 做 shift 反向对齐),以及不要用 after_trading 的数据回填当日交易决策。RQAlpha 不会替你识别这类问题。
会。RQAlpha 按 release/x.y.z 发布(最新 release/6.3.0,2026-07-23),API 细节请以你安装版本对应的官方文档为准;本页只做导航与要点归纳。