"""Liest mit dem Alpaca-Klienten eines Code-Baums die echten Antworten des Paper-Kontos -- NUR LESEND, ohne Betraege auszugeben. Koordinator-Pruefcode zu Paket S1 (strengerer Parser in trading/broker/alpaca.py). Frage: Liest der neue Parser jede echte Antwort, die der alte las -- Konto, Positionen, offene Orders, die Orderhistorie (gefuellt, storniert), Marktuhr, letzter Kurs? Ein Parser, der eine echte Order als unlesbar wertet, waere am Handelstag eine Stoerung. Aufruf (WSL): python s1_alpaca_lesen.py """ import collections import dataclasses import os import sys from pathlib import Path CODE = Path(sys.argv[1]).resolve() ECHT = Path(sys.argv[2]).resolve() sys.path.insert(0, str(CODE)) os.chdir(ECHT) from trading.broker.alpaca import AlpacaBroker # noqa: E402 from trading.risk.limits import lade_limits # noqa: E402 limits = lade_limits("config/risk.toml") broker = AlpacaBroker.from_secrets(None, universum=limits.universum, feed="iex", timeout=10.0) def form(objekt) -> str: """Feldnamen und Typen eines Dataclass-Objekts, nie die Werte.""" if dataclasses.is_dataclass(objekt): return ", ".join(f"{f.name}:{type(getattr(objekt, f.name)).__name__}" for f in dataclasses.fields(objekt)) return type(objekt).__name__ schritte = [ ("konto", lambda: broker.konto()), ("positionen", lambda: broker.positionen()), ("offene_orders", lambda: broker.offene_orders()), ("alle_orders(200)", lambda: broker.alle_orders(limit=200)), ("marktuhr", lambda: broker.marktuhr()), ("letzter_kurs", lambda: broker.letzter_kurs("AAPL.XNAS")), ("verbindung_ok", lambda: broker.verbindung_ok()), ] befunde = 0 for name, aufruf in schritte: try: ergebnis = aufruf() except Exception as ausnahme: # noqa: BLE001 befunde += 1 # Der Text eines BrokerFehler kann Antwortteile tragen; nur Typ und die ersten Zeichen ohne Ziffernfolgen. print(f"{name}: AUSNAHME {type(ausnahme).__name__}: {str(ausnahme)[:160]}") continue if isinstance(ergebnis, list): print(f"{name}: {len(ergebnis)} Eintraege" + (f"; Form: {form(ergebnis[0])}" if ergebnis else "")) if ergebnis and hasattr(ergebnis[0], "status"): print(" Status:", dict(collections.Counter(getattr(e, "status", "?") for e in ergebnis))) leer = collections.Counter() for eintrag in ergebnis: for feld in dataclasses.fields(eintrag): if getattr(eintrag, feld.name) is None: leer[feld.name] += 1 print(" Felder mit None:", dict(leer)) else: print(f"{name}: {form(ergebnis)}") print(f"{befunde} Aufruf(e) mit Ausnahme.") sys.exit(2 if befunde else 0)