diff --git a/tradier_broker/client.py b/tradier_broker/client.py index e422f91..1263ff1 100644 --- a/tradier_broker/client.py +++ b/tradier_broker/client.py @@ -339,18 +339,32 @@ class TradierClient: raw = _one_or_many(payload.get("positions"), "position") if not raw: return [] - # Tradier positions carry no mark — price them off /markets/quotes + # Tradier positions carry no mark. Price them off the Alpaca data + # client's REAL-TIME trades when available — the exit manager's + # breakeven/trail logic reads current_price, and Tradier sandbox + # quotes are 15-min delayed (stale marks = lagging trails). Tradier + # /markets/quotes is the fallback (real-time on funded live accounts). symbols = sorted({str(p["symbol"]) for p in raw if p.get("symbol")}) lasts: dict[str, float] = {} - try: - qp = self._request("GET", "/markets/quotes", - params={"symbols": ",".join(symbols)}) or {} - for q in _one_or_many(qp.get("quotes"), "quote"): - last = q.get("last") - if q.get("symbol") and last is not None: - lasts[q["symbol"]] = float(last) - except Exception: # noqa: BLE001 — quotes down: positions still report, unmarked - logger.warning("tradier quotes lookup failed; positions unmarked") + if self.data_client is not None: + try: + for sym, t in (self.data_client.get_latest_trades(symbols) or {}).items(): + px = t.get("p") + if px is not None: + lasts[sym] = float(px) + except Exception: # noqa: BLE001 — fall through to Tradier quotes + logger.warning("alpaca latest-trades mark failed; falling back to tradier quotes") + missing = [s for s in symbols if s not in lasts] + if missing: + try: + qp = self._request("GET", "/markets/quotes", + params={"symbols": ",".join(missing)}) or {} + for q in _one_or_many(qp.get("quotes"), "quote"): + last = q.get("last") + if q.get("symbol") and last is not None: + lasts[q["symbol"]] = float(last) + except Exception: # noqa: BLE001 — quotes down: positions still report, unmarked + logger.warning("tradier quotes lookup failed; positions unmarked") return [translate_position(p, lasts.get(str(p.get("symbol") or ""))) for p in raw] def get_positions(self, fresh: bool = False) -> list[dict]: