由於本科在校期間身邊有許多朋友是金融專業的,他們時長在我耳邊談起股票情況,受他們影響,耳濡目染地對證券時長有了興趣。畢業前幾個月找實習單位時,又機緣巧合地在這方面工作了一段時間,學習了證券交易的各種理論(道氏理論、日本蠟燭圖技術、波浪理論等),雖然后期轉行做了本專業工作(數據挖掘),但對證券交易這塊一直在關注。閑來無事就用Python來實現了一下蠟燭圖,話不多說,直接上代碼:
# 導入需要的包和模塊 import datetime import pandas as pd import tushare as ts # 該模塊是一個免費提供股票交易數據的API
# 我們將看看從2016年1月1日開始過去一年的股票價格
start = datetime.date(2016,1,1)
end = datetime.date.today()
# 得到國金證券公司的股票數據;股票代碼是600109
# 第一個參數是獲取股票數據的股票代碼串,第二個參數是開始日期,第三個參數是結束日期
guojin = ts.get_h_data('600109',str(start),str(end),'qfq')
type(guojin)
guojin.head()
得到股票數據如下:

# 可視化股票數據 import matplotlib as mlp import matplotlib.pyplot as plt %matplotlib inline %pylab inline
mlp.rcParams['figure.figsize'] = (15,9)
guojin['close'].plot(grid=True)
得到國金證券2015-2016年的收盤價走勢情況:

# 導入畫圖蠟燭圖所需模塊
from matplotlib.dates import DateFormatter
from matplotlib.dates import WeekdayLocator
from matplotlib.dates import MONDAY
from matplotlib.dates import DayLocator
from matplotlib.finance import candlestick_ohlc
# 定義畫圖函數
def pandas_candlestick_ohlc(dat,stick='day',otherseries=None):
"""
參數dat:pandas DataFrame對象采用datetime64指數,和浮點數列
“開盤價”,“最高價”,“收盤價”,“最低價”
參數stick:一個字符串或數字只是的時間段覆蓋單一的蠟桿。有效
地字符串輸入包括“day”,“week”,“month”,“year”(默認是day)
和任何數字輸入,該數字表明一段時間內包括的交易日
參數otherseries:一個可迭代的,它將被強制轉換為一個列表,包含dat包
含的其他series將被回執為線條的列
這將顯示一個存儲在dat中的股票數據的日本蠟燭K線圖
"""
mondays = WeekdayLocator(MONDAY) # 每周一的主要刻度
alldays = DayLocator() # 每周日的次要此刻度
dayFormatter = DateFormatter("%d")
# 創建一個新的DataFrame,包含按色呼入制定的每個階段的OHLC數據
transdat = dat.loc[:,["open","high","low","close"]]
if type(stick) == str:
if stick == "day":
plotdat = transdat
stick = 1
elif stick in ['week','month','year']:
if stick == 'week':
transdat['week'] = pd.to_datetime(transdat.index).map(
lambda x: x.isocalendar()[1]) #確定周
elif stick == 'month':
transdat['month'] = pd.to_datetime(transdat.index).map(
lambda x: x.month) # 確定月
transdat['year'] = pd.to_datetime(transdat.index).map(
lambda x: x.isocalendar()[0]) # 確定年
# 按年和其他適當變量分組
grouped = transdat.groupby(list(set(['year',stick])))
# 創建將要包含繪圖的空數據框
plotdat = pd.DataFrame({"open":[],"high":[],"low":[],"close":[]})
for name, group in grouped:
plotdat = plotdat.append(pd.DataFrame({"open":group.iloc[0,0],
"high":max(group.high),
"low":min(group.low),
"close":group.iloc[-1,3]},
index = [group.index[0]]))
if stick == "weed":
stick = 5
elif stick == "month":
stick = 30
elif stick == "year":
stick = 365
elif type(stick) == int and stick >=1:
transdat["stick"] = [np.float(i/stick) for i in range(len(transdat.index))]
grouped = transdat.groupby("stick")
# 創建將要包含繪圖的空數據框
plotdat = pd.DataFrame({"open":[],"high":[],"low":[],"close":[]})
grouped = transdat.groupby('stick')
for name,group in grouped:
plotdat = plotdat.append(pd.DataFrame({"open": group.iloc[0,0],
"high": max(group.high),
"low": min(group.low),
"close": group.iloc[-1,3]},
index = [group.index[0]]))
else:
raise ValueError('Valid inputs to argument "stick" include the\
strings "day","week","month","year",or a positive integer')
# 設置plot參數,包括用繪制的軸線對象ax
fig, ax = plt.subplots()
fig.subplots_adjust(bottom=0.2)
if plotdat.index[-1] - plotdat.index[0] < pd.Timedelta('730 days'):
weekFormatter = DateFormatter("%b %d") # 例如,1月12
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)
# 創建K線圖
candlestick_ohlc(ax,list(zip(list(date2num(plotdat.index.tolist())),
plotdat["open"].tolist(),
plotdat["high"].tolist(),
plotdat["low"].tolist(),
plotdat["close"].tolist())),
colorup = "black",colordown='red')
# 繪制其他series(如移動平均線)作為線
if otherseries != None:
if type(otherseries) != list:
otherseries = [otherseries]
dat.loc[:,otherseries].plot(ax=ax,lw=1.3,grid=True)
ax.xaxis_date()
ax.autoscale_view()
plt.setp(plt.gca().get_xticklabels(),rotation=45,
horizontalalignment='right')
plt.show()
下面調用該函數,輸出結果:
pandas_candlestick_ohlc(guojin)

該圖看起來和商用交易軟件顯示結果差不多,但還是存在些問題,如圖像中對於未開盤日期K線不連續,不能縮放等,后期繼續加以改進。
