You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Williams AD指标函数调用报错:Timestamp与int无法比较的解决方法

Williams AD指标函数报错解决办法

问题重现

使用实现William's Accumulation/Distribution指标的函数,传入yfinance获取的SPY股票数据(索引为Timestamp类型的DataFrame)时,调用williams_ad(df)触发以下错误:

TypeError: '>' not supported between instances of 'Timestamp' and 'int'

错误原因

函数中通过if index > 0判断是否为第一行之后的数据,但DataFrame的索引是Timestamp类型,无法直接与整数0进行比较,导致类型不匹配。

解决方案

方案1:使用位置索引替代标签索引

修改循环逻辑,通过enumerate获取迭代的位置序号,避免直接使用Timestamp索引进行判断,同时修复已弃用的set_value方法:

def williams_ad(data, high_col='High', low_col='Low', close_col='Close'):
    # 复制数据避免修改原DataFrame
    data_copy = data.copy()
    data_copy['williams_ad'] = 0.0
    
    for pos, (index, row) in enumerate(data_copy.iterrows()):
        if pos > 0:
            prev_index = data_copy.index[pos-1]
            prev_value = data_copy.at[prev_index, 'williams_ad']
            prev_close = data_copy.at[prev_index, close_col]
            
            if row[close_col] > prev_close:
                ad = row[close_col] - min(prev_close, row[low_col])
            elif row[close_col] < prev_close:
                ad = row[close_col] - max(prev_close, row[high_col])
            else:
                ad = 0.0
                                                                                                        
            data_copy.at[index, 'williams_ad'] = ad + prev_value
        
    return data_copy

方案2:临时重置为整数索引

先将DataFrame索引重置为整数,计算完成后恢复原索引:

def williams_ad(data, high_col='High', low_col='Low', close_col='Close'):
    data_copy = data.copy().reset_index()
    data_copy['williams_ad'] = 0.0
    
    for index, row in data_copy.iterrows():
        if index > 0:
            prev_value = data_copy.at[index-1, 'williams_ad']
            prev_close = data_copy.at[index-1, close_col]
            if row[close_col] > prev_close:
                ad = row[close_col] - min(prev_close, row[low_col])
            elif row[close_col] < prev_close:
                ad = row[close_col] - max(prev_close, row[high_col])
            else:
                ad = 0.0
                                                                                                        
            data_copy.at[index, 'williams_ad'] = ad + prev_value
    
    # 恢复原索引
    return data_copy.set_index(data.index.name)

方案3:Pandas向量化操作(高效推荐)

用向量化运算替代循环,大幅提升处理大数据的效率:

import numpy as np
import pandas as pd

def williams_ad(data, high_col='High', low_col='Low', close_col='Close'):
    data_copy = data.copy()
    prev_close = data_copy[close_col].shift(1)
    
    # 计算AD增量
    cond_up = data_copy[close_col] > prev_close
    cond_down = data_copy[close_col] < prev_close
    
    ad = pd.Series(0.0, index=data_copy.index)
    ad[cond_up] = data_copy.loc[cond_up, close_col] - np.minimum(prev_close[cond_up], data_copy.loc[cond_up, low_col])
    ad[cond_down] = data_copy.loc[cond_down, close_col] - np.maximum(prev_close[cond_down], data_copy.loc[cond_down, high_col])
    
    # 累加得到最终Williams AD值
    data_copy['williams_ad'] = ad.cumsum()
    
    return data_copy

验证

调用修改后的函数即可正常运行:

import pandas as pd
import yfinance as yF

df = yF.download(tickers="SPY", period="5y", interval="1d", prepost=False, repair=True)
result_df = williams_ad(df)
print(result_df['williams_ad'].tail())

内容的提问来源于stack exchange,提问作者prashanth manohar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 04:08:13