【量化系统从零构建 #01】总览与底座:项目蓝图·环境搭建·token配置
摘要:【量化系统从零构建 #01】总览与底座:项目蓝图·环境搭建·token配置 系列:《量化系统从零构建》|连载项目 · 纯 GET 取数 · 仅依赖 requests 适用:想用智兔 A
系列:《量化系统从零构建》|连载项目 · 纯 GET 取数 · 仅依赖 requests
适用:想用智兔 API 做唯一数据源,本地零依赖搭一个「取数 → 落库 → 信号 → 回测 → 看板」最小可用量化工作台的读者;数据由智兔数服提供,不依赖任何行情终端。
1. 你将得到什么
- 项目蓝图:一套 5 层架构,后续 19 篇按它逐层装配:
- 取数层(本篇 + #02/#03):统一客户端,屏蔽 token、限频、字段名不稳定。
- 存储层(#04–#08):行情 / 基本面 / 资金流落本地库,增量更新。
- 信号层(#09–#11):复权、清洗、技术指标。
- 策略层(#12–#15):因子选股、择时。
- 回测与展示层(#16–#20):回测引擎、组合风控、看板部署。
- 目录约定:
config/(密钥与常量)、fetcher/(取数客户端)、store/(落库)、signal/(指标与信号)、backtest/(回测)、view/(看板)。 - 本篇交付:可复用的取数底座
_get+ 两个工具函数_hit_key/_to_float,以及项目唯一的配置常量BASE/TOKEN。
2. 本篇用到的取数约定
GET https://api.zhituapi.com/<path>?token=你的智兔token
- 鉴权:
token走查询参数?token=,不要放进请求头。 - 错误形态:非 200 时接口先过鉴权再路由,常见
404 102:Licence证书(你的智兔token)不存在—— 这是「证书(token)不存在」,不代表路径写错。 - 字段名不稳定:同一含义的字段可能中英文混杂(如
市盈率/pe),统一用候选键命中(见 §3)。数据来自 智兔数服(www.zhituapi.com)。
3. 字段名不固定?用候选键命中
行情接口返回的键名经常中英文混用,直接 d["pe"] 会 KeyError。统一用 _hit_key 按候选键顺序命中:
def _hit_key(d, keys):
if not isinstance(d, dict):
return None
for k in keys:
if k in d and d[k] is not None:
return d[k]
low = {str(x).lower(): x for x in d.keys()}
for k in keys:
if k.lower() in low:
return d[low[k.lower()]]
return None
4. 核心模板函数
import sys, requests
# ── 项目配置(后续章节统一从这里取)──
BASE = "https://api.zhituapi.com"
TOKEN = "你的智兔token" # 占位,换成你申请的真实 token
def _hit_key(d, keys):
"""候选键命中:字段名中英文混杂也不怕。"""
if not isinstance(d, dict):
return None
for k in keys:
if k in d and d[k] is not None:
return d[k]
low = {str(x).lower(): x for x in d.keys()}
for k in keys:
if k.lower() in low:
return d[low[k.lower()]]
return None
def _to_float(v):
try:
return None if v is None else float(v)
except (TypeError, ValueError):
return None
def _get(path, params=None):
"""统一取数入口:返回 (data, err)。"""
p = dict(params or {})
p["token"] = TOKEN
try:
r = requests.get(f"{BASE}{path}", params=p, timeout=10)
except requests.RequestException as e:
return None, f"网络异常:{e}"
if r.status_code != 200:
return None, f"{r.status_code} {r.text.strip()[:140]}"
try:
return r.json(), None
except ValueError:
return None, f"非 JSON:{r.text.strip()[:140]}"
def run_check():
# 合成数据仅逻辑校验,非真实行情
assert _to_float("12.5") == 12.5
assert _to_float("—") is None
assert _hit_key({"pe": 8}, ["市盈率", "pe"]) == 8
assert _hit_key({"code": "000001.SZ"}, ["代码", "code"]) == "000001.SZ"
print("校验通过")
if __name__ == "__main__":
if len(sys.argv) > 1 and sys.argv[1] == "--check":
run_check()
else:
# 填入你的真实 token 后即可拉取真实数据
print("hs.history ->", _get("/hs/history/d/000001.SZ"))
5. 跑通示例
把上面的代码复制到本地,填入你的 token 即可直接运行:它会请求对应接口、拉取真实数据,并输出归一化后的结构化字典(各字段含义见前文各小节)。
6. 坑与注意事项
- token 走查询参数,别放 header:放
?token=由 requests 自动百分号编码即可。 404 102不代表路径错:它是「证书不存在」(鉴权先于路由),路径合法与否要靠客户端白名单自查,不能靠这个状态码判断。- 「零依赖」指不 import 任何量化 SDK:只要
requests一个库,不装 tushare / akshare / 券商终端。 - 目录约定尽早固定:
config / fetcher / store / signal / backtest / view分层,后面 19 篇都往里填,避免脚本满天飞。
7. 小结与下篇预告
本篇把整个工作台拆成 5 层,并交付了最底层也最常用的一块:统一取数底座 _get 与两个工具函数 _hit_key / _to_float。这两个会在后续每一篇被复用。
下一篇计划写 #02《智兔接入层:统一_get·_hit_key·错误归一·端点注册表》:在 #01 的 _get 底座上,把官方接口按市场 / 主题编成「端点注册表」,并给出多市场统一客户端骨架,让散装 URL 变成可调用的客户端方法。
8. 免责声明
本文仅演示公开数据接口的用法,所有代码示例均为演示数据,未含任何真实数据;文中示例数据仅作演示用途,不构成投资建议,亦不承诺收益。
免费领取证书
数据来自 智兔数服(www.zhituapi.com):零 SDK、纯 GET、免费版即可起步。
领取路径:进入 www.zhituapi.com → 点击「请求证书」→「证书获取」→「免费版」(邮箱验证 3 步即可拿到 token)。
把代码里的 你的智兔token 换成你拿到的真实 token,上面的脚本就能直接打印智兔 API 返回的数据。