Files
my_wiki/raw/量化/abuquant-src/abupy/IndicatorBu/ABuNDAtr.py
T

239 lines
9.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- encoding:utf-8 -*-
"""
ATR
ATR又称 Average true range平均真实波动范围,简称ATR指标,是由J.Welles Wilder 发明的,ATR指标主要是用来衡量市场波动的强烈度,
即为了显示市场变化率的指标。
计算方法:
1. TR=∣最高价-最低价∣,∣最高价-昨收∣,∣昨收-最低价∣中的最大值
2. 真实波幅(ATR= MA(TR,N)(TR的N日简单移动平均)
3. 常用参数N设置为14日或者21日
"""
from __future__ import absolute_import
from __future__ import print_function
from __future__ import division
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from ..CoreBu.ABuPdHelper import pd_ewm_mean
from ..UtilBu import ABuScalerUtil
from .ABuNDBase import plot_from_order, g_calc_type, ECalcType
__author__ = '阿布'
__weixin__ = 'abu_quant'
# noinspection PyUnresolvedReferences
def _calc_atr_from_ta(high, low, close, time_period=14):
"""
使用talib计算atr,即透传talib.ATR计算结果
:param high: 最高价格序列,pd.Series或者np.array
:param low: 最低价格序列,pd.Series或者np.array
:param close: 收盘价格序列,pd.Series或者np.array
:param time_period: atr的N值默认值14int
:return: atr值序列,np.array对象
"""
import talib
if isinstance(high, pd.Series):
high = high.values
if isinstance(low, pd.Series):
low = low.values
if isinstance(close, pd.Series):
close = close.values
atr = talib.ATR(high, low, close, timeperiod=time_period)
return atr
def _calc_atr_from_pd(high, low, close, time_period=14):
"""
通过atr公式手动计算atr
:param high: 最高价格序列,pd.Series或者np.array
:param low: 最低价格序列,pd.Series或者np.array
:param close: 收盘价格序列,pd.Series或者np.array
:param time_period: atr的N值默认值14int
:return: atr值序列,np.array对象
"""
if isinstance(close, pd.Series):
# shift(1)构成昨天收盘价格序列
pre_close = close.shift(1).values
else:
from scipy.ndimage.interpolation import shift
# 也可以暂时转换为pd.Series进行shift
pre_close = shift(close, 1)
pre_close[0] = pre_close[1]
if isinstance(high, pd.Series):
high = high.values
if isinstance(low, pd.Series):
low = low.values
# ∣最高价 - 最低价∣
tr_hl = np.abs(high - low)
# ∣最高价 - 昨收∣
tr_hc = np.abs(high - pre_close)
# ∣昨收 - 最低价∣
tr_cl = np.abs(pre_close - low)
# TR =∣最高价 - 最低价∣,∣最高价 - 昨收∣,∣昨收 - 最低价∣中的最大值
tr = np.maximum(np.maximum(tr_hl, tr_hc), tr_cl)
# ATR= MA(TR, N)(TR的N日简单移动平均), 这里没有完全按照标准公式使用简单移动平均,使用了pd_ewm_mean,即加权移动平均
atr = pd_ewm_mean(pd.Series(tr), span=time_period, min_periods=1)
# 返回atr值序列,np.array对象
return atr.values
"""通过在ABuNDBase中尝试import talib来统一确定指标计算方式"""
calc_atr = _calc_atr_from_pd if g_calc_type == ECalcType.E_FROM_PD else _calc_atr_from_ta
def atr14(high, low, close):
"""
通过high, low, close计算atr14序列值
:param high: 最高价格序列,pd.Series或者np.array
:param low: 最低价格序列,pd.Series或者np.array
:param close: 收盘价格序列,pd.Series或者np.array
:return: atr值序列,np.array对象
"""
atr = calc_atr(high, low, close, 14)
return atr
def atr21(high, low, close):
"""
通过high, low, close计算atr21序列值
:param high: 最高价格序列,pd.Series或者np.array
:param low: 最低价格序列,pd.Series或者np.array
:param close: 收盘价格序列,pd.Series或者np.array
:return: atr值序列,np.array对象
"""
atr = calc_atr(high, low, close, 21)
return atr
def atr14_min(high, low, close):
"""
确定常数阀值时使用,通过high, low, close计算atr14序列值,返回计算结果atr14序列中的最小值
:param high: 最高价格序列,pd.Series或者np.array
:param low: 最低价格序列,pd.Series或者np.array
:param close: 收盘价格序列,pd.Series或者np.array
:return: atr值序列,atr14序列中的最小值,float
"""
_atr14 = atr14(high, low, close)
_atr14 = pd.Series(_atr14)
_atr14.fillna(method='bfill', inplace=True)
_atr14 = _atr14.min()
return _atr14
def atr14_max(high, low, close):
"""
确定常数阀值时使用,通过high, low, close计算atr14序列值,返回计算结果atr14序列中的最大值
:param high: 最高价格序列,pd.Series或者np.array
:param low: 最低价格序列,pd.Series或者np.array
:param close: 收盘价格序列,pd.Series或者np.array
:return: atr值序列,atr14序列中的最大值,float
"""
_atr14 = atr14(high, low, close)
_atr14 = pd.Series(_atr14)
_atr14.fillna(method='bfill', inplace=True)
_atr14 = _atr14.max()
return _atr14
def atr21_min(high, low, close):
"""
确定常数阀值时使用,通过high, low, close计算atr21序列值,返回计算结果atr21序列中的最小值
:param high: 最高价格序列,pd.Series或者np.array
:param low: 最低价格序列,pd.Series或者np.array
:param close: 收盘价格序列,pd.Series或者np.array
:return: atr值序列,atr21序列中的最小值,float
"""
_atr21 = atr21(high, low, close)
_atr21 = pd.Series(_atr21)
_atr21.fillna(method='bfill', inplace=True)
_atr21 = _atr21.min()
return _atr21
def atr21_max(high, low, close):
"""
确定常数阀值时使用,通过high, low, close计算atr21序列值,返回计算结果atr21序列中的最大值
:param high: 最高价格序列,pd.Series或者np.array
:param low: 最低价格序列,pd.Series或者np.array
:param close: 收盘价格序列,pd.Series或者np.array
:return: atr值序列,atr21序列中的最大值,float
"""
_atr21 = atr21(high, low, close)
_atr21 = pd.Series(_atr21)
_atr21.fillna(method='bfill', inplace=True)
_atr21 = _atr21.max()
return _atr21
def plot_atr_from_klpd(kl_pd, with_points=None, with_points_ext=None, **kwargs):
"""
封装plot_atr,绘制收盘价格,atr曲线
:param kl_pd: 金融时间序列,pd.DataFrame对象
:param with_points: 这里的常规用途是传入买入order, with_points=buy_index=pd.to_datetime(orders['buy_date']))
:param with_points_ext: 这里的常规用途是传入卖出order, with_points_ext=sell_index=pd.to_datetime(orders['sell_date']))
:param kwargs: 绘制技术指标需要的其它关键字参数,time_period, 最终透传给plot_atr
"""
plot_atr(kl_pd.high, kl_pd.low, kl_pd.close, kl_pd.index,
with_points=with_points, with_points_ext=with_points_ext, **kwargs)
def plot_atr_from_order(order, date_ext=120, **kwargs):
"""
封装ABuNDBase中的plot_from_order与模块中绘制技术指标的函数,完成技术指标可视化及标注买入卖出点位
:param order: AbuOrder对象转换的pd.DataFrame对象or pd.Series对象
:param date_ext: int对象 eg. 如交易在2015-06-01执行,如date_ext120,择start向前推120天,end向后推120天
:param kwargs: 绘制技术指标需要的其它关键字参数,time_period, 最终透传给plot_atr
"""
return plot_from_order(plot_atr_from_klpd, order, date_ext, **kwargs)
def plot_atr(high, low, close, kl_index, with_points=None, with_points_ext=None, time_period=14):
"""
分别在上下两个子画布上绘制收盘价格,以及对应的atr曲线,如果有with_points点位标注,
则只画在一个画布上,且将两个曲线进行缩放到一个数值级别
:param high: 最高价格序列,pd.Series或者np.array
:param low: 最低价格序列,pd.Series或者np.array
:param close: 收盘价格序列,pd.Series或者np.array
:param kl_index: pd.Index时间序列
:param with_points: 这里的常规用途是传入买入order, with_points=buy_index=pd.to_datetime(orders['buy_date']))
:param with_points_ext: 这里的常规用途是传入卖出order, with_points_ext=sell_index=pd.to_datetime(orders['sell_date']))
:param time_period: atr的N值默认值14int
"""
atr = calc_atr(high, low, close, time_period)
plt.figure(figsize=(14, 7))
if with_points is not None or with_points_ext is not None:
# 如果需要标准买入卖出点,就绘制在一个画布上
p1 = plt.subplot(111)
p2 = p1
# 绘制在一个画布上, 将两个曲线进行缩放到一个数值级别
matrix = ABuScalerUtil.scaler_matrix([atr, close])
atr, close = matrix[matrix.columns[0]], matrix[matrix.columns[1]]
# with_points和with_points_ext的点位使用竖线标注
if with_points is not None:
p1.axvline(with_points, color='green', linestyle='--')
if with_points_ext is not None:
p1.axvline(with_points_ext, color='red')
else:
# 绘制在两个子画布上面
p1 = plt.subplot(211)
p2 = plt.subplot(212)
p1.plot(kl_index, close, "b-", label="close")
p2.plot(kl_index, atr, "r-.", label="period={} atr".format(time_period), lw=2)
p1.grid(True)
p1.legend()
p2.grid(True)
p2.legend()
plt.show()