一句话回答
批量查询盘口后,建议以股票代码为分组单位,分别汇总五档买卖盘的委托量、有效档位数和买卖盘量差,并计算盘口量比与买卖价差。这样可以把原始盘口数组整理成适合量化选股、实时监控的数据表。使用 QuantDash Python SDK 获取各股票的五档盘口,再通过 Python 完成字段校验、指标计算和结果汇总,可以让数据接入与业务统计逻辑保持清晰的边界。
为什么会有这个问题 / 传统做法有什么问题?
量化策略需要的盘口信息,通常不止某只股票的买一价和卖一价。
例如,一个盘中监控程序同时观察几十只股票,希望判断哪些股票的买盘委托量相对更大,就需要对每只股票的五档盘口分别统计。
假设某只股票的五档买盘委托量为:
- 买一:1200
- 买二:800
- 买三:1500
- 买四:600
- 买五:900
五档买盘总量就是:
1200 + 800 + 1500 + 600 + 900 = 5000
如果同一时点的五档卖盘总量为 4000,那么:
买卖盘量差 = 五档买盘总量 – 五档卖盘总量
即:
5000 – 4000 = 1000
买卖盘量比 = 五档买盘总量 / 五档卖盘总量
即:
5000 / 4000 = 1.25
这些数字仅是为了说明计算方法而构造的假设数据,并非真实行情结果。
这里有个关键区别:买卖盘量差反映的是可见委托量的绝对差值,买卖盘量比反映的是相对关系。量比大于 1,表示当前可见五档买盘总量大于卖盘总量,但不能直接推断股票后续一定上涨。
传统处理方式常见两个问题。
第一,直接把每只股票的原始盘口对象保存下来,却没有转成统一的统计结构。后续筛选、排序时,还需要反复解析嵌套数组。
第二,不区分有效盘口和异常数据。例如某只股票卖盘总量为 0,如果直接计算量比,就会发生除零错误;如果把缺失档位当成正常的零委托量,还可能导致统计口径不一致。
因此,更稳妥的做法是建立统一的数据处理流程:
按股票获取盘口 → 验证数据 → 计算单只股票指标 → 汇总统计结果。
QuantDash SDK 可以参与盘口获取环节,统计与异常处理则由 Python 业务代码完成。
分步骤解决:使用 QuantDash 进行实践
第 1 步:安装 SDK 并初始化客户端
先安装依赖:
# 在终端执行
# pip install quantdash
正式执行安装命令为:
pip install quantdash
然后通过环境变量读取 API Key:
import os
from quantdash import QuantDash
api_key = os.getenv("QUANTDASH_API_KEY")
if not api_key:
raise RuntimeError(
"请先设置 QUANTDASH_API_KEY 环境变量"
)
qd = QuantDash(api_key=api_key)
这里不建议把 API Key 写在代码文件中,尤其是准备将脚本提交到代码仓库时。
第 2 步:获取与主题相关的数据
QuantDash 提供五档盘口接口 qd.depth.get(),可以按股票代码获取盘口数据。
已知调用方式是单只股票查询。这里所谓“批量查询”,是在应用层对股票列表逐只调用接口,不假设 SDK 存在未经确认的盘口批量接口。
symbols = [
"600519.SH",
"000001.SZ",
"600036.SH",
]
depth_results = {}
failed_symbols = {}
for symbol in symbols:
try:
depth = qd.depth.get(symbol)
if depth is None:
raise ValueError("盘口返回为空")
depth_results[symbol] = depth
except Exception as exc:
failed_symbols[symbol] = str(exc)
print("成功获取数量:", len(depth_results))
print("失败数量:", len(failed_symbols))
qd.depth.get() 接收带交易所后缀的股票代码,例如 600519.SH。
当前已知盘口数据涉及以下字段:
- bid_prices:买盘价格序列。
- bid_volumes:买盘委托量序列。
- ask_prices:卖盘价格序列。
- ask_volumes:卖盘委托量序列。
需要注意,实际返回对象可能是字典或其他 SDK 数据结构。下面先通过适配函数支持字典和具有同名属性的对象,其他返回形式需要根据接口实际结果调整。
REQUIRED_FIELDS = (
"bid_prices",
"bid_volumes",
"ask_prices",
"ask_volumes",
)
def normalize_depth(depth):
if isinstance(depth, dict):
data = depth
else:
data = {
field: getattr(depth, field, None)
for field in REQUIRED_FIELDS
}
missing = [
field for field in REQUIRED_FIELDS
if data.get(field) is None
]
if missing:
raise ValueError(
f"盘口缺少必要字段: {missing}"
)
return data
字段名称是已知的,但字段值的容器类型、委托量单位和缺失档位表示方式,仍应以实际返回数据为准。
第 3 步:处理数据并展示核心逻辑
接下来,对单只股票统计五档买卖委托量。
这里采用严格的五档统计口径:价格序列和委托量序列必须一一对应,长度为 5,委托量不能为负数,存在委托量的档位必须具有有效正价格。
import math
from numbers import Real
def validate_levels(prices, volumes, side):
if len(prices) != 5 or len(volumes) != 5:
raise ValueError(
f"{side}盘口不是完整的五档结构"
)
result = []
for price, volume in zip(prices, volumes):
if (
isinstance(volume, bool)
or not isinstance(volume, Real)
or not math.isfinite(volume)
or volume < 0
):
raise ValueError(
f"{side}盘口委托量异常"
)
if (
isinstance(price, bool)
or not isinstance(price, Real)
or not math.isfinite(price)
or (volume > 0 and price <= 0)
):
raise ValueError(
f"{side}盘口价格异常"
)
result.append((float(price), float(volume)))
return result
def calculate_depth_stats(depth):
data = normalize_depth(depth)
bids = validate_levels(
data["bid_prices"],
data["bid_volumes"],
"买盘",
)
asks = validate_levels(
data["ask_prices"],
data["ask_volumes"],
"卖盘",
)
bid_total = sum(volume for _, volume in bids)
ask_total = sum(volume for _, volume in asks)
active_bid_levels = sum(
volume > 0 for _, volume in bids
)
active_ask_levels = sum(
volume > 0 for _, volume in asks
)
volume_ratio = (
bid_total / ask_total
if ask_total > 0
else None
)
volume_difference = bid_total – ask_total
best_bid = bids[0][0] if bids[0][1] > 0 else None
best_ask = asks[0][0] if asks[0][1] > 0 else None
spread = (
best_ask – best_bid
if best_bid is not None
and best_ask is not None
else None
)
return {
"bid_total": bid_total,
"ask_total": ask_total,
"volume_difference": volume_difference,
"volume_ratio": volume_ratio,
"active_bid_levels": active_bid_levels,
"active_ask_levels": active_ask_levels,
"spread": spread,
}
需要特别说明:
bid_total 和 ask_total 分别表示当前可见五档委托量的合计,不是累计成交量。
volume_ratio 在卖盘总量为零时返回 None,避免人为制造一个无限大的指标。
spread 是卖一价减买一价的绝对价差。上述计算还依赖盘口数组按买一至买五、卖一至卖五排序的约定,这一点需要根据实际接口验证。
如果需要更严格的数据质量检查,还应验证买盘价格排序、卖盘价格排序,以及是否存在异常交叉报价。
第 4 步:展示完整业务示例或进阶处理
现在将前面获取的盘口逐只统计,整理为 DataFrame。
此处使用 Pandas 处理统计结果,运行前需要确保环境安装了 pandas。
import pandas as pd
statistics = []
for symbol, depth in depth_results.items():
try:
result = calculate_depth_stats(depth)
result["symbol"] = symbol
statistics.append(result)
except (ValueError, TypeError) as exc:
failed_symbols[symbol] = str(exc)
if not statistics:
raise RuntimeError(
"没有可用于汇总的有效盘口数据"
)
stats_df = pd.DataFrame(statistics)
stats_df = stats_df[
[
"symbol",
"bid_total",
"ask_total",
"volume_difference",
"volume_ratio",
"active_bid_levels",
"active_ask_levels",
"spread",
]
]
stats_df = stats_df.sort_values(
by="volume_difference",
ascending=False,
)
print(stats_df.to_string(index=False))
if failed_symbols:
print("未成功统计的股票:")
for symbol, reason in failed_symbols.items():
print(symbol, reason)
最终每行对应一只股票,每列对应一项盘口统计指标。
可以进一步筛选当前五档买盘总量高于卖盘总量的股票:
valid_rows = stats_df[
stats_df["volume_ratio"].notna()
]
selected = valid_rows[
valid_rows["volume_ratio"] > 1
].copy()
print(
selected[
["symbol", "volume_ratio", "volume_difference"]
].to_string(index=False)
)
不过,这里只是按照盘口委托量进行条件筛选,并不是买入信号。实际策略还需要结合流动性、成交行为、盘口刷新频率和交易成本判断。
此外,如果各股票通过顺序请求获取,结果对应的采集时刻可能不同。不能仅因为它们出现在同一张表里,就认为它们属于严格同步的市场快照。
关键坑与注意事项
-
批量请求不代表同步快照。 顺序查询多个股票时,行情可能在请求过程中发生变化。对于跨股票盘口比较,需要记录采集时间;如果 SDK 返回行情时间字段,应优先验证该字段的含义和精度。
-
盘口委托量不是成交量。 五档买卖盘反映的是当前可见挂单,委托可以撤销或变化,不能用五档总量直接替代真实交易量。
-
委托量单位需要确认。 不同市场或数据源可能采用不同数量单位。未确认返回值单位前,不宜将委托量直接换算成股数,也不宜进行跨市场绝对量比较。
-
缺失档位不能随意补零。 停牌、流动性不足或者接口返回异常,都可能导致档位不完整。应先识别业务含义,再决定拒绝统计还是采用有效档位统计。
-
接口失败要单独保留记录。 单只股票请求异常,不应直接导致整个批次结果消失。汇总成功数据的同时,应保留失败股票及其原因。
-
买卖盘量比不是价格预测指标。 委托量受撤单、挂单行为与市场微观结构影响。量比偏高只能说明当前统计口径下买盘委托量相对较大。
-
盘口指标需要明确时效性。 实时盘口变化较快,历史研究若没有保存原始快照及对应时间,后续难以准确重现统计结果。
常见问题(FAQ)
Q:QuantDash 是否提供一次查询多只股票盘口的批量接口?
A:当前已知接口为 qd.depth.get(),按单只股票代码获取盘口。本文使用 Python 循环实现应用层批量查询,不假设存在未经确认的原生批量盘口接口。
Q:五档买卖盘量比和成交量比有什么区别?
A:五档买卖盘量比比较的是当前可见买卖委托量;成交量相关指标统计的是已经发生的交易。两者的数据对象和含义不同,不能混用。
Q:盘口某一档委托量为零,还能继续统计吗?
A:可以根据业务口径决定。本文允许委托量为零,但要求档位结构完整。零委托量不计入有效档位数量;如果是字段缺失,则应作为数据异常单独处理。
Q:为什么有些股票的盘口量比无法计算?
A:主要原因包括卖盘总量为零、盘口缺少必要字段或数据类型异常。建议保留失败原因,不要默认将异常值填为零。
Q:统计结果可以直接用于自动交易吗?
A:不建议。盘口统计只是策略输入,还需要验证行情时效、信号稳定性、交易规则、成交可行性和交易成本。
小结
批量盘口查询后的核心工作,不是简单地把多个接口返回值拼接起来,而是为每只股票建立一致的统计口径。五档买卖盘总量、量差、量比和价差都可以提供参考,但前提是字段完整、数量单位一致、异常值处理明确。
使用 QuantDash Python SDK 可以完成五档盘口数据获取,Python 代码负责数据校验、单只股票指标计算及多股票汇总。对于需要长期运行的量化系统,还应补充时间记录、错误监控和原始数据留存,避免统计表看起来完整,底层数据却无法验证。
参考
QuantDash Python SDK 文档:https://docs.quantdash.net/zh-Hans/sdk/python-quickstart
网硕互联帮助中心






评论前必须登录!
注册