yfinance获取ITT股票市场价格及前收盘价数据异常问题咨询
异常原因
- 接口缓存一致性问题:yfinance底层调用雅虎财经公开接口,雅虎的多CDN节点缓存更新存在时差,尤其是在美股盘后/盘前的非交易时段,部分节点缓存的是当日交易时段的正式数据,部分节点已经更新了盘后撮合的临时数据,不同请求命中不同节点就会出现价格跳变,你遇到的99.69和95.76来回切换就是命中了新旧两套缓存。
- 字段取值逻辑不稳定:
regularMarketPrice、regularMarketPreviousClose两个字段在非交易时段没有明确的取值规则,雅虎接口会随机在「当日正式收盘价」「盘后成交价」「下一日预估值」几个值之间切换,没有固定标准。 - 代码实现问题:你在每次循环中都重新初始化
yf.Ticker(symbol)实例,每次初始化都会发起新的独立请求,进一步提升了命中不同缓存节点的概率,放大了数据波动的问题。
解决方案
- 复用Ticker实例:不要每次循环新建实例,复用同一个实例会复用内部的会话连接,大概率会请求同一个CDN节点,减少缓存不一致的问题。
- 替换更稳定的取值接口:用
fast_info代替info字段取值,fast_info是yfinance专门优化的轻量接口,数据更新逻辑更一致,异常值出现概率远低于info。 - 增加数据校验规则:添加简单的阈值校验,比如如果当前价格与上一次有效值的涨跌幅超过10%(ITT属于低波动工业股,正常情况下单日涨跌幅极少超过10%),则判定为异常值,重试获取直到拿到合理值,或者直接丢弃异常值。
- 非交易时段优先取正式清算数据:如果需要稳定的前收盘价,不要依赖
regularMarketPreviousClose字段,改用download接口获取最近1个交易日的正式收盘数据,该数据是交易所清算后的终值,不会出现跳变。
优化后参考代码
from datetime import datetime import yfinance as yf import time symbol = 'ITT' print ('Ticker: ', symbol) # 复用Ticker实例 stock_info = yf.Ticker(symbol) # 存储上一次有效值用于校验 last_valid_price = None price_fluctuation_threshold = 0.1 # 允许最大波动10% count = 0 while count < 20: try: # 用fast_info代替info取值 market_price = stock_info.fast_info['regularMarketPrice'] previous_close_price = stock_info.fast_info['regularMarketPreviousClose'] # 简单数据校验 if last_valid_price is not None: change_rate = abs(market_price - last_valid_price) / last_valid_price if change_rate > price_fluctuation_threshold: print(f"异常值跳过:当前价格{market_price},上一次有效值{last_valid_price},波动超过阈值") time.sleep(2) continue last_valid_price = market_price except Exception as e: print ('Ticker: ', symbol, ', Error getting prices: ', str(e)) else: now = datetime.now() print(now.strftime("%Y-%m-%d %H:%M:%S"), ', market price:' , market_price, ', previous close price:', previous_close_price) count = count + 1 time.sleep(10)
内容的提问来源于stack exchange,提问作者Pop Pop
相关产品推荐
相关产品推荐

