算法交易脚本运行Sharpe/Sortino函数触发KeyError: 'Close'求助
算法交易脚本KeyError问题解决
问题现象
CAGR和Volatility函数可正常运行,但执行Sharpe和Sortino函数时出现KeyError: 'Close'错误,错误定位到CAGR函数中的df["return"] = DF["Close"].pct_change()代码行。
原代码及错误栈
import yfinance as yf import numpy as np import pandas as pd tickers = ["AAPL","AMC","SPY","BBBY"] ohlcv_data = {} for ticker in tickers: temp = yf.download(ticker, period="7mo", interval="1d") temp.dropna(how="any", inplace=True) ohlcv_data[ticker] = temp def CAGR(DF): df = DF.copy() df["return"] = DF["Close"].pct_change() df["cum_return"] = (1+df["return"]).cumprod() n = len(df)/252 CAGR = (df["cum_return"][-1])**(1/n) - 1 return CAGR for ticker in ohlcv_data: print("GAGR for {} = {}".format(ticker, CAGR(ohlcv_data[ticker]))) def Volatility(DF): df = DF.copy() df["return"] = DF["Close"].pct_change() vol = df["return"].std() * np.sqrt(252) return vol for ticker in ohlcv_data: print("Volatility of {} = {}".format(ticker, Volatility(ohlcv_data[ticker]))) def Sharpe(DF, rf=0.03): df = DF.copy() return (CAGR(df)- rf)/Volatility(df) for ticker in ohlcv_data: print("Sharpe for {} = {}".format(ticker, Sharpe(ohlcv_data, 0.03))) def Sortino(DF, rf=0.03): df= DF.copy() df["return"] = df["Close"].pct_change() neg_return = np.where(df["return"]>0,0,df["return"]) neg_vol = pd.Series(neg_return[neg_return!=0]).std() return (CAGR(df)- rf)/neg_vol for ticker in ohlcv_data: print("Sortino for {} = {}".format(ticker, Sortino(ohlcv_data, 0.03)))
错误栈:
File "c:\users\cryst\onedrive\documents\algotradingcode\untitled11.py", line 56, in <module> print("Sharpe for {} = {}".format(ticker, Sharpe(ohlcv_data, 0.03))) File "c:\users\cryst\onedrive\documents\algotradingcode\untitled11.py", line 53, in Sharpe return (CAGR(df)- rf)/Volatility(df) File "c:\users\cryst\onedrive\documents\algotradingcode\untitled11.py", line 26, in CAGR df["return"] = DF["Close"].pct_change() KeyError: 'Close'
错误原因
调用Sharpe和Sortino函数时,错误地传入了整个ohlcv_data字典(键为ticker,值为对应股票的OHLCV DataFrame),而非单个ticker对应的DataFrame。字典本身没有"Close"键,只有DataFrame中才包含"Close"列,因此触发KeyError。
修正后的代码
只需修改Sharpe和Sortino的循环调用部分,将传入的ohlcv_data改为ohlcv_data[ticker],同时优化Sortino函数中负波动率的计算逻辑:
import yfinance as yf import numpy as np import pandas as pd tickers = ["AAPL","AMC","SPY","BBBY"] ohlcv_data = {} for ticker in tickers: temp = yf.download(ticker, period="7mo", interval="1d") temp.dropna(how="any", inplace=True) ohlcv_data[ticker] = temp def CAGR(DF): df = DF.copy() df["return"] = DF["Close"].pct_change() df["cum_return"] = (1+df["return"]).cumprod() n = len(df)/252 CAGR = (df["cum_return"][-1])**(1/n) - 1 return CAGR for ticker in ohlcv_data: print("GAGR for {} = {}".format(ticker, CAGR(ohlcv_data[ticker]))) def Volatility(DF): df = DF.copy() df["return"] = DF["Close"].pct_change() vol = df["return"].std() * np.sqrt(252) return vol for ticker in ohlcv_data: print("Volatility of {} = {}".format(ticker, Volatility(ohlcv_data[ticker]))) def Sharpe(DF, rf=0.03): df = DF.copy() return (CAGR(df)- rf)/Volatility(df) # 修正:传入单个ticker的DataFrame for ticker in ohlcv_data: print("Sharpe for {} = {}".format(ticker, Sharpe(ohlcv_data[ticker], 0.03))) def Sortino(DF, rf=0.03): df= DF.copy() df["return"] = df["Close"].pct_change() # 优化负波动率计算:直接筛选负收益后取标准差,再年化 neg_returns = df["return"][df["return"] < 0] neg_vol = neg_returns.std() * np.sqrt(252) return (CAGR(df)- rf)/neg_vol # 修正:传入单个ticker的DataFrame for ticker in ohlcv_data: print("Sortino for {} = {}".format(ticker, Sortino(ohlcv_data[ticker], 0.03)))
内容的提问来源于stack exchange,提问作者Rene Rodriguez
相关产品推荐
相关产品推荐

