You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Alpaca API获取实时股票数据遇阻:get_position调用报错

问题:调用Alpaca API的.get_position方法报错(404/position does not exist)

尝试制作实时股票数据图表,但调用Alpaca API的get_position()方法时无法正常工作,收到以下报错:

  • APIError: position does not exist
  • 404 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 06:24:22