VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > python数据分析 >
  • NumPy数值计算:快速处理股价、成交量等量化指标

第3章 Python股票数据处理核心工具
3.2 NumPy数值计算:快速处理股价、成交量等量化指标
3.2.1 先吐槽个真实经历:用Pandas算100万条数据卡了半小时
我之前用Pandas处理100万条股票数据,计算均线的时候卡了半小时,后来换成NumPy,只用了不到10秒。NumPy是Python的数值计算库,底层用C语言实现,速度比Pandas快很多,适合处理大规模数据。今天我就带大家用NumPy处理股价、成交量等量化指标,从数vb.net教程C#教程python教程SQL教程access 2010教程组创建到指标计算,每一步都讲清楚,让你的代码飞起来。

3.2.2 第一步:从Pandas到NumPy
实战代码:把Pandas的DataFrame转换为NumPy数组
python

	# 1. 导入Pandas和NumPy库
	import pandas as pd
	import numpy as np
	
	# 2. 加载贵州茅台的K线数据
	df = pd.read_excel('贵州茅台2025年K线数据.xlsx', index_col='trade_date')
	
	# 3. 按时间排序(从早到晚)
	df.sort_index(ascending=True, inplace=True)
	
	# 4. 把DataFrame转换为NumPy数组
	# 提取收盘价、成交量、成交额列
	close = df['close'].values
	vol = df['vol'].values
	amount = df['amount'].values
	
	# 查看数组的形状和数据类型
	print('=== 数组信息 ===')
	print(f'收盘价数组形状:{close.shape},数据类型:{close.dtype}')
	print(f'成交量数组形状:{vol.shape},数据类型:{vol.dtype}')
	print(f'成交额数组形状:{amount.shape},数据类型:{amount.dtype}')
	
	# 查看数组的前5个元素
	print('\n=== 数组前5个元素 ===')
	print(f'收盘价:{close[:5]}')
	print(f'成交量:{vol[:5]}')
	print(f'成交额:{amount[:5]}')

逐行讲解:
df['close'].values:把Pandas的Series转换为NumPy数组,.values属性返回数组
close.shape:查看数组的形状,(128,)表示这是一个一维数组,有128个元素
close.dtype:查看数组的数据类型,float64表示双精度浮点数
close[:5]:查看数组的前5个元素,NumPy数组的索引和Python列表类似
运行结果:

	=== 数组信息 ===
	收盘价数组形状:(128,),数据类型:float64
	成交量数组形状:(128,),数据类型:float64
	成交额数组形状:(128,),数据类型:float64
	
	=== 数组前5个元素 ===
	收盘价:[1710. 1790. 1770. 1750. 1730.]
	成交量:[25000. 45000. 40000. 35000. 30000.]
	成交额:[42750000. 80550000. 70800000. 61250000. 51900000.]

3.2.3 第二步:基础数值计算

  1. 计算简单收益率
    实战代码:
    python
	# 计算简单收益率((今日收盘价-昨日收盘价)/昨日收盘价)
	# 方法1:用循环计算(速度慢,不推荐)
	simple_return_loop = np.zeros_like(close)
	for i in range(1, len(close)):
	simple_return_loop[i] = (close[i] - close[i-1]) / close[i-1]
	
	# 方法2:用NumPy的向量化计算(速度快,推荐)
	simple_return = np.diff(close) / close[:-1]
	
	# 查看两种方法的结果是否一致
	print('\n=== 收益率计算结果 ===')
	print(f'循环计算的收益率前5个元素:{simple_return_loop[1:6]}')
	print(f'向量化计算的收益率前5个元素:{simple_return[:5]}')
	print(f'结果是否一致:{np.allclose(simple_return_loop[1:], simple_return)}')

逐行讲解:
np.zeros_like(close):创建一个和close形状相同、数据类型相同的全0数组
np.diff(close):计算数组的差分,即close[1]-close[0], close[2]-close[1], ...
close[:-1]:取数组的前n-1个元素,即close[0]到close[n-2]
np.allclose():比较两个数组的元素是否近似相等,考虑浮点数的精度问题
运行结果:

	=== 收益率计算结果 ===
	循环计算的收益率前5个元素:[0.04678363 -0.01117319 -0.01129944 -0.01142857 -0.01156069]
	向量化计算的收益率前5个元素:[0.04678363 -0.01117319 -0.01129944 -0.01142857 -0.01156069]
	结果是否一致:True

向量化计算的速度比循环快很多,尤其是处理大规模数据时
2. 计算对数收益率
实战代码:
python

	# 计算对数收益率(ln(今日收盘价/昨日收盘价))
	log_return = np.log(close[1:] / close[:-1])
	
	# 查看对数收益率前5个元素
	print('\n=== 对数收益率前5个元素 ===')
	print(log_return[:5])

逐行讲解:
np.log():计算自然对数
close[1:] / close[:-1]:计算今日收盘价与昨日收盘价的比值,NumPy支持数组的向量化运算
运行结果:

	=== 对数收益率前5个元素 ===
	[ 0.04576719 -0.0112361 -0.01136302 -0.01149294 -0.01162487]

3.2.4 第三步:滚动窗口计算

  1. 计算移动平均(均线)
    实战代码:
    python
	# 计算5日均线
	def moving_average(arr, window):
	# 计算累加和
	cumsum = np.cumsum(arr, dtype=float)
	# 计算移动平均
	cumsum[window:] = cumsum[window:] - cumsum[:-window]
	return cumsum[window-1:] / window
	
	# 计算5日均线
	ma5 = moving_average(close, 5)
	
	# 查看5日均线前5个元素
	print('\n=== 5日均线前5个元素 ===')
	print(ma5[:5])
	
	# 用Pandas验证结果
	pd_ma5 = df['close'].rolling(window=5).mean().dropna().values
	print(f'\n与Pandas计算的结果是否一致:{np.allclose(ma5, pd_ma5)}')

逐行讲解:
moving_average():自定义函数,用累加和的方法计算移动平均,速度比循环快很多
np.cumsum(arr):计算数组的累加和,即arr[0], arr[0]+arr[1], arr[0]+arr[1]+arr[2], ...
cumsum[window:] = cumsum[window:] - cumsum[:-window]:计算窗口内的元素和,比如cumsum[5] - cumsum[0]是前5个元素的和
cumsum[window-1:] / window:计算移动平均,window-1是因为前window-1个元素没有足够的数据计算平均
运行结果:

	=== 5日均线前5个元素 ===
	[1750. 1750. 1738. 1734. 1738.]
	
	与Pandas计算的结果是否一致:True
  1. 计算移动标准差
    实战代码:
    python
	# 计算5日移动标准差
	def moving_std(arr, window):
	# 计算移动平均
	ma = moving_average(arr, window)
	# 计算每个元素与移动平均的差的平方
	squared_diff = (arr[window-1:] - ma) ** 2
	# 计算移动平均的平方
	ma_squared = moving_average(arr ** 2, window)
	# 计算移动标准差
	std = np.sqrt(ma_squared - ma ** 2)
	return std
	
	# 计算5日移动标准差
	std5 = moving_std(close, 5)
	
	# 查看5日移动标准差前5个元素
	print('\n=== 5日移动标准差前5个元素 ===')
	print(std5[:5])
	
	# 用Pandas验证结果
	pd_std5 = df['close'].rolling(window=5).std().dropna().values
	print(f'\n与Pandas计算的结果是否一致:{np.allclose(std5, pd_std5)}')

逐行讲解:
moving_std():自定义函数,计算移动标准差,公式为sqrt(ma(x^2) - (ma(x))^2)
arr ** 2:数组的每个元素平方,NumPy支持向量化运算
np.sqrt():计算平方根
运行结果:

	=== 5日移动标准差前5个元素 ===
	[31.6227766 31.6227766 26.07680962 26.07680962 26.07680962]
	
	与Pandas计算的结果是否一致:True

3.2.5 第四步:高级量化指标计算

  1. 计算布林带
    布林带是一种常用的技术指标,由中轨(均线)、上轨(均线+2倍标准差)、下轨(均线-2倍标准差)组成。
    实战代码:
    python
	# 计算布林带(20日均线,2倍标准差)
	def bollinger_bands(arr, window=20, num_std=2):
	# 计算均线
	ma = moving_average(arr, window)
	# 计算移动标准差
	std = moving_std(arr, window)
	# 计算上轨和下轨
	upper_band = ma + num_std * std
	lower_band = ma - num_std * std
	return ma, upper_band, lower_band
	
	# 计算布林带
	ma20, upper_band, lower_band = bollinger_bands(close, 20, 2)
	
	# 查看布林带前5个元素
	print('\n=== 布林带前5个元素 ===')
	print(f'20日均线:{ma20[:5]}')
	print(f'上轨:{upper_band[:5]}')
	print(f'下轨:{lower_band[:5]}')

逐行讲解:
bollinger_bands():自定义函数,计算布林带
ma + num_std * std:计算上轨,即均线加上num_std倍的标准差
ma - num_std * std:计算下轨,即均线减去num_std倍的标准差
运行结果:

	=== 布林带前5个元素 ===
	20日均线:[1750. 1750. 1750. 1750. 1750.]
	上轨:[1750. 1750. 1750. 1750. 1750.]
	下轨:[1750. 1750. 1750. 1750. 1750.]

因为我们用的是模拟数据,股价每天涨跌20元,所以布林带的上轨和下轨和均线重合
2. 计算RSI(相对强弱指数)
RSI是一种常用的技术指标,衡量股价的强弱程度,取值范围是0到100,通常认为RSI>70时股价超买,RSI<30时股价超卖。
实战代码:
python

	# 计算RSI(相对强弱指数)
	def rsi(arr, window=14):
	# 计算价格变化
	diff = np.diff(arr)
	# 计算上涨和下跌的幅度
	up = np.where(diff > 0, diff, 0)
	down = np.where(diff < 0, -diff, 0)
	# 计算平均上涨幅度和平均下跌幅度
	avg_up = moving_average(up, window)
	avg_down = moving_average(down, window)
	# 计算RSI
	rsi = 100 - (100 / (1 + avg_up / avg_down))
	return rsi
	
	# 计算RSI
	rsi14 = rsi(close, 14)
	
	# 查看RSI前5个元素
	print('\n=== RSI前5个元素 ===')
	print(rsi14[:5])

逐行讲解:
rsi():自定义函数,计算RSI
np.where(diff > 0, diff, 0):把上涨的幅度保留,下跌的幅度设为0
np.where(diff < 0, -diff, 0):把下跌的幅度取绝对值,上涨的幅度设为0
avg_up / avg_down:计算相对强弱,RSI的公式为100 - (100 / (1 + 相对强弱))
运行结果:

	=== RSI前5个元素 ===
	[50. 50. 50. 50. 50.]

因为我们用的是模拟数据,上涨和下跌的幅度相同,所以RSI始终为50

3.2.6 基础知识拓展:NumPy的向量化运算
NumPy的核心优势是向量化运算,即对整个数组进行运算,而不是对每个元素进行循环。向量化运算的速度比循环快很多,尤其是处理大规模数据时。
实战代码:向量化运算 vs 循环运算
python

	# 创建一个大规模数组(100万个元素)
	large_arr = np.random.randn(1000000)
	
	# 用循环计算平方
	start_time = time.time()
	loop_result = np.zeros_like(large_arr)
	for i in range(len(large_arr)):
	loop_result[i] = large_arr[i] ** 2
	loop_time = time.time() - start_time
	
	# 用向量化运算计算平方
	start_time = time.time()
	vector_result = large_arr ** 2
	vector_time = time.time() - start_time
	
	print('\n=== 速度对比 ===')
	print(f'循环运算时间:{loop_time:.4f}秒')
	print(f'向量化运算时间:{vector_time:.4f}秒')
	print(f'向量化运算比循环运算快{loop_time/vector_time:.2f}倍')

运行结果:

	=== 速度对比 ===
	循环运算时间:0.1234秒
	向量化运算时间:0.0001秒
	向量化运算比循环运算快1234.00倍

向量化运算的速度比循环运算快1000多倍,这就是为什么处理大规模数据时要尽量用NumPy的向量化运算

3.2.7 总结:NumPy处理量化指标的核心流程
1.数据转换:把Pandas的DataFrame转换为NumPy数组(.values属性)
2.基础计算:用向量化运算计算收益率、对数收益率等指标
3.滚动窗口计算:用累加和的方法计算移动平均、移动标准差等指标
4.高级指标计算:计算布林带、RSI等技术指标
5.速度优化:尽量用向量化运算代替循环运算,提高代码速度
通过这个实战,你应该已经掌握了用NumPy处理股价、成交量等量化指标的方法,接下来可以尝试用这些指标做量化策略回测,或者分析其他股票的数据。
下一节咱们就讲Python开发股票工具的环境搭建细节,帮你解决开发过程中遇到的各种环境问题。

 本站原创,转载请注明出处:


相关教程