Documentation Index
Fetch the complete documentation index at: https://docs.reportify.cn/llms.txt
Use this file to discover all available pages before exploring further.
Quant Module
quant 模块提供量化分析工具,包括技术指标计算、因子分析、OHLCV 行情数据和策略回测。
公式语法基于 Mai-language,兼容通达信/同花顺。
快速开始
from reportify_sdk import Reportify
client = Reportify(api_key="your-api-key")
# 计算 RSI 指标
df = client.quant.factors_compute(["000001"], "RSI(14)")
# 因子选股
stocks = client.quant.factors_screen(formula="RSI(14) < 30")
# 获取 OHLCV 数据
ohlcv = client.quant.ohlcv("000001")
# 策略回测
result = client.quant.backtest(
start_date="2023-01-01",
end_date="2024-01-01",
symbols=["000001"],
entry_formula="CROSS(MA(CLOSE, 5), MA(CLOSE, 20))",
)
因子 (Factors)
factors()
获取可用因子列表(变量和函数)。
factors = client.quant.factors()
for f in factors:
print(f"{f['name']} ({f['type']}, level {f['level']}): {f['description']}")
因子分级:
- Level 0 变量: CLOSE, OPEN, HIGH, LOW, VOLUME, AMOUNT 及别名
- Level 0 函数: MA, EMA, REF, HHV, LLV, STD 等核心函数
- Level 1 函数: CROSS, COUNT, EVERY 等应用函数
- Level 2 函数: MACD, KDJ, RSI, BOLL 等技术指标
factors_compute()
计算因子值,使用 Mai-language 语法。
df = client.quant.factors_compute(
symbols=["000001"],
formula="RSI(14)",
market="cn",
start_date="2024-01-01",
end_date="2024-06-01"
)
公式示例:
# 简单指标
df = client.quant.factors_compute(["000001"], "RSI(14)")
# 获取 MACD 的 DIF 线
df = client.quant.factors_compute(["000001"], "MACD().dif")
# 收盘价是否高于 20 日均线(布尔值)
df = client.quant.factors_compute(["000001"], "CLOSE > MA(CLOSE, 20)")
# MA20 偏离度(百分比)
df = client.quant.factors_compute(["000001"], "(CLOSE - MA(CLOSE, 20)) / MA(CLOSE, 20) * 100")
# 复合条件
df = client.quant.factors_compute(["000001"], "(CLOSE > MA(CLOSE, 20)) & (MA(CLOSE, 20) > MA(CLOSE, 60))")
支持的运算符:
| 类型 | 运算符 | 说明 |
|---|
| 比较 | >, <, >=, <=, ==, != | 比较运算 |
| 逻辑与 | & 或 AND | 大小写不敏感 |
| 逻辑或 | | 或 OR | 大小写不敏感 |
| 逻辑非 | ~ 或 NOT | 大小写不敏感 |
| 算术 | +, -, *, / | 四则运算 |
支持的变量:
| 变量 | 别名 | 说明 |
|---|
CLOSE | C | 收盘价 |
OPEN | O | 开盘价 |
HIGH | H | 最高价 |
LOW | L | 最低价 |
VOLUME | V, VOL | 成交量 |
AMOUNT | - | 成交额 |
LISTING_DATE | - | 上市日期(YYYY-MM-DD 字符串,可直接与日期字符串比较) |
市场状态函数:
| 函数 | 说明 |
|---|
IS_LIMIT_UP() | 是否一字涨停(一字板封涨停) |
IS_LIMIT_DOWN() | 是否一字跌停(一字板封跌停) |
IS_ST() | 是否为 ST 股票 |
IS_CHAIN_MAIN() | 是否为中国主板股票(60/000开头) |
IS_CHAIN_STAR() | 是否为科创板股票(68开头) |
IS_CHAIN_CHINEXT() | 是否为创业板股票(30开头) |
factors_screen()
因子选股,筛选满足条件的股票。
stocks = client.quant.factors_screen(
formula="RSI(14) < 30",
market="cn", # 可选
check_date="2024-06-01", # 可选,默认最新交易日
symbols=None # 可选,None 表示当前市场
)
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|
formula | str | 是 | 选股公式 |
market | str | 否 | 市场,默认 cn |
check_date | str | 否 | 检查日期,默认最新交易日 |
symbols | list[str] | 否 | 股票池,None 表示当前市场 |
选股示例:
# RSI 超卖
stocks = client.quant.factors_screen(formula="RSI(14) < 30")
# 金叉
stocks = client.quant.factors_screen(formula="CROSS(MA(CLOSE, 5), MA(CLOSE, 10))")
# 上升趋势
stocks = client.quant.factors_screen(formula="(CLOSE > MA(CLOSE, 20)) & (MA(CLOSE, 20) > MA(CLOSE, 60))")
# 突破布林带上轨
stocks = client.quant.factors_screen(formula="CLOSE > BOLL(20, 2).upper")
# 行业筛选(申万行业)
stocks = client.quant.factors_screen(formula='INDUSTRY("银行") & (PE_TTM() < 10)')
# 在指定股票池中筛选
stocks = client.quant.factors_screen(
formula="RSI(14) < 30",
symbols=["000001", "600519", "000002"]
)
行情 (Quotes)
ohlcv()
获取单个股票的 OHLCV 日线数据。
df = client.quant.ohlcv(
symbol="000001",
market="cn",
start_date="2024-01-01",
end_date="2024-06-01"
)
print(df[["date", "open", "high", "low", "close", "volume"]])
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|
symbol | str | 是 | 股票代码 |
market | str | 否 | 市场,默认 cn |
start_date | str | 否 | 开始日期,默认 1 个月前 |
end_date | str | 否 | 结束日期,默认今天 |
ohlcv_batch()
批量获取多个股票的 OHLCV 数据。
df = client.quant.ohlcv_batch(
symbols=["000001", "600519", "000002"],
market="cn",
start_date="2024-01-01",
end_date="2024-06-01"
)
print(df[["symbol", "date", "close", "volume"]])
数据按日期(降序)、股票代码排序。
kline()
获取单个股票的 K 线数据,支持多种周期。
df = client.quant.kline(
symbol="000001",
kline_type="5M",
start_datetime="2024-01-01 09:30:00",
end_datetime="2024-01-01 15:00:00",
market="cn"
)
print(df[["datetime", "open", "high", "low", "close", "volume"]])
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|
symbol | str | 是 | 股票代码 |
kline_type | str | 否 | K 线类型,默认 1D,支持 1M/5M/15M/30M/60M/1D/1W/1MO |
market | str | 否 | 市场,默认 cn |
stock_type | str | 否 | 品种类型,默认 stock,支持 stock/etf/index/sw |
start_datetime | str | 否 | 开始时间(YYYY-MM-DD HH:MM:SS),未指定时自动推算 |
end_datetime | str | 否 | 结束时间(YYYY-MM-DD HH:MM:SS) |
kline_batch()
批量获取多个股票的 K 线数据。
df = client.quant.kline_batch(
symbols=["000001", "600519", "000002"],
kline_type="1D",
market="cn"
)
print(df[["symbol", "datetime", "close", "volume"]])
数据按日期(升序)、股票代码排序。
minute()
获取单个股票的分钟数据。
df = client.quant.minute(
symbol="000001",
start_datetime="2024-01-01 09:30:00",
end_datetime="2024-01-01 15:00:00",
market="cn"
)
print(df[["datetime", "open", "high", "low", "close", "volume"]])
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|
symbol | str | 是 | 股票代码 |
start_datetime | str | 是 | 开始时间(YYYY-MM-DD HH:MM:SS) |
end_datetime | str | 是 | 结束时间(YYYY-MM-DD HH:MM:SS) |
market | str | 否 | 市场,默认 cn |
minute_batch()
批量获取多个股票的分钟数据。
df = client.quant.minute_batch(
symbols=["000001", "600519", "000002"],
start_datetime="2024-01-01 09:30:00",
end_datetime="2024-01-01 15:00:00",
market="cn"
)
print(df[["symbol", "datetime", "close", "volume"]])
数据按日期(升序)、股票代码排序。
回测 (Backtest)
backtest()
执行策略回测。
result = client.quant.backtest(
start_date="2023-01-01",
end_date="2024-01-01",
symbols=["000001"],
market="cn",
entry_formula="CROSS(MA(CLOSE, 5), MA(CLOSE, 20))", # 买入信号:MA5 上穿 MA20
exit_formula="CROSSDOWN(MA(CLOSE, 5), MA(CLOSE, 20))", # 卖出信号(可选)
initial_cash=100000, # 初始资金
commission=0.0003, # 佣金费率
position_size=0.2, # 单个股票最大仓位 20%
max_positions=5, # 最大持仓股票数量
cheat_on_open=False, # 是否启用 T 日信号当日开盘成交
auto_close=True, # 自动平仓
signal_factors={"rsi": "RSI(14)", "ma20": "MA(CLOSE, 20)"} # 额外指标(可选)
)
参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|
start_date | str | 是 | - | 回测开始日期(YYYY-MM-DD) |
end_date | str | 是 | - | 回测结束日期(YYYY-MM-DD) |
symbols | list[str] | 否 | None | 股票代码列表(不传则需传 filter_formula) |
filter_formula | str | 否 | None | 前置过滤公式 |
market | str | 否 | cn | 市场(cn/hk/us) |
entry_formula | str | 否 | None | 买入/开仓公式(不传则需传 strategy_code) |
strategy_code | str | 否 | None | 自定义回测策略 Python 源码代码。代码中必须定义 handle_data(context, datas) 函数。 |
exit_formula | str | 否 | None | 卖出/平仓公式(结果 > 0 触发卖出) |
initial_cash | float | 否 | 100000 | 初始资金(元) |
commission | float | 否 | 0 | 佣金费率(如 0.0003 表示万三) |
buy_commission | float | 否 | 0 | 买入手续费率(优先于 commission) |
sell_commission | float | 否 | 0 | 卖出手续费率(优先于 commission) |
min_commission_amount | float | 否 | 0 | 单笔最低手续费金额(元) |
slippage | float | 否 | 0 | 滑点比例(买入价上浮、卖出价下浮) |
position_size | float | None | 否 | None | 单只股票最大仓位比例(None = 不限制) |
max_positions | int | None | 否 | None | 最大持仓股票数量(None = 不限制) |
min_volume | int | 否 | 100 | 最小买入股数 |
auto_close | bool | 否 | True | 是否在回测结束时自动平仓 |
cheat_on_open | bool | 否 | False | 是否在 T 日信号生成后的 T 日开盘执行(False = T+1 开盘执行) |
signal_factors | dict[str, str] | 否 | None | 预计算因子字典,用于 strategy_code 模式 |
返回结果:
{
"success": True,
"initial_cash": 100000,
"final_cash": 115000,
"total_return": 15000,
"total_return_pct": 0.15,
"max_drawdown": 0.08,
"profit_factor": 1.5,
"win_rate": 0.6,
"total_trades": 10,
"winning_trades": 6,
"losing_trades": 4,
"trades": [...],
"portfolio_value": {...},
"benchmark_value": {...},
"benchmark_return_pct": 0.12,
"sharpe_ratio": 1.18,
"alpha": 0.04,
"beta": 0.92,
"max_drawdown_start": "2023-08-15",
"max_drawdown_end": "2023-10-23",
"daily_returns": {...},
"drawdown_series": {...},
"error_msg": None
}
使用示例:
# 1. 简单金叉策略(只有买入信号)
result = client.quant.backtest(
start_date="2023-01-01",
end_date="2024-01-01",
symbols=["000001"],
entry_formula="CROSS(MA(CLOSE, 5), MA(CLOSE, 20))"
)
print(f"总收益: {result['total_return']:.2f}")
print(f"收益率: {result['total_return_pct']:.2%}")
print(f"最大回撤: {result['max_drawdown']:.2%}")
print(f"胜率: {result['win_rate']:.2%}")
print(f"盈亏比: {result['profit_factor']:.2f}")
print(f"交易次数: {result['total_trades']}")
# 2. 买入和卖出信号都指定
result = client.quant.backtest(
start_date="2023-01-01",
end_date="2024-01-01",
symbols=["000001"],
entry_formula="CROSS(MA(CLOSE, 5), MA(CLOSE, 20))", # 金叉买入
exit_formula="CROSSDOWN(MA(CLOSE, 5), MA(CLOSE, 20))" # 死叉卖出
)
# 3. RSI 超卖超买策略
result = client.quant.backtest(
start_date="2023-01-01",
end_date="2024-01-01",
symbols=["000001"],
entry_formula="RSI(14) < 30", # RSI 低于 30 买入
exit_formula="RSI(14) > 70" # RSI 高于 70 卖出
)
# 4. 使用 signal_factors 记录额外指标
result_indicator = client.quant.backtest(
start_date="2023-01-01",
end_date="2024-01-01",
symbols=["000001"],
entry_formula="CROSS(MA(CLOSE, 5), MA(CLOSE, 10))",
exit_formula="CROSS(MA(CLOSE, 10), MA(CLOSE, 5))",
signal_factors={
"ma5": "MA(CLOSE, 5)",
"ma10": "MA(CLOSE, 10)"
}
)
# 5. 自定义策略
custom_code = """
def handle_data(context, datas):
for data in datas:
symbol = data.name
position = context.portfolio.get_position(symbol)
if position is None:
if data.close > data.open: # 阳线买入
context.order_target_percent(symbol, 0.2)
else:
if data.close < data.open: # 阴线卖出
context.order_target_percent(symbol, 0)
"""
result_custom = client.quant.backtest(
start_date="2023-01-01",
end_date="2024-01-01",
symbols=["000001"],
strategy_code=custom_code
)
backtest_upload()
上传 Excel 文件进行回测。使用自己的行情数据(而非系统内置数据源)。
result = client.quant.backtest_upload(
file_path="my_stock_data.xlsx",
start_date="2023-06-01",
end_date="2024-01-01",
entry_formula="CROSS(MA(CLOSE, 5), MA(CLOSE, 10))",
exit_formula="CROSS(MA(CLOSE, 10), MA(CLOSE, 5))",
initial_cash=100000,
commission=0.0003
)
参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|
file_path | str | 否* | None | Excel 文件路径(与 file_content 二选一) |
file_content | bytes | 否* | None | Excel 文件字节内容(与 file_path 二选一) |
file_name | str | 否 | None | 文件名(使用 file_content 时可指定) |
start_date | str | 否 | None | 回测开始日期(YYYY-MM-DD),指标计算后按此过滤 |
end_date | str | 否 | None | 回测结束日期(YYYY-MM-DD),指标计算后按此过滤 |
entry_formula | str | 否 | None | 买入/开仓公式(不传则需传 strategy_code) |
strategy_code | str | 否 | None | 自定义回测策略 Python 源码 |
exit_formula | str | 否 | None | 卖出/平仓公式 |
initial_cash | float | 否 | 100000 | 初始资金(元) |
commission | float | 否 | 0 | 佣金费率 |
buy_commission | float | 否 | 0 | 买入手续费率(优先于 commission) |
sell_commission | float | 否 | 0 | 卖出手续费率(优先于 commission) |
min_commission_amount | float | 否 | 0 | 单笔最低手续费金额(元) |
slippage | float | 否 | 0 | 滑点比例(买入价上浮、卖出价下浮) |
position_size | float | None | 否 | None | 单只股票最大仓位比例。传 None 表示不限制 |
max_positions | int | None | 否 | None | 最大持仓股票数量。传 None 表示不限制 |
min_volume | int | 否 | 1 | 最小买入股数 |
auto_close | bool | 否 | True | 是否自动平仓 |
cheat_on_open | bool | 否 | False | True 时 T 日信号在 T 日开盘成交,False 时在 T+1 开盘成交 |
signal_factors | dict[str, str] | 否 | None | 指标与因子字典 |
Excel 文件格式:
| 列名 | 是否必须 | 说明 |
|---|
date | 必须 | 交易日期 |
open | 必须 | 开盘价 |
high | 必须 | 最高价 |
low | 必须 | 最低价 |
close | 必须 | 收盘价 |
symbol | 多标的时必须 | 股票代码 |
volume | 可选 | 成交量 |
amount | 可选 | 成交额 |
支持中文列名自动映射:
| 中文列名 | 映射到 |
|---|
| 日期 / 时间 / 交易日期 / 交易日 | date |
| 开盘 / 开盘价 | open |
| 最高 / 最高价 | high |
| 最低 / 最低价 | low |
| 收盘 / 收盘价 | close |
| 成交量 / 交易量 | volume |
| 成交额 / 交易额 | amount |
| 代码 / 股票代码 / 证券代码 | symbol |
自定义字段列名仍须为 ASCII 字符(英文字母、数字、下划线)。
使用示例:
# 从文件字节上传
with open("my_data.xlsx", "rb") as f:
content = f.read()
result = client.quant.backtest_upload(
file_content=content,
file_name="my_data.xlsx",
entry_formula="CROSS(MA(CLOSE, 5), MA(CLOSE, 20))"
)
完整示例
技术分析工作流
from reportify_sdk import Reportify
client = Reportify(api_key="your-api-key")
# 1. 获取股票数据
df = client.quant.ohlcv("000001", start_date="2024-01-01")
# 2. 计算多个指标
rsi = client.quant.factors_compute(["000001"], "RSI(14)")
macd = client.quant.factors_compute(["000001"], "MACD()")
boll = client.quant.factors_compute(["000001"], "BOLL(20, 2)")
# 3. 合并数据
import pandas as pd
data = df.merge(rsi[["date", "rsi"]], on="date")
data = data.merge(macd[["date", "dif", "dea", "macd"]], on="date")
data = data.merge(boll[["date", "upper", "mid", "lower"]], on="date")
print(data.tail())
选股并回测
# 1. 选股:RSI 超卖
oversold_stocks = client.quant.factors_screen(formula="RSI(14) < 30")
print(f"发现 {len(oversold_stocks)} 只超卖股票")
# 2. 对每只股票进行回测
for stock in oversold_stocks[:5]: # 取前 5 只
result = client.quant.backtest(
start_date="2023-01-01",
end_date="2024-01-01",
symbols=[stock["symbol"]],
entry_formula="CROSS(RSI(14), 30)" # RSI 上穿 30 买入
)
print(f"{stock['symbol']}: 收益率 {result['total_return_pct']:.2%}")