如何在TDA-API Python脚本中添加循环实现多ticker期权数据查询
实现多标的期权数据查询的修改方案
核心改动点
你原有代码的逻辑完全不用动,只需要做3处调整即可:
- 定义要查询的标的代码列表,把你需要查的所有股票代码都放进去
- 把单标的查询、数据解析的逻辑套进列表遍历的for循环中
- 新增标的标识字段,方便区分不同股票的期权数据
以下是两种常用的实现方式,按需选择即可:
方案1:所有标的数据合并导出到同一个CSV
适合需要批量分析多标的期权的场景,所有数据汇总在一个文件里,新增symbol列区分标的。
from tda import auth, client import json import config import pandas as pd import datetime # 可选:如果需要加请求间隔防限流,导入time # import time try: c = auth.client_from_token_file(config.token_path, config.api_key) except FileNotFoundError: from selenium import webdriver with webdriver.Chrome(executable_path='/Users/capnb/Documents/TDAmeritrade/chromedriver') as driver: c = auth.client_from_login_flow( driver, config.api_key, config.redirect_uri, config.token_path) # ========== 改动1:自定义要查询的股票代码列表 ========== ticker_list = ['AAPL', 'MSFT', 'TSLA', 'GOOG', 'AMZN'] all_data = [] # ========== 改动2:套入循环遍历所有标的 ========== for ticker in ticker_list: r = c.get_option_chain(ticker) data = json.loads(r.text) ret = [] for date in data["callExpDateMap"]: for strike in data["callExpDateMap"][date]: ret.extend(data["callExpDateMap"][date][strike]) for date in data["putExpDateMap"]: for strike in data["putExpDateMap"][date]: ret.extend(data["putExpDateMap"][date][strike]) # ========== 改动3:给每条数据加对应标的代码 ========== for item in ret: item['symbol'] = ticker all_data.extend(ret) # 可选:查询超过20个标的的话加间隔,避免限流 # time.sleep(1) # 后续处理逻辑和原有一致 df = pd.DataFrame(all_data) for col in ("tradeTimeInLong", "quoteTimeInLong", "expirationDate", "lastTradingDay"): df[col] = pd.to_datetime(df[col], unit="ms") filename = datetime.datetime.now().strftime('multi_option_prices-%Y-%m-%d-%H-%M.csv') path = "c:/Users/capnb/Desktop/" df.to_csv(path+filename, index=False, encoding='utf_8_sig')
方案2:每个标的单独导出CSV
适合需要单独管理每个标的期权数据的场景,每个股票生成一个独立的文件,文件名带标的代码,避免数据覆盖。
只需要把循环部分的逻辑调整成下面这样即可,认证部分的代码和原有一致:
ticker_list = ['AAPL', 'MSFT', 'TSLA', 'GOOG', 'AMZN'] path = "c:/Users/capnb/Desktop/" for ticker in ticker_list: r = c.get_option_chain(ticker) data = json.loads(r.text) ret = [] for date in data["callExpDateMap"]: for strike in data["callExpDateMap"][date]: ret.extend(data["callExpDateMap"][date][strike]) for date in data["putExpDateMap"]: for strike in data["putExpDateMap"][date]: ret.extend(data["putExpDateMap"][date][strike]) df = pd.DataFrame(ret) for col in ("tradeTimeInLong", "quoteTimeInLong", "expirationDate", "lastTradingDay"): df[col] = pd.to_datetime(df[col], unit="ms") # 文件名带标的代码,避免覆盖 filename = f"{ticker}_option_prices_{datetime.datetime.now().strftime('%Y-%m-%d-%H-%M')}.csv" df.to_csv(path+filename, index=False, encoding='utf_8_sig') # 可选:加请求间隔避免限流 # time.sleep(1)
注意事项
- 代码里新增的
index=False和encoding='utf_8_sig'参数,是为了避免导出的CSV打开乱码、出现多余的序号列,不需要可以删掉 - TDA API公开调用频率限制是每分钟120次,如果你要查的标的数量超过100,建议把sleep的间隔调到0.5秒以上,避免触发限流
- 如果某个标的没有上市期权,接口返回的行权日字典是空的,不会报错,只是不会生成该标的的数据
内容的提问来源于stack exchange,提问作者Capnbigal
相关产品推荐
相关产品推荐

