使用卷积计算移动平均值

时间:2021-04-25 00:44:45

  CSVComma-Separated Value,逗号分隔值)格式是一种常见的文件格式。NumPy中的loadtxt函数可以方便地读取CSV文件,自动切分字段,并将数据载入NumPy数组。 

  我们以某公司的历史股价数据为例展开叙述。股价数据存储在CSV文件中,第一列为yyyy-mm-dd格式的日期,随后各列依次是收盘价、成交量、开盘价、最高价、最低价。下面为前几行数据: 

使用卷积计算移动平均值

  我们只关注股票的收盘价和成交量。我们将收盘价和成交量分别载入到两个数组中:

c, v = np.loadtxt('Stock_Prices.csv', delimiter=',', usecols=(1,2), unpack=True)

  可以看到,数据存储在Stock_Prices.csv文件中,delimiter参数指定了文件中的分隔符为英文逗号 ","usecols的参数为一个元组,以获取第1列和第2列的数据,也就是股票的收盘价和成交量数据。 unpack参数设置为True,意思是分拆存储不同列的数据,即分别将收盘价和成交量的数组赋值给变量cv。 

1. 计算成交量平均价格

  VWAP Volume-Weighted Average Price,成交量加权平均价格)是一个非常重要的经济学量,它代表着金融资产的“平均”价格。某个价格的成交量越高,该价格所占的权重就越大。 VWAP就是以成交量为权重计算出来的加权平均值,常用于算法交易。 

import numpy as np

c, v
= np.loadtxt('Stock_Prices.csv', delimiter=',', usecols=(1,2), unpack=True)

vwap
= np.average(c, weights = v)

print "VWAP =", vwap

The output is
VWAP = 37.00109716 

我们仅仅调用了average函数,并将v作为权重参数使用,就完成了加权平均值的计算。此外, NumPy中也有计算算术平均值的函数mean。 

2. 计算算数平均值

print "mean =", np.mean(c)

mean = 37.0013015873

3. 简单移动平均线

  简单移动平均线(moving average)通常用于分析时间序列上的数据。为了计算它,我们需要定义一个N个周期的移动窗口,在我们的例子中即N个交易日。我们按照时间序列滑动这个窗口,并计算窗口内数据的均值。 

  移动平均线只需要少量的循环和均值函数即可计算得出,但使用NumPy还有更优的选择——convolve函数。简单移动平均线只不过是计算与等权重的指示函数的卷积,当然,也可以是不等权重的。卷积是分析数学中一种重要的运算,定义为一个函数与经过翻转和平移的另一个函数的乘积的积分。 

  按照如下步骤计算简单移动平均线:

  (1) 使用ones函数创建一个长度为N的元素均初始化为1的数组,然后对整个数组除以N,即可得到权重 

N = int(sys.argv[1])
weights
= np.ones(N) / N
print "Weights", weights

  在N = 5时,输出结果如下:
  Weights [ 0.2 0.2 0.2 0.2 0.2]

  (2) 使用这些权重值,调用convolve函数:

  c = np.loadtxt('Stock_Prices.csv', delimiter=',', usecols=(1,), unpack=True)
  ma
= np.convolve(weights, c)[N-1:-N+1]

  (3) 使用Matplotlib进行绘图

    在ipython中运行如下代码: %run  calculate_ma.py  5

import numpy as np
import sys
from matplotlib.pyplot import plot
from matplotlib.pyplot import show

N
= int(sys.argv[1])
weights
= np.ones(N) / N

c
= np.loadtxt('Stock_Prices.csv', delimiter=',', usecols=(1,), unpack=True)
ma
= np.convolve(weights, c)[N-1:-N+1]

t
= np.arange(N - 1, len(c))
plot(t, c[N
-1:], lw=1.0)
plot(t, ma, lw
=2.0)
show()

  在下图中,相对较平滑的粗线描绘的是5日移动平均线,而锯齿状的细线描绘的是每天的收盘价。 

使用卷积计算移动平均值


  •   序列的基本运算

   在数字信号处理中,序列通常有下面几种运算形式:

1. 序列相加

  序列之间的加法,是指两个序列的同序号的值逐项对应相加。即在同一时刻n,对幅值进行叠加:

  $$y(n)=x_1(n)+x_2(n)$$

 2. 序列乘常数

  一个常数乘以序列,是指该常数乘以序列的每一个值,如:

$$y(n)= k \cdot x(n)$$

  k可以是复数也可以是实数。当k为实数,且k>1时,就是通常所说的放大作用,即把序列x(n)的幅度放大了k倍。

3. 序列相乘

  序列之间的乘法,是指两个序列的同序号的值逐项对应相乘:

$$y(n)=x_1(n) \cdot x_2(n)$$

4. 序列移位

  序列x(n)向右(左)平移,是将序列号减去(加上)m(m>0),如:

$y(n)=x(n-m)$,右移m

$y(n)=x(n+m)$,左移m

  下图中分别表示了原序列x(n)、x(n+2)和x(n-1)的图形。由图可见,x(n+2)表示原序列左移2个单位,通常称序列的超前;x(n-1)表示原序列右移1个单位,通常称序列的延时。 作为实现序列延时的实际离散系统就是移位寄存器或存储器。 

 使用卷积计算移动平均值使用卷积计算移动平均值使用卷积计算移动平均值

 5. 序列翻转

  设序列x(n)用下图a表示,其翻转序列x(-n)用图b表示。x(n)与x(-n)关于纵坐标轴对称。

使用卷积计算移动平均值

 6. 序列卷积

  两个序列的线性卷积定义为

 $$x(n)*y(n)=\sum_{k=-\infty}^{\infty}x(k)y(n-k)$$

   其中,符号“*”表示一种特定的运算形式,称作“卷积”。

  卷积运算的求解过程为:

  ①. 将x(n)和y(n)用x(k)和y(k)表示,并将y(k)翻转,形成y(-k);

  ②. 将y(-k)移位n,得到y(n-k)。当n>0时,序列右移;当n<0时,序列左移;

  ③. 将x(k)和y(n-k)相同k的序列值对应相乘后,再相加

  按以上3个步骤可得到卷积结果x(n)*y(n)。

  下面通过图例来说明。如计算序列h(n)与x(n)的卷积y(n),先将坐标n换成坐标m,n成为m坐标中的参变量 

使用卷积计算移动平均值

  将x(m)沿纵轴翻转得到x(-m)

使用卷积计算移动平均值

  将x(-m)的值每次右移一次,分别得到x(1-m),x(2-m),...,x(n-k)。当n<0时(如n=-1),从图中可以看出此时x(n-m)与h(m)没有相互重叠的区域,则卷积为0。

使用卷积计算移动平均值

  当n=0时x(-m)与h(m)在m=0点有重叠,故y(0)不为零。以后随着n的增加x(n-m)逐渐右移,x(n-m)与h(m)相互重叠的值也越来越多。当n=时3时,x(3-m)已有一个值移出h(m)所在的区间。当n>5时,x(n-m)已全部移出h(m)所在的区间,此时卷积y(n)又等于零了。

使用卷积计算移动平均值

  卷积y(n)波形图(f)所示:

使用卷积计算移动平均值

  可以使用numpy中的convolve函数进行验证:

h = np.ones(3)
x
= np.array([0.5,1,1.5,2])
y
= np.convolve(h, x)

print y

使用卷积计算移动平均值

  卷积运算服从交换律: x(n) * y(n) = y(n) * x(n)

  卷积运算服从加法分配律: y(n) * [x1(n) + x2(n)] = y(n) * x1(n) + y(n) * x2(n)

  卷积也服从结合律:x(n) * h1(n) * h2(n) = [x(n) * h1(n)] * h2(n) = [x(n) * h2(n)] * h1(n) = x(n) *[h1(n) * h2(n)] 

7. 序列的能量

  序列的能量定义为序列各采样值的平方和,即

$$E=\sum_{n=-\infty}^{\infty}|x(n)|^2$$

  序列的能量可以是有限的,如能量信号;也可能是无限的,如功率信号。

 

 

 

 

参考:

移动平均

《数字信号处理及应用》  北京邮电大学出版社