From 5320d25d6df411721762cdb6ec4f384f75b067ed Mon Sep 17 00:00:00 2001 From: Richard Date: Thu, 6 Aug 2026 17:13:14 +0200 Subject: [PATCH] P1b: System.Drawing aus der Fachlogik entfernt - TradeRowColoring liefert jetzt eine TradeRowTint-Kategorie (Loss/SmallWin/BigWin) statt einer System.Drawing.Color. Die Schwellenlogik bleibt getestet, die konkrete Farbe legt die UI fest (neu: Ui/TradeRowPalette.cs im CopyTrading-Modul). Bessere Schichtung und Voraussetzung dafuer, dass das Modul spaeter net8.0 wird. - TradeRowColoringTests prueft die Kategorie statt der Farbe (gleiche Abdeckung). - Models/DashboardRow.cs: verwaistes using System.Drawing entfernt. System.Drawing liegt damit ausschliesslich noch in UI-Ordnern - die Fachlogik in Core und Modulen ist frei davon. 442 Tests gruen, --smoke-ui gruen. Co-Authored-By: Claude Opus 5 --- Models/DashboardRow.cs | 3 +- .../Logic/TradeRowColoring.cs | 34 ++++++++++++++----- .../Ui/ClosedTradesView.cs | 4 +-- .../Ui/OpenTradesView.cs | 4 +-- .../Ui/TradeRowPalette.cs | 27 +++++++++++++++ .../PolyTrader.Tests/TradeRowColoringTests.cs | 31 ++++++++--------- 6 files changed, 71 insertions(+), 32 deletions(-) create mode 100644 src/PolyTrader.Modules.CopyTrading/Ui/TradeRowPalette.cs diff --git a/Models/DashboardRow.cs b/Models/DashboardRow.cs index 8f1e0be..6aea1ed 100644 --- a/Models/DashboardRow.cs +++ b/Models/DashboardRow.cs @@ -1,5 +1,4 @@ -using System.ComponentModel; -using System.Drawing; +using System.ComponentModel; namespace PolyTraderSharp.Models { diff --git a/src/PolyTrader.Modules.CopyTrading/Logic/TradeRowColoring.cs b/src/PolyTrader.Modules.CopyTrading/Logic/TradeRowColoring.cs index e6f607e..b954d63 100644 --- a/src/PolyTrader.Modules.CopyTrading/Logic/TradeRowColoring.cs +++ b/src/PolyTrader.Modules.CopyTrading/Logic/TradeRowColoring.cs @@ -1,18 +1,34 @@ -using System.Drawing; - namespace PolyTrader.Modules.CopyTrading.Logic { + /// Farbkategorie einer Trade-Zeile. Die konkrete Farbe legt die jeweilige UI fest. + public enum TradeRowTint + { + /// < 0 % – Verlust. + Loss, + + /// 0–10 % – kleiner Gewinn. + SmallWin, + + /// > 10 % – deutlicher Gewinn. + BigWin + } + /// - /// Reine Zeilenfärbung nach realisiertem/unrealisiertem PnL-Prozent (getestet, damit die - /// Schwellen belastbar sind): Verlust rot, 0–10 % hellgrün, > 10 % kräftiges Grün. + /// Reine Einstufung von Trade-Zeilen nach realisiertem/unrealisiertem PnL-Prozent (getestet, + /// damit die Schwellen belastbar sind): Verlust, 0–10 %, > 10 %. + /// + /// Liefert bewusst eine -Kategorie statt einer Farbe: Die + /// Modul-Logik ist damit frei von System.Drawing (seit .NET 7 Windows-only) und die + /// Zuordnung Kategorie → Farbe liegt dort, wo sie hingehört – in der jeweiligen Oberfläche. /// public static class TradeRowColoring { - public static readonly Color Loss = Color.FromArgb(245, 200, 200); // < 0 % – rot - public static readonly Color SmallWin = Color.FromArgb(212, 240, 212); // 0–10 % – hellgrün - public static readonly Color BigWin = Color.FromArgb(140, 214, 140); // > 10 % – grün + /// Schwelle, ab der ein Gewinn als deutlich gilt (in Prozent, exklusiv). + public const decimal BigWinThresholdPercent = 10m; - public static Color ForPnlPercent(decimal pnlPercent) => - pnlPercent < 0m ? Loss : (pnlPercent > 10m ? BigWin : SmallWin); + public static TradeRowTint ForPnlPercent(decimal pnlPercent) => + pnlPercent < 0m + ? TradeRowTint.Loss + : (pnlPercent > BigWinThresholdPercent ? TradeRowTint.BigWin : TradeRowTint.SmallWin); } } diff --git a/src/PolyTrader.Modules.CopyTrading/Ui/ClosedTradesView.cs b/src/PolyTrader.Modules.CopyTrading/Ui/ClosedTradesView.cs index a8e6348..76221e8 100644 --- a/src/PolyTrader.Modules.CopyTrading/Ui/ClosedTradesView.cs +++ b/src/PolyTrader.Modules.CopyTrading/Ui/ClosedTradesView.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; @@ -156,7 +156,7 @@ namespace PolyTrader.Modules.CopyTrading.Ui { foreach (DataGridViewRow row in dgvTrades.Rows) if (row.DataBoundItem is ClosedTradeRow r) - row.DefaultCellStyle.BackColor = TradeRowColoring.ForPnlPercent(r.PnlPercent); + row.DefaultCellStyle.BackColor = TradeRowPalette.ForPnlPercent(r.PnlPercent); } private string ResolveAccount(int accountId, bool isDemo) diff --git a/src/PolyTrader.Modules.CopyTrading/Ui/OpenTradesView.cs b/src/PolyTrader.Modules.CopyTrading/Ui/OpenTradesView.cs index ad94ea0..37d03ef 100644 --- a/src/PolyTrader.Modules.CopyTrading/Ui/OpenTradesView.cs +++ b/src/PolyTrader.Modules.CopyTrading/Ui/OpenTradesView.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; @@ -84,7 +84,7 @@ namespace PolyTrader.Modules.CopyTrading.Ui { foreach (DataGridViewRow row in dgvOpen.Rows) if (row.DataBoundItem is OpenTradeRow r) - row.DefaultCellStyle.BackColor = TradeRowColoring.ForPnlPercent(r.UnrealizedPct); + row.DefaultCellStyle.BackColor = TradeRowPalette.ForPnlPercent(r.UnrealizedPct); } private string ResolveAccount(int accountId, bool isDemo) diff --git a/src/PolyTrader.Modules.CopyTrading/Ui/TradeRowPalette.cs b/src/PolyTrader.Modules.CopyTrading/Ui/TradeRowPalette.cs new file mode 100644 index 0000000..a74cd0c --- /dev/null +++ b/src/PolyTrader.Modules.CopyTrading/Ui/TradeRowPalette.cs @@ -0,0 +1,27 @@ +using System.Drawing; +using PolyTrader.Modules.CopyTrading.Logic; + +namespace PolyTrader.Modules.CopyTrading.Ui +{ + /// + /// WinForms-Farbpalette zu den -Kategorien. Die Schwellenlogik liegt + /// (getestet) in ; hier steht nur noch, wie die Kategorien aussehen. + /// Die Avalonia-UI bekommt später ihre eigene Palette zu denselben Kategorien. + /// + internal static class TradeRowPalette + { + public static readonly Color Loss = Color.FromArgb(245, 200, 200); // rot + public static readonly Color SmallWin = Color.FromArgb(212, 240, 212); // hellgrün + public static readonly Color BigWin = Color.FromArgb(140, 214, 140); // grün + + public static Color For(TradeRowTint tint) => tint switch + { + TradeRowTint.Loss => Loss, + TradeRowTint.BigWin => BigWin, + _ => SmallWin + }; + + /// Bequemlichkeit für die Grids: PnL-Prozent direkt in die Zeilenfarbe. + public static Color ForPnlPercent(decimal pnlPercent) => For(TradeRowColoring.ForPnlPercent(pnlPercent)); + } +} diff --git a/tests/PolyTrader.Tests/TradeRowColoringTests.cs b/tests/PolyTrader.Tests/TradeRowColoringTests.cs index 5864944..fb961e7 100644 --- a/tests/PolyTrader.Tests/TradeRowColoringTests.cs +++ b/tests/PolyTrader.Tests/TradeRowColoringTests.cs @@ -3,27 +3,24 @@ using Xunit; namespace PolyTrader.Tests { - /// Sicherheitsnetz für die PnL-Zeilenfärbung (Slice 3): Schwellen -10/0/10. + /// + /// Sicherheitsnetz für die PnL-Zeileneinstufung (Slice 3): Schwellen 0 und 10 %. + /// Prüft seit der Linux-Portierung die Kategorie statt der Farbe – die Schwellenlogik ist + /// das Fachliche, die konkrete Farbe Sache der jeweiligen UI (siehe TradeRowPalette). + /// public class TradeRowColoringTests { [Theory] - [InlineData(-0.01, "loss")] - [InlineData(-25.0, "loss")] - [InlineData(0.0, "small")] // Break-even = hellgrün (kein Verlust) - [InlineData(5.0, "small")] - [InlineData(10.0, "small")] // genau 10 % noch hellgrün - [InlineData(10.01, "big")] - [InlineData(80.0, "big")] - public void Color_matches_threshold(double pct, string expected) + [InlineData(-0.01, TradeRowTint.Loss)] + [InlineData(-25.0, TradeRowTint.Loss)] + [InlineData(0.0, TradeRowTint.SmallWin)] // Break-even = kein Verlust + [InlineData(5.0, TradeRowTint.SmallWin)] + [InlineData(10.0, TradeRowTint.SmallWin)] // genau 10 % noch kleiner Gewinn + [InlineData(10.01, TradeRowTint.BigWin)] + [InlineData(80.0, TradeRowTint.BigWin)] + public void Tint_matches_threshold(double pct, TradeRowTint expected) { - var c = TradeRowColoring.ForPnlPercent((decimal)pct); - var want = expected switch - { - "loss" => TradeRowColoring.Loss, - "big" => TradeRowColoring.BigWin, - _ => TradeRowColoring.SmallWin - }; - Assert.Equal(want, c); + Assert.Equal(expected, TradeRowColoring.ForPnlPercent((decimal)pct)); } } }