numpy数组符号化与函数向量化

计算净额成交量

Key_Function:

np.sign(数组): 返回数组中每个元素的正负符号

np.piecewise(数组, 条件列表, 返回值列表): 通过条件列表中的元素, 判断数组中的元素在条件列表中的索引, 取返回值列表对应的索引, 当做返回值, 用这些返回值组成一个新的数组

Code:

import numpy as np
import matplotlib.pyplot as plt

c, v = np.loadtxt('BHP.csv', delimiter=',', usecols=(6,7), unpack=True)
# c是每日收盘价, v是每日成交量
'''
c
[ 93.72  95.64  94.56  93.3   93.93  92.39  92.11  92.36  91.76  93.91
  94.6   93.27  94.43  96.02  95.76  94.47  94.34  92.22  88.31  89.59
  89.02  86.95  84.88  87.38  88.56  89.59  88.71  90.02  91.26  90.67]
v
[ 1741900.  2620800.  2461300.  3270900.  2650200.  4667300.  5359800.
  7768400.  4799100.  3448300.  4719800.  3898900.  3727700.  3379400.
  2463900.  3590900.  3805000.  3271700.  5507800.  2996800.  3434800.
  5008300.  7809799.  3947100.  3809700.  3098200.  3500200.  4285600.
  3918800.  3632200.]

'''
# 计算每日收盘价的差
change = np.diff(c)
print(change)
'''
[ 1.92 -1.08 -1.26  0.63 -1.54 -0.28  0.25 -0.6   2.15  0.69 -1.33  1.16
  1.59 -0.26 -1.29 -0.13 -2.12 -3.91  1.28 -0.57 -2.07 -2.07  2.5   1.18
  1.03 -0.88  1.31  1.24 -0.59]
'''

signs = np.sign(change)
print(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.]
'''
# 通过判断数组元素是否满足条件, 返回满足条件的返回值
pieces = np.piecewise(change, [change < 0, change > 0], [-1, 1])
print(pieces)
'''
[ 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.]
'''

print(np.array_equal(signs, pieces))
# True

# 计算OBV值  OBV值,就是当天的成交量, 但其正负依赖于收盘价的变化量
print(v[1:] * signs)
'''
[ 2620800. -2461300. -3270900.  2650200. -4667300. -5359800.  7768400.
 -4799100.  3448300.  4719800. -3898900.  3727700.  3379400. -2463900.
 -3590900. -3805000. -3271700. -5507800.  2996800. -3434800. -5008300.
 -7809799.  3947100.  3809700.  3098200. -3500200.  4285600.  3918800.
 -3632200.]
'''

交易过程模拟

Key_Function:

np.vectorize函数: 相当于python的map函数, 将函数向量化, 即输入参数从单个元素变成向量

  避免了使用循环遍历数组中的每一个元素

ndarray对象可以在[]中填入条件, 进行元素的过滤

def myfunc(a, b):
    "Return a-b if a>b, otherwise return a+b"
    if a > b:
        return a - b
    else:
        return a + b
    

vfunc = np.vectorize(myfunc)

vfunc([1, 2, 3, 4], 2)
# array([3, 4, 1, 2])
       

Code:

import numpy as np
import matplotlib.pyplot as plt

o, h, l, c = np.loadtxt('BHP.csv', delimiter=',', usecols=(3,4,5,6), unpack=True)
# 开盘价,最高价, 最低价, 收盘价

def calc_profit(open, high, low, close):
    # 以比开盘价稍低的价格买入
    buy = open * float(0.999)
    # 当日股价区间
    if low < buy < high:
        return (close - buy) / buy     # 计算当日相对利润
    else:
        return 0
    
# np.vectorize() 将函数向量化
func = np.vectorize(calc_profit)    # 将4个输入数组, 输出成一个数组

profits = func(o, h, l, c)
print(profits)
'''
[ 0.00755895  0.0123267   0.0021668   0.00780612  0.          0.00154302
 -0.01006869  0.00568316 -0.00614746  0.00560552 -0.00121617 -0.01774473
  0.00675817  0.00225356 -0.00274807 -0.02015786  0.00762307 -0.00675369
 -0.00675957  0.          0.01065112  0.02904986 -0.01558377  0.00168882
 -0.0098442  -0.00499634 -0.00783465  0.00603003  0.00540779  0.00376864]
'''
    
real_trades = profits[profits != 0]     # 过滤掉等于0的元素
print(len(real_trades),"  ", round(100.0 * len(real_trades)/len(c),2), "%")
# 28    93.33 %
# 数组的除法是对应元素相除

print(round(np.mean(real_trades) * 100,2 )) # 2表示取两位有效数字
# 0.02

winning_trades = profits[profits > 0]
print(len(winning_trades), round(100.0 * len(winning_trades)/len(c), 2), "%")
# 16 53.33 %
print(round(np.mean(winning_trades) * 100, 2))
# 0.72


losing_trades = profits[profits < 0]
print(len(losing_trades), round(100.0 * len(losing_trades)/len(c), 2), "%")
# 12 40.0 %
print(round(np.mean(losing_trades) * 100, 2))
# -0.92
原文地址:https://www.cnblogs.com/draven123/p/11392021.html