使用Pandas实现加权移动平均(WMA)迭代26次后值归零的BUG求助
加权移动平均(WMA)计算函数BUG排查求助
问题概述
测试价格指标计算用的WMA函数时,迭代至索引27后,WMA值突然降至0.0,无法定位原因,请求协助排查。
数据处理规范
测试用CSV列名均为小写,需用以下代码预处理:
data = pd.read_csv(csv_path) data = data.drop(['symbol'], axis=1) data.rename(columns={'open': 'Open', 'high': 'High', 'low': 'Low', 'close': 'Close', 'volume': 'Volume'}, inplace=True)
CSV仅包含Open/High/Low/Close/Volume字段,input_mode参数不可超过4(无HL2、HLC3等衍生价格数据)。
WMA计算函数代码
使用默认参数测试以下函数:
def wma(price_df: PandasDataFrame, n: int = 14, input_mode: int = 2, from_price: bool = True, *, indicator_name: str = 'None') -> PandasDataFrame: if from_price: name_var, state = input_type(__input_mode__=input_mode) else: if indicator_name == 'None': raise TypeError('Invalid input argument. indicator_name cannot be set to None if from_price is False.') else: name_var = indicator_name wma_n = pd.DataFrame(index=range(price_df.shape[0]), columns=range(1)) wma_n.rename(columns={0: f'WMA{n}'}, inplace=True) weight = np.arange(1, (n + 1)).astype('float64') weight = weight * n norm = sum(weight) weight_df = pd.DataFrame(weight) weight_df.rename(columns={0: 'weight'}, inplace=True) product = pd.DataFrame() product_sum = 0 for i in range(price_df.shape[0]): if i < (n - 1): # 创建无法计算WMA的NaN值 wma_n[f'WMA{n}'].iloc[i] = np.nan elif i == (n - 1): product = price_df[f'{name_var}'].iloc[:(i + 1)] * weight_df['weight'] product_sum = product.sum() wma_n[f'WMA{n}'].iloc[i] = product_sum / norm print(f'index: {i}, wma: ', wma_n[f'WMA{n}'].iloc[i]) print(product_sum) print(norm) product = product.iloc[0:0] product_sum = 0 elif i > (n - 1): product = price_df[f'{name_var}'].iloc[(i - (n - 1)): (i + 1)] * weight_df['weight'] product_sum = product.sum() wma_n[f'WMA{n}'].iloc[i] = product_sum / norm print(f'index: {i}, wma: ', wma_n[f'WMA{n}'].iloc[i]) print(product_sum) print(norm) product = product.iloc[0:0] product_sum = 0 return wma_n
辅助函数代码
def input_type(__input_mode__: int) -> (str, bool): list_of_inputs = ['Open', 'Close', 'High', 'Low', 'HL2', 'HLC3', 'OHLC4', 'HLCC4'] if __input_mode__ in range(1, 10, 1): input_name = list_of_inputs[__input_mode__ - 1] state = True return input_name, state else: raise TypeError('__input_mode__ out of range.')
实际输出结果
index: 13, wma: 14467.42857142857 product_sum: 21267120.0 norm 1470.0 index: 14, wma: 14329.609523809524 product_sum: 21064526.0 norm 1470.0 index: 15, wma: 14053.980952380953 product_sum: 20659352.0 norm 1470.0 index: 16, wma: 13640.480952380953 product_sum: 20051507.0 norm 1470.0 index: 17, wma: 13089.029523809522 product_sum: 19240873.4 norm 1470.0 index: 18, wma: 12399.72 product_sum: 18227588.4 norm 1470.0 index: 19, wma: 11572.234285714285 product_sum: 17011184.4 norm 1470.0 index: 20, wma: 10607.100952380953 product_sum: 15592438.4 norm 1470.0 index: 21, wma: 9504.32 product_sum: 13971350.4 norm 1470.0 index: 22, wma: 8263.905714285715 product_sum: 12147941.4 norm 1470.0 index: 23, wma: 6885.667619047619 product_sum: 10121931.4 norm 1470.0 index: 24, wma: 5369.710476190477 product_sum: 7893474.4 norm 1470.0 index: 25, wma: 3716.270476190476 product_sum: 5462917.6 norm 1470.0 index: 26, wma: 1926.48 product_sum: 2831925.6 norm 1470.0 index: 27, wma: 0.0 product_sum: 0.0 norm 1470.0 index: 28, wma: 0.0 product_sum: 0.0 norm 1470.0
内容的提问来源于stack exchange,提问作者Jakub Szurlej
相关产品推荐
相关产品推荐

