Files
claude-regelwerk/.vault-tools/trading-plattform-pruefung/abbau_alpaca_lesen.py
T
Pascal MichelandClaude Opus 5 3784322a76 Automatischer Push: 8 Datei(en) geändert
- .vault-tools/trading-plattform-pruefung/LIESMICH.md
- .vault-tools/trading-plattform-pruefung/abbau_alpaca_lesen.py
- .vault-tools/trading-plattform-pruefung/abbau_glattstellen.sh
- .vault-tools/trading-plattform-pruefung/abbau_ibkr_lesen.sh
- .vault-tools/trading-plattform-pruefung/abbau_restbestand.py
- .vault-tools/trading-plattform-pruefung/abbau_restbestand_angriffe.py
- .vault-tools/trading-plattform-pruefung/abbau_restbestand_einrichten.ps1
- AI/Regelwerk/windows-shell.md

Erzeugt vom PostToolUse-Hook .vault-tools/auto-push/auto_push.py.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-10-08 04:00:01 +02:00

102 lines
4.2 KiB
Python

"""Abbau Restbestand: liest Marktuhr, Positionen und offene Orders des Alpaca-Paper-Kontos, nur lesend.
Ersteller: Pascal Michel
Erstellt: 2026-10-07
Doku: LIESMICH.md in diesem Ordner, Abschnitt "Paket AB"
Laeuft in WSL mit dem Venv des Alpaca-Ordners (~/venvs/trading); gestartet von abbau_restbestand.py
ueber wsl.exe --exec. Ruft nur marktuhr(), positionen() und offene_orders() von AlpacaBroker
(trading/broker/alpaca.py: GET /v2/clock, /v2/positions, /v2/orders?status=open). Nichts davon
schreibt beim Broker oder auf der Platte.
Ausgabe: genau eine JSON-Zeile auf stdout mit
uhr {"offen": bool, "sekunden_bis_schluss": int} oder null
uhr_fehler Text oder null
positionen [{"symbol": str, "menge": int}] oder null; menge ist negativ bei short
orders Zahl der offenen Orders oder null
bestand_fehler Text oder null
Nie ein Betrag: Von einer Position gehen nur Symbol und Stueckzahl weiter, von den Orders nur die
Zahl. Fehlertexte laufen durch ohne_kontonummer() aus abendkontrolle_wsl.py (Kontonummern, dann
maskiere()) und danach durch DEZIMAL: jede Dezimalzahl wird [x], ganze Zahlen bleiben.
Den Projektordner nennt der Aufrufer (--projekt); hier steht kein echter Pfad.
Aufruf: python abbau_alpaca_lesen.py --projekt <alpaca-ordner>
Exit: 0 mit der JSON-Zeile (auch wenn darin Fehler stehen), 2 Bedienfehler.
"""
import argparse
import json
import os
import re
import sys
from datetime import datetime
from datetime import timezone
from pathlib import Path
HIER = Path(__file__).resolve().parent
sys.path.insert(0, str(HIER))
from abendkontrolle_wsl import ohne_kontonummer # noqa: E402
GEHEIMNISSE = "/home/claude/.config/trading-plattform/secrets.toml"
RISIKO = "config/risk.toml"
FEHLERTEXT_MAX = 200
# Jede Dezimalzahl, auch ohne Geldwort davor; maskiere() faengt nur Zahlen hinter Geldwoertern,
# vor Waehrungen oder mit vielen Stellen.
DEZIMAL = re.compile(r"-?\d+[.,]\d+")
def fehlertext(ausnahme: BaseException) -> str:
"""Typ und Text einer Ausnahme: Kontonummern als [konto], Betraege als [x], gekuerzt."""
text = ohne_kontonummer(f"{type(ausnahme).__name__}: {ausnahme}")
return DEZIMAL.sub("[x]", text)[:FEHLERTEXT_MAX]
def lies(broker, jetzt: datetime) -> dict:
"""Marktuhr und Bestand; jede Frage fuer sich, ein Fehler in der einen haelt die andere nicht auf."""
ergebnis = {"uhr": None, "uhr_fehler": None, "positionen": None, "orders": None, "bestand_fehler": None}
try:
uhr = broker.marktuhr()
ergebnis["uhr"] = {
"offen": bool(uhr.is_open),
"sekunden_bis_schluss": int((uhr.next_close - jetzt).total_seconds()),
}
except Exception as ausnahme:
ergebnis["uhr_fehler"] = fehlertext(ausnahme)
try:
positionen = broker.positionen()
orders = broker.offene_orders()
ergebnis["positionen"] = [
{"symbol": position.symbol, "menge": int(position.menge)} for position in positionen
]
ergebnis["orders"] = len(orders)
except Exception as ausnahme:
ergebnis["positionen"] = None
ergebnis["orders"] = None
ergebnis["bestand_fehler"] = fehlertext(ausnahme)
return ergebnis
def main(argv=None) -> int:
zerleger = argparse.ArgumentParser(description=__doc__.splitlines()[0], allow_abbrev=False)
zerleger.add_argument("--projekt", required=True, help="Ordner der Alpaca-Instanz in WSL")
argumente = zerleger.parse_args(argv)
os.environ.setdefault("TRADING_GEHEIMNISSE", GEHEIMNISSE)
try:
os.chdir(argumente.projekt)
sys.path.insert(0, str(Path(argumente.projekt).resolve()))
from trading.broker.alpaca import AlpacaBroker
from trading.risk.limits import lade_limits
broker = AlpacaBroker.from_secrets(None, universum=lade_limits(RISIKO).universum)
except Exception as ausnahme:
grund = fehlertext(ausnahme)
print(json.dumps(
{"uhr": None, "uhr_fehler": grund, "positionen": None, "orders": None, "bestand_fehler": grund},
ensure_ascii=False,
))
return 0
print(json.dumps(lies(broker, datetime.now(timezone.utc)), ensure_ascii=False))
return 0
if __name__ == "__main__":
sys.exit(main())