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
@@ -58,6 +58,7 @@ class FundamentalDataModel extends Equatable {
final List<CompanyExecutiveModel> executives;
final List<FinancialStatementModel> financialStatements;
final List<ForwardEstimateModel> estimates;
final List<TickerModel> availableTickers;
const FundamentalDataModel({
required this.isin,
@@ -111,6 +112,7 @@ class FundamentalDataModel extends Equatable {
required this.executives,
required this.financialStatements,
required this.estimates,
this.availableTickers = const [],
});
factory FundamentalDataModel.fromJson(Map<String, dynamic> json) {
@@ -187,6 +189,10 @@ class FundamentalDataModel extends Equatable {
?.map((e) => ForwardEstimateModel.fromJson(e))
.toList() ??
[],
availableTickers: (json['availableTickers'] as List?)
?.map((e) => TickerModel.fromJson(e))
.toList() ??
[],
);
}
@@ -242,6 +248,7 @@ class FundamentalDataModel extends Equatable {
'executives': executives.map((e) => e.toJson()).toList(),
'financialStatements': financialStatements.map((e) => e.toJson()).toList(),
'estimates': estimates.map((e) => e.toJson()).toList(),
'availableTickers': availableTickers.map((e) => e.toJson()).toList(),
};
}
@@ -297,6 +304,7 @@ class FundamentalDataModel extends Equatable {
executives,
financialStatements,
estimates,
availableTickers,
];
}
@@ -526,3 +534,38 @@ class ForwardEstimateModel extends Equatable {
@override
List<Object?> get props => [period, expectedRevenue, expectedEps, expectedGrowthRate];
}
class TickerModel extends Equatable {
final String ticker;
final String? exchange;
final String? tradingCurrency;
final double currentPrice;
const TickerModel({
required this.ticker,
this.exchange,
this.tradingCurrency,
required this.currentPrice,
});
factory TickerModel.fromJson(Map<String, dynamic> json) {
return TickerModel(
ticker: json['ticker']?.toString() ?? '',
exchange: json['exchange']?.toString(),
tradingCurrency: json['tradingCurrency']?.toString(),
currentPrice: json['currentPrice'] != null ? double.tryParse(json['currentPrice'].toString()) ?? 0.0 : 0.0,
);
}
Map<String, dynamic> toJson() {
return {
'ticker': ticker,
'exchange': exchange,
'tradingCurrency': tradingCurrency,
'currentPrice': currentPrice,
};
}
@override
List<Object?> get props => [ticker, exchange, tradingCurrency, currentPrice];
}
@@ -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,