diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml
index 53a8e6b..d1a8241 100644
--- a/.gitea/workflows/build.yml
+++ b/.gitea/workflows/build.yml
@@ -30,22 +30,16 @@ jobs:
with:
dotnet-version: '10.0.x'
- # Windows: die gesamte Projektmappe, inklusive der alten WinForms-Shell.
- - name: Build (Windows, gesamte Mappe)
- if: matrix.os == 'windows-latest'
- run: |
- dotnet build IBKRTrader.slnx -c Release
- dotnet test IBKRTrader.slnx --no-build -c Release --logger "trx;LogFileName=test-results.trx"
+ # Die gesamte Projektmappe baut auf beiden Plattformen – seit die WinForms-Shell
+ # entfernt ist, gibt es kein Projekt mehr mit Windows-Bindung.
+ - name: Restore
+ run: dotnet restore IBKRTrader.slnx
- # Linux: alles AUSSER IBKRTrader.App (WinForms, net10.0-windows) – das lässt sich hier
- # naturgemäß nicht bauen. Diese Aufzählung entfällt, sobald die WinForms-Shell aus dem
- # Build genommen wird; dann baut auch hier wieder die ganze Mappe.
- - name: Build (Linux, plattformneutrale Projekte)
- if: matrix.os == 'ubuntu-latest'
- run: |
- dotnet build src/IBKRTrader.App.Avalonia -c Release
- dotnet build src/IBKRTrader.Daemon -c Release
- dotnet test tests/IBKRTrader.Tests -c Release --logger "trx;LogFileName=test-results.trx"
+ - name: Build
+ run: dotnet build IBKRTrader.slnx --no-restore -c Release
+
+ - name: Test
+ run: dotnet test IBKRTrader.slnx --no-build -c Release --logger "trx;LogFileName=test-results.trx"
# Die Konstruktionsprüfung der Oberfläche braucht mit Avalonia KEIN Anzeigegerät mehr
# (SetupWithoutStarting). Mit WinForms war das auf einem Build-Server nicht möglich.
diff --git a/IBKRTrader.App.csproj b/IBKRTrader.App.csproj
deleted file mode 100644
index 172ccd5..0000000
--- a/IBKRTrader.App.csproj
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-
- WinExe
- net10.0-windows
- enable
- true
- enable
- en
- PerMonitorV2
- IBKRTrader.App
- IBKRTrader
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- True
- True
- Resources.resx
-
-
- ResXFileCodeGenerator
- Resources.Designer.cs
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
-
-
diff --git a/IBKRTrader.slnx b/IBKRTrader.slnx
index 3a81a0c..d274988 100644
--- a/IBKRTrader.slnx
+++ b/IBKRTrader.slnx
@@ -1,5 +1,4 @@
-
diff --git a/LauncherForm.cs b/LauncherForm.cs
deleted file mode 100644
index 6af25b7..0000000
--- a/LauncherForm.cs
+++ /dev/null
@@ -1,163 +0,0 @@
-using IBKRTrader.Core.Time;
-using IBKRTrader.Core.Logging;
-using IBKRTrader.Core.Modularity;
-using IBKRTrader.Core.Settings;
-using IBKRTrader.Core.Workers;
-using IBKRTrader.UI;
-using Microsoft.Extensions.DependencyInjection;
-
-namespace IBKRTrader;
-
-///
-/// Launcher – das Basis-Fenster (Shell). Zeigt je registrierter View einen Button, führt beim Start
-/// Migrationen aus, startet Module und die WorkerEngine, und trägt das gemeinsame Fenster-Menü.
-/// Die inhaltlichen Ansichten (Logs, Settings, Workers, Module) sind eigenständige Fenster.
-///
-public sealed class LauncherForm : Form
-{
- private readonly ShellUiHost _uiHost;
- private readonly IServiceProvider _services;
- private readonly LoggingService _logger;
- private readonly WorkerEngine _workerEngine;
- private readonly IReadOnlyList _modules;
-
- private readonly Dictionary _viewButtons = new(StringComparer.OrdinalIgnoreCase);
- private readonly ToolStripStatusLabel _status = new("Start...");
-
- public LauncherForm(ShellUiHost uiHost, IServiceProvider services)
- {
- _uiHost = uiHost;
- _services = services;
- _logger = services.GetRequiredService();
- _workerEngine = services.GetRequiredService();
- _modules = services.GetServices().ToList();
-
- Text = "IBKRTrader — Launcher";
- Width = 720;
- Height = 540;
- StartPosition = FormStartPosition.CenterScreen;
-
- _uiHost.SetMainWindow(this);
-
- BuildUi();
- _uiHost.OpenStateChanged += UpdateButtonStates;
- }
-
- private void BuildUi()
- {
- var menu = new MenuStrip { Dock = DockStyle.Top, ImageScalingSize = new Size(24, 24) };
- WindowMenu.Wire(menu, _uiHost, null);
-
- // Fenster-Buttons in einem ToolStrip (Icon über Text) – wie im PolytraderSharp-Launcher.
- var toolstrip = new ToolStrip
- {
- Dock = DockStyle.Top,
- GripStyle = ToolStripGripStyle.Hidden,
- ImageScalingSize = new Size(32, 32),
- AutoSize = true,
- Padding = new Padding(4)
- };
-
- foreach (var view in _uiHost.Views.OrderBy(v => v.Order).ThenBy(v => v.Title))
- {
- var id = view.Id;
- var btn = new ToolStripButton(view.Title, ViewIcons.Resolve(view.IconKey))
- {
- DisplayStyle = ToolStripItemDisplayStyle.ImageAndText,
- ImageScaling = ToolStripItemImageScaling.None,
- TextImageRelation = TextImageRelation.ImageAboveText,
- AutoSize = true,
- Padding = new Padding(6, 2, 6, 2)
- };
- btn.Click += (_, _) => _uiHost.OpenView(id);
- _viewButtons[id] = btn;
- toolstrip.Items.Add(btn);
- }
-
- var content = new Panel { Dock = DockStyle.Fill, BackColor = SystemColors.ControlLightLight };
- content.Controls.Add(new Label
- {
- Text = "IBKRTrader — Launcher\nFenster über die Leiste oben öffnen.",
- Dock = DockStyle.Fill, TextAlign = ContentAlignment.MiddleCenter,
- ForeColor = SystemColors.GrayText, Font = new Font(Font.FontFamily, 11f)
- });
-
- var statusStrip = new StatusStrip();
- statusStrip.Items.Add(_status);
-
- // Dock-Stacking: zuletzt hinzugefügtes Top-Control liegt oben → Menü über ToolStrip.
- Controls.Add(content);
- Controls.Add(statusStrip);
- Controls.Add(toolstrip);
- Controls.Add(menu);
- MainMenuStrip = menu;
- }
-
- protected override void OnLoad(EventArgs e)
- {
- base.OnLoad(e);
- _ = StartupAsync();
- }
-
- protected override void OnFormClosing(FormClosingEventArgs e)
- {
- // Auch das Schließen-X läuft über die Sicherheitsabfrage.
- if (!_uiHost.ShutdownConfirmed)
- {
- e.Cancel = true;
- BeginInvoke((Action)(() => _uiHost.RequestShutdown()));
- return;
- }
-
- _uiHost.CloseAllViews();
- try
- {
- foreach (var module in _modules)
- module.StopAsync(default).GetAwaiter().GetResult();
- }
- catch { /* Shutdown darf nicht am Modul scheitern */ }
- // Worker/Services stoppt der Host in Program.Main via AppHost.StopAsync() nach Application.Run.
-
- base.OnFormClosing(e);
- }
-
- private async Task StartupAsync()
- {
- _logger.Info("Core", "=== IBKRTrader startet ===");
- _logger.Info("Core", $"Version: 1.0.0 | .NET {Environment.Version}");
-
- // Log-Level aus Settings.
- var levelStr = _services.GetRequiredService().Settings.Logging.Level;
- if (Enum.TryParse(levelStr, true, out var level))
- _logger.SetMinLevel(level);
-
- // Das gesamte Schema (core_ + ct_) läuft über EF-Migrationen, extern via
- // `dotnet ef database update` angewendet – keine Laufzeit-Migration mehr.
-
- // Worker/Services laufen bereits (Generic Host, AppHost.Start()). Hier nur noch Modul-Start.
- foreach (var module in _modules)
- {
- try { await module.StartAsync(default); }
- catch (Exception ex) { _logger.Error(module.Name, $"{module.Name}: Start fehlgeschlagen.", ex); }
- }
-
- _logger.Info("Core", "IBKRTrader bereit.");
- SetStatus("Bereit");
- UpdateButtonStates();
- }
-
- private void UpdateButtonStates()
- {
- if (IsDisposed) return;
- if (InvokeRequired) { BeginInvoke((Action)UpdateButtonStates); return; }
- foreach (var (id, btn) in _viewButtons)
- btn.Checked = _uiHost.IsOpen(id);
- }
-
- private void SetStatus(string text)
- {
- if (IsDisposed) return;
- if (InvokeRequired) { BeginInvoke((Action)(() => SetStatus(text))); return; }
- _status.Text = $"Status: {text} | {AppTimeZone.Now:HH:mm:ss}";
- }
-}
diff --git a/Program.cs b/Program.cs
deleted file mode 100644
index c710707..0000000
--- a/Program.cs
+++ /dev/null
@@ -1,133 +0,0 @@
-using IBKRTrader.Core.Logging;
-using IBKRTrader.Core.Modularity;
-using IBKRTrader.Core.Settings;
-using IBKRTrader.Core.Trading;
-using IBKRTrader.Core.Workers;
-using IBKRTrader.Hosting;
-using IBKRTrader.UI;
-using IBKRTrader.UI.Views;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
-
-namespace IBKRTrader;
-
-///
-/// Einstiegspunkt der WinForms-Shell (Windows).
-///
-/// Der Host selbst kommt aus und ist plattformneutral – hier
-/// wird er nur um Fensterverwaltung und Launcher ergänzt. Derselbe Host trägt den kopflosen
-/// Linux-Dienst IBKRTrader.Daemon; so kann keine der beiden Varianten eine Registrierung
-/// vergessen.
-///
-internal static class Program
-{
- public static IHost? AppHost { get; private set; }
-
- [STAThread]
- static void Main(string[] args)
- {
- // Headless-Smoke-Test der UI (konstruiert jede View + Launcher, ohne Message-Loop).
- if (args.Length > 0 && string.Equals(args[0], "--smoke-ui", StringComparison.OrdinalIgnoreCase))
- {
- Environment.ExitCode = RunSmokeUi();
- return;
- }
-
- ApplicationConfiguration.Initialize();
-
- var modules = AppHostBuilder.CreateModules();
- AppHost = AppHostBuilder.Build(modules, RegisterShellServices);
-
- AppHostBuilder.RunStartupChecks(AppHost.Services);
-
- // Host starten → alle Worker/Services (IHostedService) laufen an.
- AppHost.Start();
-
- // Views registrieren (Core + Module), dann Launcher starten.
- var uiHost = AppHost.Services.GetRequiredService();
- RegisterCoreViews(uiHost, AppHost.Services);
- foreach (var module in modules)
- module.RegisterUi(uiHost, AppHost.Services);
- ModuleViews.Register(uiHost, AppHost.Services);
- ViewIcons.AssignDefaults(uiHost);
-
- Application.Run(AppHost.Services.GetRequiredService());
- AppHost.StopAsync().GetAwaiter().GetResult();
- }
-
- /// Nur die Dienste, die es ohne Oberfläche nicht gibt.
- private static void RegisterShellServices(IServiceCollection services, IConfiguration configuration)
- {
- services.AddSingleton();
- services.AddSingleton(sp => sp.GetRequiredService());
- services.AddSingleton();
- }
-
- /// Registriert die Core-Views (Dashboard, Workers, Logs, Settings) bei der Shell.
- private static void RegisterCoreViews(IModuleUiHost uiHost, IServiceProvider sp)
- {
- uiHost.RegisterView(new ModuleView
- {
- Id = "core.dashboard", Title = "Dashboard", Group = "Core", Order = 5,
- CreateView = () => new DashboardView(
- sp.GetRequiredService(),
- sp.GetRequiredService(),
- sp.GetServices(),
- sp.GetRequiredService(),
- sp.GetServices())
- });
- uiHost.RegisterView(new ModuleView
- {
- Id = "core.workers", Title = "Workers / Services", Group = "Core", Order = 10,
- CreateView = () => new WorkersView(sp.GetRequiredService())
- });
- uiHost.RegisterView(new ModuleView
- {
- Id = "core.logs", Title = "Logs", Group = "Core", Order = 20,
- CreateView = () => new LogsView(sp.GetRequiredService())
- });
- uiHost.RegisterView(new ModuleView
- {
- Id = "core.settings", Title = "Settings", Group = "Core", Order = 30,
- CreateView = () => new SettingsView(sp.GetRequiredService())
- });
- }
-
- ///
- /// Headless-Smoke-Test: baut den Host, registriert Views + Modul-UI und konstruiert jede
- /// registrierte View sowie den Launcher – ohne Message-Loop. Gibt die Fehleranzahl zurück.
- /// Der Host wird bewusst NICHT gestartet: sonst liefen Worker und Broker-Verbindungen an,
- /// was für eine reine Konstruktionsprüfung unerwünscht ist.
- ///
- private static int RunSmokeUi()
- {
- ApplicationConfiguration.Initialize();
-
- var modules = AppHostBuilder.CreateModules();
- using var host = AppHostBuilder.Build(modules, RegisterShellServices);
-
- AppHostBuilder.RunStartupChecks(host.Services);
-
- var uiHost = host.Services.GetRequiredService();
- RegisterCoreViews(uiHost, host.Services);
- foreach (var module in modules)
- module.RegisterUi(uiHost, host.Services);
- ModuleViews.Register(uiHost, host.Services);
- ViewIcons.AssignDefaults(uiHost);
-
- var failures = 0;
- Console.WriteLine("=== Smoke-UI: View-Konstruktion ===");
- foreach (var view in uiHost.Views)
- {
- try { using var form = (Form)view.CreateView(); Console.WriteLine($"[OK] {view.Id} ({view.Title})"); }
- catch (Exception ex) { failures++; Console.WriteLine($"[FEHLER] {view.Id}: {ex.GetType().Name}: {ex.Message}"); }
- }
-
- try { using var launcher = host.Services.GetRequiredService(); Console.WriteLine("[OK] LauncherForm konstruiert"); }
- catch (Exception ex) { failures++; Console.WriteLine($"[FEHLER] LauncherForm: {ex.GetType().Name}: {ex.Message}"); }
-
- Console.WriteLine(failures == 0 ? "=== Smoke-UI OK ===" : $"=== Smoke-UI: {failures} Fehler ===");
- return failures;
- }
-}
diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs
deleted file mode 100644
index 5637a2e..0000000
--- a/Properties/Resources.Designer.cs
+++ /dev/null
@@ -1,303 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// Dieser Code wurde von einem Tool generiert.
-// Laufzeitversion:4.0.30319.42000
-//
-// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
-// der Code erneut generiert wird.
-//
-//------------------------------------------------------------------------------
-
-namespace IBKRTrader.Properties {
- using System;
-
-
- ///
- /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
- ///
- // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
- // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
- // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
- // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class Resources {
-
- private static global::System.Resources.ResourceManager resourceMan;
-
- private static global::System.Globalization.CultureInfo resourceCulture;
-
- [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- internal Resources() {
- }
-
- ///
- /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
- ///
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Resources.ResourceManager ResourceManager {
- get {
- if (object.ReferenceEquals(resourceMan, null)) {
- global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("IBKRTrader.Properties.Resources", typeof(Resources).Assembly);
- resourceMan = temp;
- }
- return resourceMan;
- }
- }
-
- ///
- /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
- /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
- ///
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Globalization.CultureInfo Culture {
- get {
- return resourceCulture;
- }
- set {
- resourceCulture = value;
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap accept_button {
- get {
- object obj = ResourceManager.GetObject("accept_button", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap add {
- get {
- object obj = ResourceManager.GetObject("add", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap cancel {
- get {
- object obj = ResourceManager.GetObject("cancel", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap coins_in_hand {
- get {
- object obj = ResourceManager.GetObject("coins_in_hand", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap cross_reference {
- get {
- object obj = ResourceManager.GetObject("cross_reference", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap dashboard {
- get {
- object obj = ResourceManager.GetObject("dashboard", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap delete {
- get {
- object obj = ResourceManager.GetObject("delete", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap diskette {
- get {
- object obj = ResourceManager.GetObject("diskette", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap emotion_batman {
- get {
- object obj = ResourceManager.GetObject("emotion_batman", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap error_log {
- get {
- object obj = ResourceManager.GetObject("error_log", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap file_start_workflow {
- get {
- object obj = ResourceManager.GetObject("file_start_workflow", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap money {
- get {
- object obj = ResourceManager.GetObject("money", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap money_add {
- get {
- object obj = ResourceManager.GetObject("money_add", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap money_delete {
- get {
- object obj = ResourceManager.GetObject("money_delete", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap money_dollar {
- get {
- object obj = ResourceManager.GetObject("money_dollar", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap refresh_all {
- get {
- object obj = ResourceManager.GetObject("refresh_all", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap setting_tools {
- get {
- object obj = ResourceManager.GetObject("setting_tools", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap stop {
- get {
- object obj = ResourceManager.GetObject("stop", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap system_time {
- get {
- object obj = ResourceManager.GetObject("system_time", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap token_quantifier {
- get {
- object obj = ResourceManager.GetObject("token_quantifier", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap traffic_lights_green {
- get {
- object obj = ResourceManager.GetObject("traffic_lights_green", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap traffic_lights_red {
- get {
- object obj = ResourceManager.GetObject("traffic_lights_red", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap traffic_lights_yellow {
- get {
- object obj = ResourceManager.GetObject("traffic_lights_yellow", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
-
- ///
- /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap warning {
- get {
- object obj = ResourceManager.GetObject("warning", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
- }
-}
diff --git a/Properties/Resources.resx b/Properties/Resources.resx
deleted file mode 100644
index 18293c6..0000000
--- a/Properties/Resources.resx
+++ /dev/null
@@ -1,133 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- ..\Resources\accept_button.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
- ..\Resources\add.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
- ..\Resources\cancel.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
- ..\Resources\coins_in_hand.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
- ..\Resources\cross_reference.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
- ..\Resources\dashboard.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
- ..\Resources\delete.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
- ..\Resources\diskette.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
- ..\Resources\emotion_batman.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
- ..\Resources\error_log.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
- ..\Resources\file_start_workflow.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
- ..\Resources\money.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
- ..\Resources\money_add.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
- ..\Resources\money_delete.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
- ..\Resources\money_dollar.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
- ..\Resources\refresh_all.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
- ..\Resources\setting_tools.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
- ..\Resources\stop.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
- ..\Resources\system_time.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
- ..\Resources\token_quantifier.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
- ..\Resources\traffic_lights_green.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
- ..\Resources\traffic_lights_red.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
- ..\Resources\traffic_lights_yellow.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
- ..\Resources\warning.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
diff --git a/README.md b/README.md
index e219f33..3f98174 100644
--- a/README.md
+++ b/README.md
@@ -4,13 +4,20 @@ Modulares C#-Trading-Framework für Interactive-Brokers-Aktien. **Harter Core +
Strategie-Module + Launcher**, der die Fenster der Module öffnet. Konzept nach dem Vorbild von
PolytraderSharp (nur IBKR statt Polymarket).
+**Läuft auf Windows und Linux** – wahlweise mit Oberfläche (Avalonia) oder kopflos als Dienst.
+
## Architektur (Kurzform)
```
-IBKRTrader.App WinExe – Generic Host + Launcher/Shell (WinForms)
+src/IBKRTrader.App.Avalonia Oberfläche (Avalonia, plattformneutral)
+src/IBKRTrader.Daemon kopfloser Dienst (systemd) – dieselbe Anwendung ohne Fenster
+src/IBKRTrader.Hosting Host-Zusammenstellung, von beiden Einstiegspunkten geteilt
src/IBKRTrader.Core Contracts, EF-Persistenz, Trading-Kern, Worker, Security
src/IBKRTrader.Modules.* je Modul ein eigenes Projekt (referenziert nur Core)
tests/IBKRTrader.Tests xUnit (Unit + EF-InMemory)
```
+Alle Projekte sind `net10.0` ohne Plattformbindung. Der UI-Contract im Core ist toolkit-neutral
+(`Func