Files
IBKRTrader/grok.txt
T
RichardandClaude Opus 4.8 ebeb035e92 Initial commit: IBKRTrader
.NET WinForms-Anwendung (Core, Modules/CongressTrading, UI).
Enthaelt .gitignore und settings.example.json als Konfigurationsvorlage.
Echte settings.json mit Zugangsdaten ist bewusst ausgeschlossen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-26 18:19:47 +02:00

129 lines
7.3 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Deine Datenbankstruktur sollte genau auf die IBKR-Web-API abgestimmt sein vor allem auf den zentralen conid (Contract ID).
Ich habe mir die komplette Web-API-Dokumentation zum Tag „Trading-Contracts“ (und die damit verknüpften Endpoints /iserver/secdef/search, /trsrv/stocks, /trsrv/secdef etc.) angeschaut. Die wichtigsten Erkenntnisse daraus:
Symbol allein reicht nie (AAPL gibt es z. B. auf NASDAQ, MEXI, LSE etc.).
Der conid ist der einzige stabile, eindeutige Schlüssel in IBKR (z. B. AAPL US Stock = conid: 265598). Er ändert sich nie und wird für alle Market-Data-, Order- und Positions-Calls verwendet.
IBKR liefert über die Search-Endpoints automatisch companyName, sector, primaryExchange, validExchanges etc. mit das kannst du direkt in die DB schreiben.
Historische Daten (und alle Trades) referenzieren immer nur den conid.
Genau das nutzen wir für die Datenbank. Ich schlage eine saubere, skalierbare und zukunftssichere Struktur vor (PostgreSQL + TimescaleDB für die Zeitreihen ist ideal, funktioniert aber auch mit normalem Postgres).
1. Kern-Tabellen (relational)
SQL-- 1. Instruments = IBKR-Contract (der zentrale „Single Source of Truth“)
CREATE TABLE instruments (
id BIGSERIAL PRIMARY KEY,
ibkr_conid BIGINT NOT NULL UNIQUE, -- wichtigster Key!
symbol VARCHAR(20) NOT NULL,
sec_type VARCHAR(10) NOT NULL, -- STK, OPT, FUT, BOND ...
exchange VARCHAR(20) NOT NULL, -- NASDAQ, SMART, NYSE ...
primary_exchange VARCHAR(20),
currency VARCHAR(3) NOT NULL,
company_name TEXT,
local_symbol VARCHAR(20),
trading_class VARCHAR(20),
isin VARCHAR(12), -- oft nützlich
sector VARCHAR(100),
industry VARCHAR(100),
description TEXT,
has_options BOOLEAN,
asset_class VARCHAR(10),
listing_exchange VARCHAR(20),
last_fetched TIMESTAMPTZ DEFAULT NOW(),
active BOOLEAN DEFAULT true,
custom_metadata JSONB, -- flexibler Platz für alles, was du später brauchst
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- 2. External Identifiers = Verknüpfung zu allen anderen Quellen
CREATE TABLE external_identifiers (
id BIGSERIAL PRIMARY KEY,
instrument_id BIGINT REFERENCES instruments(id) ON DELETE CASCADE,
source VARCHAR(50) NOT NULL, -- 'yahoo', 'alpha_vantage', 'bloomberg', 'web_scrape', 'manual', 'tradingview' ...
ticker VARCHAR(50) NOT NULL,
additional_params JSONB, -- z. B. {'exchange': 'NYSE', 'region': 'US'}
priority SMALLINT DEFAULT 1, -- falls mehrere Ticker für dieselbe Quelle existieren
last_verified TIMESTAMPTZ,
UNIQUE (instrument_id, source, ticker)
);
-- Index für schnelle Lookups
CREATE INDEX idx_external_source_ticker ON external_identifiers(source, ticker);
CREATE INDEX idx_instrument_conid ON instruments(ibkr_conid);
Warum diese Trennung?
Du bekommst z. B. von einer Web-Analyse oder einem Scraping-Tool den Ticker „AAPL“. Du schaust in external_identifiers nach → findest sofort das instrument_id → hast den ibkr_conid und alle IBKR-spezifischen Daten.
2. Eigene Informationen & Analysen (sehr flexibel)
Du kannst zwei Wege gehen ich empfehle beide gleichzeitig:
Variante A (einfach & schnell): Die Spalte custom_metadata JSONB in der instruments-Tabelle (siehe oben). Dort kannst du beliebig strukturierte eigene Daten speichern:
JSON{
"ai_sentiment_score": 0.87,
"my_strategy_rating": "strong_buy",
"notes": "Apple AI-Investitionen 2025 sehr interessant",
"last_ai_analysis": "2026-05-10",
"custom_pe_target": 32.5,
"watchlist_tags": ["growth", "tech", "ai"]
}
Variante B (noch flexibler, für sehr viele eigene Felder): Eine separate EAV-Tabelle:
SQLCREATE TABLE instrument_custom_data (
id BIGSERIAL PRIMARY KEY,
instrument_id BIGINT REFERENCES instruments(id) ON DELETE CASCADE,
key VARCHAR(100) NOT NULL, -- z. B. 'ai_sentiment', 'my_risk_score'
value JSONB,
source VARCHAR(20), -- 'user', 'gpt-4o', 'claude' ...
created_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE (instrument_id, key)
);
3. Historische Marktdaten (Time-Series)
SQL-- Mit TimescaleDB (empfohlen) oder normaler Postgres-Tabelle
CREATE TABLE market_data (
instrument_id BIGINT REFERENCES instruments(id) ON DELETE CASCADE,
data_source VARCHAR(20) DEFAULT 'ibkr', -- 'ibkr', 'yahoo', 'polygon' ...
bar_size VARCHAR(10) NOT NULL, -- '1min', '5min', '15min', '1hour', 'daily', 'weekly' ...
timestamp TIMESTAMPTZ NOT NULL,
open NUMERIC(12,6),
high NUMERIC(12,6),
low NUMERIC(12,6),
close NUMERIC(12,6),
volume BIGINT,
wap NUMERIC(12,6), -- weighted average price (IBKR)
count INTEGER, -- Anzahl Trades in der Bar
additional_data JSONB, -- falls andere Quellen mehr Felder liefern
PRIMARY KEY (instrument_id, data_source, bar_size, timestamp)
);
-- Timescale-Hypertable (sehr performant bei Millionen von Zeilen)
SELECT create_hypertable('market_data', 'timestamp', chunk_time_interval => INTERVAL '7 days');
Zukunftssicherheit:
Durch data_source kannst du später problemlos Polygon, Yahoo, Alpha Vantage etc. hinzufügen, ohne die Struktur zu ändern.
4. Zusätzliche nützliche Tabellen (optional, aber sehr empfehlenswert)
data_imports → Log-Tabelle (wann welcher Ticker von welcher Quelle importiert wurde, Status, Fehler)
fundamental_data → Bilanz-/Gewinn- und Verlustdaten (kann auch als JSONB in instruments oder eigene Tabelle)
orders / trades → Deine automatisch platzierten IBKR-Orders (mit ibkr_conid, Order-ID, Status etc.)
watchlists / portfolios → Deine eigenen Watchlists mit eigenen Tags
Praktische Umsetzungstipps
Mapping-Prozess (wichtigster Teil deines Tools):
Neue externe Ticker kommen herein → erst /iserver/secdef/search?symbol=... oder /trsrv/stocks?symbols=... aufrufen.
Ergebnis in instruments speichern (falls neu) + Mapping in external_identifiers.
Danach immer nur noch über ibkr_conid arbeiten.
Performance & Skalierung:
ibkr_conid + symbol + exchange stark indizieren.
Für sehr viele Instrumente (>> 10.000) lohnt sich eine separate instrument_aliases oder Cache-Layer (Redis).
Flexibilität für weitere Datenquellen:
Immer data_source und external_identifiers benutzen → du bist komplett unabhängig von IBKR als einziger Datenquelle.
Eigene Infos für Apple & Co.:
Einfach in custom_metadata oder instrument_custom_data schreiben. Die AI kann dort direkt Ergebnisse ablegen.
Diese Struktur ist praxisbewährt (ähnliche Schemata laufen bei vielen algo-Tradern mit IBKR + externen Daten). Sie ist gleichzeitig schlank und extrem erweiterbar.
Wenn du möchtest, kann ich dir:
das komplette SQL-Skript (mit allen Indizes, Triggers, Timescale-Setup),
ein Python-Beispiel mit SQLAlchemy + IBKR-WebAPI-Client zum automatischen Mapping,
oder ein ER-Diagramm (Mermaid) liefern.
Sag einfach Bescheid, wo du als Nächstes tiefer einsteigen willst!