【量化笔记】使用python捕捉K线图形态

首先绘制K线图

import pandas as pd
ssec2015=pd.read_csv('ssec2015.csv')

ssec2015=ssec2015.iloc[:,1:]

ssec2015.head()
DateOpenHighLowCloseVolume
02015-03-023332.7209473336.7600103298.6689453336.284912346400
12015-03-033317.6950683317.6950683260.4289553263.052002382000
22015-03-043264.1818853286.5878913250.4838873279.532959293600
32015-03-053264.0849613266.6379393221.6660163248.476074320700
42015-03-063248.0358893266.9331053234.5329593241.187012282900
ssec2015.tail(n=3)
DateOpenHighLowCloseVolume
192015-03-273686.1340333710.4770513656.8310553691.095947408900
202015-03-303710.6120613795.9350593710.6120613786.568115564700
212015-03-313822.9870613835.5668953737.0429693747.898926561700
from matplotlib.dates import DateFormatter,WeekdayLocator,DayLocator,MONDAY,date2num

from datetime import datetime

ssec2015.Date=[date2num(datetime.strptime(date,"%Y-%m-%d")) for date in ssec2015.Date]

ssec15list
[Date      735659.000000
 Open        3332.720947
 High        3336.760010
 Low         3298.668945
 Close       3336.284912
 Volume    346400.000000
 Name: 0, dtype: float64, Date      735660.000000
 Open        3317.695068
 High        3317.695068
 Low         3260.428955
 Close       3263.052002
 Volume    382000.000000
 Name: 1, dtype: float64, Date      735661.000000
 Open        3264.181885
 High        3286.587891
 Low         3250.483887
 Close       3279.532959
 Volume    293600.000000
 Name: 2, dtype: float64, Date      735662.000000
 Open        3264.084961
 High        3266.637939
 Low         3221.666016
 Close       3248.476074
 Volume    320700.000000
 Name: 3, dtype: float64, Date      735663.000000
 Open        3248.035889
 High        3266.933105
 Low         3234.532959
 Close       3241.187012
 Volume    282900.000000
 Name: 4, dtype: float64, Date      735666.000000
 Open        3224.313965
 High        3307.701904
 Low         3198.370117
 Close       3302.407959
 Volume    321500.000000
 Name: 5, dtype: float64, Date      735667.000000
 Open        3289.084961
 High        3309.915039
 Low         3277.094971
 Close       3286.068115
 Volume    285800.000000
 Name: 6, dtype: float64, Date      735668.000000
 Open        3289.593994
 High        3325.053955
 Low         3278.470947
 Close       3290.899902
 Volume    283000.000000
 Name: 7, dtype: float64, Date      735669.000000
 Open        3314.812988
 High        3360.053955
 Low         3300.488037
 Close       3349.322998
 Volume    357300.000000
 Name: 8, dtype: float64, Date      735670.000000
 Open        3359.488037
 High        3391.254883
 Low         3352.149902
 Close       3372.910889
 Volume    328400.000000
 Name: 9, dtype: float64, Date      735673.000000
 Open        3391.157959
 High        3449.304932
 Low         3377.086914
 Close       3449.304932
 Volume    399100.000000
 Name: 10, dtype: float64, Date      735674.000000
 Open        3469.603027
 High        3504.123047
 Low         3459.694092
 Close       3502.846924
 Volume    520900.000000
 Name: 11, dtype: float64, Date      735675.000000
 Open        3510.500977
 High        3577.662109
 Low         3503.853027
 Close       3577.301025
 Volume    545200.000000
 Name: 12, dtype: float64, Date      735676.000000
 Open        3576.019043
 High        3600.684082
 Low         3546.843994
 Close       3582.270996
 Volume    537300.000000
 Name: 13, dtype: float64, Date      735677.000000
 Open        3587.083984
 High        3632.337891
 Low         3569.379883
 Close       3617.318115
 Volume    516700.000000
 Name: 14, dtype: float64, Date      735680.000000
 Open        3640.104004
 High        3688.249023
 Low         3635.485107
 Close       3687.728027
 Volume    536100.000000
 Name: 15, dtype: float64, Date      735681.000000
 Open        3692.569092
 High        3715.873047
 Low         3600.697998
 Close       3691.409912
 Volume    639600.000000
 Name: 16, dtype: float64, Date      735682.000000
 Open        3680.952881
 High        3693.150879
 Low         3634.559082
 Close       3660.727051
 Volume    521900.000000
 Name: 17, dtype: float64, Date      735683.000000
 Open        3641.941895
 High        3707.318115
 Low         3615.010986
 Close       3682.094971
 Volume    488600.000000
 Name: 18, dtype: float64, Date      735684.000000
 Open        3686.134033
 High        3710.477051
 Low         3656.831055
 Close       3691.095947
 Volume    408900.000000
 Name: 19, dtype: float64, Date      735687.000000
 Open        3710.612061
 High        3795.935059
 Low         3710.612061
 Close       3786.568115
 Volume    564700.000000
 Name: 20, dtype: float64, Date      735688.000000
 Open        3822.987061
 High        3835.566895
 Low         3737.042969
 Close       3747.898926
 Volume    561700.000000
 Name: 21, dtype: float64, Date      735659.000000
 Open        3332.720947
 High        3336.760010
 Low         3298.668945
 Close       3336.284912
 Volume    346400.000000
 Name: 0, dtype: float64, Date      735660.000000
 Open        3317.695068
 High        3317.695068
 Low         3260.428955
 Close       3263.052002
 Volume    382000.000000
 Name: 1, dtype: float64, Date      735661.000000
 Open        3264.181885
 High        3286.587891
 Low         3250.483887
 Close       3279.532959
 Volume    293600.000000
 Name: 2, dtype: float64, Date      735662.000000
 Open        3264.084961
 High        3266.637939
 Low         3221.666016
 Close       3248.476074
 Volume    320700.000000
 Name: 3, dtype: float64, Date      735663.000000
 Open        3248.035889
 High        3266.933105
 Low         3234.532959
 Close       3241.187012
 Volume    282900.000000
 Name: 4, dtype: float64, Date      735666.000000
 Open        3224.313965
 High        3307.701904
 Low         3198.370117
 Close       3302.407959
 Volume    321500.000000
 Name: 5, dtype: float64, Date      735667.000000
 Open        3289.084961
 High        3309.915039
 Low         3277.094971
 Close       3286.068115
 Volume    285800.000000
 Name: 6, dtype: float64, Date      735668.000000
 Open        3289.593994
 High        3325.053955
 Low         3278.470947
 Close       3290.899902
 Volume    283000.000000
 Name: 7, dtype: float64, Date      735669.000000
 Open        3314.812988
 High        3360.053955
 Low         3300.488037
 Close       3349.322998
 Volume    357300.000000
 Name: 8, dtype: float64, Date      735670.000000
 Open        3359.488037
 High        3391.254883
 Low         3352.149902
 Close       3372.910889
 Volume    328400.000000
 Name: 9, dtype: float64, Date      735673.000000
 Open        3391.157959
 High        3449.304932
 Low         3377.086914
 Close       3449.304932
 Volume    399100.000000
 Name: 10, dtype: float64, Date      735674.000000
 Open        3469.603027
 High        3504.123047
 Low         3459.694092
 Close       3502.846924
 Volume    520900.000000
 Name: 11, dtype: float64, Date      735675.000000
 Open        3510.500977
 High        3577.662109
 Low         3503.853027
 Close       3577.301025
 Volume    545200.000000
 Name: 12, dtype: float64, Date      735676.000000
 Open        3576.019043
 High        3600.684082
 Low         3546.843994
 Close       3582.270996
 Volume    537300.000000
 Name: 13, dtype: float64, Date      735677.000000
 Open        3587.083984
 High        3632.337891
 Low         3569.379883
 Close       3617.318115
 Volume    516700.000000
 Name: 14, dtype: float64, Date      735680.000000
 Open        3640.104004
 High        3688.249023
 Low         3635.485107
 Close       3687.728027
 Volume    536100.000000
 Name: 15, dtype: float64, Date      735681.000000
 Open        3692.569092
 High        3715.873047
 Low         3600.697998
 Close       3691.409912
 Volume    639600.000000
 Name: 16, dtype: float64, Date      735682.000000
 Open        3680.952881
 High        3693.150879
 Low         3634.559082
 Close       3660.727051
 Volume    521900.000000
 Name: 17, dtype: float64, Date      735683.000000
 Open        3641.941895
 High        3707.318115
 Low         3615.010986
 Close       3682.094971
 Volume    488600.000000
 Name: 18, dtype: float64, Date      735684.000000
 Open        3686.134033
 High        3710.477051
 Low         3656.831055
 Close       3691.095947
 Volume    408900.000000
 Name: 19, dtype: float64, Date      735687.000000
 Open        3710.612061
 High        3795.935059
 Low         3710.612061
 Close       3786.568115
 Volume    564700.000000
 Name: 20, dtype: float64, Date      735688.000000
 Open        3822.987061
 High        3835.566895
 Low         3737.042969
 Close       3747.898926
 Volume    561700.000000
 Name: 21, dtype: float64]
ssec15list=list()

for i in range(len(ssec2015)):
    ssec15list.append(ssec2015.iloc[i,:])
## 按照包
%pip install https://github.com/matplotlib/mpl_finance/archive/master.zip
Collecting https://github.com/matplotlib/mpl_finance/archive/master.zip
  Downloading https://github.com/matplotlib/mpl_finance/archive/master.zip
[K     \ 471kB 8.3kB/s
Requirement already satisfied: matplotlib in /Users/yaochenli/anaconda3/lib/python3.7/site-packages (from mpl-finance==0.10.0) (3.0.3)
Requirement already satisfied: numpy>=1.10.0 in /Users/yaochenli/anaconda3/lib/python3.7/site-packages (from matplotlib->mpl-finance==0.10.0) (1.16.2)
Requirement already satisfied: cycler>=0.10 in /Users/yaochenli/anaconda3/lib/python3.7/site-packages (from matplotlib->mpl-finance==0.10.0) (0.10.0)
Requirement already satisfied: kiwisolver>=1.0.1 in /Users/yaochenli/anaconda3/lib/python3.7/site-packages (from matplotlib->mpl-finance==0.10.0) (1.0.1)
Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /Users/yaochenli/anaconda3/lib/python3.7/site-packages (from matplotlib->mpl-finance==0.10.0) (2.3.1)
Requirement already satisfied: python-dateutil>=2.1 in /Users/yaochenli/anaconda3/lib/python3.7/site-packages (from matplotlib->mpl-finance==0.10.0) (2.8.0)
Requirement already satisfied: six in /Users/yaochenli/anaconda3/lib/python3.7/site-packages (from cycler>=0.10->matplotlib->mpl-finance==0.10.0) (1.12.0)
Requirement already satisfied: setuptools in /Users/yaochenli/anaconda3/lib/python3.7/site-packages (from kiwisolver>=1.0.1->matplotlib->mpl-finance==0.10.0) (40.8.0)
Building wheels for collected packages: mpl-finance
  Building wheel for mpl-finance (setup.py) ... [?25ldone
[?25h  Stored in directory: /private/var/folders/q9/2krqssqd16v76z26x_flv77m0000gn/T/pip-ephem-wheel-cache-rvgseok2/wheels/8f/bf/8a/6c858b2a3be945c7b2d658fbf6ab797b451d686cbee8aa2679
Successfully built mpl-finance
Installing collected packages: mpl-finance
Successfully installed mpl-finance-0.10.0
Note: you may need to restart the kernel to use updated packages.
from mpl_finance import candlestick_ohlc
import matplotlib.pyplot as plt
ax=plt.subplot()
mondays=WeekdayLocator(MONDAY)
weekFormatter = DateFormatter('%y %m %d')
ax.xaxis.set_major_locator(mondays)
ax.xaxis.set_minor_locator(DayLocator())
ax.xaxis.set_major_formatter(weekFormatter)
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
ax.set_title('201503 K plot')
candlestick_ohlc(ax,ssec15list,width=0.7,colorup='r',colordown='g')
#plt.setp(plt.gca().get_xticklabels(),rotation=50,horizontalalignment='center')
plt.show()

在这里插入图片描述

包装成函数

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter, WeekdayLocator,\
    DayLocator, MONDAY,date2num
#from matplotlib.finance import  candlestick_ohlc
import numpy as np


def candlePlot(seriesData,title="a"):
	#设定日期格式
    Date=[date2num(date) for date in seriesData.index]
    seriesData.loc[:,'Date']=Date
    listData=[]
    for i in range(len(seriesData)):
        a=[seriesData.Date[i],\
        seriesData.Open[i],seriesData.High[i],\
        seriesData.Low[i],seriesData.Close[i]]
        listData.append(a)

	#设定绘图相关参数
    ax = plt.subplot()
    mondays = WeekdayLocator(MONDAY)
    #日期格式为‘15-Mar-09’形式
    weekFormatter = DateFormatter('%y %b %d')
    ax.xaxis.set_major_locator(mondays)
    ax.xaxis.set_minor_locator(DayLocator())
    ax.xaxis.set_major_formatter(weekFormatter)

	#调用candlestick_ohlc函数
    candlestick_ohlc(ax,listData, width=0.7,\
                     colorup='r',colordown='g')
    ax.set_title(title) #设定标题
    #设定x轴日期显示角度
    plt.setp(plt.gca().get_xticklabels(), \
    rotation=50,horizontalalignment='center')
    return(plt.show())

#蜡烛图与线图
def candleLinePlots(candleData, candleTitle='a', **kwargs):
    Date = [date2num(date) for date in candleData.index]
    candleData.loc[:,'Date'] = Date
    listData = []
    
    for i in range(len(candleData)):
        a = [candleData.Date[i],\
            candleData.Open[i],candleData.High[i],\
            candleData.Low[i],candleData.Close[i]]
        listData.append(a)
    # 如 果 不 定 长 参 数 无 取 值 , 只 画 蜡 烛 图
    ax = plt.subplot()
    
    # 如 果 不 定 长 参 数 有 值 , 则 分 成 两 个 子 图
    flag=0
    if kwargs:
        if kwargs['splitFigures']:
            ax = plt.subplot(211)
            ax2= plt.subplot(212)
            flag=1;
        # 如 果 无 参 数 splitFigures , 则 只 画 一 个 图 形 框
        # 如 果 有 参 数 splitFigures , 则 画 出 两 个 图 形 框
        
        for key in kwargs:
            if key=='title':
                ax2.set_title(kwargs[key])
            if key=='ylabel':
                ax2.set_ylabel(kwargs[key])
            if key=='grid':
                ax2.grid(kwargs[key])
            if key=='Data':
                plt.sca(ax)
                if flag:
                    plt.sca(ax2)
                    
                #一维数据
                if kwargs[key].ndim==1:
                    plt.plot(kwargs[key],\
                             color='k',\
                             label=kwargs[key].name)
                    plt.legend(loc='best')
                #二维数据有两个columns
                elif all([kwargs[key].ndim==2,\
                          len(kwargs[key].columns)==2]):
                    plt.plot(kwargs[key].iloc[:,0], color='k', 
                             label=kwargs[key].iloc[:,0].name)
                    plt.plot(kwargs[key].iloc[:,1],\
                             linestyle='dashed',\
                             label=kwargs[key].iloc[:,1].name)
                    plt.legend(loc='best')
    
    mondays = WeekdayLocator(MONDAY)
    weekFormatter = DateFormatter('%y %b %d')
    ax.xaxis.set_major_locator(mondays)
    ax.xaxis.set_minor_locator(DayLocator())
    ax.xaxis.set_major_formatter(weekFormatter)
    plt.sca(ax)
    
    candlestick_ohlc(ax,listData, width=0.7,\
                     colorup='r',colordown='g')
    ax.set_title(candleTitle)
    plt.setp(ax.get_xticklabels(),\
             rotation=20,\
             horizontalalignment='center')
    ax.autoscale_view()
    
    return(plt.show())

#蜡烛图与成交量柱状图
def candleVolume(seriesData,candletitle='a',bartitle='b'):
    Date=[date2num(date) for date in seriesData.index]
    seriesData.index=list(range(len(Date)))
    seriesData['Date']=Date
    listData=zip(seriesData.Date,seriesData.Open,seriesData.High,seriesData.Low,
                 seriesData.Close)
    ax1 = plt.subplot(211)
    ax2 = plt.subplot(212)
    for ax in ax1,ax2:
        mondays = WeekdayLocator(MONDAY)
        weekFormatter = DateFormatter('%m/%d/%Y')
        ax.xaxis.set_major_locator(mondays)
        ax.xaxis.set_minor_locator(DayLocator())
        ax.xaxis.set_major_formatter(weekFormatter)
        ax.grid(True)

    ax1.set_ylim(seriesData.Low.min()-2,seriesData.High.max()+2)
    ax1.set_ylabel('蜡烛图及收盘价线')
    candlestick_ohlc(ax1,listData, width=0.7,colorup='r',colordown='g')
    plt.setp(plt.gca().get_xticklabels(),\
            rotation=45,horizontalalignment='center')
    ax1.autoscale_view()
    ax1.set_title(candletitle)
    ax1.plot(seriesData.Date,seriesData.Close,\
               color='black',label='收盘价')
    ax1.legend(loc='best')

    ax2.set_ylabel('成交量')
    ax2.set_ylim(0,seriesData.Volume.max()*3)
    ax2.bar(np.array(Date)[np.array(seriesData.Close>=seriesData.Open)]
    ,height=seriesData.iloc[:,4][np.array(seriesData.Close>=seriesData.Open)]
    ,color='r',align='center')
    ax2.bar(np.array(Date)[np.array(seriesData.Close<seriesData.Open)]
    ,height=seriesData.iloc[:,4][np.array(seriesData.Close<seriesData.Open)]
    ,color='g',align='center')
    ax2.set_title(bartitle)
    return(plt.show())

用Python捕捉K线图的形态

# 早晨之星
# 获取上证指数2012的日度交易数据
ssec2012=pd.read_csv('ssec2012.csv')
ssec2012.index=ssec2012.iloc[:,1]
ssec2012.index=pd.to_datetime(ssec2012.index,format='%Y-%m-%d')
ssec2012=ssec2012.iloc[:,2:]

ssec2012.head(2)
OpenHighLowCloseVolume
Date
2012-01-042211.9951172217.5200202168.6440432169.38989349200
2012-01-052160.8969732183.4040532145.5559082148.45190458800
# 提取收盘数据
Close=ssec2012.Close
# 提取开盘数据
Open=ssec2012.Open
# 计算每个交易日收盘价与开盘价之间差值
ClOp=Close-Open
ClOp.head()
Date
2012-01-04   -42.605224
2012-01-05   -12.445069
2012-01-06    15.248047
2012-01-09    61.148926
2012-01-10    63.911865
dtype: float64
ClOp.describe()
count    243.000000
mean       2.244368
std       22.884043
min      -73.685059
25%      -11.442016
50%        1.513183
75%       14.296997
max       91.843994
dtype: float64
# 捕捉绿色实体,十字形和红色实体
Shape=[0,0,0]

lag1ClOp=ClOp.shift(1)
lag2ClOp=ClOp.shift(2)

for i in range (3,len(ClOp)):
    if all([lag2ClOp[i]<-11, abs(lag1ClOp[i])<2, ClOp[i]>6, abs(ClOp[i])>abs(lag2ClOp[i]*0.5)]):
        Shape.append(1)
    else:
        Shape.append(0)
        
Shape.index(1)
165
# 定义十字星的位置,十字形实体要在其前后绿色实体和红色实体的下方
lagOpen=Open.shift(1)
lagClose=Close.shift(1)
lag2Close=Close.shift(2)
# 捕捉符合十字形位置的蜡烛图
Doji=[0,0,0]
for i in range(3, len(Open),1):
    if all([lagOpen[i]<Open[i],lagOpen[i]<lag2Close[i],lagClose[i]<Open[i],lagClose[i]<lag2Close[i]]):
        Doji.append(1)
    else:
        Doji.append(0)
Doji.count(1)
12
# 定义下跌趋势
ret = Close/Close.shift(1)-1
lag1ret=ret.shift(1)
lag2ret=ret.shift(2)
# 寻找向下趋势
Trend=[0,0,0]
for i in range(3,len(ret)):
    if all([lag1ret[i]<0,lag2ret[i]<0]):
        Trend.append(1)
    else:
        Trend.append(0)
# 综合三个条件
StarSig=[]
for i in range(len(Trend)):
    if all([Shape[i]==1,Doji[i]==1,Trend[i]==1]):
        StarSig.append(1)
    else:
        StarSig.append(0)
#输出2012年出现早晨之星形态的日期
for i in range(len(StarSig)):
    if StarSig[i]==1:
        print(ssec2012.index[i])
2012-09-06 00:00:00
#绘制9月6日附近的K线图
ssec201209 = ssec2012['2012-08-21':'2012-09-30']
candlePlot(ssec201209,title='201209 K Plot')
/Users/yaochenli/anaconda3/lib/python3.7/site-packages/pandas/core/indexing.py:362: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  self.obj[key] = _infer_fill_value(value)
/Users/yaochenli/anaconda3/lib/python3.7/site-packages/pandas/core/indexing.py:543: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  self.obj[item] = s

在这里插入图片描述

用Python捕捉乌云盖顶形态

import pandas as pd
ssec2011=pd.read_csv('ssec2011.csv')
ssec2011.index=ssec2011.iloc[:,1]
ssec2011.index=pd.to_datetime(ssec2011.index,format='%Y-%m-%d')
ssec2011=ssec2011.iloc[:,2:]
ssec2011.head()
OpenHighLowCloseVolume
Date
2011-01-042825.3291022855.3959962810.1079102852.647949110000.0
2011-01-052833.1159672850.4929202824.2958982839.220947104400.0
2011-01-062838.4350592853.8750002816.9509282824.19702184800.0
2011-01-072820.6650392868.0048832807.8701172838.801025113200.0
2011-01-102832.6220702847.3579102786.8610842791.80908290800.0
#提取价格数据
Close11=ssec2011.Close
Open11=ssec2011.Open
# 刻画捕捉符合乌云盖顶形态的两个连续蜡烛实体
lagClose11=Close11.shift(1)
lagOpen11 =Open11.shift(1)
Cloud=pd.Series(0,index=Close11.index)
for i in range(1,len(Close11)):
    if all([Close11[i]<Open11[i],lagClose11[i]>lagOpen11[i],\
           Open11[i]>lagClose11[i],\
           Close11[i]<0.5*(lagClose11[i]+lagOpen11[i]),\
           Close11[i]>lagOpen11[i]]):
        Cloud[i]=1

#定义前期上升趋势
Trend=pd.Series(0,index=Close11.index)
for i in range(2,len(Close)):
    if Close11[i-1]>Close11[i-2]>Close11[i-3]:
        Trend[i]=1
#寻找乌云盖顶形态
darkCloud=Cloud+Trend
darkCloud[darkCloud==2]
Date
2011-05-19    2
2011-08-16    2
dtype: int64
#绘制5月19日附近K线图
ssec201105=ssec2011['2011-05-01':'2011-05-30']
candlePlot(ssec201105, title='201105 K Plot')
/Users/yaochenli/anaconda3/lib/python3.7/site-packages/pandas/core/indexing.py:635: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  self.obj[item_labels[indexer[info_axis]]] = value

在这里插入图片描述

# 绘制8月16日前后的K线图
ssec201108=ssec2011['2011-08-01':'2011-08-31']
candlePlot(ssec201108,title='201108 K Plot')

在这里插入图片描述


版权声明:本文为yao09605原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。