$npx -y skills add lzwme/finance-quant-skills --skill rqalphaRQAlpha 米筐开源事件驱动回测框架。支持A股和期货,模块化架构,可自由扩展;当用户需要快速回测A股/期货策略、使用内置数据(download-bundle)、开发Mod插件,或提及 rqalpha、米筐时使用。与 backtrader 相比,rqalpha 内置A股日线数据、安装更简便,适合快速验证;backtrader 更灵活、社区更大。若用户仅需数据获取而无回测需求,引导使用 baostock/akshare/tushare 等数据 Skill。
| 1 | # RQAlpha(米筐开源回测框架) |
| 2 | |
| 3 | [RQAlpha](https://github.com/ricequant/rqalpha) 是 [米筐科技](https://www.ricequant.com) 开发的开源事件驱动回测框架。提供A股和期货市场的策略开发、回测和模拟交易完整解决方案。高度模块化,支持插件(Mod)系统扩展。 |
| 4 | |
| 5 | > 文档:https://rqalpha.readthedocs.io |
| 6 | |
| 7 | ## 安装 |
| 8 | |
| 9 | ```bash |
| 10 | pip install rqalpha |
| 11 | |
| 12 | # 下载内置数据包(A股日线数据) |
| 13 | rqalpha download-bundle |
| 14 | |
| 15 | # 验证安装 |
| 16 | python -c "import rqalpha; print(rqalpha.__version__)" |
| 17 | ``` |
| 18 | |
| 19 | ## 策略结构 |
| 20 | |
| 21 | ```python |
| 22 | from rqalpha.api import * # 导入所有 API 函数(含 logger) |
| 23 | |
| 24 | def init(context): |
| 25 | """策略启动时调用一次 — 设置订阅和参数""" |
| 26 | context.stock = '000001.XSHE' |
| 27 | context.fired = False |
| 28 | |
| 29 | def handle_bar(context, bar_dict): |
| 30 | """每根K线调用 — 主要交易逻辑""" |
| 31 | if not context.fired: |
| 32 | order_shares(context.stock, 1000) |
| 33 | context.fired = True |
| 34 | logger.info('买入完成') # logger 通过 from rqalpha.api import * 自动可用 |
| 35 | |
| 36 | def before_trading(context): |
| 37 | """每个交易日开盘前调用""" |
| 38 | pass |
| 39 | |
| 40 | def after_trading(context): |
| 41 | """每个交易日收盘后调用""" |
| 42 | pass |
| 43 | ``` |
| 44 | |
| 45 | > **注意**:`from rqalpha.api import *` 会自动导入 `logger`,可直接使用 `logger.info()`、`logger.warn()`、`logger.error()` 输出日志。 |
| 46 | |
| 47 | ## 运行回测 |
| 48 | |
| 49 | ### 命令行 |
| 50 | |
| 51 | ```bash |
| 52 | rqalpha run \ |
| 53 | -f strategy.py \ |
| 54 | -s 2024-01-01 \ |
| 55 | -e 2024-06-30 \ |
| 56 | --account stock 100000 \ |
| 57 | --benchmark 000300.XSHG \ |
| 58 | --plot |
| 59 | ``` |
| 60 | |
| 61 | ### Python API |
| 62 | |
| 63 | ```python |
| 64 | from rqalpha.api import * |
| 65 | from rqalpha import run_func |
| 66 | |
| 67 | config = { |
| 68 | "base": { |
| 69 | "start_date": "2024-01-01", |
| 70 | "end_date": "2024-06-30", |
| 71 | "accounts": {"stock": 100000}, |
| 72 | "benchmark": "000300.XSHG", |
| 73 | "frequency": "1d", |
| 74 | }, |
| 75 | "extra": { |
| 76 | "log_level": "warning", |
| 77 | }, |
| 78 | "mod": { |
| 79 | "sys_analyser": {"enabled": True, "plot": True}, |
| 80 | }, |
| 81 | } |
| 82 | |
| 83 | result = run_func(init=init, handle_bar=handle_bar, config=config) |
| 84 | print(result) |
| 85 | ``` |
| 86 | |
| 87 | --- |
| 88 | |
| 89 | ## 代码格式 |
| 90 | |
| 91 | | 市场 | 后缀 | 示例 | |
| 92 | |---|---|---| |
| 93 | | 上海A股 | `.XSHG` | `600000.XSHG`(浦发银行) | |
| 94 | | 深圳A股 | `.XSHE` | `000001.XSHE`(平安银行) | |
| 95 | | 指数 | `.XSHG/.XSHE` | `000300.XSHG`(沪深300) | |
| 96 | | 期货 | `.XSGE/.XDCE/.XZCE/.CCFX` | `IF2401.CCFX`(沪深300期货) | |
| 97 | |
| 98 | --- |
| 99 | |
| 100 | ## 下单函数 |
| 101 | |
| 102 | ### 股票下单 |
| 103 | |
| 104 | ```python |
| 105 | # 按股数买卖 |
| 106 | order_shares('000001.XSHE', 1000) # 买入1000股 |
| 107 | order_shares('000001.XSHE', -500) # 卖出500股 |
| 108 | |
| 109 | # 按手买入(1手=100股) |
| 110 | order_lots('000001.XSHE', 10) # 买入10手(1000股) |
| 111 | |
| 112 | # 按金额买入 |
| 113 | order_value('000001.XSHE', 50000) # 买入5万元 |
| 114 | |
| 115 | # 按组合比例买入 |
| 116 | order_percent('000001.XSHE', 0.5) # 买入组合值50%的仓位 |
| 117 | |
| 118 | # 目标仓位 |
| 119 | order_target_value('000001.XSHE', 100000) # 调整到10万元 |
| 120 | order_target_percent('000001.XSHE', 0.3) # 调整到组合的30% |
| 121 | |
| 122 | # 撤单 |
| 123 | cancel_order(order_id) |
| 124 | ``` |
| 125 | |
| 126 | ### 期货下单 |
| 127 | |
| 128 | ```python |
| 129 | # 开仓 |
| 130 | buy_open('IF2401.CCFX', 1) # 买入开多1手 |
| 131 | sell_open('IF2401.CCFX', 1) # 卖出开空1手 |
| 132 | |
| 133 | # 平仓 |
| 134 | sell_close('IF2401.CCFX', 1) # 卖出平多1手 |
| 135 | buy_close('IF2401.CCFX', 1) # 买入平空1手 |
| 136 | ``` |
| 137 | |
| 138 | ## 数据查询函数 |
| 139 | |
| 140 | ```python |
| 141 | def handle_bar(context, bar_dict): |
| 142 | # 当前K线数据 |
| 143 | bar = bar_dict['000001.XSHE'] |
| 144 | price = bar.close |
| 145 | volume = bar.volume |
| 146 | dt = bar.datetime |
| 147 | |
| 148 | # 历史数据(返回DataFrame) |
| 149 | prices = history_bars('000001.XSHE', bar_count=20, frequency='1d', |
| 150 | fields=['close', 'volume', 'open', 'high', 'low']) |
| 151 | |
| 152 | # 检查股票是否可交易 |
| 153 | tradable = is_valid_price(bar.close) |
| 154 | |
| 155 | # 检查是否停牌 |
| 156 | suspended = is_suspended('000001.XSHE') |
| 157 | ``` |
| 158 | |
| 159 | ## 投资组合与持仓 |
| 160 | |
| 161 | ```python |
| 162 | def handle_bar(context, bar_dict): |
| 163 | # 组合信息 |
| 164 | cash = context.portfolio.cash # 可用资金 |
| 165 | total = context.portfolio.total_value # 总资产 |
| 166 | market_value = context.portfolio.market_value # 持仓市值 |
| 167 | pnl = context.portfolio.pnl # 总盈亏 |
| 168 | returns = context.portfolio.daily_returns # 日收益率 |
| 169 | |
| 170 | # 持仓信息 |
| 171 | positions = context.portfolio.positions |
| 172 | for stock, pos in positions.items(): |
| 173 | print(f'{stock}: quantity={pos.quantity}, ' |
| 174 | f'sellable={pos.sellable}, ' |
| 175 | f'avg_price={pos.avg_price:.2f}, ' |
| 176 | f'market_value={pos.market_value:.2f}, ' |
| 177 | f'pnl={pos.pnl:.2f}') |
| 178 | ``` |
| 179 | |
| 180 | ## 定时调度 |
| 181 | |
| 182 | ```python |
| 183 | from rqalpha.api import * |
| 184 | |
| 185 | def init(context): |
| 186 | # 每个交易日指定时间运行函数 |
| 187 | scheduler.run_daily(rebalance, time_rule=market_open(minute=5)) |
| 188 | # 每周运行(每周一) |
| 189 | scheduler.run_weekly(weekly_task, tradingday=1, time_rule=market_open(minute=5)) |
| 190 | # 每月运行(首个交易日) |
| 191 | scheduler.run_monthly(monthly_task, tradingday=1, time_rule=market_open(minute=5)) |
| 192 | |
| 193 | def rebalance(context, bar_dict): |
| 194 | pass |
| 195 | ``` |
| 196 | |
| 197 | --- |
| 198 | |
| 199 | ## Mod系统(插件) |
| 200 | |
| 201 | RQAlpha的模块化架构允许通过Mod扩展功能: |
| 202 | |
| 203 | ```python |
| 204 | config = { |
| 205 | "mod": { |
| 206 | "sys_analyser": { |
| 207 | "enabled": True, |
| 208 | "plot": True, |
| 209 | "benchmark": "000300.XSHG", |
| 210 | }, |
| 211 | "sys_simulation": { |
| 212 | "enabled": True, |
| 213 | "matching_type": "current_bar", # 撮合方式:current_bar(当前Bar)或 next_bar(下一Bar) |
| 214 | "slippage": 0.01, # 滑点(元) |
| 215 | }, |
| 216 | "sys_transaction_ |