🧪 Skills

rqalpha

RQAlpha — open-source event-driven backtesting framework by RiceQuant, supporting A-shares and futures with modular architecture.

v1.0.0
❤️ 0
⬇️ 22
👁 1
Share

Description


name: rqalpha description: RQAlpha — open-source event-driven backtesting framework by RiceQuant, supporting A-shares and futures with modular architecture. version: 1.0.0 homepage: https://github.com/ricequant/rqalpha metadata: {"clawdbot":{"emoji":"🍚","requires":{"bins":["python3"]}}}

RQAlpha (RiceQuant Backtesting Framework)

RQAlpha is an open-source, event-driven backtesting framework developed by RiceQuant. It provides a complete solution for strategy development, backtesting, and paper trading for China A-shares and futures markets. Highly modular with a plugin (mod) system.

Docs: https://rqalpha.readthedocs.io/

Installation

pip install rqalpha

# Download built-in bundle data (A-share daily data)
rqalpha download-bundle

Strategy Structure

def init(context):
    """Called once at strategy start — set up subscriptions and parameters."""
    context.stock = '000001.XSHE'
    context.fired = False

def handle_bar(context, bar_dict):
    """Called on every bar — main trading logic."""
    if not context.fired:
        order_shares(context.stock, 1000)
        context.fired = True

def before_trading(context):
    """Called before market open each day."""
    pass

def after_trading(context):
    """Called after market close each day."""
    pass

Running a Backtest

Command Line

rqalpha run \
    -f strategy.py \
    -s 2024-01-01 \
    -e 2024-06-30 \
    --account stock 100000 \
    --benchmark 000300.XSHG \
    --plot

Python API

from rqalpha.api import *
from rqalpha import run_func

config = {
    "base": {
        "start_date": "2024-01-01",
        "end_date": "2024-06-30",
        "accounts": {"stock": 100000},
        "benchmark": "000300.XSHG",
        "frequency": "1d",
    },
    "extra": {
        "log_level": "warning",
    },
    "mod": {
        "sys_analyser": {"enabled": True, "plot": True},
    },
}

result = run_func(init=init, handle_bar=handle_bar, config=config)
print(result)

Symbol Format

Market Suffix Example
Shanghai A-shares .XSHG 600000.XSHG (SPDB)
Shenzhen A-shares .XSHE 000001.XSHE (Ping An Bank)
Index .XSHG/.XSHE 000300.XSHG (CSI 300)
Futures .XSGE/.XDCE/.XZCE/.CCFX IF2401.CCFX (CSI 300 futures)

Order Functions

# Buy/sell by share count
order_shares('000001.XSHE', 1000)       # Buy 1000 shares
order_shares('000001.XSHE', -500)       # Sell 500 shares

# Buy by lot (1 lot = 100 shares)
order_lots('000001.XSHE', 10)           # Buy 10 lots (1000 shares)

# Buy by value
order_value('000001.XSHE', 50000)       # Buy 50,000 CNY worth

# Buy by percentage of portfolio
order_percent('000001.XSHE', 0.5)       # Buy 50% of portfolio value

# Target position
order_target_value('000001.XSHE', 100000)   # Adjust to 100,000 CNY
order_target_percent('000001.XSHE', 0.3)    # Adjust to 30% of portfolio

# Cancel order
cancel_order(order_id)

Data Query Functions

def handle_bar(context, bar_dict):
    # Current bar data
    bar = bar_dict['000001.XSHE']
    price = bar.close
    volume = bar.volume
    dt = bar.datetime

    # Historical data (returns DataFrame)
    prices = history_bars('000001.XSHE', bar_count=20, frequency='1d',
                          fields=['close', 'volume', 'open', 'high', 'low'])

    # Check if stock is tradable
    tradable = is_valid_price(bar.close)

    # Check if suspended
    suspended = is_suspended('000001.XSHE')

Portfolio & Position

def handle_bar(context, bar_dict):
    # Portfolio info
    cash = context.portfolio.cash                    # Available cash
    total = context.portfolio.total_value            # Total portfolio value
    market_value = context.portfolio.market_value    # Position market value
    pnl = context.portfolio.pnl                      # Total PnL
    returns = context.portfolio.daily_returns        # Daily return

    # Position info
    positions = context.portfolio.positions
    for stock, pos in positions.items():
        print(f'{stock}: quantity={pos.quantity}, '
              f'sellable={pos.sellable}, '
              f'avg_price={pos.avg_price:.2f}, '
              f'market_value={pos.market_value:.2f}, '
              f'pnl={pos.pnl:.2f}')

Scheduler

from rqalpha.api import *

def init(context):
    # Run function at specific time every trading day
    scheduler.run_daily(rebalance, time_rule=market_open(minute=5))
    # Run weekly (every Monday)
    scheduler.run_weekly(weekly_task, tradingday=1, time_rule=market_open(minute=5))
    # Run monthly (first trading day)
    scheduler.run_monthly(monthly_task, tradingday=1, time_rule=market_open(minute=5))

def rebalance(context, bar_dict):
    pass

Mod System (Plugins)

RQAlpha's modular architecture allows extending functionality via mods:

config = {
    "mod": {
        "sys_analyser": {
            "enabled": True,
            "plot": True,
            "benchmark": "000300.XSHG",
        },
        "sys_simulation": {
            "enabled": True,
            "matching_type": "current_bar",    # Order matching: current_bar or next_bar
            "slippage": 0.01,                  # Slippage (CNY)
        },
        "sys_transaction_cost": {
            "enabled": True,
            "commission_rate": 0.0003,         # Commission rate
            "tax_rate": 0.001,                 # Stamp tax (sell only)
            "min_commission": 5,               # Minimum commission
        },
    },
}

Available Built-in Mods

Mod Description
sys_analyser Performance analysis and plotting
sys_simulation Order matching simulation
sys_transaction_cost Commission and tax calculation
sys_accounts Account management
sys_benchmark Benchmark tracking
sys_progress Progress bar display
sys_risk Risk management checks

Advanced Examples

Dual Moving Average Crossover Strategy

import numpy as np
from rqalpha.api import *

def init(context):
    context.stock = '600000.XSHG'
    context.fast = 5
    context.slow = 20
    scheduler.run_daily(trade_logic, time_rule=market_open(minute=5))

def trade_logic(context, bar_dict):
    prices = history_bars(context.stock, context.slow + 1, '1d', fields=['close'])
    if len(prices) < context.slow:
        return

    closes = prices['close']
    fast_ma = np.mean(closes[-context.fast:])
    slow_ma = np.mean(closes[-context.slow:])

    pos = context.portfolio.positions.get(context.stock)
    has_position = pos is not None and pos.quantity > 0

    if fast_ma > slow_ma and not has_position:
        order_target_percent(context.stock, 0.9)
        logger.info(f'BUY: fast_ma={fast_ma:.2f} > slow_ma={slow_ma:.2f}')
    elif fast_ma < slow_ma and has_position:
        order_target_percent(context.stock, 0)
        logger.info(f'SELL: fast_ma={fast_ma:.2f} < slow_ma={slow_ma:.2f}')

def handle_bar(context, bar_dict):
    pass

Multi-Stock Equal-Weight Rebalancing

from rqalpha.api import *

def init(context):
    context.stocks = ['600000.XSHG', '000001.XSHE', '601318.XSHG',
                       '600036.XSHG', '000858.XSHE']
    scheduler.run_monthly(rebalance, tradingday=1, time_rule=market_open(minute=30))

def rebalance(context, bar_dict):
    # Sell stocks not in target list
    for stock in list(context.portfolio.positions.keys()):
        if stock not in context.stocks:
            order_target_percent(stock, 0)

    # Equal-weight allocation
    weight = 0.95 / len(context.stocks)
    for stock in context.stocks:
        if not is_suspended(stock):
            order_target_percent(stock, weight)
            logger.info(f'Rebalance: {stock} -> {weight:.1%}')

def handle_bar(context, bar_dict):
    pass

Tips

  • RQAlpha is a local-only framework — no cloud dependency, ideal for offline research.
  • Use rqalpha download-bundle to get free built-in daily data for A-shares.
  • The mod system allows plugging in custom data sources, brokers, and risk modules.
  • For live trading, connect via rqalpha-mod-vnpy to use vn.py's broker gateways.
  • Supports both daily and minute-level backtesting.
  • Docs: https://rqalpha.readthedocs.io/

社区与支持

大佬量化 (Boss Quant) 维护 — 量化交易教学与策略研发团队。

微信客服: bossquant1 · Bilibili · 搜索 大佬量化 on 微信公众号 / Bilibili / 抖音

Reviews (0)

Sign in to write a review.

No reviews yet. Be the first to review!

Comments (0)

Sign in to join the discussion.

No comments yet. Be the first to share your thoughts!

Compatible Platforms

Pricing

Free

Related Configs