Behebt #570. "Trading pausieren" hielt drei Wege nicht an, die Orders am CLOB platzieren: 1. SellLadderService: Eine laufende Verkaufsleiter preiste alle 5 s weiter nach, storniert und neu platziert. Sie pruefte weder Pause noch Modus. Die Engine ignoriert bei Pause zwar alle Signale, die bereits laufende Leiter lief aber ungebremst. 2. TraderMonitorService: Der REST-Pre-Redeem feuert aus der Positions-Synchronisierung, die bewusst auch bei Pause weiterlaeuft. Er pruefte nur LiveTradingMode. 3. PolymarketWssClient: Die Pause wurde nur beim Verbindungsaufbau geprueft. Auf einer bereits offenen Verbindung loesten Kursmeldungen den Auto-Redeem weiter aus. Die Ursache ist allen gemeinsam: Jeder Dienst hat seine Sperre selbst nachgebaut, und jeder hat etwas anderes vergessen. Die Regeln liegen jetzt an einer Stelle, in TradingGate, und alle drei benutzen sie: - Verkaufsleiter: Pause oder Modus des Kontotyps "Inaktiv" friert sie ein, bei "Nur Verkauf" laeuft sie weiter. Das entspricht der Engine. - Pre-Redeem (REST und WSS): wie bisher nur bei Modus Aktiv, jetzt zusaetzlich nicht bei Pause. Eine eingefrorene Leiter storniert nichts und platziert nichts. Das gilt auch am Floor, wenn dort die ruhende Order fehlt. Die ruhende GTC-Order bleibt am Buch, genau wie beim Beenden der Anwendung. LastActionAt bleibt unveraendert, nach der Freigabe geht es an der aktuellen Stufe weiter. Protokolliert wird einmal beim Einfrieren und einmal beim Fortsetzen, nicht alle 5 s. CLOB-kritisch, deshalb: - Vor der Aenderung gesichert unter agentspace/scripts/backups/*.vor-570-*.bak. - Orderaufbau und Preislogik sind nicht angefasst. Der Diff umfasst eine Sperre und drei Bedingungen. - Die Sperre steht vor dem ersten CLOB-Zugriff. Die Harness von SellLadderServiceTests setzt jetzt Live = Aktiv. Mit dem Standard Inaktiv waere Floor_replaces_order rot geworden, und Floor_holds_... waere gruen geblieben, aber aus dem falschen Grund: keine Order, weil eingefroren, nicht weil die Order noch ruht. Neu in SellLadderFreezeTests: Pause, Inaktiv, "Nur Verkauf", Floor im eingefrorenen Zustand, Fortsetzen an der aktuellen Stufe, dazu die Entscheidungstabellen von TradingGate. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
50 lines
2.2 KiB
C#
50 lines
2.2 KiB
C#
using PolyTraderSharp;
|
|
|
|
namespace PolyTrader.Modules.CopyTrading.Logic
|
|
{
|
|
/// <summary>
|
|
/// Die Sperren für automatische Verkäufe an einer Stelle (#570).
|
|
///
|
|
/// <para>Bis zum 13.09.2026 baute jeder Dienst seine Sperre selbst nach, und jeder vergaß etwas
|
|
/// anderes. Die Verkaufsleiter prüfte weder Pause noch Modus. Der REST-Pre-Redeem im
|
|
/// TraderMonitorService prüfte nur den Modus, weil die Positions-Synchronisierung, aus der er
|
|
/// feuert, bewusst auch bei Pause weiterläuft. Der WSS-Auto-Redeem prüfte die Pause nur beim
|
|
/// Verbindungsaufbau, nicht auf einer bereits offenen Verbindung. "Trading pausieren" hielt damit
|
|
/// keinen dieser drei Wege an, und alle drei platzieren Orders am CLOB.</para>
|
|
///
|
|
/// <para>Die Regeln selbst sind unverändert übernommen, ergänzt um die Pause:
|
|
/// Pre-Redeem verlangt wie bisher den Modus Aktiv. Eine laufende Leiter läuft bei
|
|
/// "Nur Verkauf" weiter, wie die Engine dort Verkäufe zulässt.</para>
|
|
/// </summary>
|
|
public static class TradingGate
|
|
{
|
|
/// <summary>
|
|
/// Warum eine laufende Verkaufsleiter gerade nicht nachpreisen darf, oder <c>null</c>, wenn sie darf.
|
|
/// Die Pause sperrt; der Modus des Kontotyps "Inaktiv" ebenfalls; "Nur Verkauf" und Aktiv lassen sie laufen.
|
|
/// </summary>
|
|
public static string? LadderFreezeReason(TradingState state, bool isDemo)
|
|
{
|
|
if (state.GlobalTradingPaused)
|
|
return "globale Pause ist aktiv";
|
|
|
|
TradingMode mode = isDemo ? state.DemoTradingMode : state.LiveTradingMode;
|
|
return mode == TradingMode.Inactive
|
|
? $"{(isDemo ? "Demo" : "Live")}-Modus ist inaktiv"
|
|
: null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ob ein Pre-Redeem-Verkauf (REST oder WSS) ausgelöst werden darf: keine Pause und der Modus des
|
|
/// Kontotyps auf Aktiv.
|
|
/// </summary>
|
|
public static bool PreRedeemAllowed(TradingState state, bool isDemo)
|
|
{
|
|
if (state.GlobalTradingPaused)
|
|
return false;
|
|
|
|
TradingMode mode = isDemo ? state.DemoTradingMode : state.LiveTradingMode;
|
|
return mode == TradingMode.Active;
|
|
}
|
|
}
|
|
}
|