如何整理包括退市在內的歷史數據
與退市或被收購的公司合作在如何組織價格數據以進行回測方面存在一些困難。我一直在用 Yahoo! 的免費數據對一些投資算法進行回測。我沒有與退市公司合作的問題。我可以簡單地將調整後的收盤價作為權威價格。我可以使用(Python)pandas DataFrame 將這些數據保存在記憶體中。
對於退市,情況有點複雜,我想知道如何處理,以便當我開始購買沒有倖存者偏差的數據時,我可以將其整理成統一的格式,以進行客觀的回測。
最簡單的情況是公司破產了。例如,LEH (Lehman Bros.) 在某些時候剛剛變為 0。但還有其他情況:
- 收購購買公司的股份(TSLA 和 SCTY 可能會發生這種情況)。非倖存者偏向數據如何處理這種情況?如果我從 1996 年開始進行回測,並且這樣的事件發生在 2000 年,那麼 SCTY-X 的調整後收盤價是否會在買斷日期之後簡單地跟踪 TSLA-X?否則,將不得不以某種方式手動整理數據,這將是一件痛苦的事情。
- 現金收購(例如,PFZ 對 MDVN 的收購)也與在事件發生後將調整後的收盤價保持在固定價格實際上並不相同。該事件需要以某種方式進行標記,以便投資策略現在可以將現金與停滯投資區分開來。
我的問題歸結為為單個股票組織帶有 TimeSeries 索引的 DataFrame 的最佳方法,以便算法可以處理除股息和拆分之外的此類事件,“Adj Close”列會為您處理這些事件。返回的 DataFrame
pandas
作為 columns返回['Open', 'High', 'Low', 'Close', 'Volume', 'Adj Close']
。需要在這個資料結構中添加什麼來啟用包括各種已退市公司的回測?
你描述的問題不是微不足道的。主要是因為一旦你解決了所有目前已知的案例,就會有人想出一種方法來做一些不同的事情並弄亂你的系統。
以下是我看到的一些成功使用的方法。我不會聲稱他們會給你所有案例的完整報導,但他們可能會給你一些開始的想法。
第一個建議是不要使用股票程式碼作為公司的主要 ID。您希望與您打交道的每家公司都有自己的數據 ID 形式。這將與用於轉換您的 ID 和可能的符號的系統配對。該系統需要了解不同數據源使用的符號系統以及符號隨時間的變化。
這解決了股票程式碼永遠不會改變並且在數據源之間保持一致的錯誤假設。這使您可以更好地控制股票程式碼的變化、轉向粉紅色的表格和許多其他情況。如果您不單獨跟踪公司與符號,則極容易將符號更改誤認為公司被摘牌。
我的下一個建議是始終維護一組 RAW 數據以供使用。這將是當時列出的實際價格。調整後的數據集可以很好地使用,但是當您將事件預烘焙到數據中時,很容易掩蓋事件的真正含義。舉個簡單的例子,在有股息的股票上執行的交易系統可能不關心股息是交易中的一個因素,但股息事件可能會產生重大的稅收影響,具體取決於退出的時間。在預先調整的數據集中發現情況是很棘手的。
下一部分是在您的分析系統中建立一個儲存和檢索事件的系統。我的小組解決這個問題的方法是擁有一個與公司 ID 和事件日期時間相關聯的公司行為數據集。這將包括有關事件的描述性資訊,但也包括附加的操作。
這些行動是對當時股票發生情況的簡化程序描述。該操作包含程序可以用來修改目前資產的指令。這可能包括現金支付、拆分、符號更改等……每條指令都告訴程序在特定情況下要做什麼。
作為對您的退市問題的具體回答,我們將採取行動特別說明退市,並讓我們的分析系統根據該情況對交易採取行動。對於其他類似情況,例如可能會或可能不會導致退市的交易持有,這些需要分開。
系統將查詢某個日期範圍內的數據,並將其與該時間段內的操作進行比較,並根據具體需要調整所有內容。然後,這將輸出分析數據集和有關分析所需事件的任何註釋。
編輯 - 我正在提供詳細資訊以幫助解決以下問題。
這是使用的資料結構的簡化範例;
公司位於表格中,並由特定 ID 表示。每家公司都與 StockSeries 有一對多的關係(每個公司都有一個唯一的 ID)。還有一個實用程序表,可根據引用的時間點將數據源符號轉換為特定的 StockSeries。這可以雙向用於查找。
每個 StockSeries 都有一個與之鍊接的原始數據時間序列。(注意 - 我們不為此使用數據庫,但這無關緊要。)
每個公司都與一個包含關於公司事件的描述性、定性和基本事件特定定量資訊的事件表具有一對多的關係。這允許我們對事件進行分組和分類,但它並不是專門用於處理數據。
每個事件與 Actions 表具有一對多的關係。每個操作都是針對特定 StockSeries 的任何交易持有採取的特定程序化操作。
例子;操作{DateTime: XXXXX, SeriesID:12345, Action: SplitShares, Value: .5} Action {DateTime: XXXXX, SeriesID:12345, Action: DisburseCash, Value .25}
這種設置方式意味著您確實需要注意該操作適用於哪個系列,但它也允許我們從公司層面了解正在發生的事情。
老實說,這是一個巨大的過度簡化。當您建構這樣的系統時,您會發現一個接一個的案例不適合或需要一些特殊處理。
我根據數據庫結構描述了所有內容,因為您的問題似乎推斷出您的想法,但其中大部分是在沒有正式數據庫的情況下完成的。您應該找到最適合您的數據管理系統。
如果您有具體問題,我可以分享我過去所做的事情。我相信其他人也會有很好的建議。