Files
PolyTraderSharp/tests/PolyTrader.Tests/StartupOrderReconciliationTests.cs
T
RichardandClaude Opus 4.8 c75a958e36 Supervisor S-1: Dossier-Generator + Modul-Skelett mit Dossier-Browser + Journal-Nachverdrahtung
Neues Modul PolyTrader.Modules.Supervisor (IPolyTraderModule, Name=Supervisor, DbPrefix=sup_,
nur Core-Referenz, strikt read-only):
- DossierBuilder (Core/Analytics, pur+getestet): TradeDossier aus Entscheidungen + Order-Events +
  Trades + Log-Zeilen, chronologisch, mit Markdown-Rendering (Tabellen, Pipe-Escaping).
- DossierService (Modul): beschafft Journal/Events/Trade-Log per SignalId + JSONL-Zeilen per CID
  (nur Tagesdateien im Ereignis-Zeitfenster +-1 Tag); RecentSignals-Uebersicht (Journal gruppiert).
- SupervisorMainForm: Dossier-Browser - links juengste Signale, rechts Markdown-Dossier;
  SignalId-Suche; Analyse-Chat (OpenRouter) folgt in S-2. In Launcher/Smoke registriert.

Journal-Nachverdrahtung (S-0-Vervollstaendigung):
- TraderMonitor: Profit-Target erzeugt eigene SignalId -> Leiter + Journal (ProfitTargetTriggered);
  Stale-Cleanup-Cancels als OrderEvents (StaleCleanupCancel).
- StartupOrderReconciliation: K2-Cancels als OrderEvents (StartupReconcileCancel).
- RF: Demo-Einstiege (DemoFilled, eigene SignalId) + Resolution-Closes (SystemResolutionClose)
  im Journal - damit sind ALLE Module im Entscheidungsjournal vertreten.

Tests: +3 DossierBuilder; 4 Service-Builder auf neue Ctors. Build 0 Fehler, 344 Tests gruen,
--smoke-ui: [OK] supervisor.main (alle 5 Views gruen).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 10:09:02 +02:00

84 lines
2.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Threading;
using System.Threading.Tasks;
using PolyTrader.Tests.Fakes;
using PolyTraderSharp;
using PolyTraderSharp.Models;
using PolyTraderSharp.Services;
using Xunit;
namespace PolyTrader.Tests
{
/// <summary>
/// Slice 2 (Fable-Fixes) K2 Neustart-Reconciliation: Beim Start werden alle offenen CLOB-Orders
/// je Live-Account pauschal storniert, damit die Engine gegen keine Waisen-Orders anläuft.
/// </summary>
public class StartupOrderReconciliationTests
{
private static AccountState LiveAccount(int id, string name)
{
return new AccountState
{
AccountId = id,
Name = name,
IsDemo = false,
ApiKey = "k",
ApiSecret = "s",
ApiPassphrase = "p",
PrivateKey = "0xabc"
};
}
[Fact]
public async Task Cancels_all_open_orders_for_live_accounts()
{
var state = new TradingState();
var acc = LiveAccount(1, "Live");
state.Accounts[acc.AccountId] = acc;
var clob = new FakeClobClient();
clob.AllOpenOrders.Add(("o1", "SELL", 0.40m));
clob.AllOpenOrders.Add(("o2", "BUY", 0.55m));
var svc = new StartupOrderReconciliationService(state, clob, new TerminalLogger(), new FakeOrderEventLog());
await svc.StartAsync(CancellationToken.None);
Assert.Equal(new[] { "o1", "o2" }, clob.CanceledOrderIds);
}
[Fact]
public async Task Skips_demo_accounts_and_accounts_without_credentials()
{
var state = new TradingState();
var demo = LiveAccount(1, "Demo");
demo.IsDemo = true;
var noCreds = new AccountState { AccountId = 2, Name = "NoCreds", IsDemo = false };
state.Accounts[demo.AccountId] = demo;
state.Accounts[noCreds.AccountId] = noCreds;
var clob = new FakeClobClient();
clob.AllOpenOrders.Add(("x", "SELL", 0.40m));
var svc = new StartupOrderReconciliationService(state, clob, new TerminalLogger(), new FakeOrderEventLog());
await svc.StartAsync(CancellationToken.None);
Assert.Empty(clob.CanceledOrderIds); // weder Demo noch credential-lose Accounts angefasst
}
[Fact]
public async Task No_open_orders_cancels_nothing()
{
var state = new TradingState();
var acc = LiveAccount(1, "Live");
state.Accounts[acc.AccountId] = acc;
var clob = new FakeClobClient(); // AllOpenOrders leer
var svc = new StartupOrderReconciliationService(state, clob, new TerminalLogger(), new FakeOrderEventLog());
await svc.StartAsync(CancellationToken.None);
Assert.Empty(clob.CanceledOrderIds);
}
}
}