yahoo finance python中的错误规模

yahoo finance python中的错误规模,python,yahoo-finance,Python,Yahoo Finance,我正在尝试使用雅虎金融下载一些共同基金和ETF的历史价格。我认为雅虎财务有一个漏洞,它混淆了价格的规模,我认为这不是一个分裂的问题。见下图 无论如何,这里有一个MWE来重现问题 import yfinance as yf import pandas as pd from pandas_datareader import data as pdr yf.pdr_override() tickers = ["0P0001FE43.L", "0P00014IJX.L&q

我正在尝试使用雅虎金融下载一些共同基金和ETF的历史价格。我认为雅虎财务有一个漏洞,它混淆了价格的规模,我认为这不是一个分裂的问题。见下图

无论如何,这里有一个MWE来重现问题

import yfinance as yf
import pandas as pd 
from pandas_datareader import data as pdr
yf.pdr_override()

tickers = ["0P0001FE43.L", "0P00014IJX.L", "SGLN.L"]

start_date = "2019-01-01" 
today      = "2021-04-27"

def getData(ticker):
        #print (ticker)
        data = pdr.get_data_yahoo(ticker, start=start_date, end=today)
        data["yahoo_ticker"] = ticker
        files.append(data)

files=[]
for tik in tickers:
    getData(tik)

df = pd.concat(files)
df = df[ [ "Adj Close", "yahoo_ticker"]]
仔细观察调整后的价格可以发现:


我想不出任何系统性的方法来纠正这个问题,所以非常感谢您的帮助。

我查看了SGLN。我很快只查看了雅虎的财务页面,数据对齐。我不是一个市场专家,所以我不能说这里发生了什么,但这些数据似乎是相符的。此外,在这段时间内,音量的上升/下降变得更加不稳定,因此可能与此有关


我查看了SGLN。我很快只看到了雅虎的财务页面,而且数据一致。我不是一个市场专家,所以我不能说这里发生了什么,但这些数据似乎是相符的。此外,在这段时间内,音量的上升/下降变得更加不稳定,因此可能与此有关

为了捕捉和修复一天的活动,我通常会检查一天中是否有很大的间隔。类似这样的东西,将每次收盘与上一次和下一次收盘进行比较,应该可以解决1/100或1*100问题,但没有任何东西阻止您设置另一个阈值或同时使用多个阈值。当历史序列中的差距是由于管理不善造成的时,多重比较可以避免更正

代码:

虽然这样做是可行的,但如果你能下载所有调整后的OHLC字段,我会使用彭博专业版作为数据提供商,我不知道雅虎是否支持,你应该始终将它们相互比较,而不是只比较前一个和下一个的收盘价。这将是一种更稳健的方法,同时你也可以检查O和C是否在H-L范围内,以及其他更常见但微妙的错误。

要捕获并修复一天事件,我通常会检查一天中的间隔是否很大。类似这样的东西,将每次收盘与上一次和下一次收盘进行比较,应该可以解决1/100或1*100问题,但没有任何东西阻止您设置另一个阈值或同时使用多个阈值。当历史序列中的差距是由于管理不善造成的时,多重比较可以避免更正

代码:


虽然这样做是可行的,但如果你能下载所有调整后的OHLC字段,我会使用彭博专业版作为数据提供商,我不知道雅虎是否支持,你应该始终将它们相互比较,而不是只比较前一个和下一个的收盘价。这将是一种更稳健的方法,同时你也可以检查O和C是否在H-L范围内,以及其他更常见但微妙的错误。

一种方法是简单地找出接近100倍的差异,不幸的是,股票可能会大幅波动,因此这可能并不总是有效:

以yf形式导入yf财务 作为pd进口熊猫 从PDU数据读取器将数据作为pdr导入 yf.pdr_覆盖 股票代码=[0P0001FE43.L、0P00014IJX.L、SGLN.L] 开始日期=2019-01-01 今天=2021-04-27 def getDataticker: data=pdr.get\u data\u yahooticker,start=start\u date,end=today 数据[雅虎股票代码]=股票代码 修复超过40倍于最小值的数据 掩码=数据['Adj Close']<40*数据['Adj Close'].min 数据['Adj Close']=数据['Adj Close']*1+99*掩码 printf'Fixed{summask}/{lenmask}用于ticker{ticker}的数据点 返回数据 df=pd.concat[getDatatik用于tik-in-tickers] df=df[[Adj Close,yahoo_ticker]] printdf
一种方法是简单地找出接近100倍的差异,不幸的是,股票可能会大幅波动,因此这可能并不总是有效:

以yf形式导入yf财务 作为pd进口熊猫 从PDU数据读取器将数据作为pdr导入 yf.pdr_覆盖 股票代码=[0P0001FE43.L、0P00014IJX.L、SGLN.L] 开始日期=2019-01-01 今天=2021-04-27 def getDataticker: data=pdr.get\u data\u yahooticker,start=start\u date,end=today 数据[雅虎股票代码]=股票代码 修复超过40倍于最小值的数据 掩码=数据['Adj Close']<40*数据['Adj Close'].min 数据['Adj Close']=数据['Adj Close']*1+99*掩码 printf'Fixed{summask}/{lenmask}用于ticker{ticker}的数据点 返回数据 df=pd.concat[getDatatik用于tik-in-tickers] df=df[[Adj Close,yahoo_ticker]] printdf
我找到了另一个解决方案,我认为它应该比我的另一个答案更可靠。这并不是看整个历史,而是看50倍或更高的单日跳跃,这永远不会自然发生

以yf形式导入yf财务 作为pd进口熊猫 从PDU数据读取器将数据作为pdr导入 yf.pdr_覆盖 股票代码=[0P0001FE43.L、0P00014IJX.L、SGLN.L] 开始日期=2019-01-01 今天=2021-04-27 def getDataticker: data=pdr.get\u data\u yahooticker,start=start\u date,end=today 数据[雅虎股票代码]=股票代码 修复跳转100倍的错误yahoo数据 向上跳转=数据['Adj Close']/data['Adj Close'] '].shift>50 向下跳转=数据['Adj Close']/data['Adj Close'].shift<.02 校正系数=100.**向下跳转.cumsum-向上跳转.cumsum 数据['Adj Close']*=校正系数 股票代码{ticker}的printfFixed{sumcorrection_factor!=1}/{lendata} f min:{data['Adj Close'].min},max:{data['Adj Close'].max} 返回数据 df=pd.concat[getDatatik用于tik-in-tickers] df=df[[Adj Close,yahoo_ticker]] printdf
我找到了另一个解决方案,我认为它应该比我的另一个答案更可靠。这并不是看整个历史,而是看50倍或更高的单日跳跃,这永远不会自然发生

以yf形式导入yf财务 作为pd进口熊猫 从PDU数据读取器将数据作为pdr导入 yf.pdr_覆盖 股票代码=[0P0001FE43.L、0P00014IJX.L、SGLN.L] 开始日期=2019-01-01 今天=2021-04-27 def getDataticker: data=pdr.get\u data\u yahooticker,start=start\u date,end=today 数据[雅虎股票代码]=股票代码 修复跳转100倍的错误yahoo数据 向上跳转=数据['Adj Close']/data['Adj Close'].shift>50 向下跳转=数据['Adj Close']/data['Adj Close'].shift<.02 校正系数=100.**向下跳转.cumsum-向上跳转.cumsum 数据['Adj Close']*=校正系数 股票代码{ticker}的printfFixed{sumcorrection_factor!=1}/{lendata} f min:{data['Adj Close'].min},max:{data['Adj Close'].max} 返回数据 df=pd.concat[getDatatik用于tik-in-tickers] df=df[[Adj Close,yahoo_ticker]] printdf 事实上,这是数据集中的一个错误,而不是包中的一个bug。

对于影响几天的情况,我建议用NaN替换错误行,然后使用

事实上,这是数据集中的一个错误,而不是包中的一个bug。

对于影响几天的情况,我建议用NaN替换错误行,然后使用


你是对的,这是一个URL:雅虎方面的记录似乎不好,而不是一个编程错误。你是对的,这是一个URL:雅虎方面的记录似乎不好,而不是一个编程错误。它与其他有问题的代码一起工作。因此,该方法看起来相当稳健。它与那些加上其他有问题的报价器一起工作。因此,该方法看起来相当稳健。您应该仅在缺少数据时进行插值,而不是小数点错误。您应该修复小数点错误。如果你用插值法填写N/A,你还应该记得在整个市场关闭或股票因任何原因未交易时添加一个标志以避免交易。你的回溯测试将向你展示一笔交易,而实际上这是一笔无法完成的交易。很好的观点@nico9T。如果是小数点错误,则有必要确定错误10^x,然后将错误数据缩放10^x。感谢您的反馈。您应该仅在缺少数据时进行插值,而不是小数点错误。您应该修复小数点错误。如果你用插值法填写N/A,你还应该记得在整个市场关闭或股票因任何原因未交易时添加一个标志以避免交易。你的回溯测试将向你展示一笔交易,而实际上这是一笔无法完成的交易。很好的观点@nico9T。如果是小数点错误,则有必要确定错误10^x,然后将错误数据缩放10^x。谢谢你的反馈。
fixed = [l[0]]

i = 1

while i < len(l) -1:
        
    p = l[i] / l[i-1]
    n = l[i+1] / l[i]

    if p < 0.1 and n >= 100:
        fixed.append(l[i] * 100)      
    elif p >= 100 and n < 0.1:
        fixed.append(round(l[i] / 100, 5))
    else:
        fixed.append(l[i])
    
    i += 1
            
# Last value
        
p =  fixed[-1] / l[-1]

if p >= 100:
    fixed.append(l[i] * 100)      
elif p < 0.1:
    fixed.append(round(l[i] / 100, 5))
else:
    fixed.append(l[i])
l = [171.062, 1.71945, 172.901, 172.184]
[171.062, 171.945, 172.901, 172.184]

l = [1.71062, 1.71945, 172.901, 1.72184]
[1.71062, 1.71945, 1.72901, 1.72184]
Fixed 5/587 datapoints for ticker 0P0001FE43.L
Fixed 1/587 datapoints for ticker 0P00014IJX.L
Fixed 288/586 datapoints for ticker SGLN.L
Fixed 5/587 for ticker 0P0001FE43.L (min: 97.52300262451172, max: 174.1580047607422)
Fixed 1/587 for ticker 0P00014IJX.L (min: 169.8939971923828, max: 376.5379943847656)
Fixed 288/586 for ticker SGLN.L (min: 2195.0, max: 3388.9999389648438)
faulty = df['Adj Close'].le(df['Adj Close'].shift()*0.1)
df.at[faulty[faulty].index, :] = np.nan
df['Adj Close'] = df['Adj Close'].interpolate()