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

如何提升Yahoo finance(yf)获取ticker.info字段的响应速度

多余请求的产生原因

1. yfinance库本身的设计问题

你调用的Ticker.info属性在旧版本yfinance中默认会拉取标的全量数据,除了基础行情外,还会自动请求股东列表、财务数据、持仓信息等你不需要的接口,对应你看到的额外3次GET请求,这些多余请求直接拖慢了响应速度。

2. 业务代码重复触发请求

你观察到的两轮重复请求,大概率是两处逻辑重复调用了lookup1:一是你路由的循环中已经查询了一次股票信息,二是index.html模板渲染时又重复调用lookup1获取价格或名称字段,相当于每个标的查了两次。
另外你把单条response.info转DataFrame的操作完全多余,没有必要为了3个字段引入DataFrame的序列化开销。

高效优化方案

1. 替换为轻量化的行情接口

用yfinance专门优化过的fast_info属性替代info,fast_info只会拉取基础行情字段,不会触发多余的财务、股东接口请求,速度比info快3倍以上,优化后的lookup1可以直接返回字典,不需要转DataFrame:

def lookup1(symbol):
    ticker = yf.Ticker(symbol)
    fast_info = ticker.fast_info
    return {
        "shortName": fast_info.get("shortName", symbol),
        "currentPrice": fast_info.get("lastPrice", 0),
        "symbol": symbol
    }

2. 批量查询替代单标的循环请求

你当前循环中每个标的单独发请求,改成一次性批量查询所有需要的标的,仅触发1次请求即可拿到所有数据:

@app.route("/")
@login_required
def index():
    """Show portfolio of stocks"""
    stocks = db.execute("SELECT symbol, SUM(number_of_shares) as sumshares, AVG(price) as avgprice FROM 'transaction' WHERE user_id = :i_d GROUP BY symbol", i_d=session["user_id"])
    cash = db.execute("SELECT cash FROM users WHERE id = ?", session["user_id"])[0]["cash"]
    totalPortValue = 0

    # 先收集所有需要查询的标的,过滤掉持仓为0的标的
    valid_symbols = [stock["symbol"] for stock in stocks if stock["sumshares"] > 0]
    batch_quotes = {}
    if valid_symbols:
        # 批量拉取最新行情,开启多线程提升速度
        batch_data = yf.download(tickers=valid_symbols, period='1d', interval='1m', group_by='ticker', threads=True)
        for symbol in valid_symbols:
            batch_quotes[symbol] = {
                "currentPrice": batch_data[symbol]['Close'].iloc[-1],
                # 股票名称建议存在本地库,这里可以直接取缓存
                "shortName": symbol # 替换为你本地存储的名称即可
            }

    for stock in stocks:
        sumshares = stock['sumshares']
        symbol = stock['symbol']
        if sumshares == 0:
            stock['ap'] = 0
            db.execute("DELETE FROM 'transaction' WHERE symbol = :symbol AND user_id =:ui", symbol=symbol, ui=session["user_id"])
            continue
        # 直接从批量查询结果取数,不用单独发请求
        quote = batch_quotes.get(symbol, {"currentPrice": 0, "shortName": symbol})
        price = float(quote["currentPrice"])
        stock['name'] = quote["shortName"]
        stock['ap'] = price
        stock['total'] = sumshares * price
        totalPortValue += sumshares * price

    availableCash = cash
    grandTotal = availableCash + totalPortValue

    return render_template("/index.html",availableCash=availableCash, stocks=stocks, totalPortValue=totalPortValue, grandTotal=grandTotal)

3. 增加缓存避免重复查询

  • 静态字段如股票名称shortName不会变动,可以新增一张stock_info表存在本地数据库,第一次查询后就存入,后续不需要再请求接口。
  • 价格字段可以用flask-caching加内存缓存,设置30-60秒的有效期,短时间内用户刷新页面不会重复请求接口。

4. 排查模板重复调用

检查index.html模板,确认没有在循环中再次调用lookup1获取价格或名称,直接使用路由中已经赋值好的stock['name']、stock['ap']等字段即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 04:18:03