使用Alpaca API获取实时股票数据遇阻:get_position调用报错
问题:调用Alpaca API的.get_position方法报错(404/position does not exist)
尝试制作实时股票数据图表,但调用Alpaca API的get_position()方法时无法正常工作,收到以下报错:
APIError: position does not exist404 Client Error: Not Found for url: https://paper-api.alpaca.markets/v2/positions/AAPL
直接访问该URL会显示禁止访问提示。
原始代码
import matplotlib.pyplot as plt from itertools import count from matplotlib.animation import FuncAnimation import threading import time api_key = '<API_KEY>' api_secret = '<SECRET_KEY>' base_url = 'https://paper-api.alpaca.markets' api = tradeapi.REST(api_key, api_secret, base_url, api_version='v2') account = api.get_account() def stock_grabber(): global position SYMBOL = 'AAPL' try: position = api.get_position(symbol=SYMBOL) except Exception as exception: if exception.__str__() == 'position does not exist': position = 0 print(position) def threadz(): while True: x = threading.Thread(target=stock_grabber) x.start() time.sleep(0.4) t = threading.Thread(target=threadz) t.start() stock_grabber() x = [] y = [] index = count() def animate(i): x.append(next(index)) y.append(position) plt.cla() plt.plot(x, y) ani = FuncAnimation(plt.gcf(), animate, interval=400) plt.tight_layout() plt.show()
解决方法
1. 报错原因解析
get_position()仅在你实际持有对应股票仓位时返回数据,无持仓时API会返回404错误。- 直接在浏览器访问API URL被拒绝,是因为API要求请求头携带API密钥进行身份验证,浏览器请求不包含这些信息,所以被禁止。
2. 优化异常处理逻辑
原代码通过字符串匹配异常信息的方式不可靠,建议直接捕获Alpaca的APIError并根据状态码处理:
from alpaca_trade_api.rest import APIError # 导入Alpaca专属异常类 def stock_grabber(): global position SYMBOL = 'AAPL' try: pos = api.get_position(symbol=SYMBOL) # 提取持仓数量并转为数值类型(原返回的是Position对象,无法直接用于绘图) position = float(pos.qty) except APIError as e: if e.status_code == 404: position = 0.0 print("当前无AAPL持仓") else: print(f"API错误: {e}") except Exception as e: print(f"未知错误: {e}")
3. 修复线程安全问题
多个线程同时修改全局变量position会引发竞态条件,使用threading.Lock()保证线程安全:
import threading position_lock = threading.Lock() position = 0.0 # 初始化全局变量 def stock_grabber(): global position SYMBOL = 'AAPL' current_pos = position # 默认保持原有值 try: pos = api.get_position(symbol=SYMBOL) current_pos = float(pos.qty) except APIError as e: if e.status_code == 404: current_pos = 0.0 print("当前无AAPL持仓") else: print(f"API错误: {e}") except Exception as e: print(f"未知错误: {e}") # 加锁修改全局变量 with position_lock: position = current_pos
4. 若需求是获取股票实时价格而非持仓
如果你的图表是要展示股票价格而非持仓数量,应该使用价格查询接口替代get_position():
def stock_grabber(): global price SYMBOL = 'AAPL' try: # 获取最近1分钟K线的收盘价 bars = api.get_bars(SYMBOL, '1Min', limit=1).df price = bars['close'].iloc[-1] except Exception as e: print(f"获取价格失败: {e}") # 出错时保持原有价格(避免图表出现断层) if 'price' not in globals(): price = 0.0 # 后续绘图逻辑中使用price替代position def animate(i): x.append(next(index)) y.append(price) plt.cla() plt.plot(x, y)
内容的提问来源于stack exchange,提问作者Callum
相关产品推荐
相关产品推荐

