rquote 是一个提供 A股/港股/美股/ETF基金/期货 历史数据获取的Python库
当前版本:0.6.4
- ✅ 支持多市场数据获取(A股、港股、美股、期货、基金)
- ✅ 统一的API接口,使用简单
- ✅ 内置缓存机制,提升性能
- ✅ 完善的错误处理和异常体系
- ✅ 可配置的HTTP客户端(超时、重试等)
- ✅ 模块化设计,易于扩展
- ✅ pandas 为可选依赖:默认返回
list[dict],无需安装 pandas;需要 DataFrame 时传as_dataframe=True
pip install rquote或使用 uv:
uv pip install rquote安装 pandas 支持(可选,用于获取 DataFrame 格式数据):
pip install "rquote[dataframe]"安装 orjson 加速(可选,per_key_json 读缓存时自动启用,解析更快):
pip install "rquote[orjson]"from rquote import get_price
# 获取上证指数数据(默认返回 list[dict],无需 pandas)
sid, name, records = get_price('sh000001')
print(records[0]) # {'date': '2024-02-06', 'open': 2680.48, 'close': 2789.49, ...}
# 需要 pandas DataFrame 时,传 as_dataframe=True(需安装 pandas)
sid, name, df = get_price('sh000001', as_dataframe=True)
print(df.head())# 获取指定日期范围的数据
sid, name, records = get_price('sz000001', sdate='2024-01-01', edate='2024-02-01')from rquote import get_price, MemoryCache
# 创建缓存实例(ttl 单位:秒)
cache = MemoryCache(ttl=3600) # 缓存 1 小时
# 使用缓存(通过dd参数传递MemoryCache实例)
sid, name, df = get_price('sh000001', dd=cache)
# 注意:MemoryCache 是内存缓存,数据仅在当前进程运行期间有效
# 脚本运行结束后,缓存数据会丢失缓存生命周期说明:
MemoryCache是纯内存缓存,数据存储在进程内存中- 缓存数据仅在当前脚本运行期间有效
- 脚本运行结束后,所有缓存数据会丢失
持久化缓存支持跨进程/跨运行的缓存持久化,数据会保存到本地文件。支持多种存储后端,通过工厂按名称选择。
安装可选依赖:
pip install rquote[persistent]
# 或
uv pip install "rquote[persistent]"推荐:使用工厂创建(指定后端类型)(ttl 单位为秒,默认 None 表示永久不过期)
from rquote import get_price, create_persistent_cache
# 按后端名称创建,默认路径为 ~/.rquote/cache.{db|jsonl|pkl|cache_json}
cache = create_persistent_cache(backend='sqlite')
cache = create_persistent_cache(backend='jsonl', path='/tmp/cache.jsonl') # 需过期可传 ttl=86400(秒)
cache = create_persistent_cache(backend='per_key_json', path='/data/daily') # 每 key 一 JSON 文件,path 为目录
# 使用缓存
sid, name, df = get_price('sh000001', dd=cache)
cache.close()兼容旧写法(不指定 backend 时):
from rquote import get_price, PersistentCache
# 不传 backend 时默认用 sqlite;ttl 单位秒,默认 None 即永久不过期
cache = PersistentCache()
cache = PersistentCache(db_path='./my_cache.db')
sid, name, df = get_price('sh000001', dd=cache)
cache.close()持久化缓存特性:
- ✅ 跨进程/跨运行持久化:数据保存在本地文件,下次运行仍可使用
- ✅ 智能数据合并:相同股票的数据会自动合并,key 不包含日期范围
- ✅ 智能扩展:当请求的日期范围超出缓存时,自动扩展并合并数据
- ✅ 支持 TTL:可设置缓存过期时间
- ✅ 多后端:sqlite / jsonl / pickle / per_key_json,均为标准库、无额外依赖,见下方选择维度
后端选择维度
| 维度 | sqlite | jsonl | pickle | per_key_json |
|---|---|---|---|---|
| 依赖 | 标准库,无额外依赖 | 标准库,无额外依赖 | 标准库 | 标准库 |
| 内存占用 | 低(按需从文件读) | 低(按需从文件读) | 高(整库常驻内存) | 低(按 key 读单文件) |
| 写入方式 | 单文件、随机写 | 单文件、整文件重写 | 单文件、整库序列化 | 每 key 一 JSON 文件 |
| 适用场景 | 通用、嵌入式、内存紧张 | 通用、可读性好、批量快更 | 兼容旧版、小数据量 | 单 key 更新、并发友好、不区分市场 |
per_key_json:每个 key 对应一个独立 JSON 文件,初始化 path 为所有 JSON 文件所在目录。文件名规则:base_key 中 : 替换为 _,如 sz000001:day:qfq → sz000001_day_qfq.json。不区分市场,适合单标的面更新、并发写入。若环境已安装 orjson(pip install rquote[orjson]),读 JSON 时自动使用 orjson 加速。
内存有限时的建议:
- 优先使用
sqlite或jsonl:两者都不会把整份缓存加载进内存,按 key 读写,适合本机内存紧张、树莓派或容器环境。 - 避免在内存紧张时使用
pickle:每次读写会整体加载/保存字典,数据量大时易 OOM。
获取股票、基金、期货的历史价格数据
参数:
i: 股票代码,使用新浪/腾讯的id形式sdate: 开始日期 (可选,格式:YYYY-MM-DD)edate: 结束日期 (可选,格式:YYYY-MM-DD)freq: 频率,默认'day' (日线),可选:(港A)'week', 'month', (美股)'min'days: 获取天数,默认320天fq: 复权方式,默认'qfq' (前复权),可选:'hfq' (后复权)dd: 本地缓存字典 (可选,已废弃,建议使用MemoryCache)as_dataframe: 为True时返回pd.DataFrame(需安装pandas),默认False返回list[dict]
代码格式说明:
- A股:
sh000001表示上证指数,sz000001表示深市000001股票平安银行 - ETF:
sh510050表示上证50指数ETF - 港股:
hk00700表示港股腾讯 - 期货: 需加
fu前缀,如fuAP2110,fuBTC表示比特币 - 美股: 需加对应交易所后缀,如
usBABA.N,usC.N,usAAPL.OQ等 - 比特币:使用
fuBTC代码
示例:
from rquote import get_price
# 获取上证指数数据(返回 list[dict])
sid, nm, records = get_price('sh000001')
print(records[0]) # {'date': '2024-02-06', 'open': 2680.48, ...}
# 获取指定日期范围的数据
sid, nm, records = get_price('sz000001', sdate='2024-01-01', edate='2024-02-01')
# 获取比特币数据
sid, nm, records = get_price('fuBTC')
# 获取期货分钟数据
sid, nm, records = get_price('fuM2601', freq='min')
# 需要 DataFrame 时(需安装 pandas)
sid, nm, df = get_price('sh000001', as_dataframe=True)
print(df.head())返回数据格式(as_dataframe=False,默认):
[
{'date': '2024-02-06', 'open': 2680.48, 'close': 2789.49, 'high': 2802.93, 'low': 2669.67, 'vol': 502849313},
{'date': '2024-02-07', 'open': 2791.51, 'close': 2829.70, 'high': 2829.70, 'low': 2770.53, 'vol': 547117439},
...
]返回数据格式(as_dataframe=True,需 pandas):
| date | open | close | high | low | vol |
|---|---|---|---|---|---|
| 2024-02-06 | 2680.48 | 2789.49 | 2802.93 | 2669.67 | 502849313 |
| 2024-02-07 | 2791.51 | 2829.70 | 2829.70 | 2770.53 | 547117439 |
获取更长时间的历史数据,默认获取2年数据,并且参数与 get_price 保持一致
from rquote import get_price_longer
# 获取3年的历史数据(返回 list[dict])
sid, nm, records = get_price_longer('sh000001', l=3)
# 指定结束日期与频率
sid, nm, records = get_price_longer('sh000001', l=3, edate='2024-02-01', freq='week', fq='qfq')
# 需要 DataFrame 时
sid, nm, df = get_price_longer('sh000001', l=3, as_dataframe=True)获取A股股票列表,按成交额排序,默认筛选成交额大于2亿的股票
from rquote import get_cn_stock_list
# 获取成交额大于5亿的股票列表
stocks = get_cn_stock_list(money_min=5e8)
# 返回格式: [{code, name, pe_ttm, volume, turnover/亿, ...}, ...]获取港股列表(按当日成交额排序,每页500只)。默认只取第1页;可传 max_pages=2~5 取多页(最多5页)。
from rquote import get_hk_stocks_500
stocks = get_hk_stocks_500() # 默认前500只
stocks = get_hk_stocks_500(max_pages=5) # 最多2500只
# 返回格式: [[code, name, price, -, -, -, -, volume, turnover, ...], ...]获取美股最大市值的k支股票列表
from rquote import get_us_stocks
us_stocks = get_us_stocks(k=100) # 获取前100只
# 返回格式: [{name, symbol, market, mktcap, pe, ...}, ...]获取中国指数成分股列表
from rquote import get_cnindex_stocks
# 获取沪深300成分股
hs300_stocks = get_cnindex_stocks('hs300')
# 获取中证500成分股
zz500_stocks = get_cnindex_stocks('zz500')
# 获取中证1000成分股
zz1000_stocks = get_cnindex_stocks('zz1000')
# 返回格式: [{SECURITY_CODE, SECURITY_NAME_ABBR, INDUSTRY, WEIGHT, EPS, BPS, ROE, FREE_CAP, ...}, ...]支持的指数类型:
'hs300': 沪深300'sz50': 上证50'zz500': 中证500'kc500': 科创500'zz1000': 中证1000'zz2000': 中证2000
获取A股ETF基金列表,按成交额排序
from rquote import get_cn_fund_list
funds = get_cn_fund_list()
# 返回格式: [code, name, change, amount, price]获取国内期货合约列表
from rquote import get_cn_future_list
futures = get_cn_future_list()
# 返回格式: ['fuSC2109', 'fuRB2110', 'fuHC2110', ...]获取所有行业板块列表
from rquote import get_all_industries
industries = get_all_industries()
# 返回格式: [code, name, change, amount, price, sina_sw2_id]获取指定股票所属的概念板块
from rquote import get_stock_concepts
# 获取平安银行的概念板块
concepts = get_stock_concepts('sz000001')
# 返回概念代码列表,如 ['BK0420', 'BK0900', ...]获取指定股票所属的行业板块
from rquote import get_stock_industry
# 获取平安银行的行业板块
industries = get_stock_industry('sz000001')获取指定行业板块的股票列表
from rquote import get_industry_stocks
# 获取行业板块股票
stocks = get_industry_stocks('sw2_480200')获取实时行情数据
from rquote import get_tick
# 获取美股实时行情
tick_data = get_tick(['AAPL', 'GOOGL'])
# 返回格式: [{'name': 'Apple Inc', 'price': '150.25', 'price_change_rate': '1.2%', ...}]绘制K线图
from rquote import PlotUtils
import plotly.graph_objs as go
# 绘制平安银行的K线图
data, layout = PlotUtils.plot_candle('sz000001', sdate='2024-01-01', edate='2024-02-01')
# 使用plotly显示
fig = go.Figure(data=data, layout=layout)
fig.show()from rquote import config
# 使用默认配置
default_config = config.default_config
# 创建自定义配置
custom_config = config.Config(
http_timeout=15,
http_retry_times=5,
cache_enabled=True,
cache_ttl=7200 # 单位:秒
)
# 从环境变量创建配置
import os
os.environ['RQUOTE_HTTP_TIMEOUT'] = '20'
config_from_env = config.Config.from_env()默认情况下,日志功能是关闭的。 如果需要启用日志,可以通过环境变量手动开启:
# 设置日志级别为 INFO(会同时输出到文件和控制台)
export RQUOTE_LOG_LEVEL=INFO
# 可选:自定义日志文件路径(默认为 /tmp/rquote.log)
export RQUOTE_LOG_FILE=/path/to/your/logfile.log
# 然后运行你的Python脚本
python your_script.pyDEBUG: 详细的调试信息INFO: 一般信息(推荐)WARNING: 警告信息ERROR: 错误信息CRITICAL: 严重错误
import os
# 在导入 rquote 之前设置环境变量
os.environ['RQUOTE_LOG_LEVEL'] = 'INFO'
os.environ['RQUOTE_LOG_FILE'] = '/tmp/rquote.log' # 可选
from rquote import get_price
# 现在日志已启用
sid, name, df = get_price('sh000001')如果不设置 RQUOTE_LOG_LEVEL 环境变量,或者设置为空值,日志功能将保持关闭状态(默认行为)。
from rquote.utils.http import HTTPClient
# 创建HTTP客户端
with HTTPClient(timeout=15, retry_times=3) as client:
response = client.get('https://example.com')
if response:
print(response.text)from rquote.cache import MemoryCache
# 创建缓存(ttl 单位:秒)
cache = MemoryCache(ttl=3600) # 缓存 1 小时
# 使用缓存
cache.put('key1', 'value1')
value = cache.get('key1')
cache.delete('key1')
cache.clear() # 清空所有缓存from rquote import get_price
from rquote.exceptions import SymbolError, DataSourceError, NetworkError
try:
sid, name, df = get_price('invalid_symbol')
except SymbolError as e:
print(f"股票代码错误: {e}")
except DataSourceError as e:
print(f"数据源错误: {e}")
except NetworkError as e:
print(f"网络错误: {e}")网络请求工具类
from rquote import WebUtils
# 获取随机User-Agent
ua = WebUtils.ua()
# 获取请求头
headers = WebUtils.headers()
# 测试代理
result = WebUtils.test_proxy('127.0.0.1:8080')基础因子计算工具类(v0.6.2 起已清空,原方法依赖 pandas 专属 API,随 pandas 改为可选依赖一并移除)
from rquote import BasicFactors
b = BasicFactors() # 可导入,空壳类,无方法v0.6.4 主要改进:
- 持久化缓存自动前向扩展逻辑改进
- 周末跳过扩展的前提:缓存已更新到上一交易日(避免周五收盘后误跳)
- 自动补齐 extend 时 API 仅返回最近 days 条导致的日期缺口(gap),循环填充直至连续
v0.6.3 主要改进:
- per_key_json 支持 orjson 加速(可选)
- 若安装
pip install rquote[orjson],per_key_json 读缓存时自动用 orjson 替代标准库 json,解析速度更快 - 未安装 orjson 时自动回退到标准库,无行为变化
- 若安装
v0.6.2 主要改进:
-
pandas 改为可选依赖
- 内部数据流统一改为
list[dict](JSON 友好,无需 pandas 即可运行) get_price/get_price_longer新增as_dataframe=False参数,指定True时在出口处转为pd.DataFrame- 安装:
pip install rquote不再依赖 pandas;需 DataFrame 支持时用pip install "rquote[dataframe]"
- 内部数据流统一改为
-
缓存层全面重写(无破坏性变更)
- 所有后端(SQLite / JSONL / Pickle / PerKeyJson)统一使用原生 JSON 序列化,废弃旧版 base64+pickle 格式
- 旧缓存文件(base64+pickle)直接废弃,删除
~/.rquote/cache*后重新拉取即可
-
BasicFactors清空为空壳类- 原
break_rise、min_resist、vol_extreme等方法依赖 pandas.rolling()专属 API,随本次重构一并移除
- 原
rquote/
├── __init__.py # 公共API导出
├── config.py # 配置管理
├── exceptions.py # 异常定义
├── main.py # 主要功能(向后兼容)
├── utils.py # 工具类(向后兼容)
├── plots.py # 绘图工具
├── cache/ # 缓存模块
│ ├── __init__.py
│ ├── base.py # 缓存基类
│ └── memory.py # 内存缓存实现
├── data_sources/ # 数据源模块
│ ├── __init__.py
│ ├── base.py # 数据源基类
│ ├── sina.py # 新浪数据源
│ └── tencent.py # 腾讯数据源
├── parsers/ # 数据解析模块
│ ├── __init__.py
│ └── kline.py # K线数据解析
└── utils/ # 工具模块
├── __init__.py
├── http.py # HTTP客户端
└── date.py # 日期工具
运行单元测试:
# 运行所有测试
python -m pytest tests/
# 运行特定测试
python -m pytest tests/test_utils.py
python -m pytest tests/test_cache.py
python -m pytest tests/test_config.py
python -m pytest tests/test_exceptions.py
python -m pytest tests/test_api.py- 数据来源: 数据来源于新浪财经、腾讯财经、东方财富等公开数据源
- 请求频率: 建议合理控制请求频率,避免被限制访问
- 代码格式:
- 期货代码需要加
fu前缀,如fuAP2110 - 美股代码需要加对应后缀,如
usAAPL.OQ(OQ->NASDAQ, N->NYSE, AM->ETF)
- 期货代码需要加
- 网络要求: 部分功能需要网络连接,请确保网络畅通
- 缓存使用: 建议使用缓存机制减少网络请求,提升性能
欢迎提交Issue和Pull Request!