Files

74 lines
2.0 KiB
Dart

import 'package:equatable/equatable.dart';
import '../models/bot_models.dart';
abstract class BotState extends Equatable {
const BotState();
@override
List<Object?> get props => [];
}
class BotInitial extends BotState {
const BotInitial();
}
class BotLoading extends BotState {
const BotLoading();
}
class BotLoaded extends BotState {
final BotStatusModel status;
final AccountSummaryModel summary;
final List<BotTradeOrderModel> positions;
final bool isPanicClosing;
final String? actionMessage;
/// True when [actionMessage] describes a failure or a partial success (e.g. a panic-close that could not
/// confirm every position was closed) rather than a full, unqualified success - the UI must not present
/// this the same way as a genuine success (Rules.md §4).
final bool actionIsWarning;
const BotLoaded({
required this.status,
required this.summary,
required this.positions,
this.isPanicClosing = false,
this.actionMessage,
this.actionIsWarning = false,
});
int get activePositionsCount => positions.where((p) => p.isActive).length;
double get totalUnrealizedPnL => positions.where((p) => p.isActive).fold(0.0, (sum, p) => sum + p.unrealizedPnlEur);
double get totalRealizedPnL => positions.fold(0.0, (sum, p) => sum + p.realizedPnlEur);
BotLoaded copyWith({
BotStatusModel? status,
AccountSummaryModel? summary,
List<BotTradeOrderModel>? positions,
bool? isPanicClosing,
String? actionMessage,
bool actionIsWarning = false,
}) {
return BotLoaded(
status: status ?? this.status,
summary: summary ?? this.summary,
positions: positions ?? this.positions,
isPanicClosing: isPanicClosing ?? this.isPanicClosing,
actionMessage: actionMessage,
actionIsWarning: actionIsWarning,
);
}
@override
List<Object?> get props => [status, summary, positions, isPanicClosing, actionMessage, actionIsWarning];
}
class BotError extends BotState {
final String message;
const BotError(this.message);
@override
List<Object?> get props => [message];
}