Mann-Kendall演算法用於金融品種長週期趨勢判斷和變點檢測,以及策略思路
之前在研究用機器學習庫Sci-kit做計算指標(特徵值)和金融產品趨勢(分類)關係學習的時候,對於如何判斷趨勢,是直接使用當前之後5根k線close值做線性迴歸,如果擬合的P值可信的直線斜率向上則是上漲,斜率向下則是下跌。具體程式碼可以見之前我之前blog。
在vnpy有個網友討論,為什麼用這樣方法判斷趨勢的時候;我做了些搜尋,才發現判斷一組時序佇列的趨勢並不是一個簡單的事情,雖然人眼看很直接,但是數學分析並不簡單,尤其考慮置信範圍和變點存在。
-
所謂置信範圍一兩句說不清,可以看看這個問答,我的理解95%置信區間就是在這個一個時序佇列裡面95%都是符合上漲趨勢,但是存在5%可能不符合:
-
突變點:變點理論是統計學中的一個經典分支,其基本定義是在一個序列或過程中,當某個統計特性(分佈型別、分佈引數)在某時間點受系統性因素而非偶然性因素影響發生變化,我們就稱該時間點為變點。變點識別即利用統計量或統計方法將該變點位置估計出來。這裡主要是用數學方法,過濾出偶爾出現的異常點,和真正改變規律的變點。
其實趨勢檢測和突變點檢測是很資料探勘很經典的話題,尤其在氣象,水文,醫藥驗證等,使用方法很多,從簡單的均值,方差,到機率線性迴歸等。這裡主要講 Mann-Kendall檢驗法 。
其他的,網上搜到的好多:
1。均值突變的檢測方法有:(1)低通濾波法;(2)t-檢驗法;(3)Cramer法;(4)滑動t-檢驗法;(5)Yamaoto法;(6)M-K法;(7)最小二乘法;(8)連續滑動t-檢驗法;(9)Pttitt法;(10)Lepage法;(11)區域性比較法。等等。在均值突變分析中,除了突變點、突變個數的估計外,一般還要分析躍變度等。
2。方差突變的檢測方法有:(1)F-檢驗法;(2)滑動F-檢驗法;(3)連續滑動F-檢驗法。等等。
3。線性迴歸突變(也稱趨勢突變)的檢測方法有:(1)最小二乘法;(2)區域性比較法;滑動引數法等等。
4。機率突變的檢測方法有:(1)極大似然法;(2)累計次數法;(3)Bayes法;等等。
曼-肯德爾法又稱Mann—Kenddall 檢驗法,是一種氣候診斷與預測技術,應用Mann-Kendall檢驗法可以判斷氣候序列中是否存在氣候突變,如果存在,可確定出突變發生的時間。Mann-Kendall檢驗法也經常用於氣候變化影響下的降水、乾旱頻次趨勢檢測。Mann—Kenddall的檢驗方法是非引數方法。非引數檢驗方法亦稱無分佈檢驗,其優點是不需要樣本遵從一定的分佈,也不受少數異常值的干擾,更適用於型別變數和順序變數,計算也比較簡便。
具體演算法推導不講了,主要有兩種用法,一個是計算這個時序佇列的趨勢;還有一個是算這個時序佇列是否有變點,如果有,是佇列中幾個點。
程式碼之前自己寫了一些,後來在這個連結發現一個非常全的,修改引用了。他還有其他幾個突變點演算法的python程式化,可以學習。
https://blog.csdn.net/u012111465/article/details/82016757
一,趨勢校驗,演算法如下
def Mann_Kenddall_Trend_desc(inputdata): # 計算總趨勢秩次和 inputdata = np.array(inputdata) n = inputdata.shape[0] sum_sgn = 0 for i in np.arange(n): if i <= (n - 1): for j in np.arange(i+1,n): if inputdata[j] > inputdata[i]: sum_sgn = sum_sgn+1 elif inputdata[j] < inputdata[i]: sum_sgn = sum_sgn-1 else: sum_sgn = sum_sgn # 計算Z統計值 if n <= 10: Z_value = sum_sgn/(n*(n-1)/2) else: if sum_sgn > 0: Z_value = (sum_sgn-1)/np.sqrt(n*(n-1)*(2*n+5)/18) elif sum_sgn == 0: Z_value = 0 else: Z_value = (sum_sgn+1)/np.sqrt(n*(n-1)*(2*n+5)/18) # 趨勢描述 # 99% ——> +—2.576 # 95% ——> +—1.96 # 90% ——> +—1.645 if np.abs(Z_value) > 1.96 and np.abs(Z_value) <= 2.576: if Z_value > 0: result_desc = u"95% up" else: result_desc = u"95% down" elif np.abs(Z_value) > 2.576: if Z_value > 0: result_desc = u"99% up" else: result_desc = u"99% down" else: result_desc = u"not trendency" return result_desc
二,突變點校驗
def Kendall_change_point_detection(inputdata): inputdata = np.array(inputdata) n=inputdata.shape[0] # 正序列計算--------------------------------- # 定義累計量序列Sk,初始值=0 Sk = [0] # 定義統計量UFk,初始值 =0 UFk = [0] # 定義Sk序列元素s,初始值 =0 s = 0 Exp_value = [0] Var_value = [0] # i從1開始,因為根據統計量UFk公式,i=0時,Sk(0)、E(0)、Var(0)均為0 # 此時UFk無意義,因此公式中,令UFk(0)=0 for i in range(1,n): for j in range(i): if inputdata[i] > inputdata[j]: s = s+1 else: s = s+0 Sk.append(s) Exp_value.append((i+1)*(i+2)/4 ) # Sk[i]的均值 Var_value.append((i+1)*i*(2*(i+1)+5)/72 ) # Sk[i]的方差 UFk.append((Sk[i]-Exp_value[i])/np.sqrt(Var_value[i])) # ------------------------------正序列計算 # 逆序列計算--------------------------------- # 定義逆序累計量序列Sk2,長度與inputdata一致,初始值=0 Sk2 = [0] # 定義逆序統計量UBk,長度與inputdata一致,初始值=0 UBk = [0] UBk2 = [0] # s歸0 s2 = 0 Exp_value2 = [0] Var_value2 = [0] # 按時間序列逆轉樣本y inputdataT = list(reversed(inputdata)) # i從2開始,因為根據統計量UBk公式,i=1時,Sk2(1)、E(1)、Var(1)均為0 # 此時UBk無意義,因此公式中,令UBk(1)=0 for i in range(1,n): for j in range(i): if inputdataT[i] > inputdataT[j]: s2 = s2+1 else: s2 = s2+0 Sk2.append(s2) Exp_value2.append((i+1)*(i+2)/4 ) # Sk[i]的均值 Var_value2.append((i+1)*i*(2*(i+1)+5)/72 ) # Sk[i]的方差 UBk.append((Sk2[i]-Exp_value2[i])/np.sqrt(Var_value2[i])) UBk2.append(-UBk[i]) # 由於對逆序序列的累計量Sk2的構建中,依然用的是累加法,即後者大於前者時s加1, # 則s的大小表徵了一種上升的趨勢的大小,而序列逆序以後,應當表現出與原序列相反 # 的趨勢表現,因此,用累加法統計Sk2序列,統計量公式(S(i)-E(i))/sqrt(Var(i)) #也不應改變,但統計量UBk應取相反數以表徵正確的逆序序列的趨勢 # UBk(i)=0-(Sk2(i)-E)/sqrt(Var) # ------------------------------逆序列計算 # 此時上一步的到UBk表現的是逆序列在逆序時間上的趨勢統計量 # 與UFk做圖尋找突變點時,2條曲線應具有同樣的時間軸,因此 # 再按時間序列逆轉結果統計量UBk,得到時間正序的UBkT, UBkT = list(reversed(UBk2)) diff = np.array(UFk) - np.array(UBkT) K = list() # 找出交叉點 for k in range(1,n): if diff[k-1]*diff[k]<0 and (UFk[k] > 1.96 or UFk[k] < -1.96) : K.append(k) # 做突變檢測圖時,使用UFk和UBkT return K
最後,我嘗試著用M-K做了期貨策略;長週期來看回測效果還不錯,但是太長了,往往就超過一個品種期間,存在跨期的風險。感覺不是和做期貨。
對於股票的大藍籌和etf更加適合,用於長線的投資。
策略思路說下:
-
讀取歷史資料,載入close資料;分析過去一組資料中是否存在變異點
-
如果有變異點,分析從變異點到最近一個close的趨勢,是否滿足95%置信區間
-
如果滿足,結合一些指標,比如布林線,唐安琦等買入或者賣出
-
持有後,繼續監控趨勢,如果低於90%置信區間,平倉。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22259926/viewspace-2651575/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 從打造3A遊戲設計理念,談長週期的超休閒品類趨勢遊戲設計
- PbootCMS奇偶數判斷(隔行變色)各種條件判斷和標籤boot
- sql日期和週末判斷SQL
- 不亞於SLG的市場表現!消除品類遊戲的市場趨勢與機會判斷遊戲
- 每週開源點評:雲原生 Java、開源安全以及更多行業趨勢Java行業
- Laravel-Echo 線上離線檢測判斷Laravel
- JavaScript判斷變數型別的四種方法JavaScript變數型別
- 品牌生命週期和產品生命週期之間的關係
- 下行的長期增長前景:趨勢、期望和政策報告
- 用於產品生命週期管理的 SOA 方法,第 2 部分: 產品生命週期管理的 SOA 參考體系架構架構
- 每週開源點評:Java 還有用嗎、Linux 桌面以及更多的行業趨勢JavaLinux行業
- PbootCMS判斷有無子選單各種條件判斷和標籤boot
- PbootCMS整理分頁判斷進階各種條件判斷和標籤boot
- 一個思路,利用T檢驗去尋找量化交易CTA趨勢
- 用Python預測「週期性時間序列」的正確姿勢Python
- 趨勢科技發現古巴勒索軟體新變種
- python 如何判斷一組數呈上升還是下降趨勢Python
- 網際網路+檢驗檢測智慧化成發展趨勢
- PbootCMS整理判斷是否連結賦值各種條件判斷和標籤boot賦值
- PbootCMS導航欄 logo 居中判斷各種條件判斷和標籤bootGo
- 阿里媽媽&天貓:新週期下消費電子趨勢洞察與商業增長報告阿里
- MMO手遊如何長期運營?網易《光明大陸》兩週年之際提供三點新思路
- 每週開源點評:Kubernetes 網路、OpenStack Train 以及更多的行業趨勢AI行業
- Redis對於過期鍵有三種清除策略Redis
- 變數,運算子,if判斷變數
- oracle 統計資訊過期判斷和自動收集Oracle
- VNPY 單品種期貨的網格交易策略的實現
- 用於產品生命週期管理的 SOA 方法,第 3 部分: 業務流程管理
- Fast角點檢測演算法AST演算法
- 休閒遊戲趨勢分析以及市場立項品類機會分析遊戲
- 關於檢測TCP連線斷開TCP
- 如何應對服裝時尚週期短,產業發展趨勢快?產業
- C語言判斷素數,判斷質素演算法C語言演算法
- 用asp判斷某IP是否屬於某網段的另類演算法演算法
- php判斷本週,上週與上上週的日期PHP
- PbootCMS判斷標籤為空時不顯示各種條件判斷和標籤boot
- PbootCMS判斷導航從第幾個開始各種條件判斷和標籤boot
- Web 開發模式演變歷史和趨勢Web模式