129 lines
4.0 KiB
Dart
129 lines
4.0 KiB
Dart
import 'package:equatable/equatable.dart';
|
|
|
|
/// Typed counterpart of the backend `EquityPointDto`
|
|
/// (see `FinlyticCore/Dtos/Simulation/SimulationDtos.cs`).
|
|
class EquityPointModel extends Equatable {
|
|
final DateTime timestampUtc;
|
|
final double portfolioValue;
|
|
final double drawdownPercent;
|
|
|
|
const EquityPointModel({
|
|
required this.timestampUtc,
|
|
required this.portfolioValue,
|
|
required this.drawdownPercent,
|
|
});
|
|
|
|
factory EquityPointModel.fromJson(Map<String, dynamic> json) {
|
|
double parseDbl(dynamic val) {
|
|
if (val == null) return 0.0;
|
|
if (val is num) return val.toDouble();
|
|
return double.tryParse(val.toString()) ?? 0.0;
|
|
}
|
|
|
|
return EquityPointModel(
|
|
timestampUtc: DateTime.tryParse(json['timestampUtc']?.toString() ?? '') ?? DateTime.now(),
|
|
portfolioValue: parseDbl(json['portfolioValue']),
|
|
drawdownPercent: parseDbl(json['drawdownPercent']),
|
|
);
|
|
}
|
|
|
|
@override
|
|
List<Object?> get props => [timestampUtc, portfolioValue, drawdownPercent];
|
|
}
|
|
|
|
/// Typed counterpart of the backend `BacktestReportDto`
|
|
/// (see `FinlyticCore/Dtos/Simulation/SimulationDtos.cs`).
|
|
///
|
|
/// `equityCurve` is intentionally a plain (possibly empty) list rather than
|
|
/// a fallback with a synthetic starting point: an empty list means "no
|
|
/// equity curve data returned" and MUST be rendered as an explicit empty
|
|
/// state, never as an invented chart (Rules.md §4).
|
|
class BacktestReportModel extends Equatable {
|
|
final String runId;
|
|
final String isin;
|
|
final String symbol;
|
|
final String strategyKey;
|
|
final String timeframe;
|
|
final int totalTrades;
|
|
final int winningTrades;
|
|
final int losingTrades;
|
|
final double winRatePercent;
|
|
final double profitFactor;
|
|
final double maxDrawdownPercent;
|
|
final double totalReturnPercent;
|
|
final double expectancyEur;
|
|
final double sharpeRatio;
|
|
final List<EquityPointModel> equityCurve;
|
|
|
|
const BacktestReportModel({
|
|
this.runId = '',
|
|
this.isin = '',
|
|
this.symbol = '',
|
|
this.strategyKey = '',
|
|
this.timeframe = '',
|
|
this.totalTrades = 0,
|
|
this.winningTrades = 0,
|
|
this.losingTrades = 0,
|
|
this.winRatePercent = 0.0,
|
|
this.profitFactor = 0.0,
|
|
this.maxDrawdownPercent = 0.0,
|
|
this.totalReturnPercent = 0.0,
|
|
this.expectancyEur = 0.0,
|
|
this.sharpeRatio = 0.0,
|
|
this.equityCurve = const [],
|
|
});
|
|
|
|
factory BacktestReportModel.fromJson(Map<String, dynamic> json) {
|
|
double parseDbl(dynamic val) {
|
|
if (val == null) return 0.0;
|
|
if (val is num) return val.toDouble();
|
|
return double.tryParse(val.toString()) ?? 0.0;
|
|
}
|
|
|
|
final rawCurve = json['equityCurve'];
|
|
final curve = rawCurve is List
|
|
? rawCurve
|
|
.whereType<Map>()
|
|
.map((e) => EquityPointModel.fromJson(Map<String, dynamic>.from(e)))
|
|
.toList()
|
|
: const <EquityPointModel>[];
|
|
|
|
return BacktestReportModel(
|
|
runId: json['runId']?.toString() ?? '',
|
|
isin: json['isin']?.toString() ?? '',
|
|
symbol: json['symbol']?.toString() ?? '',
|
|
strategyKey: json['strategyKey']?.toString() ?? '',
|
|
timeframe: json['timeframe']?.toString() ?? '',
|
|
totalTrades: (json['totalTrades'] as num?)?.toInt() ?? 0,
|
|
winningTrades: (json['winningTrades'] as num?)?.toInt() ?? 0,
|
|
losingTrades: (json['losingTrades'] as num?)?.toInt() ?? 0,
|
|
winRatePercent: parseDbl(json['winRatePercent']),
|
|
profitFactor: parseDbl(json['profitFactor']),
|
|
maxDrawdownPercent: parseDbl(json['maxDrawdownPercent']),
|
|
totalReturnPercent: parseDbl(json['totalReturnPercent']),
|
|
expectancyEur: parseDbl(json['expectancyEur']),
|
|
sharpeRatio: parseDbl(json['sharpeRatio']),
|
|
equityCurve: curve,
|
|
);
|
|
}
|
|
|
|
@override
|
|
List<Object?> get props => [
|
|
runId,
|
|
isin,
|
|
symbol,
|
|
strategyKey,
|
|
timeframe,
|
|
totalTrades,
|
|
winningTrades,
|
|
losingTrades,
|
|
winRatePercent,
|
|
profitFactor,
|
|
maxDrawdownPercent,
|
|
totalReturnPercent,
|
|
expectancyEur,
|
|
sharpeRatio,
|
|
equityCurve,
|
|
];
|
|
}
|