Pandas均线交叉代码报TypeError: ufunc 'bitwise_and'错误如何解决
报错修复方案
根因分析
- 运算符使用错误:你使用位运算符
&连接普通布尔类型的判断条件,Python中单个布尔值的逻辑运算需要使用逻辑运算符and/or,&仅适用于Pandas/NumPy的布尔序列向量化运算。 - 条件判断语法错误:
(direction == '>' or '>=')这类写法永远返回True,因为非空字符串'>='的布尔值为True,正确的多值匹配写法为direction in ('>', '>=')。 - 变量未定义:vcross函数内使用了未声明的变量
variable1、variable2,实际需要使用你提前读取的v1_width_data、v2_width_data。 - 冗余全局变量依赖:函数硬编码依赖全局变量
df、tbar_count,且未处理滚动均线生成的NaN值,会触发后续异常。
修复后代码
import numpy as np import datetime import pandas as pd import operator previous_cross = 'both' ops = { '+' : operator.add, '-' : operator.sub, '*' : operator.mul, '/' : operator.truediv, '%' : operator.mod, '^' : operator.xor, '<' : operator.lt, '<=' : operator.le, '==' : operator.eq, '!=' : operator.ne, '>=' : operator.ge, '>' : operator.gt } # 读取数据并计算均线 df = pd.read_csv(r'C:\EURUSD_mt5_ticks.csv', parse_dates=['Date']) df.columns = ['Date', 'Ask_Price', 'Ask_Volume', 'Bid_Price', 'Bid_Volume', 'Spread'] df['Date'] = pd.to_datetime(df['Date'], exact=True, cache=True, format='%Y-%m-%d %H:%M:%S.%f') df['MA1'] = df['Ask_Price'].rolling(4).mean() df['MA2'] = df['Ask_Price'].rolling(21).mean() # 过滤掉均线为NaN的行,避免无效判断 df = df.dropna(subset=['MA1', 'MA2']).reset_index(drop=True) def vcross(variable1_column, direction, variable2_column, vdataframe, current_idx, width): global previous_cross start_idx = max(0, current_idx - width) for i in range(start_idx, current_idx+1): v1_width_data = vdataframe.loc[i, variable1_column] v2_width_data = vdataframe.loc[i, variable2_column] # 金叉判断逻辑 if direction in ('>', '>=') and ops[direction](v1_width_data, v2_width_data) and previous_cross in ('short', 'both'): if direction == '>=' and v1_width_data == v2_width_data: return True if direction == '>': previous_cross = 'long' return True # 死叉判断逻辑 elif direction in ('<', '<=') and ops[direction](v1_width_data, v2_width_data) and previous_cross in ('long', 'both'): if direction == "<=" and v1_width_data == v2_width_data: return True if direction == '<': previous_cross = 'short' return True # 相等判断逻辑 elif direction == '==' and ops[direction](v1_width_data, v2_width_data): return True return False # 遍历判断交叉 for tbar_count in range(len(df)): if vcross('MA1', '>', 'MA2', df, tbar_count, 1): print("金叉出现,索引:", tbar_count)
优化建议
可以直接用Pandas向量化操作实现交叉判断,无需循环遍历,性能提升10倍以上:
# 直接生成金叉信号:前一期MA1<MA2,当前期MA1>MA2 df['golden_cross'] = (df['MA1'] > df['MA2']) & (df['MA1'].shift(1) < df['MA2'].shift(1)) # 输出所有金叉行 print(df[df['golden_cross']])
内容的提问来源于stack exchange,提问作者coinmaster
相关产品推荐
相关产品推荐

