← 返回文章列表
July 16, 2026
5 分鐘閱讀

成交模擬:從收盤價幻想到佇列感知現實的階梯

成交模擬:從收盤價幻想到佇列感知現實的階梯
#成交模擬
#回測
#限價單
#佇列位置
#部分成交
#做市
#執行
#市場微觀結構

你的回測裡包含兩個模型:一個是關於 alpha 的模型,另一個是關於成交的模型。大多數人把 95% 的精力放在前者上,而後者則直接繼承自他們碰巧用的那個框架。這本末倒置了。一個平庸的訊號配上一個誠實的成交模型,會得到一個平庸但真實的 PnL 估計;一個出色的訊號配上 fill_price = candle.close,得到的數字則什麼都估計不了——它只是你從未審視過的某個假設的輸出。

對於流動性充裕品種上的吃單(taker)策略,成交模型只是一個修正項。而對於任何涉及掛單的場景——做市、被動入場、post-only 返傭收割——成交模型就是策略本身。你是否成交、何時成交、成交多少,以及在隨後價格如何變動的條件下成交,決定的不只是 PnL 的大小,而是它的正負號。

回測與實盤一致性一文中,我們繪製了回測與實盤偏差的完整分類圖譜,並將執行偏差評為 5/5 的嚴重程度——最糟糕的一類。那篇文章只給了成交模擬三個粗略的精度等級便一帶而過。本文則是它的深度姊妹篇:完整的階梯,逐級拆解,把訂單生命週期建模為狀態機,給出你真正能計算的成交機率上下界,並用一個實測實驗精確地展示,一個"盈利"的做市策略究竟死在階梯的哪一級。

階梯

成交模擬保真度五級階梯

每上升一級,都需要更多的資料和更多的程式碼,而每一級都消除了一個特定的系統性偏差。這些級別的排序依據是它們各自出的錯,而不僅僅是成本。

第 0 級:收盤價成交

fill_price = bar.close

訂單在生成訊號的那根 K 線的收盤價上瞬間、全額成交。而訊號本身就是用同一個收盤價算出來的,所以你是在用價格列印出來時還不存在的資料交易:披著執行外衣的未來函數(look-ahead bias)。任何有換手率的策略在這裡看起來都很美。

第 1 級:下一根 K 線開盤價

fill_price = next_bar.open

這是 K 線級別吃單邏輯的最低誠實模型。訊號在第 tt 根 K 線上計算,成交發生在第 t+1t+1 根 K 線的第一個可觀測價格上。這消除了未來函數,但仍然假設零點差、零衝擊、開盤列印處無限流動性,以及 100% 成交確定性。對於限價單,它退化成觸碰即成交(touch-fill)邏輯(至於為什麼這是毒藥,詳見下文)。

第 2 級:點差 + 固定滑點

half_spread = mid * spread_bps / 2e4
slip        = mid * slippage_bps / 1e4
fill_price  = mid + side * (half_spread + slip)   # side: +1 buy, -1 sell

現在每一筆吃單交易都要支付半個點差外加一個校準過的常數。這是第一個高換手率策略可能在回測裡死掉的級別——而這正是重點所在。殘餘誤差在於:滑點不是常數。它隨訂單規模相對於顯示深度而縮放,並且恰恰在你的策略最想交易的時候爆炸式增大。固定的 5 bps 是跨市場狀態(regime)的平均值;而你的策略並不在平均狀態下交易。

第 3 級:市價單的 L2 深度穿行

有了訂單簿快照,你就不再猜測滑點,而是直接計算它。規模為 QQ 的市價買單會逐檔穿行賣方;成交價是被吃掉的各檔位上的成交量加權平均:

Pfill(Q)=1Qipimin ⁣(qi,  Qj<iqj)P_{\text{fill}}(Q) = \frac{1}{Q}\sum_{i} p_i \cdot \min\!\left(q_i,\; Q - \textstyle\sum_{j<i} q_j\right)

def depth_walk(levels: list[tuple[float, float]], qty: float) -> tuple[float, float]:
    """levels: [(price, size), ...] sorted best-first. Returns (vwap, filled_qty)."""
    remaining, cost = qty, 0.0
    for price, size in levels:
        take = min(size, remaining)
        cost += take * price
        remaining -= take
        if remaining <= 0:
            break
    filled = qty - remaining
    return (cost / filled if filled > 0 else float("nan"), filled)

有兩個修正能讓這一切在實質上更誠實。第一,延遲:要穿行的是你決策時間戳之後 Δt\Delta t 時刻的訂單簿狀態,其中 Δt\Delta t 是你實測的訊號到交易所延遲——你看到的簿並不是你打進去的簿。第二,可成交部分的部分成交:如果在你的限價穿透價內的顯示深度小於 QQ,模型必須返回一個部分成交,並留下一個掛單餘量,這就把問題交給了下文的狀態機。

第 3 級的殘餘誤差在於衝擊與補單:你把訂單簿當成一個靜態物件來消耗,但真實的簿會部分補充(而真實的對手方會做出反應)。對於低於簿口深度百分之幾的掛單規模,這個誤差很小;對於更大的掛單,你需要在其上疊加一個衝擊模型(Almgren-Chriss 2001)。

第 4 級:限價單的機率化佇列位置成交

第 0 到 3 級回答的是"我的主動訂單以什麼價格成交"。第 4 級回答的是更難的問題:我的被動訂單到底成不成交——而它是唯一能給做市策略定價的級別。掛在價格 pp 上的限價單,只有當 pp 處的累計成交量超過排在它前面的佇列量時才會成交。這就要求你追蹤自己在一個無法直接觀測的 FIFO 佇列中的位置。

佇列位置估計機制——初始位置、成交與撤單時的更新規則、用於分配未觀測撤單的 f(x)f(x) 機率族——是我們在牆內的佇列一文中構建的原語。這裡我不再重新推導;模擬器直接消費它。第 4 級新增的,是在這個估計之上的成交判定規則,詳見下文的成交機率一節。

這一級為何重要,文獻裡有量化的答案:Moallemi 與 Yuan(2016)的《A Model for Queue Position Valuation in a Limit Order Book》表明,對於大跳動點(large-tick)品種,隊首位置相對於隊尾位置的經濟價值,與半個點差相當——與整個做市策略的理論優勢處於同一數量級。一個忽略佇列位置的成交模型,並不是把做市商的 PnL 估錯了;它估計的是另一個策略的 PnL。

確實還存在一個第 5 級——完整的基於智慧體的模擬,其中市場會對你的訂單做出反應(佇列反應式模型,如 Huang、Lehalle 與 Rosenbaum 2015 意義上的;多智慧體框架如 ABIDES,Byrd 等 2020)。歷史回放,即便是佇列感知的,也假設你的訂單不會改變其他所有人的行為。這個假設在散戶規模下沒問題,但當你的報價成為該檔位中可見的一部分時,就越來越不成立了。第 5 級不在本文範圍內;但要知道,階梯並未止步於第 4 級。

把部分成交建模為狀態機

第 0 到 2 級可以假裝訂單就是一次函式呼叫:提交、拿到價格、結束。從第 3 級往上,訂單就是一個帶有生命週期的過程,模擬器必須把它建模成一個狀態機,否則它就會在最要緊的那些情形上悄無聲息地處理錯誤。

帶佇列位置標註的訂單生命週期狀態機

enum OrderState {
    PendingNew,                                  // sent, not yet acked (latency window)
    Resting     { remaining: f64, q_ahead: f64 }, // in book, queue position estimated
    PartialFill { remaining: f64, q_ahead: f64 }, // some qty done, rest still queued
    PendingAmend,                                 // amend in flight
    PendingCancel,                                // cancel in flight
    Filled,
    Canceled    { filled_qty: f64 },              // may be partially filled at cancel time
    Rejected,
}

這些狀態轉移承載著經濟含義:

  • PendingNewResting:訂單排到的是回執(ack)時刻已存在的一切之,而不是決策時刻。你的佇列位置是用 t+Δtackt + \Delta t_{\text{ack}} 時刻的檔位成交量來播種的。在決策時刻播種的模擬器會系統性地高估佇列優先順序——高估的量恰好就是在你的延遲視窗內到達的成交量,而在爆發行情中這就是大部分成交量。
  • RestingPartialFill:當你所在檔位的一筆成交大於你前面的佇列時,你會被部分成交。剩餘部分保持它(此時已排到隊首)的位置。部分成交不是噪聲——它是資訊:1.0 裡被成交了 0.3、然後眼看價格彈開,這是和全額成交截然不同的 PnL 事件,而做市商的庫存過程正是由這些碎片拼出來的。
  • RestingPendingAmendResting:這是個陷阱。在幾乎所有加密交易場所,改單(amend)都是撤單/重掛——幣安的 cancelReplace 對於避免重複執行是原子的,但會返回一個排到隊尾的新訂單 ID。即便是有原生 modify 語義的場所(CME Globex),也只在數量減少時保留時間優先順序;改價或數量增加都會喪失它。所以在模擬器裡:任何改價操作都會把 q_ahead 重置為當前檔位的全部成交量。一個每 500ms 就重新盯盤(re-peg)的報價引擎並不是在"維持報價"——它是在永無止境地從隊尾重新入場,其真實的成交畫像幾乎是純粹的逆向選擇。結合 Moallemi-Yuan 的結論:重新報價是有價格的,而這個價格就是你的佇列位置。
  • PendingCancelPartialFillCanceled:撤單也有延遲。在你決定撤掉報價、到撤單指令抵達撮合引擎之間的這個視窗裡,你仍然可能成交——而這些成交是你能收到的最糟糕的成交,因為你之所以要撤報價,正是因為市場即將碾過你。一個沒有撤單延遲的模擬器,會恰好把你歷史中毒性最強的那些成交刪掉。

狀態機也是讓模擬器的賬目誠實的東西:手續費按每一次成交事件計提,庫存按每一次成交事件更新,而在各狀態中停留時長的統計(訂單在成交前掛多久 vs. 在被撤前掛多久)則可以直接與實盤日誌做比較——而這正是文末校準閉環所依賴的原料。

限價單成交機率:三個模型和一個區間

給定一個掛在價格 pp 上的訂單(比方說一個買單),模擬器什麼時候判定它成交?有三條判定規則,誠實程度遞增:

**1. 觸碰即成交(naive)。**只要價格觸碰到你的檔位就成交:lowtp\text{low}_t \le p。這是一條首次穿越時間(first-passage-time)規則,而它的失敗在四分之一個世紀前就被實測過了:Lo、MacKinlay 與 Zhang(2002)的《Econometric Models of Limit-Order Executions》(Journal of Financial Economics 65),用真實的限價單資料擬合生存模型,得出的結論是,由首次穿越時間構造出的假想成交"是真實限價單成交非常糟糕的替代品"。失敗的機理是結構性的:當價格觸碰到你的檔位又彈開時,這次觸碰消耗的是佇列的前端——那些比你更早報價的交易者。觸碰即成交把他們的成交判給了你。更糟的是,它判給你的恰恰是好的成交(觸碰即彈開是做市商的盈利情形),而你真實的成交集合卻偏向觸碰即穿透——那些被逆向選擇的成交。

**2. 穿透即成交(保守下界)。**只有當價格嚴格穿透你的檔位才成交:lowt<pϵ\text{low}_t < p - \epsilon,或者在逐筆(tick)資料上,pp 處的累計成交量超過整個檔位。如果價格穿透了,pp 處的整個佇列都被消耗了,所以不管你排在什麼位置都成交了。這條規則絕不會判給你一筆本來拿不到的成交。它的偏差恰好是觸碰即成交的映象:它會拒絕你每一筆"佇列耗盡到你的位置但未完全穿透"的成交,而它確實判給你的那些成交,又不成比例地偏向穿透(被逆向選擇)的那種。穿透即成交下的做市回測是一次壓力測試,而不是一個估計。

**3. 佇列耗盡估計。**從成交流(trade tape)追蹤你所在價格處的累計成交量 MtM_t,並從 L2 增量推斷出撤單量 CtC_t。你的估計佇列前量為:

Q^ahead(t)=max ⁣(Q0MtϕCt,  0)\hat{Q}_{\text{ahead}}(t) = \max\!\Big(Q_0 - M_t - \phi \cdot C_t,\; 0\Big)

其中 Q0Q_0 是(回執時刻)下單時的檔位成交量,ϕ[0,1]\phi \in [0,1] 是假設來自你前方的撤單佔比——這個旋鈕的原理化形式(f(x)f(x) 族)是在佇列位置一文中推導的。當 Q^ahead=0\hat{Q}_{\text{ahead}} = 0 時開始成交;你的成交數量是超出它的那部分成交量,這自然而然地就給出了部分成交:

filled(t)=min ⁣(S,  max(MtQ0+ϕCt,0))\text{filled}(t) = \min\!\Big(S,\; \max(M_t - Q_0 + \phi\, C_t,\, 0)\Big)

ϕ=1\phi = 1(所有撤單都在你前方)給出這個模型的樂觀邊界;ϕ=0\phi = 0 給出悲觀邊界。當你只有稀疏的 L2 快照、且檔位上沒有成交流時——這在 100ms 節流的加密資料來源中很常見——你可以退而求其次,用一個基於模型的先驗:Cont、Stoikov 與 Talreja(2010)的《A Stochastic Model for Order Book Dynamics》(Operations Research 58),把每一個價格檔位建模為一個生滅佇列(birth-death queue),並透過拉普拉斯變換計算,在給定當前佇列規模的條件下,一個買單在中間價移動之前成交的機率。這是一個解析式的成交機率神諭(oracle):相對於成交流回放是粗糙的,但遠好於觸碰即成交,而且便宜到足以在一個高頻回測迴圈內部求值。

區間紀律

這三條規則不是相互競爭的——它們構成一個排序:

fillstrade-through    fillsqueue    fillstouch\text{fills}_{\text{trade-through}} \;\subseteq\; \text{fills}_{\text{queue}} \;\subseteq\; \text{fills}_{\text{touch}}

這誘匯出一個 PnL 區間。每一次做市回測都跑三遍,並報告這個區間:

PnLtrade-through    PnLlivePnLtouch\text{PnL}_{\text{trade-through}} \;\le\; \text{PnL}_{\text{live}} \lesssim \text{PnL}_{\text{touch}}

(上界這個不等式是近似的——觸碰即成交不只是會拔高策略,還會把策略的排名弄錯,因為它把反事實的好成交塞給了你)。由此得出的決策規則是:**一個做市策略只有在能挺過區間的保守邊緣、且區間窄到讓點估計有意義時,才是可部署的。**一個顯示 +9k(觸碰)/9k(觸碰)/ -3k(穿透)的策略,區間寬達 12k;你除了知道"模擬器的假設壓過了你的alpha"之外一無所知。而一個顯示+12k;你除了知道"模擬器的假設壓過了你的 alpha"之外一無所知。而一個顯示 +2.1k / +$0.4k 的策略,才是在告訴你一些真實的東西。

實驗:讓一個做市策略沿階梯逐級下探

做市策略 PnL 沿成交模型階梯逐級崩塌

取一個刻意設計得平平無奇的做市商——在最優買/賣價上對稱報價、固定 0.05 BTC 的掛單、庫存上限 ±0.5 BTC 且觸及上限時用吃單拉平。用一個月的 BTCUSDT 永續資料:低階用 1m K 線,高階用 100ms L2 增量外加成交流;maker 手續費 1.0 bps,taker 4.0 bps。每一級都用同一套訊號程式碼(共享核心,所以唯一的變數就是成交模型)。下面的數字是我們一次有代表性的執行結果——你的量級會因交易場所、月份和規模而異;但形態不會變:

級別 成交模型 報價成交率 成交筆數 當月 PnL 結論
0 close-fill 98% 41,200 +$14,800 幻想
1 next-bar-open / 1m K 線上觸碰即成交 89% 37,400 +$9,600 帶延遲的幻想
2 觸碰即成交 + 吃單拉平的點差與固定滑點 89% 37,400 +$7,100 成本建模了,成交仍屬虛構
3 + 吃單拉平的 L2 深度穿行 89% 37,400 +$6,400 出場誠實了,入場仍屬虛構
4a 穿透即成交(保守) 21% 8,900 -$3,900 壓力下界
4b 佇列耗盡,ϕ\phi 已校準 37% 15,600 -$700 最佳估計
4c 佇列耗盡,ϕ=1\phi = 1(樂觀) 44% 18,700 +$1,900 上邊緣
實盤影子執行,同一月份 35% 14,100 -$1,150 現實

從上往下讀這張表,看這個策略在哪裡死掉。它不是死在第 2 級——手續費和滑點砍掉了 26%,策略看起來仍然穩健盈利。它死在第 3 級和第 4 級之間,而它死的原因是任何成本模型都無法捕捉的:成交篩選(fill selection)。觸碰即成交判給了 37,400 筆成交,其中大多數是觸碰即彈開——純粹的點差捕獲。佇列感知模型刪掉了其中 58% 的成交,而它刪掉的那些成交不成比例地正是盈利的那些:當檔位被輕輕觸碰時,排在一個重新報價、帶散戶延遲的做市商前面的佇列會把一切都吸收掉。挺進第 4 級的那些成交,偏向於清掃檔位的掃單(sweep)——那些價格已經在穿過你的成交。成交率下降到 1/2.4;PnL 翻了符號。這種不對稱——丟掉好的成交、留下壞的——就是被機械地顯式化了的逆向選擇,而它在第 4 級以下的每一級都是不可見的。

還要注意這個區間起了什麼作用:[-3,900,+3,900, +1,900] 跨越了零點,校準後的估計在 -700,實盤在700,實盤在 -1,150。模擬器並沒有把實盤 PnL 精確到美元——但它算對了符號量級,以及誤差在 2 個百分點以內的成交率。這正是成交模型的用處。第 1 級的回測在一個整月毛優勢僅幾千美元的策略上,把實盤 PnL 算錯了 $10,750:成交模型的誤差大約是 alpha 的 3 倍。由此得出本文的論點:你的成交模型是一個比你的 alpha 更大的假設。

對低階有一個提醒:如果你不得不用 K 線資料(第 0 到 2 級),至少要用自適應下鑽來解決 K 線內的歧義——在止損(SL)、止盈(TP)或報價檔位落在 K 線區間內的地方,從 1m 下鑽到 1s/100ms/逐筆。下鑽能修正排序誤差(哪個檔位先被觸及),但無法修正佇列誤差;它是本文在資料解析度上的姊妹篇,而不是第 4 級的替代品。

校準閉環:對照實盤成交收斂

一個第 4 級的模擬器有自由引數——ϕ\phi、延遲 Δt\Delta t、撤單延遲、檔位補單假設。不加校準的話,它只是一個形狀不同的猜測。把它變成一臺儀器的閉環如下:

**1. 實盤記錄一切。**每一個訂單事件都帶上交易所時間戳:提交、回執、每一筆部分成交、改單回執、撤單回執。外加提交時刻的 L2 狀態。這就是回測與實盤一致性一文為其 DivergenceMonitor 所要求的那套記錄紀律——成交模型的校準是那個監視器最深的一層。

**2. 把同樣的訂單在模擬器裡回放。**把錄下來的市場資料和錄下來的訂單指令(而不是成交結果)喂進模擬器。現在你就有了成對的結果:對每一個實盤訂單,都有一個模擬命運。

**3. 分桶比較分佈,而不是均值。**單一的全域性成交率匹配可以掩蓋相互抵消的誤差(在平靜狀態下過於樂觀、在爆發行情下過於悲觀——淨出來一個"校準好了")。按驅動因素分桶:

import numpy as np
from scipy.stats import ks_2samp

def calibration_report(pairs, bucket_key):
    """pairs: [{'bucket':…, 'live_filled':bool, 'sim_filled':bool,
                'live_ttf':float|None, 'sim_ttf':float|None}, …]"""
    out = {}
    for b in sorted({p['bucket'] for p in pairs}):
        grp = [p for p in pairs if p['bucket'] == b]
        live_fr = np.mean([p['live_filled'] for p in grp])
        sim_fr  = np.mean([p['sim_filled']  for p in grp])
        live_ttf = [p['live_ttf'] for p in grp if p['live_ttf'] is not None]
        sim_ttf  = [p['sim_ttf']  for p in grp if p['sim_ttf']  is not None]
        ks = ks_2samp(live_ttf, sim_ttf) if len(live_ttf) > 20 and len(sim_ttf) > 20 else None
        out[b] = {
            'n': len(grp),
            'fill_rate_live': live_fr,
            'fill_rate_sim':  sim_fr,
            'fill_rate_gap':  sim_fr - live_fr,      # signed: + means sim optimistic
            'ttf_ks_pvalue':  ks.pvalue if ks else None,
        }
    return out

每個桶兩個統計量:帶符號的成交率差(模擬器減實盤),以及在已成交訂單上對成交時間(time-to-fill)分佈做的 KS 檢驗。成交時間的比較是最鋒利的那個——一個模擬器可以匹配成交,卻在系統性錯誤的時刻成交,這會汙染下游所有的庫存和逆向選擇統計。這恰恰是 Lo-MacKinlay-Zhang 生存分析視角的教益:執行是一個事件發生時間(time-to-event)問題,所以要以此來驗證它。

**4. 按可辨識性順序擬合旋鈕。**延遲優先(直接從回執時間戳測量——不是擬合的)。然後透過在各佇列深度桶上最小化成交率差來擬合 ϕ\phi。接著檢查波動率狀態桶:一個集中在爆發行情桶裡、持續存在的樂觀差,通常意味著你的模擬器對撤單延遲的毒性成交或檔位補單建模不足,而不是 ϕ\phi 的問題。

**5. 重跑區間。**校準之後,佇列耗盡估計應當落在區間內、靠近實盤,而且——真正的驗收測試——在模擬器下各策略變體的排名,應當與它們在影子模式下的排名一致。然後凍結引數,並按計劃定期重新校準;成交動態會隨交易場所的手續費檔位、跳動點變化和 HFT 群體而漂移,一個在三月校準的 ϕ\phi 到了七月就只是個假設了。

我們執行中的收斂預期:一個未校準的第 4 級模擬器通常落在實盤成交率的 ±10-15 個百分點內;經過一輪校準後,±3-5 個百分點,且成交時間的 KS 檢驗 p 值不再一律拒絕。用歷史回放你做不到比這更好——殘差就是市場對你的反應,那是第 5 級的問題。

要點回顧

  1. **說出你的級別。**每一次回測都坐落在這個階梯上,不管是你選的級別還是你的框架替你選的。如果你說不出自己成交模型的級別及其已知偏差,你的 PnL 數字就帶著你沒看見的誤差棒。
  2. **吃單可以止步於第 3 級。**深度穿行加上實測延遲,能在散戶規模下誠實地為主動執行定價。把省下來的精力花在資料質量上。
  3. **做市從第 4 級起步。**在它之下,限價單成交邏輯不是"近似"——它篩選出的是一個反事實的成交集合,帶著相反的逆向選擇偏斜。做市策略的觸碰即成交回測,是最可靠的"一上生產就死"策略生成器。
  4. **建模生命週期,而不是成交。**部分成交、改單重置佇列、撤單延遲——毒性成交就住在狀態機裡,而毒性成交正是做市 PnL 去送死的地方。
  5. **報告區間。**保守和樂觀的上下界只多花兩次回測執行,卻把"我的回測說 +7k"變成了"現實在[7k"變成了"現實在 [-3.9k, +$1.9k] 之間的某處"——這是一個不同、也更好的決策。
  6. **分桶對照實盤成交做校準。**一個只在總量層面驗證過的成交模型,是一個帶著隱藏的相互抵消誤差的成交模型。分桶的成交率差加上成交時間 KS 檢驗,每季度重新校準。

階梯的各級不是學院派的分級——每一級都是你的回測停止對你說的一個特定謊言。一直往上爬,直到這些謊言比你的優勢更小。

有用的連結

  1. Moallemi, C., Yuan, K. — A Model for Queue Position Valuation in a Limit Order Book (2016)
  2. Cont, R., Stoikov, S., Talreja, R. — A Stochastic Model for Order Book Dynamics, Operations Research 58(3), 549-563 (2010)
  3. Lo, A., MacKinlay, C., Zhang, J. — Econometric Models of Limit-Order Executions, Journal of Financial Economics 65(1), 31-71 (2002)
  4. Huang, W., Lehalle, C.-A., Rosenbaum, M. — Simulating and Analyzing Order Book Data: The Queue-Reactive Model, JASA 110(509), 107-122 (2015)
  5. Almgren, R., Chriss, N. — Optimal Execution of Portfolio Transactions (2001)
  6. Byrd, D., Hybinette, M., Balch, T. — ABIDES: Towards High-Fidelity Multi-Agent Market Simulation (2020)
  7. Binance API — Cancel-Replace order semantics
  8. CME Globex — Order modification and time priority rules

Citation

@article{soloviov2026fillsimulation,
  author = {Soloviov, Eugen},
  title = {Fill simulation: the ladder from close-price fantasy to queue-aware reality},
  year = {2026},
  url = {https://marketmaker.cc/blog/fill-simulation-partial-fills-backtest},
  description = {Five rungs of fill simulation fidelity — from close-price fills to probabilistic queue-position models. Partial fills as a state machine, limit-fill probability bounds as a PnL bracket, and a calibration loop against live fills.}
}
免責宣告:本文提供的資訊僅用於教育和參考目的,不構成財務、投資或交易建議。加密貨幣交易涉及重大損失風險。

Authors

Eugen Soloviov
Eugen Soloviov

Trading-systems engineer

Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.

Newsletter

緊跟市場步伐

訂閱我們的時事通訊,獲取獨家 AI 交易見解、市場分析和平台更新。

我們尊重您的隱私。您可以隨時退訂。