Skip to content
python.financial
Platform
China-market backtesting framework
License
Custom noncommercial license based on Apache-2.0 terms. Commercial use requires authorization
Pricing
Noncommercial use under the public license. Commercial use requires authorization
Live trading
Not provided by the public backtesting core
Best for
Testing Chinese stocks and futures with local calendars, instrument details, data, and trading rules

RQAlpha is an event-driven backtester for Chinese stocks, exchange-traded funds, and futures. It includes local instrument identifiers, trading calendars, data bundles, and account rules. It is less suitable as a general international backtester or a ready-made live-trading tool. Its public framework, available data, optional execution extensions, and RiceQuant's paid services are separate offerings.

How is RQAlpha structured?

RQAlpha drives strategy callbacks such as init, before_trading, open_auction, handle_bar, and after_trading from time-ordered market events. Strategies submit orders through a shared API while system mods handle accounts, simulation, transaction costs, risk checks, progress, and analysis.

The Mod API is the main extension boundary. A custom data source, broker, risk rule, command, or analyzer can be registered without rewriting the core engine. That flexibility is useful, but a plugin's maintenance, data assumptions, and license do not automatically match the core project. Audit each external mod separately.

How do you run a small backtest?

First install RQAlpha and fetch its public daily bundle:

python -m pip install rqalpha==6.4.0
rqalpha download-bundle

The following complete example uses run_func so the strategy and material configuration remain together. It buys one 100-share board lot of 000001.XSHE, applies 0.1% price-ratio slippage, retains the 25% bar-volume cap, uses the standard stock commission multiplier, and prints the simulated trade rather than a performance headline.

import os
from pathlib import Path

from rqalpha import run_func
from rqalpha.apis import order_shares, update_universe


def init(context):
    context.asset = "000001.XSHE"
    context.order_sent = False
    update_universe(context.asset)


def handle_bar(context, bar_dict):
    if not context.order_sent:
        order_shares(context.asset, 100)
        context.order_sent = True


bundle = Path(
    os.environ.get("RQALPHA_BUNDLE", Path.home() / ".rqalpha" / "bundle")
)
config = {
    "base": {
        "start_date": "2024-01-02",
        "end_date": "2024-01-05",
        "frequency": "1d",
        "accounts": {"stock": 100_000},
        "data_bundle_path": str(bundle),
        "capital_gain_tax_rate": 0.0,
    },
    "extra": {"log_level": "error"},
    "mod": {
        "sys_simulation": {
            "enabled": True,
            "matching_type": "current_bar",
            "slippage_model": "PriceRatioSlippage",
            "slippage": 0.001,
            "volume_limit": True,
            "volume_percent": 0.25,
        },
        "sys_transaction_cost": {
            "enabled": True,
            "stock_commission_multiplier": 1,
        },
        "sys_analyser": {"enabled": True, "plot": False},
    },
}

result = run_func(init=init, handle_bar=handle_bar, config=config)
columns = ["order_book_id", "last_quantity", "last_price", "commission", "tax"]
trades = result["sys_analyser"]["trades"]
print(trades.loc[:, columns].to_string(index=False))

Executed with RQAlpha 6.4.0 and the September 2026 public bundle, it printed:

order_book_id  last_quantity  last_price  commission  tax
  000001.XSHE            100      9.2192           5    0

The price includes the configured slippage, and the transaction-cost mod applies the minimum commission. The explicit zero capital-gain tax matches this test assumption and avoids relying on a default that RQAlpha warns will change. Update tax, commission, slippage, dates, and data for the market and account being studied. This one-order run validates the API and configuration, not a trading signal or an edge.

What data do you need?

The installation guide says RiceQuant's downloadable bundle provides free daily data for stocks, common indexes, exchange-traded funds, and futures and is updated near the start of each month. The open bundle does not provide minute data. More timely updates, minute history, fundamentals, and extended APIs may require RQData credentials or another data source.

Treat the bundle date as part of the result. Before research, confirm:

  • the last available trading date and update frequency
  • delisted instruments, code changes, and corporate actions
  • whether fundamentals and classifications are point-in-time
  • futures contract rolls, settlement prices, multipliers, margin, and expiry behavior
  • the timezone, session calendar, auction data, and frequency required by the strategy

The 6.4 release notes state that older bundles need a fund_type field for the new ETF commission categories. Update or validate an old bundle before comparing 6.4 results with earlier runs.

Which matching and cost settings matter?

RQAlpha separates strategy code from configuration, and its run modes and configuration guide documents the precedence of in-strategy, function, command-line, user-file, and default settings. Save the resolved configuration with every result.

Setting Research question
matching_type Does a daily order use the current close or volume-weighted price? Does a minute order use the current bar or next open?
slippage_model and slippage Is a price ratio or tick-size adjustment appropriate and calibrated?
volume_limit and volume_percent How much recorded bar or tick volume may simulated orders consume?
price_limit and inactive_limit Should limit-up, limit-down, and zero-volume bars prevent a fill?
transaction-cost settings Which commissions, minimums, taxes, and futures fees apply for that date and instrument type?
account and margin settings Are stock, futures, currency, margin, and forced-liquidation rules correct?

Daily bars still hide the intraday path, spread, and queue. A current-bar close fill can also be look-ahead biased if the decision uses that same bar's completed close. Use the next available decision point or finer data when the signal is not known before the modeled fill.

Is RQAlpha a live-trading platform?

The engine exposes backtest, paper, and live run types, and the Mod interface can connect execution adapters. That is an extension point, not evidence that a particular broker integration is current or production-ready. Several public live-trading mods are separate repositories with their own maintenance histories.

Before using any adapter, verify supported instruments and orders, authentication, market-data rights, restart behavior, order and position reconciliation, cancel and reject handling, rate limits, and the exact RQAlpha version it supports. Plan monitoring, alerting, secrets, persistence, and kill procedures outside the strategy callback.

What does the license allow?

RQAlpha is source-available, but describing it as ordinary Apache-2.0 software is incomplete. The repository's controlling license text applies Apache-2.0 terms to defined noncommercial use. It prohibits commercial use without RiceQuant authorization and says organizations need authorization for any use. The package metadata's shorter Apache-2.0 label does not include those conditions.

Review the actual license and obtain advice appropriate to the intended use. The page is reporting the published terms, not giving a legal conclusion.

When is RQAlpha the wrong fit?

Choose another engine when the primary markets are outside RQAlpha's data and account conventions, the team needs English-first documentation, or a maintained broker adapter is a hard requirement. A smaller library is easier for a one-off bar test, while a platform with managed international data and broker connections may reduce integration work.

RQAlpha is strongest when the research genuinely benefits from its China-market bundle, instrument rules, account models, and Mod architecture. Those advantages do not replace point-in-time data checks, calibrated execution costs, or a separate production-readiness review.

Choose which optional services may run. You can change these settings at any time.