
回測收益別被交易成本吃掉:gs-quant市場沖擊與流動性實操指南【免費下載鏈接】gs-quantPython toolkit for quantitative finance項目地址: https://gitcode.com/GitHub_Trending/gs/gs-quant如果你在 gs-quant(一套面向量化金融的 Python 工具包)上跑過回測,大概率注意到過同一個問題:回測曲線好看,策略一到實盤收益就縮水。元兇通常是被忽略的交易成本模型——當單筆訂單量達到日均成交量的百分之幾時,成交價其實已經(jīng)被推到了不利的一側(cè)。本文從 gs-quant 的回測引擎切入,講清訂單拆分、沖擊系數(shù)校準、長周期分批回測這三件事怎么做。為什么回測的成交價太好了回測默認假設(shè)你能按歷史收盤價買到任意數(shù)量,這等價于假設(shè)市場有無限流動性?,F(xiàn)實里,大單的成本大致取決于兩個變量:下單量:量越大,價格被推得越遠日均成交量:流動性越低,同樣的量需要更長時間才能完成完成時間:拖得越久,期間價格漂移的不確定性越大gs-quant 的回測入口是 Backtest 類,負責管理回測生命周期并通過get_results()拉取結(jié)果。但成本模型藏在執(zhí)行層,這才是回測結(jié)果能否復現(xiàn)實盤的關(guān)鍵。拆解執(zhí)行鏈路:訂單如何變成成交執(zhí)行邏輯在 gs_quant/backtests/execution_engine.py 的SimulatedExecutionEngine里,工作方式很簡單:submit_order把訂單放進隊列,按完成時間排序ping隨時間推進被調(diào)用,到點的訂單生成成交fill FillEvent( orderorder, filled_priceorder.execution_price(self.data_handler), filled_unitsorder.execution_quantity(), )成交價由訂單自身的execution_price決定——要建模市場沖擊,只需要換掉訂單的取價方式,引擎層不用動。gs_quant/backtests/order.py 里自帶的訂單類型:訂單類型取價邏輯適用場景OrderAtMarket指定時刻的即時市場價小單、立即成交OrderTWAP時間窗口內(nèi)價格均值大單拆分、攤薄沖擊OrderMarketOnClose指定日收盤價調(diào)倉類交易OrderCost價格為 0,直接記金額傭金、固定費用三層的調(diào)用關(guān)系: 訂單怎么拆分才能壓低沖擊OrderTWAP的默認假設(shè)是窗口內(nèi)均勻拆單、按均價成交,本質(zhì)是線性近似沖擊成本:拆得越慢,付得越少。把它和沖擊公式對照著看:成交價 ≈ 中間價 × (1 沖擊系數(shù) × 訂單量 ÷ 日均成交量)實操上常用一條規(guī)則:單次成交量不超過日均量的 5%。例如要買入 50 萬股、日均量 100 萬股,按 5% 參與率一天最多買 5 萬股,OrderTWAP的TimeWindow就要拉到至少 10 個交易日。沖擊系數(shù)怎么校準下圖是項目自帶的流動性預測思路:同一個流動性預測輸出,同時驅(qū)動市場沖擊估計、參與率約束和成交可行性判斷。校準步驟:拉出標的池近 3–6 個月的日均成交量與波動率把歷史大單按量級分桶,統(tǒng)計實際均價與理論中間價的差分桶擬合沖擊系數(shù),驗證它與參與率大致呈線性或平方根關(guān)系把擬合結(jié)果替換進訂單的execution_price,做前后對照回測回測批次設(shè)為多少合適長周期回測不能一次全跑。gs_quant/markets/portfolio_manager.py 的PortfolioManager.schedule_reports(months_per_batch6)支持把歷史區(qū)間按月切成滑動窗口分批提交,參數(shù) ≤0 會拋MqValueError。超過一年的區(qū)間建議每批 6 個月,既避免超時,也讓大單的沖擊分析更穩(wěn)定。關(guān)鍵參數(shù)推薦值:參數(shù)作用推薦值months_per_batch每批歷史回測的月數(shù)3–6 個月沖擊系數(shù)(impact_factor)每 1% 量參與的價格不利偏移幅度0.01–0.05,按資產(chǎn)分桶校準參與率上限單筆訂單量 ÷ 日均量≤5%TWAP 窗口長度訂單拆分完成的總天數(shù)由參與率反推,通常 ≥2 天如何擴展自定義成本模型線性 TWAP 不夠用時,子類化SimulatedExecutionEngine,把流動性模型注入進來:class LiquidityAwareEngine(SimulatedExecutionEngine): def __init__(self, data_handler, liquidity_model): super().__init__(data_handler) self.liquidity_model liquidity_model關(guān)鍵是保持submit_order/ping接口不變,這樣上游的 gs_quant/backtests/generic_engine.py 完全不用改,構(gòu)造時傳入新類即可。落地建議馬上可以做的兩件事:先跑成本敏感性對照:給現(xiàn)有回測分別加 10bp / 50bp 的沖擊,觀察夏普比率和收益排序變化。如果前幾名資產(chǎn)換位,說明原回測不可信。從 5% 參與率規(guī)則入手:先統(tǒng)計回測里大單超過日均量 5% 的比例,把超標的訂單換成更長窗口的OrderTWAP,這一步比完整校準沖擊模型更便宜、見效更快。延伸閱讀回測教程與示例:gs_quant/documentation/04_backtesting/官方文檔入口:docs/index.rst風險模型(配合做績效歸因):gs_quant/models/risk_model.py回測示例合集:gs_quant/content/Contents.ipynb【免費下載鏈接】gs-quantPython toolkit for quantitative finance項目地址: https://gitcode.com/GitHub_Trending/gs/gs-quant創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考