指标计算---vnpy

本文详细介绍了在Python环境中,使用vn.py进行金融量化交易策略的实现,包括计算ATR、KDJ、RSI等技术指标,以及设置止损止盈、布林带策略等。同时,展示了如何利用numpy和pandas进行数据处理,如计算收盘价的平均值和标准差,以及计算涨跌幅和振幅。
摘要由CSDN通过智能技术生成

​​​​​​​

 

print('当前x价的值,是只有一个数',bar.close_price,'\n','x价的所有值,是个数组array: ''\n',self.am.close,'\n','当前x价的前一个x价,(只有一个数)',self.am.close[-2],'\n','*='*9)

一.计算atr均线: 

atr_array = am.atr(self.atr_length, array=True)  # atr数组 如果array为True则返回整个array,如果为False则返回最新的值
atr_now = am.atr(self.atr_length)
# print('atr_now', atr_now)
self.atr_value = atr_array[-1]  # atr数组中最后一个atr 值,也就是当前atr值
# print('self.atr_value:', self.atr_value)
self.atr_ma = atr_array[-self.atr_ma_length:].mean()  # atr均线
atr_array = am.atr(self.atr_length, array=True)  # atr数组 如果array为True则返回整个array,如果为False则返回最新的值
        atr_now = am.atr(self.atr_length)
        # print('atr_now', atr_now)
        self.atr_value = atr_array[-1]  # atr数组中最后一个atr 值,也就是当前atr值
        # print('self.atr_value:', self.atr_value)
        self.atr_ma = atr_array[-self.atr_ma_length:].mean()  # atr均线
if self.atr_value > self.atr_ma,在当前atr值大于atr均值是执行策略开仓

二.计算n日收盘价的平均值和n日收盘价的标准差:

1.先来pandas 写法

df['平均值'] = df['close'].rolling(window=30).mean()
df['标准差'] = df['close'].rolling(30, min_periods=1).std(ddof=0)  # n天内close的标准差

2.,在vnpy写法(vnpy使用的numpy数组,计算n日内的平均值和标准差非常困难,所以我们要灵活机动的完成要求)

MA指标是指一定期限内,股票收盘价格的算术平均值。比如n日的收盘价之和除以n

          df['平均值']=ta.MA(df['close'],30) 

std标准差在vnpy.trader.utiliy里的ArrayManager类中的std指标已经计算,不得不说vnpy越用越爱啊.

在on_bar函数下用     df['标准差'] = self.am15.std(30)

3. 在numpy 计算n日收盘价的平均值

close_mean = np.convolve(close, np.ones(n) / n, 'valid')

三,计算n日内最高价的最大值,n天最低价的最小值!

正解:唐奇安通道的计算,该指标的计算方法为:

上线=Max(最高价,n):n天的最高价最大值
下线=Min(最低价,n):n天的最低价最小值
中线=(上线+下线)/2

四.在vnpy中收盘价:bar.close_price或am.close[-1],前收盘价:am.close[-2]

五 计算 close/前close  然后得到一个np.array: 用切片

am.close[1:] / am.close[:-1] 切片


a = [1,2,3,4,5,6]
print(a,"整个list")
print(a[::-1]," 整个list列表的反转")
print(a[1:],'保留,除了第一个之外的其他元素')
print(a[:-1],'保留,除了最后一个之外的其他元素')


am.close[1:] / am.close[:-1] # 切片

官方写法:

from scipy.ndimage.interpolation import shift

pre_close = shift(am.close, 1, cval=0) # 前收盘价 array
r = am.close / pre_close

六 指标类计算:

ATR:

# atr数组 如果array为True则返回整个array,如果为False则返回最新的值
atr_array = am.atr(self.atr_length, array=True)
# art值 
self.atr_value = atr_array[-1]  # atr数组中最后一个atr 值,也就是当前atr值
# 或
atr_now = am.atr(self.atr_length)
# atr均线
self.atr_ma = atr_array[-self.atr_ma_length:].mean()  

kdj

    def kdj(self, fastk_period, slowk_period, slowk_matype, slowd_period, slowd_matype, array=False):
        """KDJ指标
        talib 计算 KDJ值对应的函数是Stochastic Oscillator Slow (Stoch),
        其返回值有两个,一个是快速确认线值,另外一个是慢速主干线值。KDJ 需要至少最近9天的数据。
        """

        slowk, slowd = talib.STOCH(self.high, self.low, self.close, fastk_period, slowk_period,
                                   slowk_matype, slowd_period, slowd_matype)

        # 求出J值,J = (3 * D) - (2 * K)
        slowj = list(map(lambda x, y: 3 * x - 2 * y, slowk, slowd))
        if array:
            return slowk, slowd, slowj
        return slowk[-1], slowd[-1], slowj[-1]

 rsj高频波动率

class NewArrayManager(ArrayManager):

    def __init__(self, size=100):
        """"""
        super().__init__(size)

        self.return_array: np.ndarray = np.zeros(size)

    def update_bar(self, bar: BarData) -> None:
        """更新K线"""
        # 先调用父类的方法,更新K线
        super().update_bar(bar)

        # 计算涨跌变化
        if not self.close_array[-2]:      # 如果尚未初始化上一根收盘价
            last_return = 0
        else:
            last_return = self.close_array[-1] / self.close_array[-2] - 1

        # 缓存涨跌变化
        self.return_array[:-1] = self.return_array[1:]
        self.return_array[-1] = last_return

    def rsj(self, n: int) -> float:
        """计算RSJ指标"""
        # 切片出要计算用的收益率数据
        return_data = self.return_array[-n:] 

        # 计算RV
        rv = np.sum(pow(return_data, 2))

        # 计算RV +/-
        positive_data = np.array([r for r in return_data if r > 0])
        negative_data = np.array([r for r in return_data if r <= 0])

        rv_positive = np.sum(pow(positive_data, 2))
        rv_negative = np.sum(pow(negative_data, 2))

        # 计算RSJ
        rsj = (rv_positive - rv_negative) / rv
        return rsj

bool上下轨,布林带宽度

self.boll_up, self.boll_down = self.am5.boll(self.boll_window, self.boll_dev)  # 计算布林上下轨

boll_width = self.boll_up - self.boll_down  # 计算布林上下轨 宽度

RSI

self.rsi_value = self.am5.rsi(self.rsi_window)  # 计算rsi 值

k线最高价,最低价

        if self.pos == 0:
            self.intra_trade_high = bar.high_price
            self.intra_trade_low = bar.low_price



        elif self.pos > 0:
            self.intra_trade_high = max(self.intra_trade_high, bar.high_price)




        elif self.pos < 0:
            self.intra_trade_low = min(self.intra_trade_low, bar.low_price)

固定止损 百分比

# 多单固定止损

        elif self.pos > 0:
            self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
            self.intra_trade_low = bar.low_price

            long_stop = self.intra_trade_high * \
                (1 - self.trailing_percent / 100)
            self.sell(long_stop, abs(self.pos), stop=True)




# 空单固定止损

        elif self.pos < 0:
            self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
            self.intra_trade_high = bar.high_price

            short_stop = self.intra_trade_low * \
                (1 + self.trailing_percent / 100)
            self.cover(short_stop, abs(self.pos), stop=True)

固定止盈止损

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        回调新低交易数据并更新
        """
        # 固定止盈止损设定 1.先牟定开仓价 为止盈止损的标的价 ,2.然后+-固定的数值作为止盈止损价格 挂止盈止损单
        # if self.pos != 0:
        #     if trade.direction == Direction.LONG:
        #         self.long_entry = trade.price  # 标记多头止盈价为 多头持仓价
        #         self.long_stop = self.long_entry + self.fixed_tp
        #     else:
        #         self.short_entry = trade.price
        #         self.short_stop = self.short_entry - self.fixed_tp
        # self.put_event()

布林策略中轨止损
 # 触碰布林中轨马上止损=======止损进阶=========
    self.long_entry = 0
    self.long_stop = 0
    self.short_entry = 0
    self.short_stop = 0
    # 触碰布林中轨马上止损=======止损进阶==========


#     触碰布林中轨马上止损=======回测 btc/usdt 2017.9.3-2020.8.3
elif self.pos > 0:
    self.sell(self.boll_mid, abs(self.pos), True)
elif self.pos < 0:
    self.cover(self.boll_mid, abs(self.pos), True)
 # 触碰布林中轨马上止损=======止损进阶=========
            self.long_entry = 0
            self.long_stop = 0
            self.short_entry = 0
            self.short_stop = 0
            # 触碰布林中轨马上止损=======止损进阶==========


        #     触碰布林中轨马上止损=======回测 btc/usdt 2017.9.3-2020.8.3
        elif self.pos > 0:
            self.sell(self.boll_mid, abs(self.pos), True)
        elif self.pos < 0:
            self.cover(self.boll_mid, abs(self.pos), True)

布林策略 基于布林宽度的可变止损

# # 基于布林宽度的可变止损==================回测 btc/usdt 2017.9.3-2020.8.3
        # elif self.pos > 0:
        #
        #     self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
        #     condition1 = self.intra_trade_high - self.trailing_long * boll_width  # 计算多头移动止损价
        #
        #     self.long_stop = condition1
        #     self.sell(self.long_stop, abs(self.pos), stop=True)  # 挂止损单
        #
        # else:
        #     self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
        #     condition1 = self.intra_trade_low + self.trailing_short * boll_width  # 计算空头移动止损价
        #
        #     self.short_stop = condition1
        #     self.cover(self.short_stop, abs(self.pos), stop=True)  # 挂止损单
        #     # 基于布林宽度的可变止损==================

布林策略 atr倍数止损或者 布林中轨止损

# 止损进阶===============效果比基于布林宽度的可变止损 要差很多 回测 btc/usdt 2017.9.3-2020.8.3
        # elif self.pos > 0:
        #     self.intra_trade_high = max(self.intra_trade_high, bar.high_price)  # 交易中最高价
        #
        #     self.long_stop = self.intra_trade_high - self.atr_value * self.atr_multiplier  # 计算多头止损价
        #     self.long_stop = max(self.boll_mid, self.long_stop)  # 在布林中轨和多头止损价中比较最大值作为多头止损价 挂单
        #     self.sell(self.long_stop, abs(self.pos), True)
        #
        #     if self.long_stop:
        #         self.sell(self.long_stop, abs(self.pos))
        #
        # elif self.pos < 0:
        #     # self.cover(self.boll_mid, abs(self.pos), True)
        #
        #     self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
        #
        #     self.short_stop = self.intra_trade_low + self.atr_value * self.atr_multiplier
        #     self.short_stop = min(self.boll_mid, self.short_stop)
        #     self.cover(self.short_stop, abs(self.pos), True)
        #
        #     if self.short_stop:
        #         self.cover(self.short_stop, abs(self.pos))
        # # 止损进阶=============== 效果比基于布林宽度的可变止损 要差很多
# 计算前close
​​​​​​​from scipy.ndimage.interpolation import shift
pre_close = shift(am.close, 1, cval=0)

# 计算前close
​​​​​​​from scipy.ndimage.interpolation import shift
pre_close = shift(am.close, 1, cval=0)


# 计算涨跌幅 = (现收盘价-上一个交易日收盘价)/上一个交易日收盘价*100%
 self.increase = (self.am.close-pre_close)/pre_close   # 大于0是涨,小于0 是跌 ,绝对值越大k线柱越大
 print(self.increase,"计算涨跌幅")

计算涨跌幅,振幅

# 计算涨跌幅 = (现收盘价-上一个交易日收盘价)/上一个交易日收盘价*100%
 self.increase = (self.am.close[-1]-self.am.close[-2])/self.am.close[-2]   # 大于0是涨,小于0 是跌 ,绝对值越大k线柱越大
 print(self.increase,"计算涨跌幅")

 # 计算振幅 = ( 当日最高点的价格-当日最低点的价格)/昨天收盘价×100%
 self.amplitude = (self.am.high-self.am.low)/self.am.close[-2]   # 值越大两k线最高最低点差越大
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_40686234

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值