📊
⚖️
📈
🔍
首頁 / 博客 / 市場微觀結構
市場微觀結構 訂單簿 流動性 核心概念

價格變化的充要條件:從訂單簿看市場微觀結構

「買的人多就漲」——這句話你聽過幾百次了,但它真的正確嗎?本文從充要條件的角度,用訂單簿剖析價格移動的底層邏輯

江景哲
2026年3月10日 · 閱讀約 18 分鐘

在量化交易中,我們天天研究「如何預測價格走向」——但很少有人停下來思考一個更根本的問題: 價格究竟在什麼條件下才會發生變化? 搞清楚這個問題,你對市場的理解會有質的飛躍。

🎯 本文目標

讀完這篇文章,你將能夠:理解「充分條件」和「必要條件」的精確含義、用訂單簿解釋價格移動的機制、辨別市場上常見的錯誤認知、將微觀結構理解應用到量化策略設計中。

第一部分:最常見的誤區

「買的人多就漲」——你確定嗎?

幾乎每一個股市入門者都聽過這句話。它聽起來很直觀:需求大於供給,價格自然上漲。

但讓我們把這個命題精確化:

常見說法(不夠精確)
買的人多 → 價格上漲

這個說法的問題在哪裡?

  • 「買的人多」是一個模糊的描述——多少算多?
  • 股票市場的每一筆成交,都同時存在一個買方和一個賣方——買的數量永遠等於賣的數量
  • 某只股票今天成交 1000 萬股,買入了 1000 萬股,賣出也是 1000 萬股

關鍵事實:市場上每一筆成交,必然有一個主動買方和一個主動或被動賣方。從成交量的角度看,「買量」恆等於「賣量」。所以用「買的人多」來解釋漲跌,在邏輯上是不完整的。

第二部分:什麼是充要條件?

邏輯回顧

在進入市場分析之前,先回顧一下邏輯學的基本概念:

概念 含義 示例
必要條件 沒有它,結果一定不發生
(但有它,結果不一定發生)
有氧氣是燃燒的必要條件
(沒氧氣必然不燃燒)
充分條件 有它,結果一定發生
(但沒有它,結果也可能發生)
下雨是地面濕的充分條件
(下雨則地面必濕)
充要條件 有它結果必發生,沒有它結果必不發生
(等價關係)
三角形三邊相等 ⟺ 正三角形

對應到價格變化:問題的精確表述

我們要找的是:價格從 P 變化到 P' ≠ P,其充要條件是什麼?

要回答這個問題,我們需要理解市場是如何撮合交易、如何形成價格的。

第三部分:訂單簿——價格形成的舞台

什麼是訂單簿(Order Book)?

訂單簿是交易所維護的一個實時報價排隊系統。它記錄了目前所有未成交的限價掛單:

  • 賣單(Ask / Offer):願意以某價格賣出的掛單,從低到高排列
  • 買單(Bid):願意以某價格買入的掛單,從高到低排列
🏪 生活類比:菜市場的喊價板

想像一個菜市場有一塊大白板。左側寫著「我願意以 10 元/斤買大白菜,要 5 斤」;右側寫著「我願意以 10.5 元/斤賣大白菜,有 8 斤」。這就是訂單簿。當有人願意以 10.5 元購買時,右側的賣單就被「吃掉」了,成交發生。

訂單簿長什麼樣?

以某只股票為例,某一時刻的訂單簿快照:

賣出價 (Ask) 掛單量(股) 累計量
102.503,20012,800
102.302,1009,600
102.104,5007,500
102.00 ← 最優賣價3,0003,000
— 買賣價差 (Spread) = 0.10 —
101.90 ← 最優買價2,5002,500
101.701,8004,300
101.505,2009,500
101.302,90012,400

在這個訂單簿中:

  • 最優賣價(Best Ask):102.00 — 你想立即買入,最少要付 102.00
  • 最優買價(Best Bid):101.90 — 你想立即賣出,最多只能收到 101.90
  • 買賣價差(Spread):0.10 = 102.00 - 101.90,這是做市商的利潤來源

兩種訂單類型

訂單類型 行為 角色 是否影響價格?
限價單(Limit Order) 掛在訂單簿等待成交 流動性提供者(Maker) 掛單本身不影響,但增加流動性
市價單(Market Order) 立即以最優價格成交 流動性消耗者(Taker) 直接吃掉掛單,是價格變化的推手

第四部分:價格變化的充要條件(核心)

必要條件:必須有成交

首先,價格變化的必要條件是:必須有新的成交發生

如果市場沒有任何成交,訂單簿上的掛單無論怎麼變動,「最新成交價」都不會改變。這一點很直觀:價格是由成交決定的,不是由掛單決定的。

注意區分:「股價」通常指「最新成交價」,不是「最優買賣報價」。當你看到股票軟件顯示的實時價格,那是上一筆成交的價格。而買一/賣一是尚未成交的報價。

充分條件:當前價位的流動性被耗盡

這才是關鍵所在。看上面的訂單簿:最優賣價是 102.00,掛了 3,000 股。

場景A:一個買家用市價單買入 1,000 股

  • 他以 102.00 成交 1,000 股
  • 102.00 的剩餘量:3,000 - 1,000 = 2,000 股
  • 最優賣價仍然是 102.00
  • 價格沒有變化

場景B:一個買家用市價單買入 3,000 股(恰好等於掛單量)

  • 他以 102.00 成交 3,000 股
  • 102.00 的掛單全部被吃光,剩餘量:0
  • 最優賣價變為下一檔:102.10
  • 賣一價上移,價格上漲

場景C:一個買家用市價單買入 5,000 股

  • 先以 102.00 吃掉 3,000 股
  • 剩餘 2,000 股繼續以 102.10 成交
  • 最終成交均價約 102.04,最後成交價 102.10
  • 價格上漲,並產生「衝擊成本」
價格上漲的充要條件
主動買入的市價單總量
≥ 當前最優賣價(Ask)的掛單總量
價格下跌的充要條件
主動賣出的市價單總量
≥ 當前最優買價(Bid)的掛單總量
💡 精確表述:價格上漲,不是因為「買的人多」,而是因為主動買入的力量足以耗盡當前賣價的所有流動性,迫使成交價移動到更高的賣盤檔位。

還原「買的人多就漲」的真實含義

現在我們可以給這句話一個更精確的詮釋:

說法 精確含義
買的人多 主動買入的市價單持續大量湧入
賣的人少 當前賣盤(Ask side)流動性薄弱,掛單量少
買單體量超過當前賣盤流動性,最優賣價被迫上移

真正導致漲價的,是「買入力量」與「賣盤流動性」的對比,而不是單純的買方人數或成交量。

第五部分:訂單流失衡(Order Flow Imbalance)

量化交易中有一個重要指標叫做訂單流失衡(OFI, Order Flow Imbalance),它正是基於上述邏輯設計的:

import pandas as pd

def calc_ofi(trades: pd.DataFrame) -> pd.Series:
    """
    計算訂單流失衡指標
    
    trades 需包含列:
        - price: 成交價格
        - volume: 成交量
        - side: 'buy'(主動買入)或 'sell'(主動賣出)
    
    OFI > 0:主動買入佔優,價格傾向上漲
    OFI < 0:主動賣出佔優,價格傾向下跌
    OFI ≈ 0:買賣均衡,價格傾向橫盤
    """
    buy_vol  = trades[trades['side'] == 'buy']['volume'].sum()
    sell_vol = trades[trades['side'] == 'sell']['volume'].sum()
    total    = buy_vol + sell_vol
    
    if total == 0:
        return 0.0
    
    # OFI 範圍 [-1, 1]
    ofi = (buy_vol - sell_vol) / total
    return ofi

# 示例
data = pd.DataFrame({
    'price':  [100.0, 100.0, 100.1, 100.1, 100.0],
    'volume': [  100,   200,   500,   300,   150],
    'side':   ['buy', 'sell', 'buy', 'buy', 'sell']
})

ofi = calc_ofi(data)
print(f"訂單流失衡 OFI = {ofi:.3f}")
# OFI = 0.400  →  主動買入佔優

OFI 與未來價格的關係

import numpy as np
import pandas as pd

def rolling_ofi_signal(df: pd.DataFrame, window: int = 60) -> pd.DataFrame:
    """
    計算滾動 OFI 信號,作為短線方向指標
    
    參數:
        df: 包含 volume 和 side 的逐筆成交數據(已按時間排序)
        window: 滾動窗口(筆數)
    """
    df = df.copy()
    df['signed_vol'] = df.apply(
        lambda r: r['volume'] if r['side'] == 'buy' else -r['volume'], axis=1
    )
    df['ofi'] = (
        df['signed_vol'].rolling(window).sum() /
        df['volume'].rolling(window).sum()
    )
    
    # 信號:OFI 超過閾值則看多/看空
    df['signal'] = 0
    df.loc[df['ofi'] >  0.3, 'signal'] = 1   # 看多
    df.loc[df['ofi'] < -0.3, 'signal'] = -1  # 看空
    
    return df[['price', 'ofi', 'signal']]

第六部分:流動性——「阻力」的大小

為什麼同樣的買入量,有時漲很多,有時幾乎不動?

答案是流動性深度(Market Depth)的差異:

市場狀態 訂單簿特徵 相同買單的影響
流動性充足 每個價位都有大量掛單 只能推動很小幅度的漲幅
流動性一般 掛單量適中 產生中等幅度的價格衝擊
流動性匱乏 掛單稀少,價格間隔大 即使小額買單也可能推動大幅漲價
🌊 生活類比:浴缸 vs 大海

你往浴缸裡扔一塊石頭,水面會明顯波動;你往大海裡扔同一塊石頭,幾乎沒有感覺。流動性就是市場的「水量」——流動性越高,同樣的訂單衝擊造成的價格波動越小。這也解釋了為什麼大盤股比小盤股難以被「操縱」。

市場衝擊成本(Price Impact)

當你的訂單足夠大,它會推動價格對你不利,這叫做市場衝擊成本。量化策略設計中必須考慮:

def estimate_price_impact(orderbook_asks: list, buy_volume: float) -> dict:
    """
    估算市價買單的衝擊成本
    
    參數:
        orderbook_asks: [(price, volume), ...] 從低到高排列的賣盤
        buy_volume: 想要買入的股數
    
    返回:
        成交均價、最後成交價、衝擊成本(bps)
    """
    remaining = buy_volume
    total_cost = 0.0
    last_price = orderbook_asks[0][0]
    
    for price, vol in orderbook_asks:
        if remaining <= 0:
            break
        fill = min(remaining, vol)
        total_cost += fill * price
        last_price = price
        remaining -= fill
    
    if remaining > 0:
        print(f"警告:訂單簿流動性不足,{remaining} 股未成交")
    
    filled = buy_volume - remaining
    avg_price = total_cost / filled if filled > 0 else 0
    best_ask  = orderbook_asks[0][0]
    impact_bps = (avg_price - best_ask) / best_ask * 10000
    
    return {
        'avg_price':   round(avg_price, 4),
        'last_price':  last_price,
        'impact_bps':  round(impact_bps, 2),   # 基點
        'filled_vol':  filled,
    }

# 示例:使用上文訂單簿
asks = [
    (102.00, 3000),
    (102.10, 4500),
    (102.30, 2100),
    (102.50, 3200),
]

result = estimate_price_impact(asks, buy_volume=8000)
print(f"成交均價:{result['avg_price']}")
print(f"衝擊成本:{result['impact_bps']} bps")
# 成交均價:102.04375
# 衝擊成本:4.28 bps

第七部分:對量化策略的啟示

啟示一:看成交量的「方向」比「大小」重要

不是「成交量大就漲」,而是「主動買入量 vs 主動賣出量的比值」決定方向。這就是為什麼量化策略更關注主動買賣比(Buy-Sell Ratio)而非單純的成交量。

啟示二:流動性薄弱時要特別謹慎

  • 波動率通常在流動性低的時段(開盤前、收盤後、節假日)急劇放大
  • 大額訂單在流動性薄弱時執行,滑點和衝擊成本會非常高
  • 策略需要根據流動性動態調整倉位大小

啟示三:掛單變化本身就是信號

機構投資者在大量買入前,往往會先在賣盤側大量撤單(降低阻力),或在買盤側增加掛單(製造支撐假象)。這就是Level 2 訂單流分析的價值所在:

def detect_liquidity_withdrawal(prev_asks: list, curr_asks: list, 
                                threshold: float = 0.3) -> bool:
    """
    檢測賣盤流動性突然撤出——可能是機構在為大額買入「清場」
    
    如果最優賣盤量在短時間內減少超過 threshold(30%),
    則觸發預警,提示可能有上漲行情
    """
    prev_top_vol = sum(v for _, v in prev_asks[:3])  # 前三檔賣盤
    curr_top_vol = sum(v for _, v in curr_asks[:3])
    
    if prev_top_vol == 0:
        return False
    
    withdrawal_ratio = (prev_top_vol - curr_top_vol) / prev_top_vol
    return withdrawal_ratio > threshold

# 示例
prev = [(102.00, 3000), (102.10, 4500), (102.30, 2100)]
curr = [(102.00,  500), (102.10, 1200), (102.30,  800)]  # 大量撤單

alert = detect_liquidity_withdrawal(prev, curr)
print("賣盤流動性異常撤出!可能有上漲行情" if alert else "流動性正常")

啟示四:「充要條件」框架幫你避開錯誤直覺

很多散戶看到新聞說「XX 公司業績大增,機構瘋狂買入」就判斷股價一定漲。但根據充要條件框架:

  • 業績大增 → 利好,引發買入意願(這只是必要條件的前置因素
  • 如果股價已提前漲到充分消化利好的位置,賣盤就會在高位大量湧現,抵消買入力量
  • 「利好出盡是利空」——說的就是這個機制

總結

本文從充要條件的視角,揭示了價格變動的底層邏輯:

條件類型 對價格上漲的含義
必要條件 必須有新的成交發生(無成交則無價格變化)
充分條件 主動買入量 ≥ 當前最優賣盤的流動性(耗盡當前價位的賣單)
充要條件 主動買入量恰好耗盡當前賣盤,且沒有更多賣單在同一價位補充
📌 一句話總結:價格的移動,本質上是訂單流量流動性壁壘的持續突破。「多空力量的對比」——正是這個比值與流動性深度的動態博弈,決定了每一個 tick 的方向。

理解了這個底層機制,你在設計量化策略時就能更精準地定義「買入信號」——不是籠統的「看多情緒」,而是具體的訂單流失衡程度、流動性深度閾值和衝擊成本估算

江景哲

Zero2Quant 創始人,專注於量化交易系統開發和教學。擁有多年金融科技和軟件工程經驗, 致力於幫助零基礎學員掌握 Python 量化交易技能。