Baseline: Ausgangszustand vor Modularisierung
Erster Commit des bestehenden monolithischen WinForms-Copytraders, inklusive der Alt-Backups (*.bak), damit diese dauerhaft in der Historie rekonstruierbar bleiben. Threema-Lib unter libs/ wurde vendored (nested .git entfernt). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
using System;
|
||||
using MongoDB.Driver;
|
||||
using PolyTraderSharp.Extensions;
|
||||
using System.ComponentModel;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
|
||||
namespace PolyTraderSharp.Models
|
||||
{
|
||||
public class AccountState
|
||||
{
|
||||
[Browsable(false)]
|
||||
[MongoDB.Bson.Serialization.Attributes.BsonId] public int AccountId { get; set; }
|
||||
|
||||
[Category("01. General")]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
[Category("02. Wallet & Keys")]
|
||||
public string WalletAddress { get; set; } = string.Empty;
|
||||
|
||||
[Category("02. Wallet & Keys")]
|
||||
public string ApiKey { get; set; } = string.Empty;
|
||||
|
||||
[Category("02. Wallet & Keys")]
|
||||
public string ApiSecret { get; set; } = string.Empty;
|
||||
|
||||
[Category("02. Wallet & Keys")]
|
||||
public string ApiPassphrase { get; set; } = string.Empty;
|
||||
|
||||
[Category("02. Wallet & Keys")]
|
||||
public string PrivateKey { get; set; } = string.Empty;
|
||||
|
||||
[Category("01. General")]
|
||||
public bool IsDemo { get; set; }
|
||||
|
||||
[Category("01. General")]
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
[Category("01. General")]
|
||||
public bool CloseOnlyMode { get; set; } = false;
|
||||
|
||||
[Category("03. Payouts")]
|
||||
public string PayoutAddress { get; set; } = string.Empty;
|
||||
|
||||
[Category("03. Payouts")]
|
||||
public decimal PayoutLimitUsd { get; set; } = 0;
|
||||
|
||||
// Balances
|
||||
[Browsable(false)]
|
||||
public decimal TotalBalance { get; set; }
|
||||
|
||||
[Browsable(false)]
|
||||
public decimal AvailableBalance { get; set; }
|
||||
|
||||
// Risk Settings
|
||||
[Category("04. Risk Management")]
|
||||
public decimal PerMarketLimit { get; set; } = 5.0m;
|
||||
|
||||
[Category("04. Risk Management")]
|
||||
public decimal MaxPriceDifference { get; set; } = 2.0m;
|
||||
|
||||
[Category("04. Risk Management")]
|
||||
public decimal MaxBuyPrice { get; set; } = 0.98m;
|
||||
|
||||
[Category("04. Risk Management")]
|
||||
public decimal ProfitTarget { get; set; } = 50.0m;
|
||||
|
||||
[Category("04. Risk Management")]
|
||||
public decimal PreRedeemLimit { get; set; } = 0.0m;
|
||||
|
||||
[Category("04. Risk Management")]
|
||||
public decimal PerMasterLimit { get; set; } = 10.0m;
|
||||
|
||||
// Time limits
|
||||
[Category("05. Time Limits")]
|
||||
public decimal perMaxTime6h { get; set; } = 20.0m;
|
||||
|
||||
[Category("05. Time Limits")]
|
||||
public decimal perMaxTime24h { get; set; } = 20.0m;
|
||||
|
||||
[Category("05. Time Limits")]
|
||||
public decimal perMaxTime72h { get; set; } = 20.0m;
|
||||
|
||||
[Category("05. Time Limits")]
|
||||
public decimal perMaxTimeNone { get; set; } = 40.0m;
|
||||
|
||||
[Browsable(false)]
|
||||
public ConcurrentDictionary<string, Position> OpenPositions { get; } = new(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
[Browsable(false)]
|
||||
public bool HasOpenLimitOrders { get; set; } = false;
|
||||
|
||||
public void UpdateBalance(decimal available)
|
||||
{
|
||||
AvailableBalance = available;
|
||||
decimal inPositions = OpenPositions.Values.Sum(p => (decimal)p.AmountUsd);
|
||||
TotalBalance = AvailableBalance + inPositions;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
namespace PolyTraderSharp.Models
|
||||
{
|
||||
public class ClosedTrade
|
||||
{
|
||||
[MongoDB.Bson.Serialization.Attributes.BsonId] public int TradeId { get; set; }
|
||||
public int AccountId { get; set; }
|
||||
public int SourceTraderId { get; set; }
|
||||
public bool IsDemo { get; set; }
|
||||
|
||||
public string TokenId { get; set; } = string.Empty;
|
||||
public string MarketSlug { get; set; } = string.Empty;
|
||||
public string MarketQuestion { get; set; } = string.Empty;
|
||||
public string Outcome { get; set; } = string.Empty;
|
||||
|
||||
public string Side { get; set; } = string.Empty;
|
||||
public decimal EntryPrice { get; set; }
|
||||
public decimal ExitPrice { get; set; }
|
||||
public decimal Size { get; set; }
|
||||
|
||||
public decimal RealizedPnl { get; set; }
|
||||
public decimal PnlPercent { get; set; }
|
||||
public decimal TotalFees { get; set; }
|
||||
|
||||
public DateTime OpenedAt { get; set; }
|
||||
public DateTime ClosedAt { get; set; }
|
||||
public string ExitReason { get; set; } = string.Empty;
|
||||
}
|
||||
public class ClosedTradeRow : ClosedTrade
|
||||
{
|
||||
public string AccountName { get; set; } = string.Empty;
|
||||
public string SourceTraderName { get; set; } = string.Empty;
|
||||
|
||||
[System.ComponentModel.Browsable(false)]
|
||||
public string SourceTraderAddress { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
namespace PolyTraderSharp.Models
|
||||
{
|
||||
public class ClosedTrade
|
||||
{
|
||||
public int TradeId { get; set; }
|
||||
public int AccountId { get; set; }
|
||||
public int SourceTraderId { get; set; }
|
||||
public bool IsDemo { get; set; }
|
||||
|
||||
public string TokenId { get; set; } = string.Empty;
|
||||
public string MarketSlug { get; set; } = string.Empty;
|
||||
public string MarketQuestion { get; set; } = string.Empty;
|
||||
public string Outcome { get; set; } = string.Empty;
|
||||
|
||||
public string Side { get; set; } = string.Empty;
|
||||
public decimal EntryPrice { get; set; }
|
||||
public decimal ExitPrice { get; set; }
|
||||
public decimal Size { get; set; }
|
||||
|
||||
public decimal RealizedPnl { get; set; }
|
||||
public decimal PnlPercent { get; set; }
|
||||
public decimal TotalFees { get; set; }
|
||||
|
||||
public DateTime OpenedAt { get; set; }
|
||||
public DateTime ClosedAt { get; set; }
|
||||
public string ExitReason { get; set; } = string.Empty;
|
||||
}
|
||||
public class ClosedTradeRow : ClosedTrade
|
||||
{
|
||||
public string AccountName { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
namespace PolyTraderSharp.Models
|
||||
{
|
||||
public class CopySignal
|
||||
{
|
||||
public int SourceTradeId { get; set; }
|
||||
public int TraderId { get; set; }
|
||||
public string MarketSlug { get; set; } = string.Empty;
|
||||
public string ConditionId { get; set; } = string.Empty;
|
||||
public string TokenId { get; set; } = string.Empty;
|
||||
public string MarketQuestion { get; set; } = string.Empty;
|
||||
public string Side { get; set; } = "BUY";
|
||||
public decimal Price { get; set; }
|
||||
public decimal Size { get; set; }
|
||||
public string Outcome { get; set; } = string.Empty;
|
||||
public DateTime Timestamp { get; set; }
|
||||
public DateTime? EndDate { get; set; }
|
||||
public string Reason { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
|
||||
namespace PolyTraderSharp.Models
|
||||
{
|
||||
public class DashboardRow
|
||||
{
|
||||
[Browsable(false)]
|
||||
public int AccountId { get; set; }
|
||||
|
||||
[Browsable(false)]
|
||||
public bool IsDemo { get; set; }
|
||||
|
||||
[Browsable(false)]
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
[DisplayName("Account")]
|
||||
public string AccountName { get; set; } = string.Empty;
|
||||
|
||||
[DisplayName("Balance Gesamt")]
|
||||
public decimal TotalBalance { get; set; }
|
||||
|
||||
[DisplayName("Balance verfügbar")]
|
||||
public decimal AvailableBalance { get; set; }
|
||||
|
||||
[DisplayName("Balance in Positionen")]
|
||||
public decimal PositionBalance { get; set; }
|
||||
|
||||
[DisplayName("Offene Trades")]
|
||||
public int OpenTradesCount { get; set; }
|
||||
|
||||
[DisplayName("Trades (24h)")]
|
||||
public int ClosedTrades24h { get; set; }
|
||||
|
||||
[DisplayName("P&L (24h)")]
|
||||
public decimal Pnl24h { get; set; }
|
||||
|
||||
[DisplayName("Winrate (24h)")]
|
||||
public string Winrate24h { get; set; } = "0%";
|
||||
|
||||
[DisplayName("Trades (7d)")]
|
||||
public int ClosedTrades7d { get; set; }
|
||||
|
||||
[DisplayName("P&L (7d)")]
|
||||
public decimal Pnl7d { get; set; }
|
||||
|
||||
[DisplayName("Winrate (7d)")]
|
||||
public string Winrate7d { get; set; } = "0%";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace PolyTraderSharp.Models
|
||||
{
|
||||
public class JobStatusRow : INotifyPropertyChanged
|
||||
{
|
||||
private string _jobName = "";
|
||||
private string _description = "";
|
||||
private bool _isEnabled = true;
|
||||
private DateTime? _lastRun;
|
||||
private DateTime? _nextRun;
|
||||
private string _statusText = "Initializing...";
|
||||
|
||||
public string JobName { get => _jobName; set { _jobName = value; OnPropertyChanged(); } }
|
||||
public string Description { get => _description; set { _description = value; OnPropertyChanged(); } }
|
||||
public bool IsEnabled { get => _isEnabled; set { _isEnabled = value; OnPropertyChanged(); } }
|
||||
public DateTime? LastRun { get => _lastRun; set { _lastRun = value; OnPropertyChanged(); } }
|
||||
public DateTime? NextRun { get => _nextRun; set { _nextRun = value; OnPropertyChanged(); } }
|
||||
public string StatusText { get => _statusText; set { _statusText = value; OnPropertyChanged(); } }
|
||||
|
||||
public Func<Task>? ManualTriggerAction { get; set; }
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
protected void OnPropertyChanged([CallerMemberName] string? name = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
namespace PolyTraderSharp.Models
|
||||
{
|
||||
public class MarketData
|
||||
{
|
||||
[MongoDB.Bson.Serialization.Attributes.BsonId] public string Id { get; set; } = string.Empty;
|
||||
public string ConditionId { get; set; } = string.Empty;
|
||||
public string Question { get; set; } = string.Empty;
|
||||
public string Slug { get; set; } = string.Empty;
|
||||
public DateTime? EndDate { get; set; }
|
||||
public bool Active { get; set; }
|
||||
public bool Closed { get; set; }
|
||||
public string Category { get; set; } = string.Empty;
|
||||
|
||||
// Will store the JSON array string of token IDs, e.g. "[\"123\", \"456\"]"
|
||||
public string ClobTokenIds { get; set; } = string.Empty;
|
||||
|
||||
public string Outcomes { get; set; } = string.Empty; // e.g. "[\"Yes\", \"No\"]"
|
||||
|
||||
public bool NegRisk { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using MongoDB.Driver;
|
||||
using PolyTraderSharp.Extensions;
|
||||
|
||||
namespace PolyTraderSharp.Models
|
||||
{
|
||||
public class MasterTraderHistoryRecord
|
||||
{
|
||||
[MongoDB.Bson.Serialization.Attributes.BsonId] public string Id { get; set; } = MongoDB.Bson.ObjectId.GenerateNewId().ToString();
|
||||
|
||||
// Verknüpfung zum Master Trader
|
||||
public int TraderId { get; set; }
|
||||
|
||||
// Verknüpfung zum Markt
|
||||
public string TokenId { get; set; } = string.Empty;
|
||||
|
||||
// Der erfasste Profit / Loss auf Polymarket
|
||||
public decimal RealizedPnl { get; set; }
|
||||
|
||||
// Timestamp des Trades
|
||||
public DateTime ClosedAt { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
namespace PolyTraderSharp.Models
|
||||
{
|
||||
public class Position
|
||||
{
|
||||
[MongoDB.Bson.Serialization.Attributes.BsonId]
|
||||
public string TokenId { get; set; } = string.Empty;
|
||||
public string MarketSlug { get; set; } = string.Empty;
|
||||
public string ConditionId { get; set; } = string.Empty;
|
||||
public int SourceTraderId { get; set; }
|
||||
public string SourceTraderName { get; set; } = string.Empty;
|
||||
public string SourceTraderAddress { get; set; } = string.Empty;
|
||||
public string MarketQuestion { get; set; } = string.Empty;
|
||||
public string Outcome { get; set; } = string.Empty;
|
||||
public string Side { get; set; } = "BUY";
|
||||
public decimal EntryPrice { get; set; }
|
||||
public decimal Size { get; set; } // Shares
|
||||
public decimal AmountUsd { get; set; }
|
||||
public decimal CurrentPrice { get; set; }
|
||||
public decimal CurrentValueUsd { get; set; }
|
||||
public System.DateTime? ExpiryDate { get; set; }
|
||||
public System.DateTime OpenedAt { get; set; } = System.DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace PolyTraderSharp.Models
|
||||
{
|
||||
public class ServerSettings
|
||||
{
|
||||
[Category("Threema Notifications")]
|
||||
[DisplayName("Threema Enabled")]
|
||||
[Description("Enable or disable Threema notifications.")]
|
||||
public bool ThreemaEnabled { get; set; } = true;
|
||||
|
||||
[Category("Threema Notifications")]
|
||||
[DisplayName("Gateway ID")]
|
||||
[Description("The Threema Gateway ID (e.g. *3MAGW01).")]
|
||||
public string ThreemaGatewayId { get; set; } = "*3MAGW01";
|
||||
|
||||
[Category("Threema Notifications")]
|
||||
[DisplayName("Gateway Secret")]
|
||||
[Description("The secret for the Threema Gateway integration.")]
|
||||
public string ThreemaSecret { get; set; } = "";
|
||||
|
||||
[Category("Threema Notifications")]
|
||||
[DisplayName("Private Key")]
|
||||
[Description("The Private Key (hex) for End-to-End encryption.")]
|
||||
public string ThreemaPrivateKey { get; set; } = "";
|
||||
|
||||
[Category("Threema Notifications")]
|
||||
[DisplayName("Group ID")]
|
||||
[Description("The Threema Group ID to send messages to.")]
|
||||
public string ThreemaGroupId { get; set; } = "";
|
||||
|
||||
[Category("Threema Notifications")]
|
||||
[DisplayName("Webhook Port")]
|
||||
[Description("The local port to listen on for incoming Threema messages (e.g. 8080).")]
|
||||
public int ThreemaWebhookPort { get; set; } = 8080;
|
||||
|
||||
[Category("Threema Notifications")]
|
||||
[DisplayName("Report Interval (Hours)")]
|
||||
[Description("Interval for the automatic summary report.")]
|
||||
public int ThreemaReportIntervalHours { get; set; } = 6;
|
||||
|
||||
|
||||
[Category("Mullvad VPN")]
|
||||
[DisplayName("VPN Enabled")]
|
||||
[Description("Enable or disable automatic VPN rotation.")]
|
||||
public bool VpnEnabled { get; set; } = false;
|
||||
|
||||
[Category("Mullvad VPN")]
|
||||
[DisplayName("Mullvad Account")]
|
||||
[Description("Account ID for Mullvad VPN.")]
|
||||
public string MullvadAccount { get; set; } = "7748925650632296";
|
||||
|
||||
[Category("Mullvad VPN")]
|
||||
[DisplayName("VPN Location")]
|
||||
[Description("Target VPN location (e.g. cz).")]
|
||||
public string VpnLocation { get; set; } = "cz";
|
||||
|
||||
[Category("Mullvad VPN")]
|
||||
[DisplayName("Mullvad CLI Path")]
|
||||
[Description("Path to mullvad.exe")]
|
||||
public string MullvadCliPath { get; set; } = @"C:\Program Files\Mullvad VPN\resources\mullvad.exe";
|
||||
|
||||
|
||||
[Category("Blockchain Listener")]
|
||||
[DisplayName("Enable Blockchain Listener")]
|
||||
[Description("If true, connects to Alchemy WSS for faster on-chain signal detection.")]
|
||||
public bool EnableBlockchainListener { get; set; } = true;
|
||||
|
||||
[Category("Blockchain Listener")]
|
||||
[DisplayName("Polygon RPC URL")]
|
||||
[Description("RPC URL for Alchemy WSS.")]
|
||||
public string PolygonRpcUrl { get; set; } = "wss://polygon-mainnet.g.alchemy.com/v2/iWCbs9p3nf-8OpR-BtvGi";
|
||||
|
||||
[Category("Polymarket WebSockets")]
|
||||
[DisplayName("Use Polymarket WebSockets")]
|
||||
[Description("If true, connects to Polymarket WSS for live market prices and user events.")]
|
||||
public bool UsePolymarketWebsockets { get; set; } = false;
|
||||
|
||||
|
||||
public static ServerSettings Load(string path)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
return new ServerSettings();
|
||||
|
||||
try
|
||||
{
|
||||
var serializer = new XmlSerializer(typeof(ServerSettings));
|
||||
using var fs = new FileStream(path, FileMode.Open);
|
||||
return (ServerSettings?)serializer.Deserialize(fs) ?? new ServerSettings();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new ServerSettings();
|
||||
}
|
||||
}
|
||||
|
||||
public void Save(string path)
|
||||
{
|
||||
var serializer = new XmlSerializer(typeof(ServerSettings));
|
||||
using var fs = new FileStream(path, FileMode.Create);
|
||||
serializer.Serialize(fs, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using MongoDB.Driver;
|
||||
using PolyTraderSharp.Extensions;
|
||||
using System.ComponentModel;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PolyTraderSharp.Models
|
||||
{
|
||||
public class TrackedTrader
|
||||
{
|
||||
[Browsable(false)]
|
||||
[MongoDB.Bson.Serialization.Attributes.BsonId] public int Id { get; set; }
|
||||
|
||||
[Category("01. Identification")]
|
||||
public string WalletAddress { get; set; } = string.Empty;
|
||||
|
||||
[Category("01. Identification")]
|
||||
public string DisplayName { get; set; } = string.Empty;
|
||||
|
||||
[Category("02. Categorization")]
|
||||
public string Category { get; set; } = "NEW_BIG_BET";
|
||||
|
||||
[Category("02. Categorization")]
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
[Category("02. Categorization")]
|
||||
public string Reasoning { get; set; } = string.Empty;
|
||||
|
||||
[Category("03. General")]
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
[Category("03. General")]
|
||||
public bool IsHidden { get; set; } = false;
|
||||
|
||||
// Stats
|
||||
[Category("04. Statistics")]
|
||||
[ReadOnly(true)]
|
||||
public int TotalTrades { get; set; } = 0;
|
||||
|
||||
[Category("04. Statistics")]
|
||||
[ReadOnly(true)]
|
||||
public int WinningTrades { get; set; } = 0;
|
||||
|
||||
[Category("04. Statistics")]
|
||||
[ReadOnly(true)]
|
||||
public double Winrate30t { get; set; } = 0.0;
|
||||
|
||||
[Category("04. Statistics")]
|
||||
[ReadOnly(true)]
|
||||
public double TotalPnl { get; set; } = 0.0;
|
||||
|
||||
[Browsable(false)]
|
||||
public HashSet<int> AssignedAccountIds { get; set; } = new();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace PolyTraderSharp.Models
|
||||
{
|
||||
public class TraderAnalyticsResult
|
||||
{
|
||||
public int AccountId { get; set; }
|
||||
public int SourceTraderId { get; set; }
|
||||
public string SourceTraderName { get; set; } = string.Empty;
|
||||
public string SourceTraderAddress { get; set; } = string.Empty;
|
||||
public decimal Winrate30T { get; set; }
|
||||
public decimal Pnl30T { get; set; }
|
||||
public int Trades7D { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user