Python中对DataFrame日期减天数时排除周末与节假日的方法
解决方法
要解决日期减去天数后遇到周末/节假日导致API无响应的问题,推荐两种方案,优先选择方案一(无需手动维护节假日列表):
方案一:利用Polygon API自动筛选有效交易日
Polygon的get_aggregate_bars接口仅返回交易日数据,因此可以通过请求目标日期往前一段范围的K线,直接提取对应交易日的数据,自动跳过周末和节假日。
获取前一日收盘价与成交量
import pandas as pd from datetime import timedelta df['Date'] = pd.to_datetime(df['Date']) previous_day_data = [] for _, row in df.iterrows(): ticker = row['Ticker'] target_date = row['Date'] # 往前推5天作为起始范围,确保覆盖可能的节假日/周末 start_date = target_date - timedelta(days=5) # 请求日度K线数据 bars = client.get_aggregate_bars( ticker, start_date.strftime('%Y-%m-%d'), target_date.strftime('%Y-%m-%d'), adjusted=False, multiplier='1', timespan='day' ) # 取最后一条数据,即为目标日期前的最近交易日数据 if bars.get('results'): previous_day_data.append(bars['results'][-1]) else: # 处理股票未上市等无数据情况 previous_day_data.append(None)
计算过去10天平均成交量
avg_volume_list = [] for _, row in df.iterrows(): ticker = row['Ticker'] target_date = row['Date'] # 往前推20天,确保能获取至少10个交易日数据 start_date = target_date - timedelta(days=20) bars = client.get_aggregate_bars( ticker, start_date.strftime('%Y-%m-%d'), target_date.strftime('%Y-%m-%d'), adjusted=False, multiplier='1', timespan='day' ) results = bars.get('results', []) if len(results) >= 10: # 取最后10个交易日的成交量计算平均值 last_10_volumes = [bar['v'] for bar in results[-10:]] avg_volume = sum(last_10_volumes) / 10 avg_volume_list.append({'ticker': ticker, 'avg_10d_volume': avg_volume}) else: avg_volume_list.append({'ticker': ticker, 'avg_10d_volume': None})
方案二:本地计算有效交易日(需维护节假日)
如果需要提前在本地确定交易日,可以维护美股节假日列表,编写函数跳过周末和节假日:
import pandas as pd from datetime import timedelta # 示例:2023年美股节假日列表,需每年更新 us_holidays = [ pd.to_datetime('2023-01-02'), pd.to_datetime('2023-01-16'), pd.to_datetime('2023-02-20'), pd.to_datetime('2023-04-07'), pd.to_datetime('2023-05-29'), pd.to_datetime('2023-06-19'), pd.to_datetime('2023-07-04'), pd.to_datetime('2023-09-04'), pd.to_datetime('2023-11-23'), pd.to_datetime('2023-12-25') ] def get_valid_trading_day(date, holidays): current_date = date - timedelta(days=1) while True: # 跳过周末(周六=5,周日=6)和节假日 if current_date.weekday() >= 5 or current_date in holidays: current_date -= timedelta(days=1) else: return current_date # 生成前一个有效交易日列 df['Prev_Trading_Day'] = df['Date'].apply(lambda x: get_valid_trading_day(x, us_holidays)) # 调用API获取数据 previous_day_data = [] for _, row in df.iterrows(): ticker = row['Ticker'] trade_day = row['Prev_Trading_Day'] bars = client.get_aggregate_bars( ticker, trade_day.strftime('%Y-%m-%d'), trade_day.strftime('%Y-%m-%d'), adjusted=False, multiplier='1', timespan='day' ) previous_day_data.append(bars['results'] if bars.get('results') else None)
注意事项
- Polygon API有调用频次限制,批量处理时需控制请求速率,避免触发限流。
- 需处理无数据场景(如股票未上市、停牌等),避免程序报错。
内容的提问来源于stack exchange,提问作者Julien
相关产品推荐
相关产品推荐

