Python数据分析–Numpy常用函数介绍(6)–Numpy中与股票成交量有关的计算

        成交量(volume)是投资中一个非常重要的变量,它是指在某一时段内具体的交易数,可以在分时图中绘制,包括日线图、周线图、月线图甚至是5分钟、30分钟、60分钟图中绘制。

  股票市场成交量的变化反映了资金进出市场的情况,成交量是判断市场走势的重要指标。一般情况下,成交量大且价格上涨的股票,趋势向好。成交量持续低迷时,一般出现在熊市或股票整理阶段,市场交易不活跃。成交量是判断股票走势的重要依据,对分析主力行为提供了重要的依据。投资者对成交量异常波动的股票应当密切关注。

  OBV(On-Balance Volume,净额成交量或叫能量潮指标)是最简单的股价指标之一,它可以由当日收盘价、前一天的收盘价以及当日成交量计算得出。以前一日为基期计算当日的OBV值(可以认为基期的OBV值为0)。若当日收盘价高于前一日收盘价,则本日OBV等于基期OBV加上日成交量。若当日收盘价低于前一日收盘价,则本日OBV等于基期OBV减去当日成交量。若当日收盘价相比前一日没有变化,则当日成交量以0计算。

一、OBV计算

  鉴于上述计算方法,需要在成交量前面乘上一个由收盘价变化决定的正负号(收盘价低于前一交易日收盘价,负号,收盘价高于前一交易日收盘价,正号)。在本篇中,学习该问题的两种解决方法,一种是使用NumPy中的 sign 函数,另一种是使用NumPy的piecewise 函数。

1) 把数据分别加载到收盘价和成交量的数组中:

close,vol = np.loadtxt('data036.csv',delimiter=',', usecols=(5,6),converters={1:datestr2num},unpack=True)

data036.csv中的第6列和第7列分别为收盘价和当日成交量。

前篇介绍过numpy.diff()可以计算相邻的差(即上述收盘价close的差值),并利用这个差值, 用sign 函数计算正负号

changes = np.diff(close)
signs = np.sign(changes)
print ("Signs", signs)

运行结果:

Signs [-1. -1. -1. -1.  1.  1.  1. -1.  1.  1.  1. -1.  1. -1. -1. -1. -1.  1.
  1. -1. -1.  1.  1.  1.  1.  1.  1.  1. -1.  1.  1.  1. -1. -1. -1.  1.
 -1.  1.  1.  1. -1. -1.  1.  1.  1. -1. -1.  1.  1.  1.  1.  1.  1. -1....

2)也可以使用 piecewise 函数来获取数组元素的正负。 piecewise函数可以分段给定取值。使用合适的返回值和对应的条件调用该函数:

pieces = np.piecewise(changes, [changes < 0, changes > 0], [-1, 1])
print("Pieces", pieces)

3)判断是否 sign 函数和piecewise 函数计算结果是否一致用array_equal()函数:

print ("Arrays equal?", np.array_equal(signs, pieces))

运行结果:

Arrays equal? True

4)由于diff()y计算的结果是相邻数据相减,因此得到419个数据,较从文件中导入的数据420个少一位,因此无法计算首日的OBV值

obv_values = vol[1:] * signs          #计算obv值
print("obv values:",obv_values[:20]) #打印前20个obv值

完成代码如下:

import numpy as np
from datetime import datetime
import matplotlib.pyplot as plt
import sys,os

def datestr2num(s): #定义一个函数
    return datetime.strptime(s.decode('ascii'),"%Y-%m-%d").date().weekday()

close,vol = np.loadtxt('data036.csv',delimiter=',', usecols=(5,6),converters={1:datestr2num},unpack=True)
#new_close = np.loadtxt('data999.csv',delimiter=',', usecols=(5,),converters={1:datestr2num},unpack=True)

changes = np.diff(close)
signs = np.sign(changes)
print ("Signs", signs[:20])#打印前20个signs值

pieces = np.piecewise(changes, [changes < 0, changes > 0], [-1, 1])
print("Pieces", pieces[:20])#打印前20个pieces值
print ("Arrays equal?", np.array_equal(signs, pieces))

obv_values = vol[1:] * signs          #计算obv值
print("obv values:",obv_values[:20]) #打印前20个obv值

运行结果:

Python数据分析--Numpy常用函数介绍(6)--Numpy中与股票成交量有关的计算

二、 计算单个交易日的利润

1)读入数据

将所有交易数据(开盘价、收盘价、最高价、最低价,成交量等)加载到对应的数组中

import numpy as np
from datetime import datetime
import matplotlib.pyplot as plt
import sys,os

def datestr2num(s): #定义一个函数
    return datetime.strptime(s.decode('ascii'),"%Y-%m-%d").date().weekday()

opens,highs,lows,closes,vols = np.loadtxt('data036.csv',delimiter=',', usecols=(2,3,4,5,6),converters={1:datestr2num},unpack=True) #开盘价、最高价、最低价、收盘价、成交量数组。

2)调用 vectorize 函数并给定calc_profit 函数作为参数:

(1)先定义一个计算利润的函数:这个函数,是以开盘价买入,以当日收盘价卖出,所获得的利润即买入和卖出的差价。事实上,计算相对利润更为直观。

def calc_profit(opens, highs, lows, closes):
    buy = opens * 1
    if lows < buy < highs :
        return (closes - buy)/buy
    else:
        return 0

(2)调用 vectorize 函数并给定calc_profit 函数作为参数

func = np.vectorize(calc_profit)
profits=func(opens,highs,lows,closes)

print ("Profits", profits)

3)选择非零利润的交易日,并计算平均值:

real_trades = profits[profits != 0]
print ("Number of trades", len(real_trades), round(100.0 * len(real_trades)/len(closes), 2),"%")
print ("Average profit/loss %", round(np.mean(real_trades) * 100, 2))

当然也可以分别计算盈利和亏损:

real_trades = profits[profits > 0]
print ("Number of trades", len(real_trades), round(100.0 * len(real_trades)/len(closes), 2),"%")
print ("平均盈利: %", round(np.mean(real_trades) * 100, 2))

loss_trades = profits[profits < 0]
print ("Number of trades", len(loss_trades), round(100.0 * len(loss_trades)/len(closes), 2),"%")
print ("平均亏损 %", round(np.mean(loss_trades) * 100, 2))

实际运行结果:

Python数据分析--Numpy常用函数介绍(6)--Numpy中与股票成交量有关的计算

三、数据平滑

噪声数据很难处理,因此需要对其进行平滑处理,除前篇介绍的计算移动平均线的方法,还可以使用NumPy中的一个函数来平滑数据。hanning 函数是一个加权余弦的窗函数。
1)调用 hanning 函数计算权重,生成一个长度为 N 的窗口(在这个示例中 N 取8)

N=8
weights = np.hanning(N)  #调用hanning 函数计算权重,生成一个长度为8的窗口
print("Weights", weights)

运行结果:

Weights [0.         0.1882551  0.61126047 0.95048443 0.95048443 0.61126047 0.1882551  0.        ]

2)用 convolve 函数计算closes的股票收益率,以归一化处理后的 weights 作为参数

closes_returns = np.diff(closes) / closes[ : -1] #计算收盘价相邻差价
smooth_closes = np.convolve(weights/weights.sum(), closes_returns) [N-1:-N+1]#利用权重,计算数据平滑
opens_returns = np.diff(opens) / opens[ : -1] #计算开盘价相邻差价
smooth_opens = np.convolve(weights/weights.sum(), opens_returns) [N-1:-N+1]

3)用 Matplotlib 绘图

t = np.arange(N - 1, len(closes_returns))
plt.plot(t, closes_returns[N-1:], lw=1.0)
plt.plot(t, smooth_closes, lw=2.0)
plt.plot(t, opens_returns[N-1:], lw=1.0)
plt.plot(t, smooth_opens, lw=2.0)
plt.show()

运行结果:

Python数据分析--Numpy常用函数介绍(6)--Numpy中与股票成交量有关的计算

4)

如上图中的折线有交叉,这些交叉点可能就是股价趋势的转折点,至少可以表明closes和opens之间的股价关系发生了变化,这些转折点可能会经常出现,可以利用它们预测未来的股价走势。

使用多项式拟合平滑后两组数据,解出的两个多项式取值相等时(即在哪些地方存在交叉点),这等价于先对两个多项式函数作差,然后对所得的多项式函数求根。使用 polysub 函数对多项式作差如下:

t = np.arange(N - 1, len(closes_returns))
poly_closes = np.polyfit(t, smooth_closes,N) #求收盘价的多项式
poly_opens = np.polyfit(t, smooth_opens, N)  #求收盘价的多项式
poly_sub = np.polysub(poly_closes, poly_opens)  #polysub函数对多项式作差,
xpoints = np.roots(poly_sub)    #对所得的多项式函数求根
print("Intersection points:", xpoints)

运行结果:

Intersection points: [403.82451866 354.50031142 289.94335284 213.44012464 185.82581983
  97.72837787  51.03724424  18.28586259]

5)用 isreal 函数来判断数组元素是否为实数,用 select 函数选出它们。 select 函数可根据一组给定的条件,从一组元素中挑选出符合条件的元素并返回数组。

得到的实数交叉点、再去掉其中为0的元素。 trim_zeros 函数可以去掉一维数组中开头和末尾为0的元素。

reals = np.isreal(xpoints)  #用isreal 函数来判断数组元素是否为实数
print ("Real number:", reals)

xpoints = np.select([reals], [xpoints]) #select 函数根据一组给定条件,
xpoints = xpoints.real # 从一组元素中挑选出符合条件的元素并返回数组
print("Real intersection points:", xpoints)
print("Sans 0s:", np.trim_zeros(xpoints))#trim_zeros 函数可以去掉一维数组中开头和末尾为0的元素

运行结果如下:

Intersection points: [403.82451866 354.50031142 289.94335284 213.44012464 185.82581983
  97.72837787  51.03724424  18.28586259]
Real number: [ True  True  True  True  True  True  True  True]
Real intersection points: [403.82451866 354.50031142 289.94335284 213.44012464 185.82581983
  97.72837787  51.03724424  18.28586259]
Sans 0s: [403.82451866 354.50031142 289.94335284 213.44012464 185.82581983
  97.72837787  51.03724424  18.28586259]

完整代码如下:

import numpy as np
from datetime import datetime
import matplotlib.pyplot as plt

def datestr2num(s): #定义一个函数
    return datetime.strptime(s.decode('ascii'),"%Y-%m-%d").date().weekday()

opens,highs,lows,closes,vols = np.loadtxt('data036.csv',delimiter=',', usecols=(2,3,4,5,6),converters={1:datestr2num},unpack=True)
#开盘价、最高价、最低价、收盘价、成交量数组。
N=8
weights = np.hanning(N)  #调用hanning 函数计算权重,生成一个长度为8的窗口
print("Weights:", weights)
closes_returns = np.diff(closes) / closes[ : -1] #计算收盘价相邻差价
smooth_closes = np.convolve(weights/weights.sum(), closes_returns) [N-1:-N+1]#利用权重,计算数据平滑
opens_returns = np.diff(opens) / opens[ : -1]    #计算开盘价相邻差价
smooth_opens = np.convolve(weights/weights.sum(), opens_returns) [N-1:-N+1]
t = np.arange(N - 1, len(closes_returns))

#多项式拟合平滑后的数据
t = np.arange(N - 1, len(closes_returns))
poly_closes = np.polyfit(t, smooth_closes,N) #求收盘价的多项式
poly_opens = np.polyfit(t, smooth_opens, N)  #求收盘价的多项式
poly_sub = np.polysub(poly_closes, poly_opens)  #polysub函数对多项式作差,
xpoints = np.roots(poly_sub)    #对所得的多项式函数求根
print("Intersection points:", xpoints)

reals = np.isreal(xpoints)  #用isreal 函数来判断数组元素是否为实数
print ("Real number:", reals)
xpoints = np.select([reals], [xpoints]) #select 函数根据一组给定条件,
xpoints = xpoints.real # 从一组元素中挑选出符合条件的元素并返回数组
print("Real intersection points:", xpoints)
print("Sans 0s:", np.trim_zeros(xpoints))#trim_zeros 函数可以去掉一维数组中开头和末尾为0的元素

plt.plot(t, closes_returns[N-1:], lw=1.0)
plt.plot(t, smooth_closes, lw=2.0)
plt.plot(t, opens_returns[N-1:], lw=1.0)
plt.plot(t, smooth_opens, lw=2.0)
plt.show()

Python数据分析--Numpy常用函数介绍(6)--Numpy中与股票成交量有关的计算

 

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python数据分析–Numpy常用函数介绍(6)–Numpy中与股票成交量有关的计算 - Python技术站

(0)
上一篇 2023年4月2日
下一篇 2023年4月2日

相关文章

  • python数据可视化-matplotlib入门(1)–安装及绘制简单的曲线

    一、安装matplotlib 1)由于已安装anaconda,可直接打开anaconda prompt,再用命令pip install matplotlib进行安装,因镜像问题,可能较慢,建议第2种方式。 2)访问https://pypi.org/project/matplotlib/#files,并查找与你使用的Python版本匹配的wheel文件(扩展名…

    2023年4月2日
    00
  • Python数据分析–Numpy常用函数介绍(2)

    摘要:本篇我们将以分析历史股价为例,介绍怎样从文件中载入数据,以及怎样使用NumPy的基本数学和统计分析函数、学习读写文件的方法,并尝试函数式编程和NumPy线性代数运算,来学习NumPy的常用函数。 一、文件读入 :读写文件是数据分析的一项基本技能 CSV(Comma-Separated Value,逗号分隔值)格式是一种常见的文件格式。通常,数据库的转存…

    2023年4月2日
    00
  • Python数据分析–Numpy常用函数介绍(3)

    摘要:先汇总相关股票价格,然后有选择地对其分类,再计算移动均线、布林线等。 一、汇总数据 汇总整个交易周中从周一到周五的所有数据(包括日期、开盘价、最高价、最低价、收盘价,成交量等),由于我们的数据是从2020年8月24日开始导出,数据多达420条,先截取部分时间段的数据,不妨先读取开始20个交易日的价格。代码如下: import numpy as np f…

    2023年4月2日
    00
  • Python数据分析–Numpy常用函数介绍(8)–Numpy中几中常见的图形

    在NumPy中,所有的标准三角函数如sin、cos、tan等均有对应的通用函数。 一、利萨茹曲线 (Lissajous curve)利萨茹曲线是一种很有趣的使用三角函数的方式(示波器上显示出利萨茹曲线)。利萨茹曲线由以下参数方程定义: x = A sin(at + n/2) y = B sin(bt)利萨茹曲线的参数包括 A 、 B 、 a 和 b 。为简单…

    2023年4月2日
    00
  • Python数据分析–Numpy常用函数介绍(1)–工具安装及Numpy介绍

    Anaconda 是一个跨平台的版本,通过命令行来管理安装包。进行大规模数据处理、预测分析和科学计算。它包括近 200 个工具包,大数据处理需要用到的常见包有 NumPy 、 SciPy 、 pandas 、 IPython 、 Matplotlib 、 Scikit-learn 、gensim、nltk、networkx、beautifulsoup4和st…

    2023年4月2日
    00
  • python入门基础(3) 字符串、列表访问

    一、列表 列表由一系列按特定顺序排列的多个元素或空元素组成,包含字母表中所有字母、数字0~9或所有家庭成员姓名的列表;列表中各元素间可以没有任何关系;实际使用过程中,通常给列表指定一个表示复数的名称,如names,cars,letters,dog_names。 列表大多数是是动态的,列表创建后,将随着程序的运行,列表的长度,数值(或字符串值)都会不断变化,需…

    2023年4月2日
    00
  • python数据可视化-matplotlib入门(6)-从文件中加载数据

    前几篇都是手动录入或随机函数产生的数据。实际有许多类型的文件,以及许多方法,用它们从文件中提取数据来图形化。 比如之前python基础(12)介绍打开文件的方式,可直接读取文件中的数据,扩大了我们的数据来源。下面详细介绍从文件中加载数据。 一、使用内置的 csv 模块加载CSV文件 CSV文件是一种特殊的文本文件,文件中的数据以逗号作为分隔符,很适合进行数据…

    2023年4月2日
    00
  • python入门基础(5)–数值列表、切片及元组

    列表也非常适合存储一组数字,尤其是大数据处理,处理的几乎都是由数字(如气温、距离、人口数量、经济等)组成的集合。 Python提供很多工具,在数据可视化中,可高效地处理数字列表。 一、数值列表    range() 让你能够轻松地生成一系列的数字 for value in range(1,6):    print(value)# 显示结果为1,2,3,4,5…

    2023年4月2日
    00
合作推广
合作推广
分享本页
返回顶部