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>
This commit is contained in:
Richard
2026-07-26 18:19:47 +02:00
co-authored by Claude Opus 4.8
commit ebeb035e92
47 changed files with 4527 additions and 0 deletions
+207
View File
@@ -0,0 +1,207 @@
using System.ComponentModel;
namespace IBKRTrader.Core.Settings;
// ─── Database ────────────────────────────────────────────────────────────────
[TypeConverter(typeof(ExpandableObjectConverter))]
public class DatabaseSettings
{
[Category("Database")]
[DisplayName("Host")]
[Description("MySQL-Serveradresse (Hostname oder IP)")]
public string Host { get; set; } = "larx.your-database.de";
[Category("Database")]
[DisplayName("Port")]
[Description("MySQL-Port (Standard: 3306)")]
public int Port { get; set; } = 3306;
[Category("Database")]
[DisplayName("Database")]
[Description("Name der MySQL-Datenbank")]
public string Database { get; set; } = "bergisnu_db0";
[Category("Database")]
[DisplayName("User")]
[Description("MySQL-Benutzername")]
public string User { get; set; } = "bergisnu_0";
[Category("Database")]
[DisplayName("Password")]
[Description("MySQL-Passwort")]
[PasswordPropertyText(true)]
public string Password { get; set; } = "o5/A49+f}:Da";
public string BuildConnectionString() =>
$"Server={Host};Port={Port};Database={Database};" +
$"User={User};Password={Password};" +
$"AllowPublicKeyRetrieval=true;SslMode=Preferred;CharSet=utf8mb4;" +
$"ConnectionTimeout=15;DefaultCommandTimeout=30;";
public override string ToString() => $"{User}@{Host}:{Port}/{Database}";
}
// ─── IBKR TWS/Gateway (Socket API) ───────────────────────────────────────────
[TypeConverter(typeof(ExpandableObjectConverter))]
public class IBKRSettings
{
[Category("IBKR Gateway")]
[DisplayName("Host")]
[Description("Adresse des IBKR Gateway (Standard: 127.0.0.1)")]
public string Host { get; set; } = "127.0.0.1";
[Category("IBKR Gateway")]
[DisplayName("Port")]
[Description("IBKR Gateway Port (Paper: 4002, Live: 4001)")]
public int Port { get; set; } = 4001;
[Category("IBKR Gateway")]
[DisplayName("Client ID")]
[Description("Eindeutige Client-ID für die API-Verbindung")]
public int ClientId { get; set; } = 1;
public override string ToString() => $"{Host}:{Port} (Client {ClientId})";
}
// ─── IBKR Web API (Client Portal Gateway) ────────────────────────────────────
[TypeConverter(typeof(ExpandableObjectConverter))]
public class IBKRWebApiSettings
{
[Category("IBKR Web API")]
[DisplayName("Aktiviert")]
[Description("Aktiviert die IBKR Web API Marktdaten-Worker")]
public bool Enabled { get; set; } = false;
[Category("IBKR Web API")]
[DisplayName("Gateway URL")]
[Description("URL des Client Portal Gateway (Standard: https://localhost:5000)")]
public string GatewayUrl { get; set; } = "https://localhost:5000";
[Category("IBKR Web API")]
[DisplayName("History-Zeitraum")]
[Description("Zeitraum für den ersten historischen Import (z.B. 2Y, 5Y, 1Y)")]
public string HistoryPeriod { get; set; } = "2Y";
[Category("IBKR Web API")]
[DisplayName("Max Requests/Sek")]
[Description("Maximale API-Anfragen pro Sekunde (IBKR-Limit: 10, empfohlen: 5)")]
public int MaxRequestsPerSecond { get; set; } = 5;
public override string ToString() => Enabled ? $"Aktiv {GatewayUrl}" : "Deaktiviert";
}
// ─── Logging ─────────────────────────────────────────────────────────────────
[TypeConverter(typeof(ExpandableObjectConverter))]
public class LoggingSettings
{
[Category("Logging")]
[DisplayName("Log Level")]
[Description("Minimales Log-Level: Info, Warn oder Error")]
public string Level { get; set; } = "Info";
[Category("Logging")]
[DisplayName("Max. Dateigröße (MB)")]
[Description("Maximale Größe einer Log-Datei in Megabyte")]
public int MaxFileSizeMb { get; set; } = 10;
[Category("Logging")]
[DisplayName("Aufbewahrung (Tage)")]
[Description("Anzahl Tage, nach denen Log-Dateien gelöscht werden")]
public int RetentionDays { get; set; } = 30;
public override string ToString() => $"Level: {Level}";
}
// ─── Webserver ───────────────────────────────────────────────────────────────
[TypeConverter(typeof(ExpandableObjectConverter))]
public class WebserverSettings
{
[Category("Webserver")]
[DisplayName("Port")]
[Description("Port des internen Webservers (Web-UI)")]
public int Port { get; set; } = 5001;
[Category("Webserver")]
[DisplayName("Aktiviert")]
[Description("Webserver und REST-API beim Start aktivieren")]
public bool Enabled { get; set; } = false;
public override string ToString() => Enabled ? $"Aktiv auf Port {Port}" : "Deaktiviert";
}
// ─── Workers ─────────────────────────────────────────────────────────────────
[TypeConverter(typeof(ExpandableObjectConverter))]
public class WorkerSchedule
{
[Category("Worker")]
[DisplayName("Aktiviert")]
public bool Enabled { get; set; } = true;
[Category("Worker")]
[DisplayName("Interval (Minuten)")]
public int IntervalMinutes { get; set; } = 30;
public override string ToString() => Enabled ? $"alle {IntervalMinutes} min" : "Deaktiviert";
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public class WorkerSettings
{
[Category("Workers")]
[DisplayName("BackupWorker")]
[Description("Zeitplan für den automatischen Backup-Worker")]
public WorkerSchedule BackupWorker { get; set; } = new();
[Category("Workers")]
[DisplayName("IBKR Instrument-Sync")]
[Description("Zeitplan für die IBKR Stammdaten-Synchronisation (alle 30 Tage)")]
public WorkerSchedule InstrumentSyncWorker { get; set; } = new() { IntervalMinutes = 43200 }; // 30 Tage
[Category("Workers")]
[DisplayName("IBKR Preishistorie")]
[Description("Zeitplan für den täglichen IBKR Preishistorie-Abruf")]
public WorkerSchedule PriceHistoryWorker { get; set; } = new() { IntervalMinutes = 1440 }; // 24h
public override string ToString() => "Worker-Konfiguration";
}
// ─── Root ────────────────────────────────────────────────────────────────────
public class AppSettings
{
[Category("Database")]
[DisplayName("Datenbank")]
[Description("MySQL-Verbindungseinstellungen")]
public DatabaseSettings Database { get; set; } = new();
[Category("IBKR Gateway")]
[DisplayName("IBKR")]
[Description("Interactive Brokers Gateway-Verbindung (Socket API)")]
public IBKRSettings IBKR { get; set; } = new();
[Category("IBKR Web API")]
[DisplayName("IBKR Web API")]
[Description("Client Portal Gateway für Marktdaten")]
public IBKRWebApiSettings IBKRWebApi { get; set; } = new();
[Category("Logging")]
[DisplayName("Logging")]
[Description("Log-Level und Datei-Einstellungen")]
public LoggingSettings Logging { get; set; } = new();
[Category("Webserver")]
[DisplayName("Webserver")]
[Description("Interner HTTP-Server und REST-API")]
public WebserverSettings Webserver { get; set; } = new();
[Category("Workers")]
[DisplayName("Worker-Einstellungen")]
[Description("Zeitpläne der einzelnen Core-Worker")]
public WorkerSettings WorkerSettings { get; set; } = new();
}
+49
View File
@@ -0,0 +1,49 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace IBKRTrader.Core.Settings;
/// <summary>
/// Lädt und speichert settings.json neben der EXE.
/// Singleton wird beim App-Start einmalig geladen.
/// </summary>
public class SettingsService
{
private static readonly string SettingsPath =
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "settings.json");
private static readonly JsonSerializerOptions JsonOptions = new()
{
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.Never,
PropertyNameCaseInsensitive = true
};
public AppSettings Settings { get; private set; } = new();
public void Load()
{
if (!File.Exists(SettingsPath))
{
Save(); // Defaults auf Disk schreiben
return;
}
try
{
var json = File.ReadAllText(SettingsPath);
Settings = JsonSerializer.Deserialize<AppSettings>(json, JsonOptions) ?? new AppSettings();
}
catch
{
Settings = new AppSettings();
Save();
}
}
public void Save()
{
var json = JsonSerializer.Serialize(Settings, JsonOptions);
File.WriteAllText(SettingsPath, json);
}
}