2018年6月3日 星期日

AxisTradeCult 開發日誌 (4) - 預測大漲大跌訊號(暴死)

目前在研究怎麼用Machine Learning來做輔助交易, 第一個想到的輔助功能就是希望有個功能是能找出個股將會大跌的訊號, 會想做這個主要是因為股市大漲or大跌通常都是消息面的因素(財報出來, 公司接到大單,  公司作假帳等等), 雖然這種事情除了靠內線以外沒有其他方法,  可是通常來說新聞報出來已經是第三手情報了, 內線的第一第二手情報雖然拿不到, 但或許可以從價量訊息看出些大戶烙跑的端倪之類的, 基於以上理由覺得可以先試看看, 看價量資料跟個股大漲大跌是否有些許關聯性。


首先先定義問題, 我想找出股市大跌的訊息, 所以我定義了兩個參數pred_days以及change_rate, 假設pred_days = 3 以及 change_rate = 5%, 這代表如果未來三天的收盤價皆小於今天收盤價的5%, 那就是有大跌訊號(True), 反之就是盤整or上漲(False)。 會有pred_days這個參數的原因是因為我把那種只有一天大跌隔天又漲回來的訊息視為雜訊(基金的交易策略故障or交易員手殘等等烏龍原因), 如果大跌後持續3天沒有漲回來, 那就代表這個訊息是真實的。

定義好問題再來是準備features, 我目前手邊有的資料特徵如下:
[Adj Open, Adj High, Adj Low, Adj Close, Volume]
OHLC使用的是調整後的價格, 調整價格是考慮除權息, 股票分割, 增減資等情況後用現在價格往回推的實際價格, 使用調整價格可以避免訓練好的Model or 策略因為上述情況導致誤判。

除了上述的基本特徵, 另外也加上了目前手邊計算好的技術指標:
[MA, BollingerBands, KDJ]
使用的window size都預設為5。

由於股價走勢通常是有趨勢性的, 就跟各個技術指標都有使用剛剛提到的window size來做slide window計算一樣, 我這邊是很單純先把所有資料的前X天當作Neighbor特徵, 直接複製當成新的Meta Feature。
[Open_N1, High_N1, Low_N1, Close_N1, Volume_N1, MA_N1...KDJ_N5]
預設鄰居特徵大小 = 5, 最後總計有11*(1+5) = 66 個資料特徵。

雖然各個技術指標本身就有鄰居的概念了, 要做技術指標的Neighbor特徵還不如多換幾個window當成新特徵會更好也說不定, 不過這邊就未來在試吧。

都定義好之後就來準備資料吧, 我選擇的個股為DIS(迪士尼),  資料範圍為2000-1-3~2018-6-01。類別標籤為未來三天的股價跌幅跟今天比是否皆超過5%(簡單來說就是大跌5%後未來三天都沒有漲回來), 來看看得到的資料:
DataSize: 4623, PostitiveSize: 24

...........傻住了, 沒想到18年來符合這個訊號的只有24天, imbalance的比例為24:4599 = 1:191
這麼不平衡的資料訓練出來的模型不用看一定都只會預測False阿阿阿...。

先不管資料不平衡的問題, 再來是決定要怎麼驗證訓練出來的Model好壞, 一般會使用CV驗證, 可是股價資料像技術分析等都是用到過去N天的資料算出來的衍生特徵, 如果直接打散作為training testing並不合理, 也有點像是作弊了, 也會有像是用未來的資料去預測過去這種奇怪事, 所以這邊切割資料的方式如下:
1. 依時間軸切割成3份資料: D1: 2000~2006. D2: 2006~2012, D3: 2012~2018。
2. 使用D1訓練並用D2資料驗證, 在使用D2訓練並用D3資料驗證。

雖然這樣會有1/3的資料沒辦法做驗證, 不過這也沒辦法, 總之先來跑幾個分類器, 看看結果:


恩....爛透了, 除了決策樹比亂猜好一點點(或是根本沒有), 除了NaiveBayes的演算法以外其他全部都猜同一邊, 完全沒有參考價值...。

再來試著把Training data用OverSampling的方式看看能不能讓分類器多嘗試預測大跌(當然Testing Data還是原始資料), 看看結果:


雖然各個分類器比較願意預測大跌, 但是都猜錯也沒意義阿(遠望&Smile...),  神奇的是只有決策樹反過來更往False預測了, 這是為什麼阿囧?

或許連續三天都要確定大跌後沒有漲回來這個條件太嚴苛了, 把pred_days改為1(代表只預測明天是否大跌), 來看看結果:


可以看見雖然這樣大跌訊號變為18年來有47個, 但連決策樹都跟著超爛了, 這代表只用價量資料預測明天是漲是跌這件事本身就是沒有用, 或是其實根本就是不管怎樣都是在亂猜, 價量資料來預測大漲大跌訊號根本是作夢XD

轉換下思維, 可以預測大跌也代表換個方式也可以預測大漲, 修改一下方法改成未來三天的股價漲幅跟今天比是否皆超過5%來試試:


可以看到PostitiveSize比大跌多增加了個10個, 這代表這18年來大漲的訊號是比較多的, 不過結果當然甚至更爛, 根本都預測不出來。

這樣的實驗做下來, 感覺只用價量資料搭配ML去預測大跌or大漲訊號基本上是沒有用的? 還不如用技術分析直接寫個rule base的策略還要來得有用?

當然啦, 這樣下結論感覺還太早了, 雖然目前做下來只看得到黑暗囧, 不過其實很多問題可以檢討, 要下結論感覺還太早了, 目前我想到的還有下面幾個問題:

1. Data這麼imbalance, 正樣本數又這麼得少, 這樣訓練出來的model其實沒有用也很正常, 我在想是不是不應該這麼單純的把所有資料拿來訓練&測試模型, 應該用其他方式, 例如:
  • 是否應該人工萃取正樣本附近的資料以及隨機取樣一部分的負樣本數訓練各個Model, 考慮Data不imbalance的情況的效能, 或許反覆測試的結果不會像上面那樣這麼差。
2. 目前的特徵資料太少, 可以多實作幾個技術指標加入新特徵, 或許結果會好一些也說不定。

3. 預測大漲or大跌訊號並不適合波動性小的個股, 因為他們穩定也就代表本來就很少會有大漲大跌的情況, 如果只用來預測波動性較大 or 科技類股, 或許會比較適用也說不一定。

4. 預測大漲or大跌訊號本身光憑價量資料就是不可行, 如果可以拿到更細部的資料, 像是當日內外盤價, 各大劵商的買賣超數量等等, 這類資料相信是更有幫助的, 只是這種歷史資料就算真的拿得到也是要錢吧, 現在我都用免費的API拿資料, 要錢就...(遠望)。

5. 同4, 試到最後如果真的不可行, 那就放棄再找下一個能做的問題吧, 像是不要預測大漲大跌訊號, 只預測漲跌趨勢, 至少這個議題比較不會有data imbalance吧(應該)。

感覺未來還有好長的路要走阿, 慢慢前進吧~~~Fight!!

順便補一張Konosuba的圖潤飾一下這麼長的文章, 希望早點脫離這個困境XD

-----------------------------------------------------------------------
AxisTradeCult 程式原始碼:
https://github.com/zmcx16/AxisTradeCult


目前完成的功能如下:
  • 程式自動取得關注個股的歷史資訊 (每日的開盤, 收盤, 最低, 最高, 成交量, 調整收盤價, etc...) [資料來源: Quandl]
  • Stocks Overview頁面 (可新增, 移除個股至群組, 可依選擇時間顯示個股資料, 也會計算該天前3個月平均價&成交量以及一年成交價區間)
  • 各種技術分析線圖組合分析 (MA, KDJ, BollingerBands)
待完成項目:
  1. 投資組合頁面
  2. 提供機器學習模型預測
    • 自動取得、生成個股的基底、衍生特徵
    • 支援各類機器學習算法
    • 提供回歸測試模型預測率以及調適最佳參數
    • 提供增強式學習進行策略模擬

2 則留言:

  1. 辛苦了,順便找回一篇舊文

    獨立開發嘗試:如何用股票交易機器人每月賺 3500 美元?
    https://www.inside.com.tw/2017/02/13/trading-bot-as-a-side-project

    裡頭到一些書,或許能提供靈感?

    回覆刪除
  2. 您好, 不好意思現在才看到您的留言, 非常感謝您的分享!!

    這位開發者真的很厲害, 以我目前的技術要達到這程度還有好~~長的一段路, 不過我會加油的, 想到未來有機會能做到這樣的成果的話 就滿心雀躍阿~~~!!

    回覆刪除