refactor: save current workspace state including FinlyticAnalyzer fixes, FinlyticApp trade route alignment, and DTO audit documentation

This commit is contained in:
2026-08-12 18:30:42 +02:00
parent a9553e9fbf
commit 3d8af3940b
163 changed files with 3421 additions and 1751 deletions
@@ -118,6 +118,36 @@ class StrategySignalModel extends Equatable {
List<Object?> get props => [title, date, price, type];
}
class PatternPoint extends Equatable {
final DateTime time;
final double price;
const PatternPoint(this.time, this.price);
factory PatternPoint.fromJson(Map<String, dynamic> json) => PatternPoint(DateTime.tryParse(json['time'] ?? '') ?? DateTime.now(), (json['price'] as num).toDouble());
@override
List<Object?> get props => [time, price];
}
class ChartPatternModel extends Equatable {
final String type;
final List<PatternPoint> upperLine;
final List<PatternPoint> lowerLine;
const ChartPatternModel({required this.type, required this.upperLine, required this.lowerLine});
factory ChartPatternModel.fromJson(Map<String, dynamic> json) {
return ChartPatternModel(
type: json['type']?.toString() ?? 'Pattern',
upperLine: (json['upperLine'] as List<dynamic>? ?? []).map((e) => PatternPoint.fromJson(e)).toList(),
lowerLine: (json['lowerLine'] as List<dynamic>? ?? []).map((e) => PatternPoint.fromJson(e)).toList(),
);
}
@override
List<Object?> get props => [type, upperLine, lowerLine];
}
class TechnicalAnalysisModel extends Equatable {
final String symbol;
final String trend;
@@ -132,7 +162,7 @@ class TechnicalAnalysisModel extends Equatable {
final double? stopLossAtr;
final List<CandleModel> candles;
final List<IndicatorModel> indicators;
final List<String> patterns;
final List<ChartPatternModel> patterns;
final List<StrategySignalModel> signals;
const TechnicalAnalysisModel({
@@ -164,20 +194,33 @@ class TechnicalAnalysisModel extends Equatable {
var signalsList = rawSignals.map((s) => StrategySignalModel.fromJson(s as Map<String, dynamic>)).toList();
var rawPatterns = json['patterns'] as List<dynamic>? ?? [];
var patternsList = rawPatterns.map((p) => p.toString()).toList();
var patternsList = rawPatterns.map((p) => ChartPatternModel.fromJson(p as Map<String, dynamic>)).toList();
final lastInd = indicatorsList.isNotEmpty ? indicatorsList.last : null;
final regime = json['marketRegime'] as Map<String, dynamic>?;
String parsedTrend = lastInd?.supertrendDirection ?? 'Neutral';
if (parsedTrend.toUpperCase() == 'BUY') parsedTrend = 'Bullisch ▲';
if (parsedTrend.toUpperCase() == 'SELL') parsedTrend = 'Bearisch ▼';
String parsedSignal = 'HOLD';
if (signalsList.isNotEmpty) {
parsedSignal = signalsList.last.type.toUpperCase();
}
return TechnicalAnalysisModel(
symbol: json['symbol']?.toString() ?? json['isin']?.toString() ?? json['ticker']?.toString() ?? '',
trend: json['trend']?.toString() ?? json['Trend']?.toString() ?? 'Bullisch ▲',
rsi: json['rsi']?.toString() ?? json['Rsi']?.toString() ?? '58.7',
macd: json['macd']?.toString() ?? json['Macd']?.toString() ?? '0.45',
overallSignal: json['overallSignal']?.toString() ?? json['OverallSignal']?.toString() ?? 'HOLD',
sma50: json['sma50']?.toString() ?? json['Sma50']?.toString() ?? '49.50',
sma200: json['sma200']?.toString() ?? json['Sma200']?.toString() ?? '42.50',
vix: (json['vix'] as num?)?.toDouble() ?? 16.5,
sp500Trend: json['sp500Trend']?.toString() ?? 'Bullish',
dxy: (json['dxy'] as num?)?.toDouble() ?? 104.2,
stopLossAtr: (json['stopLossAtr'] as num?)?.toDouble(),
trend: parsedTrend,
rsi: lastInd?.rsi14?.toStringAsFixed(1) ?? 'N/A',
macd: lastInd?.macdHistogram?.toStringAsFixed(2) ?? lastInd?.macdLine?.toStringAsFixed(2) ?? 'N/A',
overallSignal: parsedSignal,
sma50: lastInd?.sma50?.toStringAsFixed(2) ?? 'N/A',
sma200: lastInd?.sma200?.toStringAsFixed(2) ?? 'N/A',
vix: (regime?['vixValue'] as num?)?.toDouble() ?? 16.5,
sp500Trend: regime?['marketTrend']?.toString() ?? 'Bullish',
dxy: (regime?['dxyValue'] as num?)?.toDouble() ?? 104.2,
stopLossAtr: lastInd?.recommendedStopLoss,
candles: candlesList,
indicators: indicatorsList,
patterns: patternsList,