eTrade API示例运行报错ConnectionResetError(10054)求助
ConnectionResetError 10054 远程主机强制关闭连接 - E*TRADE API 多语言示例运行失败
我是Python编程新手,运行E*TRADE API官方示例代码时遇到ConnectionResetError: [WinError 10054] 远程主机强制关闭了现有连接错误。同时尝试C#和VB.NET版本的示例,也均无法成功连接。已通过谷歌、ChatGPT等渠道查找解决方案但未解决,附上报错信息和关键代码片段,寻求帮助。
报错信息
Exception has occurred: ConnectionError ('Connection aborted.', ConnectionResetError(10054, 'An existing connection was forcibly closed by the remote host', None, 10054, None)) ConnectionResetError: [WinError 10054] 远程主机强制关闭了现有连接 During handling of the above exception, another exception occurred: urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionResetError(10054, 'An existing connection was forcibly closed by the remote host', None, 10054, None)) During handling of the above exception, another exception occurred: File "C:\Users\kg5fc\Downloads\Bots\etrade_python_client.py", line 63, in oauth request_token, request_token_secret = etrade.get_request_token( ^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\kg5fc\Downloads\Bots\etrade_python_client.py", line 111, in <module> oauth()
关键代码片段
"""This Python script provides examples on using the E*TRADE API endpoints""" from __future__ import print_function import webbrowser import json import logging import configparser import sys import requests from rauth import OAuth1Service from logging.handlers import RotatingFileHandler from accounts.accounts import Accounts from market.market import Market # loading configuration file config = configparser.ConfigParser() config.read('config.ini') # logger settings logger = logging.getLogger('my_logger') logger.setLevel(logging.DEBUG) handler = RotatingFileHandler("python_client.log", maxBytes=5*1024*1024, backupCount=3) FORMAT = "%(asctime)-15s %(message)s" fmt = logging.Formatter(FORMAT, datefmt='%m/%d/%Y %I:%M:%S %p') handler.setFormatter(fmt) logger.addHandler(handler) print('consumer_key: ' + config["DEFAULT"]["CONSUMER_KEY"]) print('consumer_secret: ' + config["DEFAULT"]["CONSUMER_SECRET"]) def oauth(): """Allows user authorization for the sample application with OAuth 1""" etrade = OAuth1Service( name="etrade", consumer_key=config["DEFAULT"]["CONSUMER_KEY"], consumer_secret=config["DEFAULT"]["CONSUMER_SECRET"], request_token_url="https://api.etrade.com/oauth/request_token", access_token_url="https://api.etrade.com/oauth/access_token", authorize_url="https://us.etrade.com/e/t/etws/authorize?key={}&token={}", base_url="https://api.etrade.com") menu_items = {"1": "Sandbox Consumer Key", "2": "Live Consumer Key", "3": "Exit"} while True: print("") options = menu_items.keys() for entry in options: print(entry + ")\t" + menu_items[entry]) selection = input("Please select Consumer Key Type: ") if selection == "1": base_url = config["DEFAULT"]["SANDBOX_BASE_URL"] break elif selection == "2": base_url = config["DEFAULT"]["PROD_BASE_URL"] break elif selection == "3": break else: print("Unknown Option Selected!") print("") # Step 1: Get OAuth 1 request token and secret request_token, request_token_secret = etrade.get_request_token( params={"oauth_callback": "oob", "format": "json"})
排查与解决方案
1. 修复API端点与环境不匹配问题
当前代码初始化OAuth1Service时硬编码了生产环境端点,即使选择沙箱环境也不会自动切换,这是核心问题。修改oauth函数,根据选择的环境动态设置对应端点:
def oauth(): """Allows user authorization for the sample application with OAuth 1""" menu_items = {"1": "Sandbox Consumer Key", "2": "Live Consumer Key", "3": "Exit"} selection = "" while True: print("") options = menu_items.keys() for entry in options: print(entry + ")\t" + menu_items[entry]) selection = input("Please select Consumer Key Type: ") if selection in ["1","2","3"]: break else: print("Unknown Option Selected!") print("") # 根据选择的环境配置端点 if selection == "1": base_url = config["DEFAULT"]["SANDBOX_BASE_URL"] request_token_url = "https://apisb.etrade.com/oauth/request_token" access_token_url = "https://apisb.etrade.com/oauth/access_token" elif selection == "2": base_url = config["DEFAULT"]["PROD_BASE_URL"] request_token_url = "https://api.etrade.com/oauth/request_token" access_token_url = "https://api.etrade.com/oauth/access_token" else: return etrade = OAuth1Service( name="etrade", consumer_key=config["DEFAULT"]["CONSUMER_KEY"], consumer_secret=config["DEFAULT"]["CONSUMER_SECRET"], request_token_url=request_token_url, access_token_url=access_token_url, authorize_url="https://us.etrade.com/e/t/etws/authorize?key={}&token={}", base_url=base_url) # Step 1: Get OAuth 1 request token and secret request_token, request_token_secret = etrade.get_request_token( params={"oauth_callback": "oob", "format": "json"})
2. 网络与安全配置检查
- 禁用本地代理、VPN,E*TRADE API会拦截非直接连接的请求
- 临时关闭防火墙/杀毒软件,验证是否被拦截对外HTTPS请求
- 强制使用TLS 1.2及以上版本,E*TRADE不支持旧版TLS:
import ssl ssl._create_default_https_context = ssl._create_unverified_context
3. 凭证有效性验证
- 确认
config.ini中的CONSUMER_KEY和CONSUMER_SECRET与E*TRADE开发者平台创建的应用一致,沙箱和生产凭证不通用 - 检查应用状态是否为已激活,未激活应用会被API拒绝连接
4. 多语言通用修复
C#/VB.NET版本需同步调整端点配置,并强制启用TLS 1.2:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
内容的提问来源于stack exchange,提问作者paris_tj
相关产品推荐
相关产品推荐

