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

基于FMP API用Pandas生成历史价格CSV报df未定义错误求解

问题根因

NameError: name 'df' is not defined报错由变量未赋值就直接引用导致,和猜测的merge、replace逻辑无关,核心问题点有两个:

  • prepare_data函数内完成行情数据清洗的变量是prices_df,后续操作的df从未在当前函数作用域内赋值,直接调用就会触发未定义错误
  • 代码附带存在几个隐性运行bug:接口请求失败时无兜底返回、Pandas 1.4.0以上版本已废弃DataFrame.append()方法、日期索引类型不匹配容易触发取值报错。
修复方案

核心改动说明

  • 在prepare_data函数内将清洗完成的prices_df赋值给df后再做索引重命名、标的列添加操作,从根源解决未定义报错
  • 给get_symbol_prices增加请求失败、返回格式异常的兜底逻辑,返回空DataFrame避免后续链式调用报错
  • 替换已废弃的append拼接逻辑,改用列表收集单标的数据后一次性pd.concat,性能更好且兼容所有Pandas版本
  • 统一日期索引格式,避免字符串日期和datetime类型索引不匹配导致的取值失败

修复后可直接运行的完整代码:

import os
from datetime import date, timedelta
import requests
import pandas as pd

TICKERS = ['A', 'AA', 'AAPL', 'ABNB', 'ADBE','AMAT', 'AMD', 'AMC', 'AMGN', 'AMZN']
LOOK_BACK_PERIOD = 100


def last_business_day():
    test_date = date.today()
    diff = 1
    if test_date.weekday() == 0:
        diff = 3
    elif test_date.weekday() == 6:
        diff = 2
    else:
        diff = 1
    res = test_date - timedelta(days=diff)
    return pd.to_datetime(res)


def get_symbol_prices(symbol, start_date, end_date):
    session = requests.Session()
    request = f"https://financialmodelingprep.com/api/v3/historical-price-full/{symbol}\
                ?apikey=YOURAPI\
                &from={start_date}&to={end_date}".replace(" ", "")
    r = session.get(request)

    if r.status_code == requests.codes.ok:
        df = pd.io.json.read_json(r.text)
        if not df.empty and 'historical' in df.columns:
            df = pd.DataFrame(df['historical'].to_list())
            df['date'] = pd.to_datetime(df['date'])
            df = df.set_index('date').sort_index()
            return df
    # 接口异常时返回空DataFrame兜底
    return pd.DataFrame()


def prepare_data(symbol, look_back_period):
    start_date = date.today() - timedelta(days=look_back_period)
    end_date = date.today()

    prices_df = get_symbol_prices(symbol=symbol, start_date=start_date, end_date=end_date)
    if prices_df.empty:
        return pd.DataFrame()
    prices_df = prices_df[['open', 'high', 'low', 'close', 'volume']]

    # 无需额外merge逻辑,直接赋值即可
    df = prices_df.copy()
    df.index.name = 'datetime'
    df['symbol'] = symbol
    return df


def get_final_df(tickers, look_back_period):
    df_list = []
    for symbol in tickers:
        symbol_df = prepare_data(symbol=symbol, look_back_period=look_back_period)
        if not symbol_df.empty:
            df_list.append(symbol_df)
    
    total_df = pd.concat(df_list)
    # 仅返回最近一个交易日的标的数据
    return total_df.loc[last_business_day()]


def main():
    historical_df = get_final_df(tickers=TICKERS, look_back_period=LOOK_BACK_PERIOD)
    output_folder = 'E:/'
    file_name = 'HISTORICALPORTFOLIO.csv'
    historical_df.to_csv(os.path.join(output_folder, file_name))


if __name__ == '__main__':
    main()
运行注意事项
  • 运行前将代码中YOURAPI替换为你在金融数据平台申请的有效API Key,否则会触发接口权限错误
  • 提前安装依赖库:执行命令pip install pandas requests
  • 如果需要导出全周期历史数据而非仅最近一个交易日的数据,将get_final_df函数最后一行返回语句改为return total_df即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 19:24:20