Files

111 lines
2.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using FinlyticCore.Dtos.TechnicalAnalysis;
using FinlyticCore.Dtos.Trading;
namespace FinlyticCore.Dtos.Bot;
[JsonConverter(typeof(JsonStringEnumConverter<BotExecutionVenue>))]
public enum BotExecutionVenue
{
AlpacaPaperTrading, // Offizielle Alpaca API (US-Equities / ETFs)
SyntheticPaperBroker // Interner Engine-Broker (EU / Knock-Outs)
}
[JsonConverter(typeof(JsonStringEnumConverter<BotPositionStatus>))]
public enum BotPositionStatus
{
Pending,
Active,
BreakEvenTriggered,
Tp1Hit,
Tp2Hit,
Closed,
StoppedOut,
KnockedOut,
Canceled
}
public record BotTradeOrderDto(
Guid OrderId,
Guid ProposalId,
string Isin,
string Symbol,
BotExecutionVenue Venue,
string? AlpacaOrderId,
string? ClientOrderId,
SignalDirection Direction,
decimal RequestedQuantity,
decimal FilledQuantity,
decimal EntryPrice,
decimal AverageBuyIn,
decimal InitialStopLoss,
decimal CurrentStopLoss,
decimal TakeProfit1,
decimal TakeProfit2,
decimal CurrentPrice,
decimal UnrealizedPnlEur,
decimal RealizedPnlEur,
BotPositionStatus Status,
ExitPlan ExitPlan,
DateTime CreatedAtUtc,
DateTime? FilledAtUtc,
DateTime? ClosedAtUtc
);
public record AccountSummaryDto(
decimal Equity,
decimal Cash,
decimal BuyingPower,
string Currency,
string Status
);
public record BotStatusDto(
bool IsRunning,
bool AutoExecutionEnabled,
int ActivePositionsCount,
int MaxPositions,
decimal RiskPerTradePercent,
int MinCompositeScore,
string VenuesActive
);
public record ExecuteProposalRequest(
Guid ProposalId,
BotExecutionVenue? PreferredVenue = null,
decimal? CustomQuantity = null
);
public record BotPortfolioSnapshotDto(
Guid Id,
DateTime SnapshotDateUtc,
decimal TotalEquityEur,
decimal CashEur,
int OpenPositionsCount,
decimal DailyRealizedPnlEur,
decimal TotalUnrealizedPnlEur,
decimal? WinRatePercent
);
public record UpdateBotSettingsRequest(
bool? AutoExecutionEnabled,
int? MaxPositions,
decimal? RiskPerTradePercent,
int? MinCompositeScore
);
/// <summary>
/// Result of an emergency "panic close" of every open paper-trading position (see
/// <see cref="FinlyticCore.Util.MqttTopics.Channels.BotPanicClose"/>). <see cref="SkippedCount"/> is
/// non-zero whenever an Alpaca position could not be liquidated (Alpaca not configured or the broker call
/// failed) — callers MUST surface that count to the user instead of only reporting <see cref="ClosedCount"/>
/// as if the whole operation succeeded (Rules.md §4: no fabricated full success on a partial result).
/// </summary>
public record PanicCloseResultDto(
int ClosedCount,
int SkippedCount,
List<BotTradeOrderDto> ClosedOrders
);