当前位置:网站首页>【數量技術宅|金融資料系列分享】套利策略的價差序列計算,恐怕沒有你想的那麼簡單
【數量技術宅|金融資料系列分享】套利策略的價差序列計算,恐怕沒有你想的那麼簡單
2020-11-06 01:18:00 【itread01】
更多精彩內容,歡迎關注公眾號:數量技術宅。想要獲取本期分享的完整策略程式碼,請加技術宅微信:sljsz01
價差計算的“誤區”
我們在測試兩個或多個金融資產相互運算產生的策略訊號時,免不了需要涉及將不同的價格時間序列,按照時間軸進行對齊,套利策略就是其中之一。然而,大部分介紹套利策略、統計套利類的文章,對於價差序列的生成計算,處理的十分簡單,基本就是兩個時間序列相減。對於較為低頻的訊號,這樣處理問題不大,但在中高頻的訊號領域,直接相減,會存在著一定的問題。
這是因為,對於不同資產的價格序列,存在著交易所推送時間、以及到達時間的差異。即使我們回測時看到的兩個Tick的時間戳是完全相同的,在實盤伺服器接收推送行情的時候,也是按照先、後順序達到的。我們在實際交易中發現,比如上海期貨交易所某個品種的不同到期交割月的合約,交易所在切片資料的推送不是同時進行的,而是按照交割月的順序推送的,例如按照RB2010、RB2101、RB2015,類似這樣的先後順序來進行推送的,其他品種也是如此,而對於同一個500ms的切片時間內,收到RB2010、RB2101、RB2015的Tick資料的時間戳,卻是相同的。
再比如數字貨幣的跨交易所套利,兩個交易所即使在相同時間傳送的Tick資料,由於交易所伺服器物理位置不同造成的傳輸時間不同,到達我們策略訊號計算伺服器的時間大概率也會不同。
一個典型的價格到達頻率不同的例子
如果說行情資料到達時間有先後,直接相減計算價差會有一定的“滯後”或“未來函式”問題的話,價格到達頻率不同,則根本就無法直接相減計算價差了。總之,我們需要一套更貼近實際交易的價差計算方式。
我們來看一個價格到達頻率不同的例子,即兩個品種資料的推送頻率是不一樣的。如果我們需要對股指期貨、股票ETF進行期現套利策略的設計,以IC與中證500ETF的資料為例,計算期現套利的價差。
IC股指期貨的Tick資料,我們的資料來源是Wind,IC對應的中金所,它的行情推送頻率是每1秒2筆資料,Level1免費行情推送的是1檔盤口,即只有買1、賣1的資料,資料時間是股指期貨的交易時間:9:29-15:00。我們來看一下IC的Tick資料樣例。
再來看中證500ETF的資料,同樣來源於Wind,500ETF行情資料的推送頻率相比較IC要低很多,每3秒會有1筆資料,Level1免費行情有5檔的盤口,即買1到買5、賣1到賣5,資料推送時間:9:15-15:00,包含股票的集合競價時間段。我們來看一下500ETF的Tick資料樣例。
巧用Pandas的Merge函式
對於這樣推送頻率有差異、時間軸也有差異的資料,計算價差,我們就需要根據時間軸來進行合成。Python Pandas庫的Merge函式,正好符合我們所需要的功能。我們簡要介紹一下Merge函式。
pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,left_index=False, right_index=False, sort=True,suffixes=('x', 'y'), copy=True, indicator=False,validate=None)
我們在做資料合成的時候,最常用到的是前4組引數:
left: 拼接的左側DataFrame物件
right: 拼接的右側DataFrame物件
on: 要加入的列或索引級別名稱。 必須在左側和右側DataFrame物件中找到,對於金融時間序列,一般來說是時間軸
how: One of ‘left’, ‘right’, ‘outer’, ‘inner’,預設inner。inner是取交集,outer取並集。比如left:[‘A’,‘B’,‘C’];right[’'A,‘C’,‘D’];inner取交集的話,left中出現的A會和right中出現的買一個A進行匹配拼接,如果沒有是B,在right中沒有匹配到,則會丟失。'outer’取並集,出現的A會進行一一匹配,沒有同時出現的會將缺失的部分新增缺失值。
而這4組引數,對於套利價差計算的預處理,how欄位最重要。我們用實際的資料,來看不同how欄位的取值,會對最終價差的計算,帶來怎樣的影響。
首先,how = “inner”,取時間軸的交集,只有兩個表DATETIME列都有的時間,才會出現在最終的總表。我們展示計算得到的總表,並計算價差序列後繪圖。
其次,how = “outer”,取時間軸的並集,只要兩個表DATETIME列任意一表有的時間,都會出現在最終的總表,若另一個表沒有資料,則按nan值填充。
由於outer的資料處理方式,存在著大量的nana值,我們無法直接計算價差,通常的處理方式是前向填充空值資料,即將nan值用離得最近的非空值進行填充替代,再計算期現(中間價)價差,並繪圖。
再次,how = 'left',按左表時間軸合併。按左表(IC)的時間軸與右表逐一匹配,左表的時間軸全部保留,右表有該時間的,則併入總表,右表沒有該時間的,以nan代替。
同樣需要前向填充空值資料,然後才能計算期現(中間價)價差。
最後,how = 'right',按右表時間軸合併。按右表(500ETF)的時間軸與左表逐一匹配,右表的時間軸全部保留,左表有該時間的,則併入總表,左表沒有改時間的,以nan代替。
由於期貨資料頻率相比股票ETF更高,nan主要出現在股票比期貨集合競價更早的階段,這部分nan資料可酌情刪除。
我們將不同價差計算方式所繪製的圖合併到一起,可以看到,左上how="inner"的圖,點最為稀疏,因為需要同時兩個價格在該時刻都有資料,才會計算價差;而右上how="outer"的圖,價差點最為密集,只需其中一組價格變動,就會計算1次價差,而下方的兩張圖how="left"、how="right",密集程度位於兩者之間。
價差計算方式不同,帶來策略驅動方式的差異
價差不同的計算方式,表面來看是Merge函式所選擇how的引數不同,造成的價差序列計算結果不同。然而不同how引數的選擇,背後實則對應著不同的策略原理、策略邏輯。
我們無論在策略的回測中,對待行情資料,都需要採用一種“事件驅動”的方式來進行測試,這是最貼近實盤交易的回測方式。我們假設歷史資料也是像實盤那樣,每生成一個新的資料,推送給我們一次,而我們每收到一個新的資料,相當於是一個新的事件,這個事件驅動了後續的策略訊號計算,以及訊號對應的開平倉條件的判斷。
我們再回到價差不同的計算方式,其對應的,實則是策略不同的驅動方式。
how=‘outer’:對應的是期貨、股票雙路行情的併發驅動,即只要有股票、期貨任意資料的更新,我們的程式就更新價差,判斷是否觸發交易訊號,此時的訊號計算和觸發,最為頻繁。
how = 'left':對應的是期貨行情的單路驅動,即我們不管股票行情是否到達,只要期貨資料更新,股票採用最新儲存的資料合併計算價差,並判斷是否觸發交易訊號。
how = 'right':對應股票行情的單路驅動,即我們不管期貨行情達到與否,只要股票資料更新,期貨用最新儲存的資料合併計算價差,並判斷是否觸發交易訊號,left和right的觸發方式,訊號不如outer頻繁。
how=‘inner’:對應的是期貨、股票雙路行情同時驅動,我們一般在回測、實盤中均不採用這種方式,在本文第一小節,為大家介紹過,行情基本上不可能同時到達,這種驅動方式太過理想化,也會在無形中減少很多交易機會。
實盤應該選用的驅動方式
綜上,我們在回測、交易中可選的交易方式,可以分為兩大類:雙路行情的併發驅動、單路行情的驅動。那麼,這兩大類不同的驅動方式,究竟又該如何選擇?
筆者根據統計套利策略的實盤交易經驗,提出如下幾點建議:
-
計算價差的兩類資產,有明確的活躍度區分、從屬關係:例如期貨的遠近月(近月合約的交易活躍度通常大於遠月)、股票與股指期貨的期現套利(股指期貨對於股票現貨有價格發現的作用)等,此時應該以交易活躍、具有領先作用的品種,作為主驅動品種,採用單路行情的驅動。
-
計算價差的兩類資產,無明確區分、從屬關係:例如數字貨幣的跨交易所套利(OKEX、火幣交易所之間的套利,活躍程度相當,關係對等),可以採用雙路行情的併發驅動,以此來捕捉更多的交易機會。
-
一旦確定了驅動方式,在資料合併、回測、以及實盤交易系統的開發中,都需要採用同一種驅動方式,以最大程度確保回測結果與實盤交易的一致性。
如果你對本次分享的Python程式碼感興趣,歡迎新增技術宅微信:sljsz01,與我交流
往期乾貨分享推薦閱讀
【數量技術宅|量化投資策略系列分享】成熟交易者期貨持倉跟隨策略
如何獲取免費的數字貨幣歷史資料
【數量技術宅|量化投資策略系列分享】多週期共振交易策略
【數量技術宅|金融資料分析系列分享】為什麼中證500(IC)是最適合長期做多的指數
商品現貨資料不好拿?商品季節性難跟蹤?一鍵解決沒煩惱的Python爬蟲分享
【數量技術宅|金融資料分析系列分享】如何正確抄底商品期貨、大宗商品
【數量技術宅|量化投資策略系列分享】股指期貨IF分鐘波動率統計策略
【數量技術宅 | Python爬蟲系列分享】實時監控股市重大公告的Python
版权声明
本文为[itread01]所创,转载请带上原文链接,感谢
https://www.itread01.com/content/1604499006.html
边栏推荐
- 微服務 - 如何解決鏈路追蹤問題
- Query意图识别分析
- Kitty中的动态线程池支持Nacos,Apollo多配置中心了
- [performance optimization] Nani? Memory overflow again?! It's time to sum up the wave!!
- Sort the array in ascending order according to the frequency
- 快快使用ModelArts,零基础小白也能玩转AI!
- vite + ts 快速搭建 vue3 專案 以及介紹相關特性
- A debate on whether flv should support hevc
- 条码生成软件如何隐藏部分条码文字
- 【C/C++ 1】Clion配置与运行C语言
猜你喜欢
随机推荐
Jmeter——ForEach Controller&Loop Controller
網路程式設計NIO:BIO和NIO
7.3.2 File Download & big file download
如何使用ES6中的参数
十二因子原则和云原生微服务 - DZone
PLC模拟量输入和数字量输入是什么
Python自动化测试学习哪些知识?
读取、创建和运行多个文件的3个Python技巧
DeepWalk模型的简介与优缺点
5.5 ControllerAdvice注解 -《SSM深入解析与项目实战》
Top 10 best big data analysis tools in 2020
03_ Detailed explanation and test of installation and configuration of Ubuntu Samba
給萌新HTML5 入門指南(二)
(1) ASP.NET Introduction to core3.1 Ocelot
快快使用ModelArts,零基础小白也能玩转AI!
如何在Windows Server 2012及更高版本中將域控制器降級
python 保存list数据
Why do private enterprises do party building? ——Special subject study of geek state holding Party branch
hadoop 命令总结
Introduction to Google software testing