Damit mehrere Agenten gleichzeitig Oberflaechen testen koennen, bekommt jedes Projekt eine feste Displaynummer (Vorgabe Richard): :99 PolyTrader, :98 Predictalytics, :97 ClawdDotNet, :96 IBKRTrader, :95 und absteigend fuer kuenftige Projekte. Zwei Prozesse auf demselben Display sehen die Fenster des jeweils anderen - Klicks landen im falschen Programm, Aufnahmen zeigen fremde Anwendungen. Beim Durcharbeiten fielen zwei weitere Kollisionspunkte auf, die zum Parallelbetrieb dazugehoeren und mit aufgenommen wurden: - Screenshot- und Logdateien in /tmp brauchen ein Projektpraefix. /tmp/v_1.png ueberschreiben sich parallel laufende Projekte gegenseitig. - "xvfb-run -a" darf NICHT mehr verwendet werden: Das -a sucht sich selbst ein freies Display und beginnt dabei bei :99 - ausgerechnet PolyTraders Nummer. Stattdessen "xvfb-run -n <nummer>". Die Warnung ist nicht theoretisch: Auf der VM lag ein verwaister X98-Socket, entstanden durch genau so einen "xvfb-run -a"-Aufruf beim smoke-ui-Test, als :99 belegt war. Er blockierte Predictalytics' reservierte Nummer, ohne dass ein Prozess lief. Entfernt, und die Anleitung erklaert jetzt, wie man verwaiste Sockets erkennt (ls /tmp/.X11-unix/ gegen pgrep -a Xvfb lesen) und aufraeumt. Weiter ergaenzt: - pkill nie ohne Displaynummer - "pkill Xvfb" erschlaegt die Sitzungen aller anderen Projekte. - DISPLAY in jedem Skript setzen, sonst landet man auf :0, dem echten Desktop. - Die Skriptvorlage hat jetzt einen Kopf mit PROJEKT/DISP/FENSTER; das ist alles, was sich je Projekt unterscheidet. Praktisch gegengetestet. - Aufraeumabschnitt und Belegungsliste um Displays und Verzeichnisse erweitert. Nebenbei aufgefallen: Das PolyTrader-Publish lag unter ~/pt-test statt ~/polytrader-test und verletzte damit die eigene Verzeichniskonvention. Umbenannt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
174 lines
11 KiB
XML
174 lines
11 KiB
XML
<UserControl xmlns="https://github.com/avaloniaui"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
xmlns:shell="using:PolyTrader.App.Avalonia.Shell"
|
|
xmlns:vm="using:PolyTrader.App.Avalonia.ViewModels"
|
|
x:Class="PolyTrader.App.Avalonia.Views.LauncherWindow">
|
|
|
|
<!--
|
|
Startseite der Anwendung. Entspricht der bisherigen LauncherForm, ist seit der Umstellung
|
|
auf die Einfenster-Shell aber eine Seite unter vielen: oben die Schnellaktionen
|
|
(Trading-Modi), dann die Kacheln zu den übrigen Ansichten, Account-Übersicht, Modul-KPIs
|
|
und die Live-Überblick-Widgets.
|
|
|
|
Die frühere Statusleiste (Trading / Module / API) steht jetzt einmal zentral in
|
|
Views/ShellWindow.axaml und nicht mehr auf dieser Seite.
|
|
-->
|
|
<DockPanel>
|
|
<Border Classes="toolbar" DockPanel.Dock="Top">
|
|
<StackPanel Orientation="Horizontal" Spacing="4">
|
|
<Button Name="btnLiveTrading" Content="LiveTrading (—)" MinWidth="170" />
|
|
<Button Name="btnDemoTrading" Content="DemoTrading (—)" MinWidth="170" />
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<!--
|
|
D-4: Update-Hinweis. Verborgen, solange keine Prüfung lief oder keine neue Version
|
|
vorliegt - erscheint nur, wenn Deploymentcenter:UpdateCheckEnabled gesetzt ist UND
|
|
tatsächlich ein Update gefunden wurde. Installiert NIE automatisch (Leitentscheidung 4).
|
|
-->
|
|
<Border Name="pnlUpdateBanner" DockPanel.Dock="Top" IsVisible="False"
|
|
Background="{DynamicResource AppWarningBrush}" Padding="10,6">
|
|
<DockPanel>
|
|
<StackPanel Orientation="Horizontal" Spacing="10" DockPanel.Dock="Right">
|
|
<Button Name="btnInstallUpdate" Content="Jetzt installieren …" />
|
|
<Button Name="btnDismissUpdate" Content="Später" />
|
|
</StackPanel>
|
|
<TextBlock Name="lblUpdateInfo" Text="—" VerticalAlignment="Center" TextWrapping="Wrap" />
|
|
</DockPanel>
|
|
</Border>
|
|
|
|
<ScrollViewer>
|
|
<StackPanel Margin="0,14,0,0" Spacing="16">
|
|
<TextBlock Text="ANSICHTEN" Classes="kicker" />
|
|
|
|
<ItemsControl Name="windowButtons">
|
|
<ItemsControl.ItemsPanel>
|
|
<ItemsPanelTemplate>
|
|
<WrapPanel Orientation="Horizontal" />
|
|
</ItemsPanelTemplate>
|
|
</ItemsControl.ItemsPanel>
|
|
<ItemsControl.ItemTemplate>
|
|
<DataTemplate x:DataType="shell:ViewTile">
|
|
<Button Command="{Binding Command}"
|
|
MinWidth="190" MinHeight="56"
|
|
Margin="0,0,8,8"
|
|
HorizontalContentAlignment="Left">
|
|
<StackPanel Orientation="Horizontal" Spacing="10">
|
|
<Image Source="{Binding Icon}" Width="28" Height="28"
|
|
VerticalAlignment="Center"
|
|
IsVisible="{Binding Icon, Converter={x:Static ObjectConverters.IsNotNull}}" />
|
|
<StackPanel VerticalAlignment="Center">
|
|
<TextBlock Text="{Binding Title}" FontWeight="{Binding FontWeight}" />
|
|
<TextBlock Text="{Binding CheckMark}" FontSize="11" Foreground="{DynamicResource AppPositiveBrush}" />
|
|
</StackPanel>
|
|
</StackPanel>
|
|
</Button>
|
|
</DataTemplate>
|
|
</ItemsControl.ItemTemplate>
|
|
</ItemsControl>
|
|
|
|
<!-- Account-Übersicht -->
|
|
<HeaderedContentControl Header="Account-Übersicht">
|
|
<DataGrid Name="gridAccounts" x:DataType="vm:AccountOverviewRow" Height="180">
|
|
<DataGrid.Columns>
|
|
<DataGridTextColumn Header="Account" Width="Auto" Binding="{Binding Name}" />
|
|
<DataGridTextColumn Header="Module" Width="Auto" Binding="{Binding Modules}" />
|
|
<DataGridTemplateColumn Header="Polymarket" Width="Auto">
|
|
<DataGridTemplateColumn.CellTemplate>
|
|
<DataTemplate x:DataType="vm:AccountOverviewRow">
|
|
<Button Content="Profil"
|
|
Padding="10,2" Margin="2"
|
|
Click="OnOpenPolymarketProfileClick"
|
|
HorizontalAlignment="Center" VerticalAlignment="Center" />
|
|
</DataTemplate>
|
|
</DataGridTemplateColumn.CellTemplate>
|
|
</DataGridTemplateColumn>
|
|
<DataGridTextColumn Header="Wallet (USDC)" Width="Auto" Binding="{Binding Balance, StringFormat=\{0:N2\}}" />
|
|
<DataGridTextColumn Header="3T PnL" Width="Auto" Binding="{Binding Pnl3d, StringFormat=\{0:N2\}}" />
|
|
<DataGridTextColumn Header="3T Winrate %" Width="Auto" Binding="{Binding WinRate3d, StringFormat=\{0:N1\}}" />
|
|
<DataGridTextColumn Header="Overall P/L" Width="Auto" Binding="{Binding OverallPnl, StringFormat=\{0:N2\}}" />
|
|
</DataGrid.Columns>
|
|
</DataGrid>
|
|
</HeaderedContentControl>
|
|
|
|
<!-- Modul-KPIs -->
|
|
<HeaderedContentControl Header="Modul-KPIs">
|
|
<ItemsControl Name="kpiTiles">
|
|
<ItemsControl.ItemsPanel>
|
|
<ItemsPanelTemplate>
|
|
<WrapPanel Orientation="Horizontal" />
|
|
</ItemsPanelTemplate>
|
|
</ItemsControl.ItemsPanel>
|
|
<ItemsControl.ItemTemplate>
|
|
<DataTemplate x:DataType="vm:ModuleKpiTile">
|
|
<Border BorderBrush="{DynamicResource AppBorderBrush}"
|
|
BorderThickness="1"
|
|
CornerRadius="4"
|
|
Background="{DynamicResource AppCardBrush}"
|
|
Padding="10,8" Margin="0,0,8,8" Width="250">
|
|
<!--
|
|
Die Vorzeichenfarbe kommt ueber Klassen + DynamicResource, nicht
|
|
mehr als im Code aufgeloester Pinsel: der wurde beim Themenwechsel
|
|
nicht neu ausgewertet und blieb dann auf der Hell-Farbe stehen -
|
|
dunkelgruen auf dunklem Grund, 2,3:1 statt der geforderten 4,5:1
|
|
(Befund B-6 des Linux-Sichttests).
|
|
-->
|
|
<StackPanel Spacing="4">
|
|
<TextBlock Text="{Binding ModuleName}" FontWeight="SemiBold" FontSize="13" />
|
|
<TextBlock Text="{Binding Text}"
|
|
Classes.positive="{Binding IsPositive}"
|
|
Classes.negative="{Binding IsNegative}"
|
|
FontFamily="{DynamicResource AppFontMono}"
|
|
FontSize="11" />
|
|
</StackPanel>
|
|
</Border>
|
|
</DataTemplate>
|
|
</ItemsControl.ItemTemplate>
|
|
</ItemsControl>
|
|
</HeaderedContentControl>
|
|
|
|
<!-- Live-Überblick Widgets (3 Spalten) -->
|
|
<Grid ColumnDefinitions="*,8,*,8,*">
|
|
<!-- Auffällige Trades (24h) -->
|
|
<HeaderedContentControl Grid.Column="0" Header="Auffällige Trades (24h)" Height="250">
|
|
<DataGrid Name="gridNotable" x:DataType="vm:NotableTradeRow">
|
|
<DataGrid.Columns>
|
|
<DataGridTextColumn Header="Modul" Width="Auto" Binding="{Binding Module}" />
|
|
<DataGridTextColumn Header="Markt" Width="*" MinWidth="180" Binding="{Binding Market}" />
|
|
<DataGridTextColumn Header="PnL" Width="Auto" Binding="{Binding Pnl, StringFormat=\{0:F2\}}" />
|
|
<DataGridTextColumn Header="PnL %" Width="Auto" Binding="{Binding PnlPct, StringFormat=\{0:F1\}}" />
|
|
</DataGrid.Columns>
|
|
</DataGrid>
|
|
</HeaderedContentControl>
|
|
|
|
<GridSplitter Grid.Column="1" Background="{DynamicResource AppBorderBrush}" />
|
|
|
|
<!-- Warnungen & Fehler (heute) -->
|
|
<HeaderedContentControl Grid.Column="2" Name="grpAlerts" Header="Warnungen & Fehler (heute)" Height="250">
|
|
<DataGrid Name="gridAlerts" x:DataType="vm:LogAlertRow">
|
|
<DataGrid.Columns>
|
|
<DataGridTextColumn Header="Zeit" Width="Auto" Binding="{Binding Time}" />
|
|
<DataGridTextColumn Header="Level" Width="Auto" Binding="{Binding Level}" />
|
|
<DataGridTextColumn Header="Nachricht" Width="*" MinWidth="180" Binding="{Binding Message}" />
|
|
</DataGrid.Columns>
|
|
</DataGrid>
|
|
</HeaderedContentControl>
|
|
|
|
<GridSplitter Grid.Column="3" Background="{DynamicResource AppBorderBrush}" />
|
|
|
|
<!-- Supervisor-KI (letzter Bericht) -->
|
|
<HeaderedContentControl Grid.Column="4" Header="Supervisor-KI (letzter Bericht)" Height="250">
|
|
<Border BorderBrush="{DynamicResource AppBorderBrush}" BorderThickness="1" Background="{DynamicResource AppCardBrush}" Padding="8">
|
|
<ScrollViewer>
|
|
<SelectableTextBlock Name="txtSupervisor" TextWrapping="Wrap" FontSize="12" FontFamily="Consolas,Menlo,monospace" />
|
|
</ScrollViewer>
|
|
</Border>
|
|
</HeaderedContentControl>
|
|
</Grid>
|
|
|
|
</StackPanel>
|
|
</ScrollViewer>
|
|
</DockPanel>
|
|
|
|
</UserControl>
|