2018年6月24日 星期日

AxisTradeCult 開發日誌 (6) - 簡單回測驗證

這周主要實作了簡單的回測功能以及針對Validation的方法做了調整, 之前Validation的方法是以ForwardingBlock的方式(我隨便取的, 我也不知道這有沒有專有名詞XD), 將整個Data Set切成N筆, 然後用第一筆當Training, 第二筆當Testing; 再用第二筆當Training, 第三筆當Testing....總計有N-1筆Training以及Testing的資料來作Validation, 可是這方法會有很大的問題, 像之前把2000~2018年的資料切成三筆, 會變成用2000-2006年的資料去建training model, 然後預測2007-2012的股價, 如果是有確定答案的問題或許沒問題, 可是像股價資料這種是時間越久關聯性就越低的, 所以基本上並不適合用這樣的方式來作驗證。 現在想想當初結果會這麼爛應該也是因為這驗證方式很有問題啊XD

總之, 現在改成了使用ForwardingLeaveOneOut的方法來驗證(一樣是我隨便取的名XD), 基本上就是往前shift的LOOCV, 首先會取出最前面的N筆資料來當training, 然後N+1天的資料來預測, 之後就shift 1天, 一樣使用N筆資料預測下一個N+1天, 所以最後總共會建立ALL-N組training model, 由於這時間開銷太大所以之前才沒有使用, 現在則是覺得好像只能這樣做了囧 反正現在都是用很簡單的分類算法做測試, 不要使用神經網路類的演算法應該是不會有太大問題。

首先設定TrDataSize = 250, 使用250個交易日資料去訓練model, 然後一直往前shift做LOOCV, 分類標籤一樣為ChangeN = 5%, pred_days = 5, 只要未來五天的收盤價平均漲超過5%就是+1,  跌超過5%就是-1, 其他則是盤整設定為0,  要預測的股票為迪士尼(DIS), 首先來看看資料分布:

---------------------
Label   Count
 0          4319
 1            143
-1            122
---------------------

一樣是非常的imbalance data, 這表示DIS本身波動性其實是不高的,  先來跑個分類模型看看結果:



結果跟之前ForwardingBlock天差地遠啊!!!  這代表用過去六年的資料來預測未來六年這件事本身就是超現實阿XDD  也代表股價資料越遠關聯性就真的越低, 如果要建Training model就不能使用太過久遠的資料。

除了跑DIS的資料以外, 由於現在手頭持股也有FB, 所以也來測測FB看看:




這樣看起來不同的分類算法用在不同的股價資料效果也更不相同, 對DIS的資料來說GaussianNB比較好, 而FB的話則是MLP較強, 另外基本上我比較關心的是上漲以及下跌的預測, 盤整反而是不這麼重要, 從資料來看普遍上漲比下跌還要好預測, 這也是因為以這兩檔來說都是穩定上漲的公司(DIS例外, 這3年一直起起落落XD)。

這樣看起來至少用ML來預測股價是都比亂猜好得多的, 不過最需要關心的問題並不是ML預測漲跌強不強, 而是他能不能幫我賺錢阿!!

為了測試這樣的預測是不是有用的, 我寫了一個簡單的回測功能, 起始資金設定為50000, 如果預測會漲就買100股, 預測會跌就全出清(下跌比上漲還難預測, 而且下跌50%等於要漲100%才能打平, 所以逃難逃得準以及快我覺得是很重要的), 由於要計算整體獲利所以最後一天會出清全部持股, 來看一下回測結果如何:




結論: "爛透了!!!!"

呼...為什麼說爛透了呢? 首先, 資料部分DIS我是取2000年1月~2018年6月, 而FB則是2012年才上市所以是2012年5月~2018年6月,  這段時間DIS從40元漲到100元總共2.5倍, 而FB則是從30元漲到200元總共6倍多, 雖然說這種話只能是後話(畢竟是從未來看回去), 不過要最賺的方法就是買了就不要賣了, 哪還需要什麼程式交易阿(翻桌!!)

嘛...先不管只有神能做到的事(預測未來), 基本上以DIS來說只有KNN有賺錢, 而ROI 62%雖然看起來很多, 可是我資料是從2000年~2018年, 扣到training的250天交易日, 等於我16年多來只賺62%, 這報酬率真的太低了, 更不用提其他模型都是賠錢的狀況!!

而以FB來說, 那種走勢本來就是避著眼睛買賣都會賺, 就看賺多賺少罷了, 除了NB的5年多2倍算不錯以外, 其他的根本不合格!!

從結果來看, 也能知道分類器預測的好壞跟能不能賺錢並不是完全正向的關係, 雖然也必須考慮回測的問題(驗證的回測只能做多不能做空), 以上述情況就像預測對了只有小賺, 預測錯了卻是大賠的感覺, 這部分就得在研究看看之後要怎麼做比較好, 要怎麼把預測用在買賣以及籌碼運用上。

另外為了讓比較結果客觀些, 這裡也做了下Random交易的回測, 回測的方法一樣, 只是用Random的方式去決定買賣, 一樣不頻繁交易情況, 2%機率買, 2%機率賣, 96%不做任何事, 然後跑Random 1000次取平均, 來看看結果:


喔喔, 沒想到Random的報酬率比我想像中的還爛, 這代表或許並不是預測太差, 而是回測的方法不好, 導致就算預測對了也賺不到錢, 這也是未來的課題之一, 要怎麼把股價預測在跟籌碼運用結合, 畢竟我真正想做的並不是預測股價, 真正要做的應該是怎麼結合預測以及交易策略來賺錢, 感覺又有幹勁了啊!!!

最後來實際看看整個回測的詳細交易內容吧, 這樣也能分析出到底問題在哪裡, 由於FB整個趨勢就是上漲看了也沒意思,  先來看看最好報酬的KNN預測DIS:




綠色是買進而紅色是賣出, 其實看得出來他找到的買賣點是十分不錯的, 這代表最大的問題並不在於預測準確度, 而是籌碼的運用上, 由於我策略就是找到買點就是買100股, 所以閒置資金的部位是十分驚人的, 這也是為什麼ROI這麼低的關係, 儘管如此, 我也不能因為閒置資金的關係就有買點就全押, 這樣到時賠也是會賠到脫褲的...。 不過看這張圖也能清楚了解, 如果籌碼運用得當, 這個回測績效應該會是ㄅㄧㄤˋㄅㄧㄤˋ叫才是XD


最後的最後, 爽完了一下該來面對下現實, 既然KNN預測DIS賺那麼少是因為籌碼問題, 那決策樹ROI -23%又是搞什麼鬼哩?  來看看到底是怎麼一回事:




結果揭曉....看來決策樹是Overfitting了, 而且還外帶大量的過度交易, 交易是有成本的, 我現在的簡單回測還沒考慮交易成本, 如果考慮進去這個ROI可能虧到60%甚至80%都有可能也說不定, 可怕可怕囧

這樣整個做下來, 又知道自己下一步要做什麼了, 再來該來研究怎麼將預測跟籌碼使用結合在一起, 這塊做出來後就等於是做個交易機器人了, 終於要開始接觸這一塊了嘛XDDD

總之, 再來我會再把預測這塊做得更完善些, code也要整理一下而且也要跟GUI稍微整合, 等完工後再來就是新計畫始動啦!!

2018年6月17日 星期日

AxisTradeCult 開發日誌 (5) - 實作更多技術指標 & 預測漲跌趨勢

上篇提到自己試著簡易預測大漲大跌訊號結果大暴死!!  由於預測效能 + data imbalance的問題一起考慮會過於複雜, 這次想先做預測趨勢這塊, 至少先確定自己建的資料特徵是有用的, 未來也才有機會預測大漲大跌這問題。

首先想到自己手邊的feature真的太少了,  之前我也只實作SMA, KDJ, BollingerBands 這三個技術指標, 這一個禮拜就開始實作各類指標以及畫圖的功能, 目前實作好的技術指標如下:
  • ATR (Average True Range)
  • Bollinger Bands
  • CCI (Commodity Channel Index)
  • DMA (Different of Moving Average)
  • DMI (Directional Moving Index)
  • EMA (Exponential Moving Average)
  • KDJ (Stochastic Oscillator)
  • MACD (Moving Average Convergence Divergence)
  • MSTD (Moving Standard Deviation)
  • MVAR (Moving Variance)
  • RSI (Relative Strength Index)
  • SMA (Simple Moving Average)
  • SMMA (Smoothed Moving Average)
  • TEMA (Triple Exponential Moving Average)
  • TR (True Range)
  • VR (Volatility Volume Ratio)
  • WR (Williams Overbought/Oversold Index)

不得不說真是他X的有夠累, 雖然有 /stockstats 的github可以參考, 可是為了驗證還是要Google以及看Yahoo財經的圖表確認自己實作有沒有錯, 真的好麻煩阿....而且這種技術指標真的太多太多了, 我目前想先實作到這, 未來有空再來繼續增加新的指標...。

秀幾張新實作好的指標圖, 幸好指標通用的GUI框架之前就做好了, 現在新增加指標也只要實作算法跟訂輸入的規格, 不用再改GUI真的是很爽XD

MACD:



EMA20 & RSI20 & WR14:




實作了那麼多技術指標, 準備資料特徵的工作算是先告一段落, 首先稍微修改一下之前的方法, 改成預測3類(上漲N%, 盤整, 下跌N%),  預測AT&T未來5天的趨勢, 股價資料期間: "2000-1-3"~"2018-6-01"。

驗證方式一樣:
1. 依時間軸切割成3份資料: D1: 2000~2006. D2: 2006~2012, D3: 2012~2018。
2. 使用D1訓練並用D2資料驗證, 在使用D2訓練並用D3資料驗證。

由於現在是預測三類, 考慮到很多分類算法只能作二類預測, 這裡使用OvR來作分類擴展。

先用之前準備好的資料特徵試試, 鄰居特徵neighbor_size = 10, 技術指標特徵使用:



[MA_W20, BollingerBands_W20, KDJ_W20]

使用的分類模型為決策樹, 預測結果:



Label1是上漲5%, Label0是盤整, Label-1則是下跌5%,  這結果很明顯的比亂猜還爛= = 畢竟資料特徵有55個都只是單純的OHLCV資料(5*(1+10)), 實際的技術指標只有6個(1+2+3), 不過跟亂猜沒兩樣真的讓我覺得頗無奈。

再來試試這一個禮拜嘔心瀝血的成果吧, 把實作的技術指標通通加進去。

預測結果:



恩....雖然還是很爛, 至少好一咪咪(?),  Data imbalance還是一樣是很大的問題(畢竟大多時候都是在盤整), 不過光是數值有稍微上去就讓我很開心了, 至少這一個多禮拜不算白費:)

再來的課題就是怎麼做feature selection, 調參數以及選擇分類算法了, 之後也打算開始多看一些相關的paper, 看其他人是怎麼用ML做股價預測的...漫漫長路阿, 希望之後能做出些許成果出來!!!

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


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


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. 提供機器學習模型預測
    • 自動取得、生成個股的基底、衍生特徵
    • 支援各類機器學習算法
    • 提供回歸測試模型預測率以及調適最佳參數
    • 提供增強式學習進行策略模擬