运维开发网

Python量化交易-MA/MACD

运维开发网 https://www.qedev.com 2021-04-08 21:06 出处:51CTO 作者:mob604756f5460a
移动均线(MA,Moving-AverageModel)当天累计的股票平均成交价格,然后将每天成交的平均价格连成线。算术平均:MA=(C1+C2+C3+C4+C5+…+Cn)/N指数平均:EMA(N)=2X/(N+1)+(N-1)EMA(N-1)/(N+1)MACD称为异同移动平均线,是从双指数移动平均线发展而来的。快的指数移动平均线(EMA12)减去慢的指数移动平均线(EMA26)得到快线DIF

Python量化交易-MA/MACD

移动均线(MA,Moving-AverageModel)

当天累计的股票平均成交价格,然后将每天成交的平均价格连成线。

算术平均:MA=(C1+C2+C3+C4+C5+…+Cn ) / N

指数平均:EMA(N)=2X/(N+1)+(N-1)EMA(N-1)/(N+1)

MACD称为异同移动平均线,是从双指数移动平均线发展而来的。

快的指数移动平均线(EMA12)减去慢的指数移动平均线(EMA26)得到快线DIF,再用2×(快线DIF-DIF的9日加权移动均线DEA)得到MACD柱。

具体的实现代码如下:

def moving_average(x, n, type='simple'):
    """
    compute an n period moving average.

    type is 'simple' | 'exponential'

    """
    x = np.asarray(x)
    if type == 'simple':
        weights = np.ones(n)
    else:
        weights = np.exp(np.linspace(-1., 0., n))
    weights /= weights.sum()
    a = np.convolve(x, weights, mode='full')[:len(x)]
    a[:n] = a[n]
    return a
def moving_average_convergence(x, nslow=26, nfast=12):

    emaslow = moving_average(x, nslow, type='exponential')
    emafast = moving_average(x, nfast, type='exponential')
    return emaslow, emafast, emafast - emaslow

使用matlibplot画出来的代码如下:

import matplotlib.dates as mdates
import matplotlib.font_manager as font_manager
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import numpy as np
import pandas as pd
import tushare as ts

# ticker = 'SPY'
# r = pd.read_csv('data/yahoofinance-SPY-20080101-20180101.csv',
#                 index_col=0,
#                 parse_dates=True,
#                 infer_datetime_format=True)

def moving_average(x, n, type='simple'):
    """
    compute an n period moving average.

    type is 'simple' | 'exponential'

    """
    x = np.asarray(x)
    if type == 'simple':
        weights = np.ones(n)
    else:
        weights = np.exp(np.linspace(-1., 0., n))
    weights /= weights.sum()
    a = np.convolve(x, weights, mode='full')[:len(x)]
    a[:n] = a[n]
    return a

def relative_strength(prices, n=14):
    """
    compute the n period relative strength indicator
    """
    deltas = np.diff(prices)
    seed = deltas[:n + 1]
    up = seed[seed >= 0].sum() / n
    down = -seed[seed < 0].sum() / n
    rs = up / down
    rsi = np.zeros_like(prices)
    rsi[:n] = 100. - 100. / (1. + rs)
    for i in range(n, len(prices)):
        delta = deltas[i - 1]  # cause the diff is 1 shorter
        if delta > 0:
            upval = delta
            downval = 0.
        else:
            upval = 0.
            downval = -delta
        up = (up * (n - 1) + upval) / n
        down = (down * (n - 1) + downval) / n
        rs = up / down
        rsi[i] = 100. - 100. / (1. + rs)

    return rsi

def moving_average_convergence(x, nslow=26, nfast=12):
    """
    compute the MACD (Moving Average Convergence/Divergence) 
    using a fast andslow exponential moving avg
    return value is emaslow, emafast, macd which are len(x) arrays
    """
    emaslow = moving_average(x, nslow, type='exponential')
    emafast = moving_average(x, nfast, type='exponential')
    return emaslow, emafast, emafast - emaslow
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# 获取数据,下载2018年到现在的每天的交易数据
r = ts.get_k_data('600519', ktype='D', autype='qfq', start='2018-01-01', end='')
r.index = pd.to_datetime(r['date'])
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#

plt.rc('axes', grid=True)
plt.rc('grid', color='0.75', linestyle='-', linewidth=0.5)
textsize = 9
left, width = 0.1, 0.8
rect1 = [left, 0.7, width, 0.2]
rect2 = [left, 0.3, width, 0.4]
rect3 = [left, 0.1, width, 0.2]

#  szhs设置选择的 绘制区域
fig = plt.figure(facecolor='white',figsize=(19,10))
axescolor = '#f6f6f6'  # the axes background color
ax1 = fig.add_axes(rect1, facecolor=axescolor)  # left, bottom, width, height
ax2 = fig.add_axes(rect2, facecolor=axescolor, sharex=ax1)
ax2t = ax2.twinx()
ax3 = fig.add_axes(rect3, facecolor=axescolor, sharex=ax1)

#  RSI 指标模型
# plot the relative strength indicator
prices = r["close"]
rsi = relative_strength(prices)
fillcolor = 'darkgoldenrod'
ax1.plot(r.index, rsi, color=fillcolor)
# 30 70 两条线,这是阈值线
ax1.axhline(70, color=fillcolor)
ax1.axhline(30, color=fillcolor)
ax1.fill_between(r.index, rsi, 70, where=(rsi >= 70),facecolor=fillcolor, edgecolor=fillcolor)
ax1.fill_between(r.index, rsi, 30, where=(rsi <= 30),facecolor=fillcolor, edgecolor=fillcolor)
ax1.text(0.6, 0.9, '>70 = overbought', va='top',transform=ax1.transAxes, fontsize=textsize)
ax1.text(0.6, 0.1, '<30 = oversold',transform=ax1.transAxes, fontsize=textsize)
# 设置纵轴的范围
ax1.set_ylim(0, 100)
ax1.set_yticks([30, 70])
ax1.text(0.025, 0.95, 'RSI (14)', va='top',transform=ax1.transAxes, fontsize=textsize)
ax1.set_title('贵州茅台(600519)', fontproperties="SimHei")

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# plot the price and volumedata
dx = r["close"] - r.close
low = r.low + dx
high = r.high + dx
#  绘制蜡烛线
deltas = np.zeros_like(prices)
deltas[1:] = np.diff(prices)
up = deltas > 0
ax2.vlines(r.index[up], low[up], high[up], color='red', label='_nolegend_')
ax2.vlines(r.index[~up], low[~up], high[~up],color='green', label='_nolegend_')
# 绘制均线
# 计算均线
ma5 = moving_average(prices, 5, type='simple')
ma10 = moving_average(prices, 10, type='simple')
ma30 = moving_average(prices, 30, type='simple')
ma60 = moving_average(prices, 60, type='simple')
ma120 = moving_average(prices, 120, type='simple')
linema5, = ax2.plot(r.index, ma5, color='yellow', lw=1, label='MA (5)')
linema10, = ax2.plot(r.index, ma10, color='magenta', lw=1, label='MA (10)')
linema30, = ax2.plot(r.index, ma30, color='lime', lw=1, label='MA (30)')
linema60, = ax2.plot(r.index, ma60, color='gold', lw=1, label='MA (60)')
linema120, = ax2.plot(r.index, ma120, color='blue', lw=1, label='MA (120)')

# # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # #
#  交易量
last = r.tail(1)
s = '%s O:%1.2f H:%1.2f L:%1.2f C:%1.2f, V:%1.1fM Chg:%+1.2f' % (
    last.index.strftime('%Y.%m.%d')[0],
    last.open, last.high,
    last.low, last.close,
    last.volume* 1e-6,
    last.close - last.open)
t4 = ax2.text(0.3, 0.9, s, transform=ax2.transAxes, fontsize=textsize)

props = font_manager.FontProperties(size=10)
leg = ax2.legend(loc='center left', shadow=True, fancybox=True, prop=props)
leg.get_frame().set_alpha(0.5)

volume= (r.close * r.volume) / 1e6  # dollar volumein millions
vmax = volume.max()
poly = ax2t.fill_between(r.index, volume, 0, label='volume',
                         facecolor=fillcolor, edgecolor=fillcolor)
ax2t.set_ylim(0, 5 * vmax)
ax2t.set_yticks([])

# # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # #
# compute the MACD indicator
fillcolor = 'darkslategrey'
nslow = 26
nfast = 12
nema = 9
emaslow, emafast, macd = moving_average_convergence(prices,
                                                    nslow=nslow, nfast=nfast)

ema9 = moving_average(macd, nema, type='exponential')
ax3.plot(r.index, macd, color='black', lw=2)
ax3.plot(r.index, ema9, color='blue', lw=1)
ax3.fill_between(r.index, macd - ema9, 0, alpha=0.5,
                 facecolor=fillcolor, edgecolor=fillcolor)
ax3.text(0.025, 0.95, 'MACD (%d, %d, %d)' % (nfast, nslow, nema), va='top',
         transform=ax3.transAxes, fontsize=textsize)

# ax3.set_yticks([])
# turn off upper axis tick labels, rotate the lower ones, etc
# for ax in ax1, ax2, ax2t, ax3:
#     if ax != ax3:
#         for label in ax.get_xticklabels():
#             label.set_visible(False)
#     else:
#         for label in ax.get_xticklabels():
#             label.set_rotation(30)
#             label.set_horizontalalignment('right')
#
#     ax.fmt_xdata = mdates.DateFormatter('%Y-%m-%d')

class MyLocator(mticker.MaxNLocator):
    def __init__(self, *args, **kwargs):
        mticker.MaxNLocator.__init__(self, *args, **kwargs)

    def __call__(self, *args, **kwargs):
        return mticker.MaxNLocator.__call__(self, *args, **kwargs)

# at most 5 ticks, pruning the upper and lower so they don't overlap
# with other ticks
# ax2.yaxis.set_major_locator(mticker.MaxNLocator(5, prune='both'))
# ax3.yaxis.set_major_locator(mticker.MaxNLocator(5, prune='both'))

ax2.yaxis.set_major_locator(MyLocator(5, prune='both'))
ax3.yaxis.set_major_locator(MyLocator(1, prune='both'))

plt.show()

扫码领视频副本.gif

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号