用matplotlib和pandas繪製股票MACD指標圖,並驗證化交易策略

    我的新書《基於股票大數據分析的Python入門實戰》於近日上架,在這篇博文向大家介紹我的新書:《基於股票大數據分析的Python入門實戰》裏,介紹了這本書的內容。這裏將摘錄出部分內容,用以推廣本書,請大家多多支持。   

1 MACD指標的計算方式

     從數學角度來分析,MACD指標是根據均線的構造原理,對股票收盤價進行平滑處理,計算出算術平均值以後再進行二次計算,它是屬於趨向類指標。

    MACD指標是由三部分構成的,分別是:DIF(離差值,也叫差離值)、DEA(離差值平均)和BAR(柱狀線)。

    具體的計算過程是,首先算出快速移動平均線(EMA1)和慢速移動平均線(EMA2),用這兩個數值來測量兩者間的差離值(DIF),在此基礎上再計算差離值(DIF)N週期的平滑移動平均線DEA(也叫MACD、DEM)線。

    如前文所述,EMA1週期參數一般取12日,EMA2一般取26日,而DIF一般取9日,在此基礎上,MACD指標的計算步驟如下所示。

    第一步:計算移動平均值(即EMA)。

    12日EMA1的計算方式是:EMA(12)= 前一日EMA(12)× 11/13 + 今日收盤價 × 2/13

    26日EMA2的計算方式是:EMA(26)= 前一日EMA(26)× 25/27 + 今日收盤價 ×2 /27

    第二步:計算MACD指標中的差離值(即DIF)。

    DIF = 今日EMA(12)- 今日EMA(26)

    第三步:計算差離值的9日EMA(即MACD指標中的DEA)。用差離值計算它的9日EMA,這個值就是差離平均值(DEA)。

    今日DEA(MACD)= 前一日DEA × 8/10 + 今日DIF × 2/10

    第四步:計算BAR柱狀線。

    BAR = 2 × (DIF - DEA)

    這裏乘以2的原因是,在不影響趨勢的情況下,從數值上擴大DIF和DEA差值,這樣觀察效果就更加明顯。

    最後,把各點(即每個交易日)的DIF值和DEA值連接起來,就能得到在x軸上下移動的兩條線,分別表示短期(即快速,EMA1,週期是12天)和長期(即慢速,EMA2,週期是26天)。而且,DIF和DEA的離差值能構成紅、綠兩種顏色的柱狀線,在x軸之上是紅色,而x軸之下是綠色。

2 遍歷數據表數據,繪製MACD指標

    同K線指標一樣,根據不同的計算週期, MACD指標也可以分爲日指標、周指標、月指標乃至年指標。在下面的DrawMACD.py範例程序中將繪製日MACD指標,在這個範例程序中可以看到關於數據結構、圖形繪製和數據庫相關的操作,由於程序代碼比較長,下面分段講解。

1    # !/usr/bin/env python
2    # coding=utf-8
3    import pandas as pd
4    import matplotlib.pyplot as plt
5    import pymysql
6    import sys
7    # 第一個參數是數據,第二個參數是週期
8    def calEMA(df, term):
9        for i in range(len(df)):
10           if i==0: # 第一天
11               df.ix[i,'EMA']=df.ix[i,'close']
12           if i>0:
13              df.ix[i,'EMA']=(term-1)/(term+1)*df.ix[i-1,'EMA']+2/(term+1) * df.ix[i,'close']
14       EMAList=list(df['EMA'])
15       return EMAList

    在第8行到第15行的calEMA方法中,根據第二個參數term,計算快速(週期是12天)和慢速(週期是26天)的EMA值。

    具體步驟是,通過第9行的for循環,遍歷由第一個參數指定的DataFrame類型的df對象,根據第10行的if條件中,如果是第一天,則EMA值用當天的收盤價,如果滿足第12行的條件,即不是第一天,則在第13行中根據8.3.1節的算法,計算當天的EMA值。

    請注意,在第11行和第13行中是通過df.ix的形式訪問索引行(比如第i行)和指定標籤列(比如EMA列)的數值,ix方法與之前loc以及iloc方法不同的是,ix方法可以通過索引值和標籤值訪問,而loc以及iloc方法只能通過索引值來訪問。計算完成後,在第14行把df的EMA列轉換成列表類型的對象並在第15行返回。

16   # 定義計算MACD的方法
17   def calMACD(df, shortTerm=12, longTerm=26, DIFTerm=9):
18       shortEMA = calEMA(df, shortTerm)
19       longEMA = calEMA(df, longTerm)
20       df['DIF'] = pd.Series(shortEMA) - pd.Series(longEMA)
21       for i in range(len(df)):
22           if i==0:         # 第一天
23               df.ix[i,'DEA'] = df.ix[i,'DIF']  # ix可以通過標籤名和索引來獲取數據
24           if i>0:
25                 df.ix[i,'DEA'] = (DIFTerm-1)/(DIFTerm+1)*df.ix[i-1,'DEA'] + 2/(DIFTerm+1)*df.ix[i,'DIF']
26       df['MACD'] = 2*(df['DIF'] - df['DEA'])
27       return df[['date','DIF','DEA','MACD']]
28       # return df

    在第15行到第27行定義的calMACD方法中,將調用第8行定義的calEMA方法來計算MACD的值。具體步驟是,在第18行和第19行通過調用calEMA方法,分別得到了快速和慢速的EMA值,在第20行,用這兩個值計算DIF值。請注意,shortEMA和longEMA都是列表類型,所以可以像第20行那樣,通過調用pd.Series方法把它們轉換成Series類對象後再直接計算差值。

    從第21行到第25行的程序語句,也是根據8.3.1節給出的公式計算DEA值,同樣要用兩條if語句區分“第一天”和“以後幾天”這兩種情況,在第26行根據計算公式算出MACD的值。

    第27行返回指定的列,在後面的代碼中還要用到df對象的其他列,此時則可以用如第28行所示的代碼返回df的全部列。

29   try:
30       # 打開數據庫連接
31       db = pymysql.connect("localhost","root","123456","pythonStock" )
32   except:
33       print('Error when Connecting to DB.')
34       sys.exit()
35   cursor = db.cursor()
36   cursor.execute("select * from stock_600895")
37   cols = cursor.description        # 返回列名
38   heads = []
39   # 依次把每個cols元素中的第一個值放入col數組
40   for index in cols:
41       heads.append(index[0])
42   result = cursor.fetchall()
43   df = pd.DataFrame(list(result))
44   df.columns=heads
45   # print(calMACD(df, 12, 26, 9)) # 輸出結果
46   stockDataFrame = calMACD(df, 12, 26, 9)

    從第29行到第35行的程序語句,建立了MySQL數據庫的連接和獲得遊標cursor對象,在第36行中,通過select類型的SQL語句,來獲取stock_600895表中的所有數據,如8.2節所述,這個數據表中的數據源自雅虎網站。

    在第37行中,得到了stock_600895數據表的字段列表。在第40行和第41行的for循環中,把字段列表中的第0行索引元素放入了heads。在第42行和第43行,把從stock_600895數據表中獲取的數據放入到df對象。在第44行的程序語句,把包含數據表字段列表的heads對象賦值給df對象的字段。

    執行到這裏,如果去掉第45行打印語句的註解,就能看到第一列輸出的是字段名列表,之後會按天輸出與MACD有關的股票指標數據。

    在第46行調用了calMACD方法,並把結果賦值給stockDataFrame對象,之後就可以根據stockDataFrame對象中的值開始繪圖。

47   # 開始繪圖
48   plt.figure()
49   stockDataFrame['DEA'].plot(color="red",label='DEA')
50   stockDataFrame['DIF'].plot(color="blue",label='DIF')
51   plt.legend(loc='best')    # 繪製圖例
52   # 設置MACD柱狀圖
53   for index, row in stockDataFrame.iterrows():
54       if(row['MACD'] >0):   # 大於0則用紅色
55           plt.bar(row['date'], row['MACD'],width=0.5, color='red')
56       else:                               # 小於等於0則用綠色
57           plt.bar(row['date'], row['MACD'],width=0.5, color='green')
58   # 設置x軸座標的標籤和旋轉角度
59   major_index=stockDataFrame.index[stockDataFrame.index%10==0]
60   major_xtics=stockDataFrame['date'][stockDataFrame.index%10==0]
61   plt.xticks(major_index,major_xtics)
62   plt.setp(plt.gca().get_xticklabels(), rotation=30)
63   # 帶網格線,且設置了網格樣式
64   plt.grid(linestyle='-.')
65   plt.title("600895張江高科的MACD圖")
66   plt.rcParams['axes.unicode_minus'] = False
67   plt.rcParams['font.sans-serif']=['SimHei']
68   plt.show()

    在第49和第50行中通過調用plot方法,以折線的形式繪製出DEA和DIF兩根線,在第51行中設置了圖例。

    在第53行到第57行的for循環中,以柱狀圖的形式依次繪製了每天的MACD值的柱狀線,這裏用第54行和第56行的if…else語句進行區分,如果row['MACD']大於0,則MACD柱是紅色,反之是綠色。

    從第59行到第61行的程序語句設置了x軸的標籤,如果顯示每天的日期,那麼x軸上的文字會過於密集,所以在第59行和第60行進行相應的處理,只顯示stockDataFrame.index%10==0(即索引值是10的倍數)的日期。

    在第62行設置了x軸文字的旋轉角度,在第64行設置了網格的式樣,在第65行設置了標題文字,最後在第68行通過調用show方法繪製了整個圖形。

    請注意,如果不編寫第66行的程序語句,那麼y軸標籤值裏的負號就不會顯示,這樣顯示結果就不正確了。讀者可以把這條語句註釋掉後,再運行一下,看看結果如何。

     至此,我們實現了計算並繪製MACD指標線的功能,讀者應該掌握瞭如何獲得指定股票在指定時間段內的交易數據,而後可以稍微改寫上述的範例程序,繪製出其他股票在指定時間範圍內的MACD走勢圖。

3 MACD與K線均線的整合效果圖

     MACD是趨勢類指標,如果把它與K線和均線整合到一起的話,就能更好地看出股票走勢的“趨勢性”。在下面的DrawKwithMACD.py範例程序中示範了整合它們的效果,由於程序代碼比較長,因而在下面的分析中略去了一些之前分析過的重複代碼,讀者可以從本書提供下載的範例程序中看到完整的代碼。

1    # !/usr/bin/env python
2    # coding=utf-8
3    import pandas as pd
4    import matplotlib.pyplot as plt
5    import pymysql
6    import sys
7    from mpl_finance import candlestick2_ochl
8    from matplotlib.ticker import MultipleLocator
9    # 計算EMA的方法,第一個參數是數據,第二個參數是週期
10   def calEMA(df, term):
11       # 省略具體實現,請參考本書提供下載的完整範例程序
12   # 定義計算MACD的方法
13   def calMACD(df, shortTerm=12, longTerm=26, DIFTerm=9):
14       # 省略中間的計算過程,請參考本書提供下載的完整範例程序
15       return df

    從第3行到第8行的程序語句通過import語句導入了必要的依賴包,第10行定義的calEMA方法和DrawMACD.py範例程序中的完全一致,所以就省略了該方法內部的代碼。第13行定義計算MACD的calMACD方法和DrawMACD.py範例程序中的同名方法也完全一致,但在最後的第15行,是通過return語句返回整個df對象,而不是返回僅僅包含MACD指標的相關列,這是因爲,在後文中需要股票的開盤價等數值來繪製K線圖。

16   try:
17       # 打開數據庫連接
18       db = pymysql.connect("localhost","root","123456","pythonStock" )
19   except:
20       print('Error when Connecting to DB.')
21       sys.exit()
22   cursor = db.cursor()
23   cursor.execute("select * from stock_600895")
24   cols = cursor.description        # 返回列名
25   heads = []
26   # 依次把每個cols元素中的第一個值放入col數組
27   for index in cols:
28       heads.append(index[0])
29   result = cursor.fetchall()
30   df = pd.DataFrame(list(result))
31   df.columns=heads
32   # print(calMACD(df, 12, 26, 9)) # 輸出結果
33   stockDataFrame = calMACD(df, 12, 26, 9)

    從第16行到第33行的程序語句把需要的數據放入了stockDataFrame這個DataFrame類型的對象中,之後就可以根據其中的數據畫圖了,這段程序代碼之前分析過,就不再重複講述了。

34   # 開始繪圖,設置大小,共享x座標軸
35   figure,(axPrice, axMACD) = plt.subplots(2, sharex=True, figsize=(15,8))
36   # 調用方法繪製K線圖
37   candlestick2_ochl(ax = axPrice, opens=stockDataFrame["open"].values, closes = stockDataFrame["close"].values, highs=stockDataFrame["high"].values,  lows = stockDataFrame["low"].values, width=0.75, colorup='red', colordown='green')
38   axPrice.set_title("600895張江高科K線圖和均線圖")   # 設置子圖的標題
39   stockDataFrame['close'].rolling(window=3).mean().plot(ax=axPrice,color="red",label='3日均線')
40   stockDataFrame['close'].rolling(window=5).mean().plot(ax=axPrice,color="blue",label='5日均線')
41   stockDataFrame['close'].rolling(window=10).mean().plot(ax=axPrice,color="green",label='10日均線')
42   axPrice.legend(loc='best')       # 繪製圖例
43   axPrice.set_ylabel("價格(單位:元)")
44   axPrice.grid(linestyle='-.')     # 帶網格線

    從第34行到第44行的程序語句繪製了指定時間範圍內“張江高科”股票的K線圖和均線,這部分代碼和第7章drawKMAAndVol.py範例程序中實現同類功能的代碼很相似,有差別的是在第35行,第二個子圖的名字設置爲“axMACD”,在第44行中通過linestyle設置了網格線的樣式。

45   # 開始繪製第二個子圖
46   stockDataFrame['DEA'].plot(ax=axMACD,color="red",label='DEA')
47   stockDataFrame['DIF'].plot(ax=axMACD,color="blue",label='DIF')
48   plt.legend(loc='best')    # 繪製圖例
49   # 設置第二個子圖中的MACD柱狀圖
50   for index, row in stockDataFrame.iterrows():
51       if(row['MACD'] >0):   # 大於0則用紅色
52           axMACD.bar(row['date'], row['MACD'],width=0.5, color='red')
53       else:                               # 小於等於0則用綠色
54           axMACD.bar(row['date'], row['MACD'],width=0.5, color='green')
55   axMACD.set_title("600895張江高科MACD")   # 設置子圖的標題
56   axMACD.grid(linestyle='-.')                # 帶網格線
57   # xmajorLocator = MultipleLocator(10)    # 將x軸的主刻度設置爲10的倍數
58   # axMACD.xaxis.set_major_locator(xmajorLocator)
59   major_xtics=stockDataFrame['date'][stockDataFrame.index%10==0]
60   axMACD.set_xticks(major_xtics)
61   # 旋轉x軸顯示文字的角度
62   for xtick in axMACD.get_xticklabels():
63       xtick.set_rotation(30)
64   plt.rcParams['font.sans-serif']=['SimHei']
65   plt.rcParams['axes.unicode_minus'] = False
66   plt.show()

    在上述程序代碼中,在axMACD子圖內繪製了MACD線,由於是在子圖內繪製,因此在第46行和第47行繪製DEA和DIF折線的時候,需要在參數裏通過“ax=axMACD”的形式指定所在的子圖。

    在第59行和第60行中設置了axMACD子圖中的x軸標籤,由於在第35行中設置了axPrice和axMACD兩子圖是共享x軸,因此K線和均線所在子圖的x軸刻度會和MACD子圖中的一樣。因爲是在子圖中,所以需要通過第62行和第63行的for循環依次旋轉x軸座標的標籤文字。

    在這段代碼中其實給出了兩種設置x軸標籤的方式。如果註釋掉第59行和第60行的代碼,並去掉第57行和第58行的註釋,會發現效果是相同的。

    需要說明的是,雖然在第57行和第59行的代碼中並沒有指定標籤文字,但在第37行調用candlestick2_ochl方法繪製K線圖時,會設置x軸的標籤文字,所以依然能看到x軸上日期的標籤。運行這個範例程序後,結果如圖所示。

4 MACD指標的指導意義

    根據MACD各項指標的含義,可以通過DIF和DEA兩者的值、DIF和DEA指標的交叉情況(比如金叉或死叉)以及BAR柱狀圖的長短與收縮的情況來判斷當前股票的趨勢。

    如下兩點是根據DIF和DEA的數值情況以及它們在x軸上下的位置來確定股票的買賣策略。

    第一,當DIF和DEA兩者的值均大於0(在x軸之上)並向上移動時,一般表示當前處於多頭行情中,建議可以買入。反之,當兩者的值均小於0且向下移動時,一般表示處於空頭行情中,建議賣出或觀望。

    第二,當DIF和DEA的值均大於0但都在向下移動時,一般表示爲上漲趨勢即將結束,建議可以賣出股票或觀望。同理,當兩者的值均小於0,但在向上移動時,一般表示股票將上漲,建議可以持續關注或買進。

    如下四點是根據DIF和DEA的交叉情況來決定買賣策略。

    第一,DIF與DEA都大於0而且DIF向上突破DEA時,說明當前處於強勢階段,股價再次上漲的可能性比較大,建議可以買進,這就是所謂MACD指標黃金交叉,也叫金叉。

    第二,DIF與DEA都小於0,但此時DIF向上突破DEA時,表明股市雖然當前可能仍然處於跌勢,但即將轉強,建議可以開始買進股票或者重點關注,這也是MACD金叉的一種形式。

    第三,DIF與DEA雖然都大於0,但而DIF卻向下突破DEA時,這說明當前有可能從強勢轉變成弱勢,股價有可能會跌,此時建議看機會就賣出,這就是所謂MACD指標的死亡交叉,也叫死叉。

    第四,DIF和DEA都小於0,在這種情況下又發生了DIF向下突破DEA的情況,這說明可能進入下一階段的弱勢中,股價有可能繼續下跌,此時建議賣出股票或觀望,這也是MACD死叉的一種形式。

    如下兩點是根據MACD中BAR柱狀圖的情況來決定買賣策略。

    第一,紅柱持續放大,這說明當前處於多頭行情中,此時建議買入股票,直到紅柱無法再進一步放大時才考慮賣出。相反,如果綠柱持續放大,這說明當前處於空頭行情中,股價有可能繼續下跌,此時觀望或賣出,直到綠柱開始縮小時才能考慮買入。

    第二,當紅柱逐漸消失而綠柱逐漸出現時,這表明當前的上漲趨勢即將結束,有可能開始加速下跌,這時建議可以賣出股票或者觀望。反之,當綠柱逐漸消失而紅柱開始出現時,這說明下跌行情即將或已經結束,有可能開始加速上漲,此時可以開始買入。

    雖然說MACD指標對趨勢的分析有一定的指導意義,但它同時也存在一定的盲點。

    比如,當沒有形成明顯的上漲或下跌趨勢時(即在盤整階段),DIF和DEA這兩個指標會頻繁地出現金叉和死叉的情況,這時由於沒有形成趨勢,因此金叉和死叉的指導意義並不明顯。

    又如,MACD指標是對趨勢而言的,從中無法看出未來時間段內價格上漲和下跌的幅度。比如在圖8-11中,股票“張江高科”在價格高位時,DIF的指標在2左右,但有些股票在高位時,DIF的指標甚至會超過5。

也就是說,無法根據DIF和DEA數值的大小來判斷股價會不會進一步漲或進一步跌。有時看似DIF和DEA到達一個高位,但如果當前上漲趨勢強勁,股價會繼續上漲,同時這兩個指標會進一步上升,反之亦然。

    因此,在實際使用中,投資者可以用MACD指標結合其他技術指標,比如之前提到的均線,從而能對買賣信號進行多重確認。

5 驗證基於柱狀圖和金叉的買點

    在CalBuyPointByMACD.py範例程序中將根據如下原則來驗證買點:DIF向上突破DEA(出現金叉),且柱狀圖在x軸上方(即當前是紅柱狀態)。

    在這個範例程序中,用的是股票“金石資源(代碼爲603505)從2018年9月到2019年5月的交易數據,程序代碼如下。

1    # !/usr/bin/env python
2    # coding=utf-8
3    import pandas as pd
4    import pymysql
5    import sys
6    # 第一個參數是數據,第二個參數是週期
7    def calEMA(df, term):
8      # 省略方法內的代碼,請參考本書提供下載的完整範例程序
9    # 定義計算MACD的方法
10   def calMACD(df, shortTerm=12, longTerm=26, DIFTerm=9):
11       # 省略中間計算過程的代碼,最後返回的是df,請參考本書提供下載的完整範例程序
12       return df

    上述代碼的calEMA和calMACD方法和8.3.4節的範例程序中的代碼完全一致,所以就不再重複講述了。

13	def getMACDByCode(code):
14	    try:
15	        # 打開數據庫連接
16	        db = pymysql.connect("localhost","root","123456","pythonStock" )
17	    except:
18	        print('Error when Connecting to DB.')
19	        sys.exit()  
20	    cursor = db.cursor()
21	    cursor.execute('select * from stock_'+code)
22	    cols = cursor.description  	# 返回列名
23	    heads = []
24	    # 依次把每個cols元素中的第一個值放入col數組
25	    for index in cols:
26	        heads.append(index[0])
27	    result = cursor.fetchall()
28	    df = pd.DataFrame(list(result))
29	    df.columns=heads
30	    stockDataFrame = calMACD(df, 12, 26, 9)
31	    return stockDataFrame

    第13行開始的getMACDByCode方法中包含了從數據表中獲取的股票交易數據並返回MACD指標的代碼, 這部分程序代碼與之前DrawKwithMACD.py範例程序中的程序也非常相似,只不過在第21行中是根據股票代碼來動態地拼接select語句。該方法在第31行中返回包含MACD指標的stockDataFrame對象。

32	# print(getMACDByCode('603505')) 	# 可去除這條語句的註解以確認數據
33	stockDf = getMACDByCode('603505')
34	cnt=0
35	while cnt<=len(stockDf)-1:
36	    if(cnt>=30):		# 前幾天有誤差,從第30天算起
37	        try:
38	            # 規則1:這天DIF值上穿DEA
39	            if stockDf.iloc[cnt]['DIF']>stockDf.iloc[cnt]['DEA'] and stockDf.iloc[cnt-1]['DIF']<stockDf.iloc[cnt-1]['DEA']:
40	                #規則2:出現紅柱,即MACD值大於0
41	                if stockDf.iloc[cnt]['MACD']>0:
42	                    print("Buy Point by MACD on:" + stockDf.iloc[cnt]['date'])
43	        except:
44	            pass
45	    cnt=cnt+1

    如果去掉第32行打印語句的註釋,執行後就能確認數據。在第35行到第45行的while循環中,依次遍歷了每個交易日的數據。有數據計算的誤差,所以在這個範例程序中通過第36行的if語句排除了剛開始29天的數據,從第30天算起。

    在第39行的if條件語句中制定了第一個規則,前一個交易日的DIF小於DEA,而且當天DIF大於DEA,即出現上穿金叉的現象。在第41行的if條件語句中制定了第二個規則,即出現金叉的當日,MACD指標需要大於0,即當前BAR柱是紅柱狀態。運行這個範例程序之後,就能看到如下輸出的買點。

    Buy Point by MACD on:2018-10-31

    Buy Point by MACD on:2019-01-09

    Buy Point by MACD on:2019-03-18

    Buy Point by MACD on:2019-04-04

    Buy Point by MACD on:2019-04-19

    下面改寫一下之前的範例程序,把股票代碼改成603505,把股票名稱改爲“金石資源”,運行後即可看到如圖所示的結果圖。 

    根據圖中的價格走勢,在表中列出了各買點的確認情況。

表  基於MACD得到的買點情況確認表

買點

對買點的分析

正確性

2018-10-31

該日出現DIF金叉,且Bar已經在紅柱狀態,後市有漲。

正確

2019-01-09

該日出現DIF金叉,且Bar柱開始逐漸變紅,後市有漲。

正確

2019-03-18

該日雖然出現金叉,Bar柱也開始變紅,但之後幾天Bar交替出現紅柱和綠柱情況,後市在下跌後,出現上漲情況。

不明確

2019-04-04

該日在出現金叉的同時,Bar柱由綠轉紅。但之後若干交易日後出現死叉,且Bar柱又轉綠,後市下跌。

不正確

2019-04-19

出現金叉,且Bar柱由綠柱一下子變很長,後市有漲。

正確

    根據這個範例程序的運行結果,可以得到的結論是:通過MACD指標的確能算出買點,但之前也說過,MACD有盲點,在盤整階段,趨勢沒有形成時,此時金叉的指導意義就不是很明顯,甚至是錯誤的。

6 驗證基於柱狀圖和死叉的賣點

    參考MACD指標,與8.4.2節描述的情況相反,如果出現如下情況,則可以賣出股票:DIF向下突破DEA(出現死叉),且柱狀圖向下運動(紅柱縮小或綠柱變長)。下面通過股票“士蘭微”(代碼爲600460)從2018年9月到2019年5月的交易數據來驗證賣點。

    先來做如下的準備工作:在MySQL的pythonStock數據庫中創建stock_600460數據表,在之前介紹的InsertDataFromYahoo.py範例程序中,把股票代碼改爲600460,運行後即可在stock_600460數據表中看到指定時間範圍內的交易數據。

    驗證MACD指標賣點的CalSellPointByMACD.py範例程序與之前CalBuyPointByMACD.py範例程序很相似,下面只分析不同的程序代碼部分。

1    # !/usr/bin/env python
2    # coding=utf-8
3    import pandas as pd
4    import pymysql
5    import sys
6    # calEMA方法中的代碼沒有變
7    def calEMA(df, term):
8        # 省略方法內的程序代碼,請參考本書提供下載的完整範例程序
9    # 定義計算MACD的方法內的程序代碼也沒有變
10   def calMACD(df, shortTerm=12, longTerm=26, DIFTerm=9):
11       # 省略方法內的程序代碼,請參考本書提供下載的完整範例程序
12   def getMACDByCode(code):
13       # 和CalBuyPointByMACD.py範例程序中的程序代碼一致
14   stockDf = getMACDByCode('600460')
15   cnt=0
16   while cnt<=len(stockDf)-1:
17       if(cnt>=30):         # 前幾天有誤差,從第30天算起
18           try:
19               # 規則1:這天DIF值下穿DEA
20               if stockDf.iloc[cnt]['DIF']<stockDf.iloc[cnt]['DEA'] and stockDf.iloc[cnt-1]['DIF']>stockDf.iloc[cnt-1]['DEA']:
21                   # 規則2:Bar柱是否向下運動
22                   if stockDf.iloc[cnt]['MACD']<stockDf.iloc[cnt-1]['MACD']:
23                       print("Sell Point by MACD on:" + stockDf.iloc[cnt]['date'])
24           except:
25               pass
26       cnt=cnt+1

    上述代碼中的calEMA、calMACD和getMACDByCode三個方法和CalBuyPointByMACD.py範例程序中的代碼完全一致,所以本節僅僅是給出了這些方法的定義,不再重複講述了。

    在第14行中通過調用getMACDByCode方法,獲取了600460(士蘭微)的交易數據,其中包含了MACD指標數據。在第16行到第26行的while循環中通過遍歷stockDf對象,計算賣點。

    具體的步驟是,通過第17行的if條件語句排除了誤差比較大的數據,隨後通過第20行的if語句判斷當天是否出現了DIF死叉的情況,即前一個交易日的DIF比DEA大,但當前交易日DIF比DEA小。

    當滿足這個條件時,再通過第22行的if語句判斷當天的Bar柱數值是否小於前一天的,即判斷Bar柱是否在向下運動。當滿足這兩個條件時,通過第23行的代碼輸出建議賣出股票的日期。運行這個範例程序代碼後,可看到如下輸出的賣點。

    Sell Point by MACD on:2018-10-11

    Sell Point by MACD on:2018-11-29

    Sell Point by MACD on:2018-12-06

    Sell Point by MACD on:2019-02-28

    Sell Point by MACD on:2019-04-04

再修改前文提到的DrawKwithMACD.py範例程序,把股票代碼改爲600460,把股票名稱改成“士蘭微”,運行後即可看到如圖所示的結果圖。

     圖  股票“士蘭微”的K線、均線整合MACD的走勢圖

    再根據價格走勢,在表中列出了各賣點的確認情況。

表  基於MACD得到的賣點情況確認表

賣點

對賣點的分析

正確性

2018-10-11

1. 該日出現DIF死叉,且DIF和DEA均在x軸下方,Bar由紅轉綠,且綠柱持續擴大。

2. 雖然能驗證該點附近處於弱勢,但由於此點已經處於弱勢,所以後市價位跌幅不大。

不明確

2018-11-29

1. 在DIF和DEA上行過程中出現死叉。

2. Bar柱從紅轉綠,後市股價有一定幅度的下跌。

正確

2018-12-06

在11月29日的賣點基礎上,再次出現死叉,且Bar柱沒有向上運動的趨勢,所以進一步確認了弱勢行情,果然後市股價有一定幅度的下跌。

正確

2019-02-28

1. 雖然出現死叉,但前後幾天DIF和DEA均在向上運動。這說明強勢並沒有結束。

2. Bar柱雖然變綠,但變綠的幅度非常小。

3. 後市價格不是下跌,而是上漲了。

不正確

2019-04-04

1. DIF和DEA在x軸上方出現死叉,說明強勢行情有可能即將結束。

2. Bar柱由紅開始轉綠。

3. 後市價位出現一波短暫反彈,這可以理解成強勢的結束,之後出現下跌,且下跌幅度不小。

正確

    從上述的驗證結果可知,從MACD指標中能看出股價發展的趨勢,當從強勢開始轉弱時,如果沒有其他利好消息,可以考慮觀望或適當賣出股票。

    在通過MACD指標確認趨勢時,應當從DIF和DEA的數值、運動趨勢(即金叉或死叉的情況)和Bar柱的運動趨勢等方面綜合評判,而不能簡單割裂地通過單個因素來考慮。

    並且,影響股價的因素非常多,在選股時,應當從資金面、消息面和指標的技術面等因素綜合考慮,哪怕在指標的技術面,也應當結合多項技術指標綜合考慮。如前文所述,單個指標難免出現盲點,當遇到盲點時就有可能出現風險而誤判。

7 總結和版權說明

    上述內容是摘自我的書,《基於股票大數據分析的Python入門實戰 視頻教學版》,京東鏈接:https://item.jd.com/69241653952.html

    

    在我的博客裏,也有其它相關介紹本書的文章,鏈接如下。

 向大家介紹我的新書:《基於股票大數據分析的Python入門實戰》 

 通過機器學習的線性迴歸算法預測股票走勢(用Python實現)    

 在我的新書裏,嘗試着用股票案例講述Python爬蟲大數據可視化等知識  

 以股票RSI指標爲例,學習Python發送郵件功能(含RSI指標確定賣點策略) 

 以預測股票漲跌案例入門基於SVM的機器學習

  用python的matplotlib和numpy庫繪製股票K線均線和成交量的整合效果(含量化驗證交易策略代碼)

  用python的matplotlib和numpy庫繪製股票K線均線的整合效果(含從網絡接口爬取數據和驗證交易策略代碼)

 

    本文可轉載,但請標明出處,同時請全文轉載,別根據自身需要在轉載時惡意刪改本文

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章