本文代码部分总结自Packt出版社的《Learn Algorithmic Trading - Fundamentals of Algorithmic Trading》,如图1。现将该书的相对强弱指标[1](RSI)部分进行总结,并对数据处理及图形绘制等函数做了相应改动,供有需要的读者学习研究。
相对强度指标 ( R S I ) (RSI) (RSI)是由美国证券分析技术大师威尔斯·威尔德(J.Welles-Wilder)提出并设计的技术分析工具,最早应用于欧美期货市场。相对强弱指标是通过比较一段时间内收盘指数或收盘价的涨跌变化情况,来分析测量多空双方买卖力量的强弱程度,从而判断未来股市走势的一种技术指标。其最大优点是能够提前提示买卖双方力量的对比,指当前价格以0到100之间的百分比进行标准化[2]。此指标名称具有误导性,因为它不是一只股票与另一只股票进行比较,而是当前股票价格与所选回溯期内的股票价格进行比较[1]。
n : 时 间 周 期 数 n:时间周期数 n:时间周期数
收 益 : 收 盘 价 − 前 收 盘 价 < 0 时 为 0 , > 0 为 所 得 值 收益:收盘价-前收盘价<0时为0,>0为所得值 收益:收盘价−前收盘价<0时为0,>0为所得值
损 失 : 前 收 盘 价 − 收 盘 价 < 0 时 为 0 , > 0 为 所 得 值 损失:前收盘价-收盘价<0时为0,>0为所得值 损失:前收盘价−收盘价<0时为0,>0为所得值
a v g _ G a i n = ∑ ∣ 过 去 n 个 时 期 内 的 收 益 ∣ n avg\_Gain=\frac{\sum|过去n个时期内的收益|}{n} avg_Gain=n∑∣过去n个时期内的收益∣
a v g _ L o s s = ∑ ∣ 过 去 n 个 时 期 内 的 损 失 ∣ n avg\_Loss=\frac{\sum|过去n个时期内的损失|}{n} avg_Loss=n∑∣过去n个时期内的损失∣
R S = a v g _ G a i n a v g _ L o s s = ∑ ∣ 过 去 n 个 时 期 内 的 收 益 ∣ ∑ ∣ 过 去 n 个 时 期 内 的 损 失 ∣ × 100 % RS= \frac{avg\_ Gain}{avg\_ Loss}=\frac{\sum|过去n个时期内的收益|}{\sum|过去n个时期内的损失|}\times 100\% RS=avg_Lossavg_Gain=∑∣过去n个时期内的损失∣∑∣过去n个时期内的收益∣×100%
R S I = 100 − 100 1 + R S RSI = 100 - \frac{100}{1 + RS} RSI=100−1+RS100
Python绘图库Matplotlib 3.2.1
Python金融数据处理库Pandas 1.0.2
Python矩阵计算库Numpy 1.16.0
# 导入及处理数据
import pandas as pd
import numpy as np
# 绘图
import matplotlib.pyplot as plt
# 设置图像标签显示中文
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
import matplotlib as mpl
# 解决一些编辑器(VSCode)或IDE(PyCharm)等存在的图片显示问题,
# 应用Tkinter绘图,以便对图形进行放缩操作
mpl.use('TkAgg')
# 导入数据并做处理
def import_csv(stock_code):
df = pd.read_csv(stock_code + '.csv')
df.rename(columns={
'date': 'Date',
'open': 'Open',
'high': 'High',
'low': 'Low',
'close': 'Close',
'volume': 'Volume'
},
inplace=True)
df['Date'] = pd.to_datetime(df['Date'], format='%Y/%m/%d')
df.set_index(['Date'], inplace=True)
return df
stock_code = 'sh600519'
# 绘制数据的规模
scale = 500
df = import_csv(stock_code)[-scale:]
time_period = 20 # 损益的回溯周期
gain_history = [] # 回溯期内的收益历史(无收益为0,有收益则为收益的幅度)
loss_history = [] # 回溯期内的损失历史(无损失为0,有损失则为损失的幅度)
avg_gain_values = [] # 存储平均收益值以便图形绘制
avg_loss_values = [] # 存储平均损失值以便图形绘制
rsi_values = [] # 存储算得的RSI值
last_price = 0
# 当前价 - 过去价 > 0 => 收益(gain).
# 当前价 - 过去价 < 0 => 损失(loss).
# 遍历收盘价以计算 RSI指标
for close in df['Close']:
if last_price == 0:
last_price = close
gain_history.append(max(0, close - last_price))
loss_history.append(max(0, last_price - close))
last_price = close
if len(gain_history) > time_period: # 最大观测值等于回溯周期
del (gain_history[0])
del (loss_history[0])
avg_gain = np.mean(gain_history) # 回溯期的平均收益
avg_loss = np.mean(loss_history) # 回溯期的平均损失
avg_gain_values.append(avg_gain)
avg_loss_values.append(avg_loss)
# 初始化rs值
rs = 0
if avg_loss > 0: # 避免除数为 0,出现错误
rs = avg_gain / avg_loss
rsi = 100 - (100 / (1 + rs))
rsi_values.append(rsi)
# 将计算所得值并入DataFrame
df = df.assign(RSAvgGainOver20D=pd.Series(avg_gain_values, index=df.index))
df = df.assign(RSAvgLossOver20D=pd.Series(avg_loss_values, index=df.index))
df = df.assign(RSIOver20D=pd.Series(rsi_values, index=df.index))
# 定义画布并添加子图
fig = plt.figure()
ax1 = fig.add_subplot(311, ylabel='%s price in ¥'%(stock_code))
df['Close'].plot(ax=ax1, color='black', lw=1., legend=True)
# sharex:设置同步缩放横轴,便于缩放查看
ax2 = fig.add_subplot(312, ylabel='RS', sharex=ax1)
df['RSAvgGainOver20D'].plot(ax=ax2, color='g', lw=1., legend=True)
df['RSAvgLossOver20D'].plot(ax=ax2, color='r', lw=1., legend=True)
ax3 = fig.add_subplot(313, ylabel='RSI', sharex=ax1)
df['RSIOver20D'].plot(ax=ax3, color='b', lw=1., legend=True)
plt.show()
[1] Sebastien Donadio,Sourav Ghosh.Learn Algorithmic Trading - Fundamentals of Algorithmic Trading.Birmingham:Packt Press,2019.P62-66.
[2] 麻道明.如何看懂技术指标.北京:中国宇航出版社,2015.163页
用mplfinance库绘制股票K线、均线图
Python绘制MACD指标图
Python绘制BOLL布林线指标图