給定 100 萬根 OHLC 燭台的歷史,您如何模擬偽現實的買/賣報價?
我目前正在回測和實時測試基於 RL 的系統,使用最後 100 萬條柱的收盤價作為要價和出價。雖然結果非常好,但這並不是一個非常現實的安排。
在沒有真實報價數據(只有歷史和實時 OHLCV 燭台)的情況下,我想通過基於最新的 100 萬根柱線即時生成詢價/出價報價來加強模擬。
我已經嘗試過一種設置,在該設置中,我可以窺視下一個(即目前)1m 柱,並分別使用最高價和最低價作為要價/買入價,並稍加捏造以確保它們至少相隔一個刻度。
儘管對於低流動性資產來說是合理的,但這會在快速變化的環境中造成不切實際的巨大價差。
我還嘗試通過跟踪實際高點和低點並根據直覺的算法調整其中一個或另一個來保持執行中的要價/出價,但它仍然感覺不對。
我嘗試過往前看,在中點將目前柱一分為二,然後在上半部分隨機選擇一個值作為要價,在下半部分作為出價。但這當然會導致劇烈波動的傳播,這使得訓練變得不切實際。
我讀過幾篇關於估計傳播的論文(Roll 1984、Corwin & Schultz 2011 等),但傳播只是問題/解決方案的一半。
是否有推薦的方法或算法大綱來根據最新的 OHLCV 條生成半現實報價?
有一篇關於使用交易價格估計 BA 價差的舊文獻:看看Estimation of the bid-ask spread and its components: A new approach The Review of Financial Studies, 4(4), 623-656, George , TJ, Kaul, G. 和 Nimalendran, M. (1991)。它依賴於這樣一個事實,即買賣差價為收益的自相關增加了一個數量,因此您可以嘗試反轉該關係並獲得差價的估計值。
但它絕不會是幾天內使用的“平均 BA-spread ”。
我的建議是將其用作基線,然後儘最大努力為兩個連續的 bin 設計一個啟發式:
- 如果您將前一個 bin 的收盤價與目前 bin 的開盤價進行比較,您可以猜出價差
- O、H、L 和 C 之間差值的絕對值的最小值也是點差的指示。
無論如何,這不會是魔法。在任何情況下,您想要的是一種了解模擬訂單是否會根據您的數據“將被執行”的方法。簡單的規則可以是
- 如果您專注於限價單,並以買單為例(在買入方):如果任何 OHLC 嚴格低於此限價,則生成交易。如果其中一個恰好是您的限價,您必須做出選擇。
- 如果您專注於市價單,您可以採用開盤價加上您以另一種方式估計的平均點差。
繼 lehalle 的回答之後,我最終得到了以下解決方案(以防這對任何人都有用)。
首先對於價差(以詢價比表示),我使用了Corwin & Schultz的論文,如下所示(在 php 中):
// Gamma: square of the ratio of the logs of the highest highs and lows $gamma = pow(log(max($curBar['high'], $prevBar['high']) / max($curBar['low'], $prevBar['low'])), 2); // Beta: sum of the squares of the logs of the high:low ratios $beta = pow(log($curBar['high'] / $curBar['low']), 2) + pow(log($prevBar['high'] / $prevBar['low']), 2); // Alpha: ((3-2√2) x √beta) - √(gamma ÷ (√2-1)) $alpha = 2.414213562373093 * pow($beta, 0.5); $alpha -= pow($gamma / 0.17157287525381, 0.5); // Abort negative or null spreads if ($alpha == 1 || $alpha <= 0) return false; // Calc spread $alpha = exp($alpha); $spread = 1 + 2 * ($alpha - 1) / ($alpha + 1); return $spread;
然後為了跟踪正在執行的詢價/出價報價,我匯總了以下內容(在 python 中):
# First time if ask == None: ask = high bid = low elif high != low: if high/low < spread: # The spread engulfs the bar ask = high bid = low else: # The bar engulfs the spread - spread around midpoint mid = (high+low)*0.5 half_spread = (((spread-1.0)*0.5)+1.0) ask = mid * half_spread bid = mid / half_spread else: # Flat bar (high==low) if high > ask: # The price moved up - shift the entire spread range up bid += high-ask ask = high elif low < bid: # Likewise downward ask -= bid-low bid = low else: # The price moved within the previous quote range - adjust whichever is nearest if abs(ask-high) <= abs(bid-low): ask = high else: bid = low # Quantize to price ticks and ensure non-parity ask = round(ask, precision) bid = round(bid, precision) if ask == bid: bid -= price_tick
它遠非完美,但猜測哪種方式可以根據高/低移動來微調報價,同時將範圍限制在估計的價差內,即使不准確,也可以合理地了解報價可能在哪裡。他們至少“看起來”正確地繪製了超過 100 萬張各種流動性的圖表。