用Python淺析股票數(shù)據(jù)

本文將使用Python來可視化股票數(shù)據(jù),比如繪制K線圖,并且探究各項指標(biāo)的含義和關(guān)系,最后使用移動平均線方法初探投資策略。

數(shù)據(jù)導(dǎo)入

這里將股票數(shù)據(jù)存儲在stockData.txt文本文件中讶舰,我們使用pandas.read_table()函數(shù)將文件數(shù)據(jù)讀入成DataFrame格式。

其中參數(shù)usecols=range(15)限制只讀取前15列數(shù)據(jù)需了,parse_dates=[0]表示將第一列數(shù)據(jù)解析成時間格式跳昼,index_col=0則將第一列數(shù)據(jù)指定為索引。

import?pandas?as?pd

import?numpy?as?np

import?matplotlib.pyplot?as?plt

%matplotlib?inline

%config?InlineBackend.figure_format?=?'retina'

%pylab?inline

pylab.rcParams['figure.figsize']?=?(10,?6)?#設(shè)置繪圖尺寸

#讀取數(shù)據(jù)

stock?=?pd.read_table('stockData.txt',?usecols=range(15),?parse_dates=[0],?index_col=0)

stock?=?stock[::-1]#逆序排列

stock.head()

以上顯示了前5行數(shù)據(jù)肋乍,要得到數(shù)據(jù)的更多信息鹅颊,可以使用.info()方法。它告訴我們該數(shù)據(jù)一共有20行墓造,索引是時間格式挪略,日期從2015年1月5日到2015年1月30日√显溃總共有14列杠娱,并列出了每一列的名稱和數(shù)據(jù)格式,并且沒有缺失值谱煤。

stock.info()


DatetimeIndex:?20?entries,?2015-01-05?to?2015-01-30

Data?columns?(total?14?columns):

open20?non-null?float64

high20?non-null?float64

close?20?non-null?float64

low?20?non-null?float64

volume20?non-null?float64

price_change20?non-null?float64

p_change20?non-null?float64

ma5?20?non-null?float64

ma1020?non-null?float64

ma2020?non-null?float64

v_ma5?20?non-null?float64

v_ma1020?non-null?float64

v_ma2020?non-null?float64

turnover20?non-null?float64

dtypes:?float64(14)

memory?usage:?2.3?KB

在觀察每一列的名稱時摊求,我們發(fā)現(xiàn)’open’的列名前面似乎與其它列名不太一樣,為了更清楚地查看刘离,使用.columns得到該數(shù)據(jù)所有的列名如下:

stock.columns


Index(['????open',?'high',?'close',?'low',?'volume',?'price_change',

?'p_change',?'ma5',?'ma10',?'ma20',?'v_ma5',?'v_ma10',?'v_ma20',

?'turnover'],

dtype='object')

于是發(fā)現(xiàn)’open’列名前存在多余的空格室叉,我們使用如下方法修正列名睹栖。


stock.rename(columns={'????open':'open'},?inplace=True)

至此,我們完成了股票數(shù)據(jù)的導(dǎo)入和清洗工作茧痕,接下來將使用可視化的方法來觀察這些數(shù)據(jù)野来。

數(shù)據(jù)觀察

首先,我們觀察數(shù)據(jù)的列名踪旷,其含義對應(yīng)如下:

openhighcolselowvolumeprice_changep_change

開盤價最高價收盤價最低價成交量價格變動漲跌幅

ma5ma10ma20v_ma5v_ma10v_ma20turnover

5日均價10日均價20日均價5日均量10日均量20日均量換手率

這些指標(biāo)總體可分為兩類:

價格相關(guān)指標(biāo)

當(dāng)日價格:開盤曼氛、收盤價,最高令野、最低價

價格變化:價格變動和漲跌幅

均價:5舀患、10、20日均價

成交量相關(guān)指標(biāo)

成交量

換手率:成交量/發(fā)行總股數(shù)×100%

成交量均量:5气破、10聊浅、20日均量

由于這些指標(biāo)都是隨時間變化的,所以讓我們先來觀察它們的時間序列圖现使。

時間序列圖

以時間為橫坐標(biāo)低匙,每日的收盤價為縱坐標(biāo),做折線圖碳锈,可以觀察股價隨時間的波動情況努咐。這里直接使用DataFrame數(shù)據(jù)格式自帶的做圖工具,其優(yōu)點是能夠快速做圖殴胧,并自動優(yōu)化圖形輸出形式。



stock['close'].plot(grid=True)



如果我們將每日的開盤佩迟、收盤價和最高团滥、最低價以折線的形式繪制在一起,難免顯得凌亂报强,也不便于分析灸姊。那么有什么好的方法能夠在一張圖中顯示出這四個指標(biāo)?答案下面揭曉秉溉。

K線圖

相傳K線圖起源于日本德川幕府時代力惯,當(dāng)時的商人用此圖來記錄米市的行情和價格波動,后來K線圖被引入到股票市場召嘶。每天的四項指標(biāo)數(shù)據(jù)用如下蠟燭形狀的圖形來記錄父晶,不同的顏色代表漲跌情況。

圖片來源:http://wiki.mbalib.com/wiki/K線理論

Matplotlib.finance模塊提供了繪制K線圖的函數(shù)candlestick_ohlc()弄跌,但如果要繪制比較美觀的K線圖還是要下點功夫的甲喝。下面定義了pandas_candlestick_ohlc()函數(shù)來繪制適用于本文數(shù)據(jù)的K線圖,其中大部分代碼都是在設(shè)置坐標(biāo)軸的格式铛只。


from?matplotlib.finance?import?candlestick_ohlc

from?matplotlib.dates?import?DateFormatter,?WeekdayLocator,?DayLocator,?MONDAY


def?pandas_candlestick_ohlc(stock_data,?otherseries=None):????


# 設(shè)置繪圖參數(shù)埠胖,主要是坐標(biāo)軸

mondays?=?WeekdayLocator(MONDAY)

alldays?=?DayLocator()??

dayFormatter?=?DateFormatter('%d')


fig,?ax?=?plt.subplots()

fig.subplots_adjust(bottom=0.2)

if?stock_data.index[-1]?-?stock_data.index[0]?<?pd.Timedelta('730 days'):

weekFormatter?=?DateFormatter('%b %d')??

ax.xaxis.set_major_locator(mondays)

ax.xaxis.set_minor_locator(alldays)

else:

weekFormatter?=?DateFormatter('%b %d, %Y')

ax.xaxis.set_major_formatter(weekFormatter)

ax.grid(True)

# 創(chuàng)建K線圖??

stock_array?=?np.array(stock_data.reset_index()[['date','open','high','low','close']])

stock_array[:,0]?=?date2num(stock_array[:,0])

candlestick_ohlc(ax,?stock_array,?colorup?=?"red",?colordown="green",?width=0.4)

# 可同時繪制其他折線圖

if?otherseries?is?not?None:

for?each?in?otherseries:

plt.plot(stock_data[each],?label=each)????????????

plt.legend()


ax.xaxis_date()

ax.autoscale_view()

plt.setp(plt.gca().get_xticklabels(),?rotation=45,?horizontalalignment='right')

plt.show()


pandas_candlestick_ohlc(stock)


這里紅色代表上漲糠溜,綠色代表下跌。

相對變化量

股票中關(guān)注的不是價格的絕對值直撤,而是相對變化量非竿。有多種方式可以衡量股價的相對值,最簡單的方法就是將股價除以初始時的價格谋竖。

stock['return']?=?stock['close']?/?stock.close.iloc[0]

stock['return'].plot(grid=True)

第二種方法是計算每天的漲跌幅红柱,但計算方式有兩種:

這兩者可能導(dǎo)致不同的分析結(jié)果,樣例數(shù)據(jù)中的漲跌幅使用的是第一個公式圈盔,并乘上了100%豹芯。

stock['p_change'].plot(grid=True).axhline(y=0,?color='black',?lw=2)

為了解決第二種方法中的兩難選擇,我們引入第三種方法驱敲,就是計算價格的對數(shù)之差铁蹈,公式如下:

close_price?=?stock['close']

log_change?=?np.log(close_price)?-?np.log(close_price.shift(1))

log_change.plot(grid=True).axhline(y=0,?color='black',?lw=2)

相關(guān)關(guān)系

在觀察了價格的走勢之后,我們來看看各指標(biāo)之間的關(guān)系众眨。下面挑選了部分代表性的指標(biāo)握牧,并使用pandas.scatter_matrix()函數(shù),將各項指標(biāo)數(shù)據(jù)兩兩關(guān)聯(lián)做散點圖娩梨,對角線是每個指標(biāo)數(shù)據(jù)的直方圖沿腰。

small?=?stock[['close',?'price_change',?'ma20','volume',?'v_ma20',?'turnover']]

_?=?pd.scatter_matrix(small)

圖中可以明顯發(fā)現(xiàn)成交量(volume)和換手率(turnover)有非常明顯的線性關(guān)系,其實換手率的定義就是:成交量除以發(fā)行總股數(shù)狈定,再乘以100%颂龙。所以下面的分析中我們將換手率指標(biāo)去除,這里使用了相關(guān)性關(guān)系來實現(xiàn)數(shù)據(jù)降維纽什。

上面的散點圖看著有些眼花繚亂措嵌,我們可以使用numpy.corrcof()來直接計算各指標(biāo)數(shù)據(jù)間的相關(guān)系數(shù)。

small?=?stock[['close',?'price_change',?'ma20','volume',?'v_ma20']]

cov?=?np.corrcoef(small.T)

cov


array([[?1.,0.30308764,0.10785519,0.91078009,?-0.37602193],

?[?0.30308764,1.,?-0.45849273,0.3721832?,?-0.25950305],

?[?0.10785519,?-0.45849273,1.,?-0.06002202,0.51793654],

?[?0.91078009,0.3721832?,?-0.06002202,1.,?-0.37617624],

?[-0.37602193,?-0.25950305,0.51793654,?-0.37617624,1.]])

如果覺得看數(shù)字還是不夠方便芦缰,我們繼續(xù)將上述相關(guān)性矩陣轉(zhuǎn)換成圖形企巢,如下圖所示,其中用顏色來代表相關(guān)系數(shù)让蕾。我們發(fā)現(xiàn)位于(0浪规,3)位置的相關(guān)系數(shù)非常大,查看數(shù)值達到0.91探孝。這兩個強烈正相關(guān)的指標(biāo)是收盤價和成交量笋婿。

img?=?plt.matshow(cov,cmap=plt.cm.winter)

plt.colorbar(img,?ticks=[-1,0,1])

plt.show()

以上我們用矩陣圖表的方式在多個指標(biāo)中迅速找到了強相關(guān)的指標(biāo)。接著做出收盤價和成交量的折線圖顿颅,因為它們的數(shù)值差異很大萌抵,所以我們采用兩套縱坐標(biāo)體系來做圖。

1stock[['close','volume']].plot(secondary_y='volume',?grid=True)

觀察這兩個指標(biāo)的走勢,在大部分時候股價上漲绍填,成交量也上漲霎桅,反之亦然。但個別情況下則不成立讨永,可能是成交量受到前期的慣性影響滔驶,或者還有其他因素。

移動平均線

吳軍老師曾講述他的投資經(jīng)驗卿闹,大意是說好的投資方式不是做預(yù)測揭糕,而是能在合適的時機做出合適的應(yīng)對和決策。同樣股市也沒法預(yù)測锻霎,我們能做的是選擇恰當(dāng)?shù)牟呗詰?yīng)對不同的情況著角。

好的指標(biāo)是能驅(qū)動決策的吏口。在上面的分析中我們一直沒有使用的一類指標(biāo)是5、10产徊、20日均價,它們又稱為移動平均值舟铜,下面我們就使用這項指標(biāo)來演示一個簡單的股票交易策略。(警告:這里僅僅是演示說明谆刨,并非投資建議。

為了得到更多的數(shù)據(jù)來演示痊夭,我們使用pandas_datareader直接從雅虎中下載最近一段時間的谷歌股票數(shù)據(jù)。

import?datetime

import?pandas_datareader.data?as?web

# 設(shè)置股票數(shù)據(jù)的時間跨度

start?=?datetime.datetime(2016,10,1)

end?=?datetime.date.today()

# 從yahoo中獲取google的股價數(shù)據(jù)。

goog?=?web.DataReader("GOOG",?"yahoo",?start,?end)

#修改索引和列的名稱难捌,以適應(yīng)本文的分析

goog.index.rename('date',?inplace=True)

goog.rename(columns={'Open':'open',?'High':'high',?'Low':'low',?'Close':'close'},?inplace=True)

goog.head()

數(shù)據(jù)中只有每天的價格和成交量膝宁,所以我們需要自己算出5日均價和10日均價,并將均價的折線圖(也稱移動平均線)與K線圖畫在一起根吁。

goog["ma5"]?=?np.round(goog["close"].rolling(window?=?5,?center?=?False).mean(),?2)

goog["ma20"]?=?np.round(goog["close"].rolling(window?=?20,?center?=?False).mean(),?2)

goog?=?goog['2017-01-01':]

pandas_candlestick_ohlc(goog,?['ma5','ma20'])

觀察上圖员淫,我們發(fā)現(xiàn)5日均線與K線圖較為接近,而20日均線則更平坦击敌,可見移動平均線具有抹平短期波動的作用介返,更能反映長期的走勢。比較5日均線和20日均線,特別是關(guān)注它們的交叉點圣蝎,這些是交易的時機刃宵。移動平均線策略,最簡單的方式就是:當(dāng)5日均線從下方超越20日均線時徘公,買入股票牲证,當(dāng)5日均線從上方越到20日均線之下時,賣出股票关面。

為了找出交易的時機坦袍,我們計算5日均價和20日均價的差值,并取其正負號等太,作于下圖捂齐。當(dāng)圖中水平線出現(xiàn)跳躍的時候就是交易時機。

goog['ma5-20']?=?goog['ma5']?-?goog['ma20']

goog['diff']?=?np.sign(goog['ma5-20'])

goog['diff'].plot(ylim=(-2,2)).axhline(y=0,?color='black',?lw=2)

為了更方便觀察缩抡,上述計算得到的均價差值奠宜,再取其相鄰日期的差值,得到信號指標(biāo)缝其。當(dāng)信號為1時挎塌,表示買入股票;當(dāng)信號為-1時内边,表示賣出股票榴都;當(dāng)信號為0時,不進行任何操作漠其。

goog['signal']?=?np.sign(goog['diff']?-?goog['diff'].shift(1))

goog['signal'].plot(ylim=(-2,2))

從上圖中看出嘴高,從今年初到現(xiàn)在,一共有兩輪買進和賣出的時機和屎。到目前為止拴驮,似乎一切順利,那么讓我們看下這兩輪交易的收益怎么樣吧套啤。

trade?=?pd.concat([

pd.DataFrame({"price":?goog.loc[goog["signal"]?==?1,?"close"],

"operation":?"Buy"}),

pd.DataFrame({"price":?goog.loc[goog["signal"]?==?-1,?"close"],

"operation":?"Sell"})????

])

trade.sort_index(inplace=True)

trade

上述表格列出了交易日期潜沦、操作和當(dāng)天的價格唆鸡。但很遺憾地發(fā)現(xiàn)争占,這兩輪交易的賣出價都小于買入價,實際上按上述方法交易我們虧本了2蟆6号浴片效!

你是否很憤怒呢淀衣?原來分析到現(xiàn)在召调,都是假的呀唠叛!我之前就警告過,這里的分析只是演示移動平均線策略的思想册舞,而并非真正的投資建議调鲸。股票市場是何其的復(fù)雜多變挽荡,又如何是一個小小的策略所能戰(zhàn)勝的呢定拟?

那么這個策略就一無是處嗎?非也株依!如果考慮更長的時間跨度勺三,比如5年需曾、10年呆万,并考慮更長的均線,比如將20日均線和50日均線比較牡彻;雖然過程中也有虧損的時候庄吼,但贏的概率更大严就。也就是說梢为,在更長的時間尺度上該策略也是可行的铸董。但即使你賺了,又能跑贏大盤嗎蕴忆?這時候還需用到其他方法孽文,比如合理配置投資比例等芋哭。

還是那句話郁副,股市有風(fēng)險存谎,投資需謹慎既荚。本文不是分析股票的文章,而是借用股票數(shù)據(jù)來說明數(shù)據(jù)分析的基本方法句各,以及演示什么樣的指標(biāo)是好的指標(biāo)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市初厚,隨后出現(xiàn)的幾起案子产禾,更是在濱河造成了極大的恐慌,老刑警劉巖纽绍,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拌夏,死亡現(xiàn)場離奇詭異障簿,居然都是意外死亡站故,警方通過查閱死者的電腦和手機毅舆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進店門憋活,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人吮成,你說我怎么就攤上這事粱甫〔柘” “怎么了乌庶?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵安拟,是天一觀的道長糠赦。 經(jīng)常有香客問我拙泽,道長顾瞻,這世上最難降的妖魔是什么荷荤? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任蕴纳,我火速辦了婚禮古毛,結(jié)果婚禮上稻薇,老公的妹妹穿的比我還像新娘塞椎。我一直安慰自己睛低,他們只是感情好莺戒,可當(dāng)我...
    茶點故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布澄暮。 她就那樣靜靜地躺著,像睡著了一般麻惶。 火紅的嫁衣襯著肌膚如雪窃蹋。 梳的紋絲不亂的頭發(fā)上警没,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天杀迹,我揣著相機與錄音树酪,去河邊找鬼嗅回。 笑死摧茴,一個胖子當(dāng)著我的面吹牛苛白,可吹牛的內(nèi)容都是我干的懂版。 我是一名探鬼主播躯畴,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼蓬抄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了夯到?” 一聲冷哼從身側(cè)響起嚷缭,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后阅爽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體路幸,經(jīng)...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年付翁,在試婚紗的時候發(fā)現(xiàn)自己被綠了简肴。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,912評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡百侧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情频蛔,我是刑警寧澤挣跋,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布查库,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜强法,卻給世界環(huán)境...
    茶點故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一蓖墅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸配猫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間幽崩,已是汗流浹背蹄溉。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留瓢谢,地道東北人。 一個月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓淫痰,卻偏偏與公主長得像火俄,于是被迫代替她去往敵國和親玻熙。 傳聞我的和親對象是個殘疾皇子卸例,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,922評論 2 361

推薦閱讀更多精彩內(nèi)容