A unified data layer for Chinese A-stock market data. Wraps 5+ data sources (通达信TCP, 腾讯HTTP, 东方财富API, 问财OpenAPI) behind a single interface with automatic failover, rate limiting, and caching.
from stockdata import get_quote, get_kline
quote = get_quote("002335") # → mootdx TCP, fallback tencent
klines = get_kline("002335") # → mootdx, fallback eastmoney (复权)
board = get_board_betting() # → eastmoney (涨停/炸板/跌停)
index = get_index_quote("000001") # → tencent (上证指数)
rank = get_fund_flow_rank(limit=20) # → eastmoney (主力净流入排行)pip install -e D:\AI\stockdata # 或从 GitHub clone 后安装from stockdata import *
from stockdata.quota import quota_manager
# 带自动兜底的行情查询
q = get_quote("002335")
print(f"{q.name}: {q.price} ({q.change_pct:+.2f}%) 来源={q.source}")
# K线数据(自动路由到最优源)
kl = get_kline("600036", count=5)
for k in kl:
print(f"{k.date} O={k.open} C={k.close}")
# 强制跳过缓存
fresh = get_quote("002335", force=True)
# 查看数据源配额状态
for s in quota_manager.status():
print(f"{s['source']}/{s['data_type']}: {s['call_count']} calls")
# 手动清除缓存
clear_all()| Function | Returns | Data Sources | Notes |
|---|---|---|---|
get_quote(code) |
Quote |
mootdx → tencent → eastmoney | 实时行情,全天候 |
get_kline(code, count=120) |
list[KLine] |
mootdx → eastmoney(复权) → tencent | 日K线,eastmoney 支持前复权 |
get_fund_flow(code) |
FundFlow |
eastmoney | 个股当日资金流 |
get_fund_flow_rank(limit=100) |
list[FundFlowRankItem] |
eastmoney | 全市场主力净流入排行 |
get_research_report(code) |
list[ResearchReport] |
eastmoney | 个股研报列表 |
get_news(code) |
list[NewsItem] |
eastmoney | 个股相关公告/新闻 |
get_board_betting() |
list[BoardBettingData] |
eastmoney | 涨停/炸板/跌停/昨涨停 |
get_block_info(name) |
BlockInfo |
eastmoney | 概念板块成分股 |
stock_screener(query) |
StockScreenerResult |
iwencai | 自然语言选股 |
get_dragon_tiger() |
list[DragonTiger] |
eastmoney | 龙虎榜 |
get_north_flow() |
list[NorthFlow] |
eastmoney | 北向资金日频 |
get_sector_spot(type) |
list[SectorSpot] |
eastmoney | 行业/概念板块涨跌幅排行 |
get_index_quote(code) |
IndexData |
tencent → eastmoney | 指数实时行情,全天候 |
get_index_kline(code) |
list[IndexData] |
eastmoney | 指数K线 |
All return types are @dataclass with typed fields defined in stockdata/types.py:
- Quote:
code, name, price, last_close, open, high, low, change_pct, change_amt, volume, amount, source - KLine:
code, date, open, close, high, low, volume, amount, ma5?, ma10?, ma20?, source - FundFlow:
code, name, main_net, retail_net, main_pct, date, source - DragonTiger:
trade_date, code, name, buy_amount, sell_amount, net_amount, reason, source - NorthFlow:
date, net_amount, sh_net, sz_net, cumulative, source - SectorSpot:
sector_name, sector_type, change_pct, up_count, down_count, source - FundFlowRankItem:
code, name, main_net, change_pct, price, source - IndexData:
code, name, price, change_pct, open, high, low, volume, amount, source
┌─ Caller ─────────────────────────────┐
│ from stockdata import get_quote │
└────────────────┬─────────────────────┘
│
┌────────────────▼─────────────────────┐
│ stockdata.router │ ← 按优先级链遍历
│ get_quote("002335") │
│ → mootdx (最快, TCP直连) │
│ → tencent (HTTP, 不封IP) │
│ → eastmoney (有风控, 兜底) │
│ → AllSourcesExhausted (全部失败) │
├──────────────────────────────────────┤
│ cache.py TTL 缓存 (行情5s, K线5m)│
│ quota.py 配额管理+冷却 │
│ config.py YAML 配置加载 │
├──────────────────────────────────────┤
│ sources/ mootdx / tencent / │
│ eastmoney / iwencai │
└──────────────────────────────────────┘
Edit config.yaml (or set STOCKDATA_CONFIG env var to point to yours):
# 路由优先级(越靠前越优先)
quote_priority:
- mootdx # 最快,TCP直连,不封IP
- tencent # HTTP,字段丰富
- eastmoney # 有风控,兜底
# 配额管理
quota_defaults:
daily_limit: 10000
min_interval: 0.05 # 最小调用间隔(秒)
max_consecutive_failures: 5
failure_cooldown: 300 # 冷却时间(秒)
# 缓存TTL
cache_ttl:
quote: 5 # 行情缓存5秒
kline: 300 # K线缓存5分钟
research_report: 3600 # 研报缓存1小时API keys are read from environment variables at runtime (never hardcoded):
| Variable | Required For | How to Set |
|---|---|---|
IWENCAI_API_KEY |
问财选股 | setx IWENCAI_API_KEY your_key |
MX_APIKEY / MX_APIKEY2 / MX_APIKEY3 |
妙想数据 (optional) | setx MX_APIKEY your_key |
# 从本地
pip install -e D:\AI\stockdata
# 从 GitHub(发布后)
pip install git+https://github.com/YOUR_USER/stockdata.git- Python ≥ 3.10
requests,pandas,pyyaml,cachetools,mootdx
Installed automatically with pip install.
| Source | Type | Auth | Reliability | 非交易时段 |
|---|---|---|---|---|
| mootdx | 通达信TCP | None | ★★★★★ | ✅ 全天候 |
| tencent | qt.gtimg.cn HTTP | None | ★★★★★ | ✅ 全天候 |
| eastmoney | push2 API | IP限流 | ★★★☆☆ | ❌ 断连 |
| iwencai | OpenAPI | Bearer token | ★★★★☆ | ✅ |
stockdata/
├── pyproject.toml # pip install -e .
├── config.yaml # 全局配置
├── .gitignore
├── README.md
├── stockdata/
│ ├── __init__.py # 统一导出
│ ├── router.py # 路由循环 + 缓存 + 配额检查
│ ├── cache.py # TTL 内存缓存
│ ├── quota.py # 每日限额 + 冷却 + 失败停用
│ ├── config.py # YAML 加载
│ ├── types.py # 统一数据类型
│ └── sources/
│ ├── __init__.py # 数据源注册表
│ ├── common.py # 共享工具 (em_get/tencent_prefix/tdx_client)
│ ├── mock_source.py # 假数据源(测试用)
│ ├── mootdx_source.py# 通达信 TCP (行情+K线)
│ ├── tencent_source.py # 腾讯 HTTP (行情+指数)
│ ├── eastmoney_source.py # 东方财富 (资金/研报/新闻/打板/板块/龙虎榜/北向/复权K线)
│ └── iwencai_source.py # 问财 HTTP (选股)
└── examples/
└── demo.py # 使用示例
# 可编辑安装(代码修改即时生效)
pip install -e .
# 快速验证
python test_minimal.py
# 全部示例
python examples/demo.pyIf you are an AI agent reading this README:
- Import:
from stockdata import get_quote(package is pip-installable) - No sys.path hacks needed: stockdata is a proper Python package
- Always handle None: data sources may return
Noneduring non-trading hours - Use force=True to skip cache when you need fresh data
- Check quota status with
quota_manager.status()if calls are being silently dropped - Config file search order:
STOCKDATA_CONFIGenv var →./config.yaml→ package dir - Sources目录添加新数据源: create file in
sources/, implement methods, callregister_source(), add to priority chain in config