diff --git a/src/PolyTrader.App.Avalonia/ViewModels/LauncherViewModels.cs b/src/PolyTrader.App.Avalonia/ViewModels/LauncherViewModels.cs
new file mode 100644
index 0000000..a0b473b
--- /dev/null
+++ b/src/PolyTrader.App.Avalonia/ViewModels/LauncherViewModels.cs
@@ -0,0 +1,44 @@
+using Avalonia.Media;
+using PolyTrader.App.Avalonia.Shell;
+
+namespace PolyTrader.App.Avalonia.ViewModels
+{
+ /// Anzeige-Zeile der Account-Übersicht im Launcher.
+ public sealed class AccountOverviewRow
+ {
+ public int AccountId { get; init; }
+ public string Name { get; init; } = string.Empty;
+ public string Modules { get; init; } = string.Empty;
+ public string WalletAddress { get; init; } = string.Empty;
+ public decimal Balance { get; init; }
+ public decimal Pnl3d { get; init; }
+ public decimal WinRate3d { get; init; }
+ public decimal OverallPnl { get; init; }
+ }
+
+ /// Anzeige-Zeile für auffällige Trades der letzten 24 Stunden.
+ public sealed class NotableTradeRow
+ {
+ public string Module { get; init; } = string.Empty;
+ public string Market { get; init; } = string.Empty;
+ public decimal Pnl { get; init; }
+ public decimal PnlPct { get; init; }
+ }
+
+ /// Anzeige-Zeile für Warnungen & Fehler aus den Tages-JSONL-Logs.
+ public sealed class LogAlertRow
+ {
+ public string Time { get; init; } = string.Empty;
+ public string Level { get; init; } = string.Empty;
+ public string Message { get; init; } = string.Empty;
+ }
+
+ /// Kachel-Datenmodell für Modul-PnL/Winrate im Launcher.
+ public sealed class ModuleKpiTile
+ {
+ public string ModuleName { get; init; } = string.Empty;
+ public string Text { get; init; } = string.Empty;
+ public bool IsPositive { get; init; } = true;
+ public IBrush ForegroundBrush => ThemeManager.Brush(IsPositive ? "AppPositiveBrush" : "AppNegativeBrush");
+ }
+}
diff --git a/src/PolyTrader.App.Avalonia/Views/LauncherWindow.axaml b/src/PolyTrader.App.Avalonia/Views/LauncherWindow.axaml
index afd6ef3..d9e66d2 100644
--- a/src/PolyTrader.App.Avalonia/Views/LauncherWindow.axaml
+++ b/src/PolyTrader.App.Avalonia/Views/LauncherWindow.axaml
@@ -2,20 +2,16 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:PolyTrader.App.Avalonia.Controls"
xmlns:shell="using:PolyTrader.App.Avalonia.Shell"
+ xmlns:vm="using:PolyTrader.App.Avalonia.ViewModels"
x:Class="PolyTrader.App.Avalonia.Views.LauncherWindow"
Title="PolyTrader"
- Width="1600" Height="700"
+ Width="1600" Height="900"
WindowState="Maximized">
@@ -65,10 +61,97 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/PolyTrader.App.Avalonia/Views/LauncherWindow.axaml.cs b/src/PolyTrader.App.Avalonia/Views/LauncherWindow.axaml.cs
index 1f4fd74..0405119 100644
--- a/src/PolyTrader.App.Avalonia/Views/LauncherWindow.axaml.cs
+++ b/src/PolyTrader.App.Avalonia/Views/LauncherWindow.axaml.cs
@@ -1,20 +1,29 @@
-using System;
+using System;
+using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.IO;
using System.Linq;
using Avalonia.Controls;
+using Avalonia.Controls.Primitives;
+using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
-using Avalonia.Media;
using Avalonia.Threading;
using Microsoft.Extensions.DependencyInjection;
using PolyTrader.App.Avalonia.Shell;
+using PolyTrader.App.Avalonia.ViewModels;
+using PolyTrader.Core.Analytics;
using PolyTrader.Core.Modularity;
+using PolyTrader.Core.Persistence;
+using PolyTrader.Modules.Supervisor.Persistence;
using PolyTraderSharp;
+using PolyTraderSharp.Models;
+using PolyTraderSharp.Services;
namespace PolyTrader.App.Avalonia.Views
{
///
/// „Startleiste" der Anwendung – Gegenstück zur bisherigen LauncherForm. Öffnet die Fenster,
- /// spiegelt deren Offen-Status und zeigt die Kernkennzahlen in der Statusleiste.
+ /// spiegelt deren Offen-Status, zeigt Kernkennzahlen und beinhaltet die Live-Überblick-Widgets.
/// Layout vollständig in LauncherWindow.axaml.
///
public partial class LauncherWindow : Window
@@ -24,6 +33,12 @@ namespace PolyTrader.App.Avalonia.Views
private readonly TradingState _state;
private readonly DispatcherTimer _statusTimer = new() { Interval = TimeSpan.FromSeconds(1) };
private readonly ObservableCollection _windowButtons = new();
+ private readonly ObservableCollection _accountRows = new();
+ private readonly ObservableCollection _kpiTiles = new();
+ private readonly ObservableCollection _notableRows = new();
+ private readonly ObservableCollection _alertRows = new();
+
+ private int _statusTicks;
public LauncherWindow() => AvaloniaXamlLoader.Load(this);
@@ -37,6 +52,11 @@ namespace PolyTrader.App.Avalonia.Views
this.FindControl("menuBar")!.Attach(uiHost, null, this);
this.FindControl("windowButtons")!.ItemsSource = _windowButtons;
+ this.FindControl("gridAccounts")!.ItemsSource = _accountRows;
+ this.FindControl("kpiTiles")!.ItemsSource = _kpiTiles;
+ this.FindControl("gridNotable")!.ItemsSource = _notableRows;
+ this.FindControl("gridAlerts")!.ItemsSource = _alertRows;
+
RebuildWindowButtons();
_uiHost.OpenStateChanged += OnOpenStateChanged;
@@ -54,6 +74,7 @@ namespace PolyTrader.App.Avalonia.Views
_statusTimer.Tick += (_, _) => UpdateStatus();
_statusTimer.Start();
UpdateStatus();
+ RefreshData();
// Schliessen des Launchers laeuft ueber dieselbe Sicherheitsabfrage wie "Beenden".
Closing += (_, e) =>
@@ -110,8 +131,6 @@ namespace PolyTrader.App.Avalonia.Views
Apply(this.FindControl