写在前面
一个很多人做过的动作:
盘后打开软件,看到今天螺纹钢涨了 1.2%,持仓量增加了 4 万手。于是心里踏实了一下——"增仓上涨,有新资金在进场,趋势是健康的",第二天加了一手。
这个动作的依据,是一张流传极广的表。它把价格的涨跌和持仓量的增减两两组合,得出四个方向判断。几乎所有入门材料都有它,很多行情软件甚至直接在盘后给你标出来。
我一直对它有个疑问,直到把数据拉下来才敢说出口:
这张表在做一件逻辑上做不到的事——它想从一个净额里,读出流水。
这是《米粒指标》的第三篇。上一篇《成交量与持仓量》讲透了持仓量是什么,结尾我说过四象限是"后面专门的一篇",刻意一个字没碰。这一篇就是它。
先说清楚本篇的态度:我不是来告诉你这张表怎么用得更好的。我是来告诉你它为什么用不了的。
一、先把这张表原样摆出来
不能只批评不引用。这是它最常见的版本:
| 持仓量增加 | 持仓量减少 | |
|---|---|---|
| 价格上涨 | 多头增仓:新多进场 → 涨势健康,看涨 | 空头回补:空头平仓推涨 → 上涨无力,警惕见顶 |
| 价格下跌 | 空头增仓:新空进场 → 跌势健康,看跌 | 多头平仓:多头认输离场 → 抛压减轻,跌势将尽 |
它诱人的地方很清楚:你手上只有两个客观数字,它却给了你一个方向判断。不需要模型、不需要参数,盘后十秒钟就能查出来。而且每一格的解释都合乎常理——新钱进场推动的行情,当然比平仓推动的更扎实。
讲得通,是这张表最危险的地方。 一个讲得通、又零成本的东西,人是不会去验证它的。
二、构造上的硬伤:一个数,两个未知数
先把持仓量没有方向这件事拿过来——上一篇已经论证完了,这里直接用:每一手持仓的背后,永远是一个多头加一个空头。所以"增仓 4 万手"的意思是,有 4 万手的人赌涨,同时有 4 万手的人赌跌。
那么问题来了。一天下来,持仓量净增 4 万手,这个数字是怎么来的?
一天之内,市场上同时在发生四件事:新多开仓、多头平仓、新空开仓、空头平仓。它们各自的量,我们一个都看不到。能看到的只有它们相抵之后的那一个净数。
用式子写出来就很清楚了:
持仓量变化 = 新开的多单 − 平掉的多单
= 新开的空单 − 平掉的空单 (两式恒等)
(这四件事怎么两两配对成一笔成交、又怎么让持仓量 +1 / 不变 / −1,上一篇第二节有一张完整的机制表,这里不重复。)
现在回头看那张四象限表。它每一格的解释,都在回答同一个问题:这次持仓量的变化,主要是谁造成的? 是新多在进场,还是空头在离场?
这是从净额反推流水。
你的银行账户当天净入账 5000 元。你能据此说"有人给我转了 5000"吗?不能。可能是收了 3 万、付出去 2.5 万,也可能真的只有一笔 5000。净额相同,底下的流水可以完全不同,而且差着数量级。
持仓量的变化是一个净额,四象限想从净额里读出流水。
这不是精度问题,是信息在生成的那一刻就被抹掉了。逐笔成交里确实带着开平标记,交易所也确实知道,但公开日行情给你的只有那一个净数。
所以这张表真正的问题不在于每一格的解释对不对——
它不是错在结论,是错在它假装自己知道谁在动。
到这一步,我们只证明了它"没有依据"。没有依据的东西,也可能碰巧有效——所以还得拿数据去查。查之前,先说三个会把结论提前决定的坑。
三、动手之前,三个坑
① 分界线画在 0 上,意味着"增仓 1 手"也算增仓
四象限用零作为增仓和减仓的分界。可持仓量每天都在动,变动 0.1% 和变动 10%,在这张表里是同一格。
我统计了样本里持仓量日变动的绝对幅度:
| 变动幅度 | 占全部交易日 |
|---|---|
| 中位数 | 2.44% |
| 小于 0.5% | 11.6% |
| 小于 1% | 22.8% |
| 小于 2% | 42.9% |
将近九分之一的交易日,被判进"增仓"或"减仓"的依据,是一个不到 0.5% 的变动。 这类日子里,持仓量基本没动,四象限却照样给出一个明确的方向结论。
做法:真要用,先设一个幅度门槛(比如 1%),门槛之下的日子直接判为"没有信息"。后面第四节我专门给这套读法留了这个优待——结果一会儿看。
② 你看的到底是哪一个持仓量
上一篇第三节把四个口径坑讲全了(单边双边、单合约与品种总量、盘中不是终值、主连有接缝),戳这里回看,这里只强调对本篇最致命的一条:
软件上那个持仓量,默认是这一份合约的,不是这个品种的。
移仓换月那几天,主力合约的持仓量在暴跌,而品种总持仓量可能几乎没动——钱只是从一份合约挪到了另一份。此时四象限会稳稳地给你一个"减仓"判断,可这个市场上根本没有人离场。
③ 最重的一条:合约有生命周期,而这张表不知道
这是跑数据时最意外的一个发现,也是本篇最想让你带走的东西。
一份期货合约不是永续的:上市、变成主力、被下一份取代、到期消失(主力是一个位置,上面的人一直在换)。所以它的持仓量天然是先升后降的形状——前期不断有人进来,后期所有人都必须走,不走的会被制度赶走(临近交割月保证金一层层加、持仓限额一档档收紧)。
我把每份合约的存续期等分成三段,数了数"减仓日"各占多少:
| 合约生命周期 | 减仓日占比 |
|---|---|
| 前 1/3 | 22.6% |
| 中 1/3 | 41.9% |
| 后 1/3 | 72.7% |
换个问法更直观——持仓量日变动的平均值,按生命周期分五段:
| 生命周期位置 | 持仓量日变动均值 |
|---|---|
| 0–20% | +2.74% |
| 20–40% | +2.07% |
| 40–60% | +0.63% |
| 60–80% | −0.08% |
| 80–100% | −5.28% |
看明白这件事的分量了吗:在一份合约的后三分之一里,你有将近四分之三的日子会被判成"减仓"。 不是因为市场在恐慌,不是因为多头认输,只是因为这份合约要到期了。
减仓最密集的地方不是恐慌,是日历。
四象限表里那两个"减仓"格子,装着大量根本不含情绪信息的日子。而你每天打开软件看到的那份主力合约,正在这条曲线上向右滑动——你越往后看,它越容易告诉你"有人在离场"。
四、实测:把它放在 7544 个交易日上查一遍
口径
- 样本:9 个品种(螺纹钢、铁矿石、沪铜、沪金、豆粕、棕榈油、白糖、甲醇、纯碱)、64 份单一合约、7544 个交易日,区间 2023-04-21 ~ 2026-05-28。公开日线数据,二手源
- 用单一合约,不用主力连续——主连的量和持仓量序列在接缝处是断的,而本篇算的就是持仓量的日变化
- 每份合约裁到流动性窗口,掐掉上市初期和临近交割的冷清段。那里几十手持仓变动就能拉出一个 ±30% 的假信号
- 前瞻收益是 t → t+1 和 t → t+5。象限由当日的价格方向和持仓量方向共同决定,而持仓量要等当日结算之后才是准数——所以能用上的最早行情就是次日的,不存在前视偏差
结果一:四格之后,价格朝上走的概率
这是本篇的核心表。数字是"次日收盘价高于今日收盘价"的比例,后面那个是一个标准误:
| 象限 | 这张表说 | 次日上涨的概率 |
|---|---|---|
| 增仓上涨 | 看涨 | 49.6% ±1.1 |
| 增仓下跌 | 看跌 | 52.4% ±1.1 |
| 减仓上涨 | 上涨无力 | 46.2% ±1.2 |
| 减仓下跌 | 跌势将尽 | 49.8% ±1.2 |
两件事:
第一,四格全在五成上下。 最高 52.4%、最低 46.2%,全挤在抛硬币附近。这张表最响亮的那个承诺——告诉你方向——没有兑现。
第二,更难堪的是:概率最高的那一格,正是它判为"看跌"的那一格。
先别急着反过来用。52.4% 离五成只有两个多标准误,五天口径上还掉回 51.1%。这不是一个可以下单的信号(第六节 ④ 说为什么)。它的价值在于说明:这张表的方向判断连符号都不一定对。
结果二:把两条腿拆开,这张表的逻辑就散了
四象限的全部逻辑,建立在一个隐含前提上:持仓量的含义会随价格方向翻转。涨的时候增仓是看涨的,跌的时候增仓是看跌的——同一个"增仓",在两格里指向相反的结论。
那就控制住价格方向,单看持仓量这条腿:
| 增仓 | 减仓 | 差值 | |
|---|---|---|---|
| 当日上涨的日子 | 49.6% | 46.2% | +3.5pp(2.1 个标准误) |
| 当日下跌的日子 | 52.4% | 49.8% | +2.7pp(1.6 个标准误) |
(表里都是"次日上涨的概率"。)
两行同号。
不管当天是涨是跌,增仓之后次日都更容易涨一点,减仓之后都更容易跌一点。持仓量这条腿的效应根本没有翻转——它压根不理会价格今天走的是哪个方向。
而四象限表的整个结构,正是建立在"它会翻转"之上。 这一条不成立,那张表就不是"不够准"的问题了,是它切分世界的方式本身就不对。
再补一刀:把周期拉到五天,"当日上涨"那一行的差值直接归零(−0.0pp)。
结果三:给它最好的条件,也没变好
第三节 ① 说过用 0 作分界太糙。所以我把门槛提到"持仓量日变动 ≥1%"再跑一遍,只留真正有幅度的增减仓,等于给这套读法开最好的条件。
四格的"次日续同向率",门槛前是 49.6 / 46.2 / 46.2 / 48.9,门槛后是 50.0 / 46.4 / 46.3 / 49.4——同一组数。
这比结果一更能说明问题:如果四象限捕捉的是真实资金动向,"持仓量猛增"的日子理应比"微增"的信号更强。它没有更强。
结果四:分品种看,离散度比均值大得多
结果二那个 +3.5pp,是九个品种揉在一起的平均。拆开看:
| 品种 | 增仓上涨 → 次日续涨 | 减仓上涨 → 次日续涨 | 差值 |
|---|---|---|---|
| 沪铜 | 47.6% | 35.2% | +12.3pp |
| 铁矿石 | 50.0% | 45.0% | +5.0pp |
| 甲醇 | 46.9% | 42.5% | +4.4pp |
| 纯碱 | 47.5% | 43.4% | +4.1pp |
| 豆粕 | 47.1% | 43.6% | +3.5pp |
| 白糖 | 50.8% | 49.7% | +1.1pp |
| 棕榈油 | 55.8% | 54.8% | +1.0pp |
| 螺纹钢 | 43.4% | 48.3% | −4.9pp |
| 沪金 | 57.9% | 67.5% | −9.6pp |
九个品种里有七个同号,看起来还行。但幅度从 +12.3pp 到 −9.6pp,离散度远远大于那个 +3.5pp 的均值。而且被打脸的两个不是冷门品种——是螺纹钢和沪金。
上一篇的教训在这里又应验了一次:一个只在总表里成立的结论,不算结论。
📌 一段本该删掉、但更该留下的记录
这一节我差点写出一个漂亮的、错的结论。
第一版脚本我用的是结算价——前面两篇实测(回撤、跳空)都用它,因为账户是按结算价盯市的,理由很充分。跑出来的四格"次日续同向率"是 57.5% / 57.0% / 55.9% / 54.8%——每一格都明显比抛硬币强。当时我已经在想标题该怎么写了。
然后我做了一次常规复核:换成收盘价再跑一遍。
| 价格口径 | 日收益一阶自相关 | 全样本次日续同向率 |
|---|---|---|
| 收盘价 | −0.050 | 47.8% |
| 结算价 | +0.215 | 56.4% |
差了八个多百分点,而这八个点一分钱都不是市场给的。
原因不复杂:结算价是全天成交量的加权均价,是一天的平均。拿一串日均价去算日收益,相邻两天的收益里含着重叠的信息,会凭空长出正的自相关。 这是时间聚合的已知产物,不是市场有记性。
用日均价算日收益,你测到的不是市场的记性,是自己求的那个平均。
我把这段留在正文里,是因为它比任何结论都值钱:那个漂亮版本的每一步都"讲得通",用的还是我自己前两篇立下的规矩。 一个口径选择,就能让一个不成立的东西看起来成立。
五、那它还剩下什么用(按价值排序)
批完了得给出路。持仓量本身极有价值,是四象限这个读法没价值。三个还站得住的用法:
5.1 用它管风险,不用它判方向
这是唯一我认为稳固的用法。
一份合约的持仓量持续萎缩,意味着愿意扛着它过夜的人在减少——成交量决定你能不能进出,持仓量决定你敢不敢过夜。这跟涨跌没关系,是你的逃生通道在变窄。
而第三节 ③ 的那条曲线正好告诉你它什么时候会发生:合约生命周期的后段,必然萎缩。 这不是预测,是日程表——所以它可靠。
5.2 只看极端值,而且只把它当成"该去查点什么"
持仓量单日变动 10% 以上,是一个值得停下来的信号。但它的正确用法不是下单,是去查:是不是移仓期、有没有交易所出了新规、这个品种是不是刚出了大消息。
它是一个"这里发生了什么"的提示,不是"该做多还是做空"的答案。
5.3 把它当成一个问句,然后去别处找答案
四象限想问的那个问题——这次价格变动,是新钱推的,还是有人在离场——本身是好问题。它错在以为自己能回答。
真要追这个问题,得去看能区分身份的数据:席位与大户持仓、基差、仓单库存。别逼一个净额回答它答不了的问题。
六、它不回答什么(请比上一节读得更用力)
① 它不回答"是谁在动"
这是全篇的根:净额抹掉了流水。上一篇说过持仓量不区分套保盘、趋势资金和散户隔夜单,它们在这个总数里长得一模一样。四象限想从这个总数里读出"是多头主动还是空头主动"——这是它做不到的那件事。
② 它不回答方向,哪怕它每一格都写着方向
四格的次日上涨概率是 49.6% / 52.4% / 46.2% / 49.8%。这张表最像"答案"的部分,恰恰是它最没有依据的部分。
③ 它在移仓期和冷清合约上会稳定地骗你
移仓那几天,单合约持仓量剧烈失真而市场没有真的离场;冷清合约上分母太小,一个大户挪个仓就能让百分比翻倍。
这两种情况的共同点是:它照样给你一个明确的结论,而且不会报错。
④ 就算某一格真有 3 个点的偏离,它也不等于能交易
这一条最容易被跳过。结果二里那个 +3.5pp,就算它是真的:
- 它是概率,不是收益。上涨的概率高 3 个点,但涨的时候涨多少、跌的时候跌多少,这里一个字都没测
- 它没扣任何成本。手续费、买卖价差、滑点,一样都没算
- 它是 2.1 个标准误,够不上稳;分品种看还有两个反号的
一个统计上的微弱偏离,和一个能赚钱的策略,中间隔着的东西比这个偏离本身大得多。
⑤ 它救不了仓位
假设你完全读对了。仓位过重的话,一夜跳空照样能把你打出局——你的判断根本没有机会被验证。
顺便:本篇这些四成六、五成二,和上一篇跑出的"跳空之后当天继续同向只有 46.9%"落在同一个区间里。这是这个号第二次在"接下来会怎么走"上跑出抛硬币。 我倾向于认为不是巧合。
七、代码
老规矩,计算逻辑写成纯函数,不绑定任何数据源。你只要有一张带 date / close / hold 三列、按时间升序的表就能用。
import numpy as np
import pandas as pd
def quadrant(df: pd.DataFrame, oi_threshold: float = 0.0) -> pd.Series:
"""把每个交易日判进四象限。
df 需含 close(收盘价)、hold(持仓量),按时间升序。
oi_threshold: 持仓量变动幅度门槛,如 0.01 表示变动不足 1% 的日子
一律判为"没有信息",而不是硬塞进某一格。
"""
ret = df["close"].pct_change()
doi = df["hold"].pct_change()
weak = doi.abs() < oi_threshold # 贴着分界线的那批天
up, inc = ret > 0, doi > 0
q = pd.Series("持平", index=df.index, dtype=object)
q[ up & inc] = "增仓上涨"
q[~up & inc] = "增仓下跌"
q[ up & ~inc] = "减仓上涨"
q[~up & ~inc] = "减仓下跌"
q[weak | ret.isna() | doi.isna() | (ret == 0) | (doi == 0)] = "持平"
return q
def forward_stats(df: pd.DataFrame, horizon: int = 1) -> pd.DataFrame:
"""每个象限之后,价格朝上走的概率与一个标准误。
⚠️ 前瞻收益从 t 日算到 t+horizon 日。象限由 t 日收盘后才能确定
(持仓量要等结算),所以最早能用上的行情就是 t+1——不要改成 t 日内。
"""
d = df.copy()
d["quad"] = quadrant(d)
d["fwd"] = d["close"].shift(-horizon) / d["close"] - 1
d = d[(d["quad"] != "持平") & d["fwd"].notna()]
g = d.groupby("quad")["fwd"].agg(
n="size", up_rate=lambda s: (s > 0).mean(), median=lambda s: s.median())
g["se"] = np.sqrt(g["up_rate"] * (1 - g["up_rate"]) / g["n"])
return g
def life_position(df: pd.DataFrame) -> pd.Series:
"""这一天处在该合约存续期的什么位置(0 = 最早,1 = 最晚)。
第三节 ③ 那张表就是按它分组算出来的。
⚠️ 只对**单一合约**有意义,主连上跑它没有意义。
"""
return pd.Series(np.linspace(0, 1, len(df)), index=df.index)
取数据(AKShare 的单合约日线,接口名与列名可能随版本变化,以官方文档为准):
import akshare as ak
def load(symbol: str) -> pd.DataFrame:
d = ak.futures_zh_daily_sina(symbol=symbol) # 返回列含 close、hold
d["date"] = pd.to_datetime(d["date"])
return d.set_index("date")[["close", "hold", "volume", "settle"]]
print(forward_stats(load("rb2605")))
⚠️ 两个必须照做的地方。
一、取的是具体合约,不是主连。 主连的持仓量序列在接缝处是断的,拿它算日变化,接缝那几天的值全是废的。
二、价格用
close,别用settle。 理由见第四节那段记录——结算价是全天均价,用它算日收益会凭空长出正自相关,把结论抬高七八个百分点。
八、三个你该自己跑一遍的实验
实验一:在你做的品种上重跑四象限
把上面的 forward_stats 在你自己做的品种上跑一遍,至少取五份历史合约。
你要看的:四格的 up_rate 是不是也都挤在 0.5 附近,以及你的品种是不是那两个反号的。我给的九个品种里就有两个是。
实验二:把持仓量画成生命周期的函数
取同一品种的连续五六份合约,各自把横轴归一化成 0 到 1(用 life_position),把持仓量画在一张图上。
你会看到:五六条线几乎重叠成同一个驼峰形状。这就是第三节 ③ 那张表的样子,而四象限对它一无所知。
这张图是本篇最值得自己做一遍的东西。 做完你很难再把"减仓"直接读成"资金在撤"。
实验三:换个口径,看结论能被推多远
把 forward_stats 里的 close 换成 settle 再跑一次,对比两组数字。
你会看到:四格的概率齐刷刷抬高好几个点。
结论:同一份数据、同一段代码,换一个看起来更"专业"的价格口径,就能让一个不成立的结论看起来成立。这个实验对你的价值,可能比本篇所有统计加起来都大。
九、三句话结论
1. 四象限在从净额里读流水。 持仓量的日变化是四股力量相抵之后的一个数,公开数据里没有拆开它的信息。这张表最像答案的地方,恰恰是它最没依据的地方。
2. 实测上它没有兑现方向。 四格的次日上涨概率全挤在五成附近,最高的那一格还正是它判为"看跌"的那一格;把两条腿拆开看,持仓量的效应根本不随价格方向翻转——而那张表的整个结构建立在它会翻转之上。
3. 持仓量该用来管风险,不是判方向。 它能可靠告诉你的是"这份合约还有多少人陪你扛着",以及"到了生命周期后段一定会萎缩"。这两件事都跟涨跌无关,也正因为跟涨跌无关,它们才靠得住。
一粒米不指望从一个总数里认出每一个人。能认出"人正在变少",已经够用了。
下一篇:回到《米粒识期》,讲交割制度——个人投资者为什么必须在最后交易日之前跑,以及不跑会发生什么。
⚠️ 风险提示 本文仅为期货知识分享与研究交流,不构成任何投资建议。文中的统计结果基于有限样本的历史数据, 历史统计不代表未来表现,文中任何一个象限、任何一个概率数字都不构成交易信号, 本文亦未对任何策略做成本与滑点假设。期货交易具有高杠杆特性,可能导致本金全部损失甚至产生 穿仓负债。文中涉及的持仓量统计口径、结算时点、交割月保证金与持仓限额等规则以各期货交易所 官方最新公告为准,数据口径以各数据源的说明为准。请通过正规期货公司开户,理性参与、独立决策、 风险自担。