feat(App): update Finlytic Flutter app UI and blocs
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
class AssetModel extends Equatable {
|
||||
final String isin;
|
||||
final String symbol;
|
||||
final String name;
|
||||
final double currentPrice;
|
||||
final String currency;
|
||||
final String exchange;
|
||||
final List<String> exchanges;
|
||||
final List<AssetTickerOption> tickers;
|
||||
final String image;
|
||||
|
||||
const AssetModel({
|
||||
required this.isin,
|
||||
required this.symbol,
|
||||
required this.name,
|
||||
this.currentPrice = 0.0,
|
||||
required this.currency,
|
||||
required this.exchange,
|
||||
required this.exchanges,
|
||||
required this.tickers,
|
||||
required this.image,
|
||||
});
|
||||
|
||||
factory AssetModel.fromJson(Map<String, dynamic> json) {
|
||||
double parseDouble(dynamic val) {
|
||||
if (val == null) return 0.0;
|
||||
if (val is num) return val.toDouble();
|
||||
return double.tryParse(val.toString()) ?? 0.0;
|
||||
}
|
||||
|
||||
return AssetModel(
|
||||
isin: json['isin']?.toString() ?? '',
|
||||
symbol: json['symbol']?.toString() ?? '',
|
||||
name: json['name']?.toString() ?? '',
|
||||
currentPrice: parseDouble(json['price'] ?? json['currentPrice']),
|
||||
currency: json['currency']?.toString() ?? 'EUR',
|
||||
exchange: json['exchange']?.toString() ?? 'XETRA',
|
||||
exchanges: (json['exchanges'] as List?)?.map((e) => e.toString()).toList() ?? [],
|
||||
tickers: (json['tickers'] as List?)
|
||||
?.map((t) => AssetTickerOption.fromJson(t))
|
||||
.toList() ??
|
||||
[],
|
||||
image: json['image']?.toString() ?? '',
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'isin': isin,
|
||||
'symbol': symbol,
|
||||
'name': name,
|
||||
'currentPrice': currentPrice,
|
||||
'currency': currency,
|
||||
'exchange': exchange,
|
||||
'exchanges': exchanges,
|
||||
'tickers': tickers.map((t) => t.toJson()).toList(),
|
||||
'image': image,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [isin, symbol, name, currentPrice, currency, exchange, exchanges, tickers, image];
|
||||
}
|
||||
|
||||
class AssetTickerOption extends Equatable {
|
||||
final String ticker;
|
||||
final String exchange;
|
||||
final String tradingCurrency;
|
||||
final double currentPrice;
|
||||
|
||||
const AssetTickerOption({
|
||||
required this.ticker,
|
||||
required this.exchange,
|
||||
required this.tradingCurrency,
|
||||
required this.currentPrice,
|
||||
});
|
||||
|
||||
factory AssetTickerOption.fromJson(Map<String, dynamic> json) {
|
||||
double parseDouble(dynamic val) {
|
||||
if (val == null) return 0.0;
|
||||
if (val is num) return val.toDouble();
|
||||
return double.tryParse(val.toString()) ?? 0.0;
|
||||
}
|
||||
|
||||
return AssetTickerOption(
|
||||
ticker: json['ticker']?.toString() ?? '',
|
||||
exchange: json['exchange']?.toString() ?? 'XETRA',
|
||||
tradingCurrency: json['tradingCurrency']?.toString() ?? json['currency']?.toString() ?? 'EUR',
|
||||
currentPrice: parseDouble(json['currentPrice'] ?? json['price']),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'ticker': ticker,
|
||||
'exchange': exchange,
|
||||
'tradingCurrency': tradingCurrency,
|
||||
'currentPrice': currentPrice,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [ticker, exchange, tradingCurrency, currentPrice];
|
||||
}
|
||||
@@ -0,0 +1,528 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
class FundamentalDataModel extends Equatable {
|
||||
final String isin;
|
||||
final String primaryTicker;
|
||||
final String ticker;
|
||||
final String companyName;
|
||||
final String? exchange;
|
||||
final String? tradingCurrency;
|
||||
final String? businessSummary;
|
||||
final String? sector;
|
||||
final String? industry;
|
||||
final String? country;
|
||||
final int? employees;
|
||||
|
||||
final double currentPrice;
|
||||
final double dayChangeAbsolute;
|
||||
final double dayChangePercent;
|
||||
final double fiftyTwoWeekHigh;
|
||||
final double fiftyTwoWeekLow;
|
||||
final double marketCapitalization;
|
||||
final double enterpriseValue;
|
||||
|
||||
final double? peRatioTrailing;
|
||||
final double? peRatioForward;
|
||||
final double? pegRatio;
|
||||
final double? pbRatio;
|
||||
final double? psRatio;
|
||||
final double? evToEbitda;
|
||||
final double? evToRevenue;
|
||||
|
||||
final double? grossMargin;
|
||||
final double? operatingMargin;
|
||||
final double? netProfitMargin;
|
||||
final double? returnOnEquity;
|
||||
final double? returnOnAssets;
|
||||
final double? returnOnInvestedCapital;
|
||||
final double? debtToEquity;
|
||||
final double? currentRatio;
|
||||
final double? quickRatio;
|
||||
final double? interestCoverage;
|
||||
|
||||
final double? dividendYield;
|
||||
final double? payoutRatio;
|
||||
final String? exDividendDate;
|
||||
final String? nextEarningsDate;
|
||||
final double? percentHeldByInstitutions;
|
||||
final double? percentHeldByInsiders;
|
||||
final double? shortRatio;
|
||||
final double? shortPercentOfFloat;
|
||||
|
||||
final String? consensusRating;
|
||||
final double? priceTargetLow;
|
||||
final double? priceTargetHigh;
|
||||
final double? priceTargetMedian;
|
||||
final double? priceTargetMean;
|
||||
|
||||
final List<CompanyExecutiveModel> executives;
|
||||
final List<FinancialStatementModel> financialStatements;
|
||||
final List<ForwardEstimateModel> estimates;
|
||||
|
||||
const FundamentalDataModel({
|
||||
required this.isin,
|
||||
required this.primaryTicker,
|
||||
required this.ticker,
|
||||
required this.companyName,
|
||||
this.exchange,
|
||||
this.tradingCurrency,
|
||||
this.businessSummary,
|
||||
this.sector,
|
||||
this.industry,
|
||||
this.country,
|
||||
this.employees,
|
||||
required this.currentPrice,
|
||||
required this.dayChangeAbsolute,
|
||||
required this.dayChangePercent,
|
||||
required this.fiftyTwoWeekHigh,
|
||||
required this.fiftyTwoWeekLow,
|
||||
required this.marketCapitalization,
|
||||
required this.enterpriseValue,
|
||||
this.peRatioTrailing,
|
||||
this.peRatioForward,
|
||||
this.pegRatio,
|
||||
this.pbRatio,
|
||||
this.psRatio,
|
||||
this.evToEbitda,
|
||||
this.evToRevenue,
|
||||
this.grossMargin,
|
||||
this.operatingMargin,
|
||||
this.netProfitMargin,
|
||||
this.returnOnEquity,
|
||||
this.returnOnAssets,
|
||||
this.returnOnInvestedCapital,
|
||||
this.debtToEquity,
|
||||
this.currentRatio,
|
||||
this.quickRatio,
|
||||
this.interestCoverage,
|
||||
this.dividendYield,
|
||||
this.payoutRatio,
|
||||
this.exDividendDate,
|
||||
this.nextEarningsDate,
|
||||
this.percentHeldByInstitutions,
|
||||
this.percentHeldByInsiders,
|
||||
this.shortRatio,
|
||||
this.shortPercentOfFloat,
|
||||
this.consensusRating,
|
||||
this.priceTargetLow,
|
||||
this.priceTargetHigh,
|
||||
this.priceTargetMedian,
|
||||
this.priceTargetMean,
|
||||
required this.executives,
|
||||
required this.financialStatements,
|
||||
required this.estimates,
|
||||
});
|
||||
|
||||
factory FundamentalDataModel.fromJson(Map<String, dynamic> json) {
|
||||
double parseDouble(dynamic val) {
|
||||
if (val == null) return 0.0;
|
||||
if (val is num) return val.toDouble();
|
||||
return double.tryParse(val.toString()) ?? 0.0;
|
||||
}
|
||||
|
||||
double? parseNullableDouble(dynamic val) {
|
||||
if (val == null) return null;
|
||||
if (val is num) return val.toDouble();
|
||||
return double.tryParse(val.toString());
|
||||
}
|
||||
|
||||
return FundamentalDataModel(
|
||||
isin: json['isin']?.toString() ?? '',
|
||||
primaryTicker: json['primaryTicker']?.toString() ?? '',
|
||||
ticker: json['ticker']?.toString() ?? '',
|
||||
companyName: json['companyName']?.toString() ?? '',
|
||||
exchange: json['exchange']?.toString(),
|
||||
tradingCurrency: json['tradingCurrency']?.toString(),
|
||||
businessSummary: json['businessSummary']?.toString(),
|
||||
sector: json['sector']?.toString(),
|
||||
industry: json['industry']?.toString(),
|
||||
country: json['country']?.toString(),
|
||||
employees: json['employees'] != null ? int.tryParse(json['employees'].toString()) : null,
|
||||
currentPrice: parseDouble(json['currentPrice']),
|
||||
dayChangeAbsolute: parseDouble(json['dayChangeAbsolute']),
|
||||
dayChangePercent: parseDouble(json['dayChangePercent']),
|
||||
fiftyTwoWeekHigh: parseDouble(json['fiftyTwoWeekHigh']),
|
||||
fiftyTwoWeekLow: parseDouble(json['fiftyTwoWeekLow']),
|
||||
marketCapitalization: parseDouble(json['marketCapitalization'] ?? json['marketCap']),
|
||||
enterpriseValue: parseDouble(json['enterpriseValue']),
|
||||
peRatioTrailing: parseNullableDouble(json['peRatioTrailing'] ?? json['peRatio']),
|
||||
peRatioForward: parseNullableDouble(json['peRatioForward']),
|
||||
pegRatio: parseNullableDouble(json['pegRatio']),
|
||||
pbRatio: parseNullableDouble(json['pbRatio']),
|
||||
psRatio: parseNullableDouble(json['psRatio']),
|
||||
evToEbitda: parseNullableDouble(json['evToEbitda']),
|
||||
evToRevenue: parseNullableDouble(json['evToRevenue']),
|
||||
grossMargin: parseNullableDouble(json['grossMargin']),
|
||||
operatingMargin: parseNullableDouble(json['operatingMargin']),
|
||||
netProfitMargin: parseNullableDouble(json['netProfitMargin']),
|
||||
returnOnEquity: parseNullableDouble(json['returnOnEquity']),
|
||||
returnOnAssets: parseNullableDouble(json['returnOnAssets']),
|
||||
returnOnInvestedCapital: parseNullableDouble(json['returnOnInvestedCapital']),
|
||||
debtToEquity: parseNullableDouble(json['debtToEquity']),
|
||||
currentRatio: parseNullableDouble(json['currentRatio']),
|
||||
quickRatio: parseNullableDouble(json['quickRatio']),
|
||||
interestCoverage: parseNullableDouble(json['interestCoverage']),
|
||||
dividendYield: parseNullableDouble(json['dividendYield']),
|
||||
payoutRatio: parseNullableDouble(json['payoutRatio']),
|
||||
exDividendDate: json['exDividendDate']?.toString(),
|
||||
nextEarningsDate: json['nextEarningsDate']?.toString(),
|
||||
percentHeldByInstitutions: parseNullableDouble(json['percentHeldByInstitutions']),
|
||||
percentHeldByInsiders: parseNullableDouble(json['percentHeldByInsiders']),
|
||||
shortRatio: parseNullableDouble(json['shortRatio']),
|
||||
shortPercentOfFloat: parseNullableDouble(json['shortPercentOfFloat']),
|
||||
consensusRating: json['consensusRating']?.toString(),
|
||||
priceTargetLow: parseNullableDouble(json['priceTargetLow']),
|
||||
priceTargetHigh: parseNullableDouble(json['priceTargetHigh']),
|
||||
priceTargetMedian: parseNullableDouble(json['priceTargetMedian']),
|
||||
priceTargetMean: parseNullableDouble(json['priceTargetMean']),
|
||||
executives: (json['executives'] as List?)
|
||||
?.map((e) => CompanyExecutiveModel.fromJson(e))
|
||||
.toList() ??
|
||||
[],
|
||||
financialStatements: (json['financialStatements'] as List?)
|
||||
?.map((e) => FinancialStatementModel.fromJson(e))
|
||||
.toList() ??
|
||||
[],
|
||||
estimates: (json['estimates'] as List?)
|
||||
?.map((e) => ForwardEstimateModel.fromJson(e))
|
||||
.toList() ??
|
||||
[],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'isin': isin,
|
||||
'primaryTicker': primaryTicker,
|
||||
'ticker': ticker,
|
||||
'companyName': companyName,
|
||||
'exchange': exchange,
|
||||
'tradingCurrency': tradingCurrency,
|
||||
'businessSummary': businessSummary,
|
||||
'sector': sector,
|
||||
'industry': industry,
|
||||
'country': country,
|
||||
'employees': employees,
|
||||
'currentPrice': currentPrice,
|
||||
'dayChangeAbsolute': dayChangeAbsolute,
|
||||
'dayChangePercent': dayChangePercent,
|
||||
'fiftyTwoWeekHigh': fiftyTwoWeekHigh,
|
||||
'fiftyTwoWeekLow': fiftyTwoWeekLow,
|
||||
'marketCapitalization': marketCapitalization,
|
||||
'enterpriseValue': enterpriseValue,
|
||||
'peRatioTrailing': peRatioTrailing,
|
||||
'peRatioForward': peRatioForward,
|
||||
'pegRatio': pegRatio,
|
||||
'pbRatio': pbRatio,
|
||||
'psRatio': psRatio,
|
||||
'evToEbitda': evToEbitda,
|
||||
'evToRevenue': evToRevenue,
|
||||
'grossMargin': grossMargin,
|
||||
'operatingMargin': operatingMargin,
|
||||
'netProfitMargin': netProfitMargin,
|
||||
'returnOnEquity': returnOnEquity,
|
||||
'returnOnAssets': returnOnAssets,
|
||||
'returnOnInvestedCapital': returnOnInvestedCapital,
|
||||
'debtToEquity': debtToEquity,
|
||||
'currentRatio': currentRatio,
|
||||
'quickRatio': quickRatio,
|
||||
'dividendYield': dividendYield,
|
||||
'payoutRatio': payoutRatio,
|
||||
'exDividendDate': exDividendDate,
|
||||
'nextEarningsDate': nextEarningsDate,
|
||||
'percentHeldByInstitutions': percentHeldByInstitutions,
|
||||
'percentHeldByInsiders': percentHeldByInsiders,
|
||||
'shortRatio': shortRatio,
|
||||
'shortPercentOfFloat': shortPercentOfFloat,
|
||||
'consensusRating': consensusRating,
|
||||
'priceTargetLow': priceTargetLow,
|
||||
'priceTargetHigh': priceTargetHigh,
|
||||
'priceTargetMedian': priceTargetMedian,
|
||||
'priceTargetMean': priceTargetMean,
|
||||
'executives': executives.map((e) => e.toJson()).toList(),
|
||||
'financialStatements': financialStatements.map((e) => e.toJson()).toList(),
|
||||
'estimates': estimates.map((e) => e.toJson()).toList(),
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
isin,
|
||||
primaryTicker,
|
||||
ticker,
|
||||
companyName,
|
||||
exchange,
|
||||
tradingCurrency,
|
||||
businessSummary,
|
||||
sector,
|
||||
industry,
|
||||
country,
|
||||
employees,
|
||||
currentPrice,
|
||||
dayChangeAbsolute,
|
||||
dayChangePercent,
|
||||
fiftyTwoWeekHigh,
|
||||
fiftyTwoWeekLow,
|
||||
marketCapitalization,
|
||||
enterpriseValue,
|
||||
peRatioTrailing,
|
||||
peRatioForward,
|
||||
pegRatio,
|
||||
pbRatio,
|
||||
psRatio,
|
||||
evToEbitda,
|
||||
evToRevenue,
|
||||
grossMargin,
|
||||
operatingMargin,
|
||||
netProfitMargin,
|
||||
returnOnEquity,
|
||||
returnOnAssets,
|
||||
returnOnInvestedCapital,
|
||||
debtToEquity,
|
||||
currentRatio,
|
||||
quickRatio,
|
||||
dividendYield,
|
||||
payoutRatio,
|
||||
exDividendDate,
|
||||
nextEarningsDate,
|
||||
percentHeldByInstitutions,
|
||||
percentHeldByInsiders,
|
||||
shortRatio,
|
||||
shortPercentOfFloat,
|
||||
consensusRating,
|
||||
priceTargetLow,
|
||||
priceTargetHigh,
|
||||
priceTargetMedian,
|
||||
priceTargetMean,
|
||||
executives,
|
||||
financialStatements,
|
||||
estimates,
|
||||
];
|
||||
}
|
||||
|
||||
class CompanyExecutiveModel extends Equatable {
|
||||
final String name;
|
||||
final String title;
|
||||
final int? age;
|
||||
final double? compensation;
|
||||
|
||||
const CompanyExecutiveModel({
|
||||
required this.name,
|
||||
required this.title,
|
||||
this.age,
|
||||
this.compensation,
|
||||
});
|
||||
|
||||
factory CompanyExecutiveModel.fromJson(Map<String, dynamic> json) {
|
||||
return CompanyExecutiveModel(
|
||||
name: json['name']?.toString() ?? '',
|
||||
title: json['title']?.toString() ?? '',
|
||||
age: json['age'] != null ? int.tryParse(json['age'].toString()) : null,
|
||||
compensation: json['compensation'] != null ? double.tryParse(json['compensation'].toString()) : null,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'name': name,
|
||||
'title': title,
|
||||
'age': age,
|
||||
'compensation': compensation,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [name, title, age, compensation];
|
||||
}
|
||||
|
||||
class FinancialStatementModel extends Equatable {
|
||||
final String periodType;
|
||||
final String endDate;
|
||||
|
||||
// Income Statement
|
||||
final double? totalRevenue;
|
||||
final double? costOfRevenue;
|
||||
final double? grossProfit;
|
||||
final double? operatingExpenses;
|
||||
final double? operatingIncome;
|
||||
final double? ebitda;
|
||||
final double? netIncome;
|
||||
final double? epsBasic;
|
||||
final double? epsDiluted;
|
||||
|
||||
// Balance Sheet
|
||||
final double? cashAndCashEquivalents;
|
||||
final double? accountsReceivable;
|
||||
final double? inventory;
|
||||
final double? totalCurrentAssets;
|
||||
final double? totalNonCurrentAssets;
|
||||
final double? currentLiabilities;
|
||||
final double? longTermDebt;
|
||||
final double? totalLiabilities;
|
||||
final double? totalStockholdersEquity;
|
||||
|
||||
// Cash Flow
|
||||
final double? operatingCashFlow;
|
||||
final double? investingCashFlow;
|
||||
final double? capitalExpenditures;
|
||||
final double? financingCashFlow;
|
||||
final double? freeCashFlow;
|
||||
|
||||
const FinancialStatementModel({
|
||||
required this.periodType,
|
||||
required this.endDate,
|
||||
this.totalRevenue,
|
||||
this.costOfRevenue,
|
||||
this.grossProfit,
|
||||
this.operatingExpenses,
|
||||
this.operatingIncome,
|
||||
this.ebitda,
|
||||
this.netIncome,
|
||||
this.epsBasic,
|
||||
this.epsDiluted,
|
||||
this.cashAndCashEquivalents,
|
||||
this.accountsReceivable,
|
||||
this.inventory,
|
||||
this.totalCurrentAssets,
|
||||
this.totalNonCurrentAssets,
|
||||
this.currentLiabilities,
|
||||
this.longTermDebt,
|
||||
this.totalLiabilities,
|
||||
this.totalStockholdersEquity,
|
||||
this.operatingCashFlow,
|
||||
this.investingCashFlow,
|
||||
this.capitalExpenditures,
|
||||
this.financingCashFlow,
|
||||
this.freeCashFlow,
|
||||
});
|
||||
|
||||
factory FinancialStatementModel.fromJson(Map<String, dynamic> json) {
|
||||
double? parseD(dynamic val) {
|
||||
if (val == null) return null;
|
||||
if (val is num) return val.toDouble();
|
||||
return double.tryParse(val.toString());
|
||||
}
|
||||
|
||||
return FinancialStatementModel(
|
||||
periodType: json['periodType']?.toString() ?? '',
|
||||
endDate: json['endDate']?.toString() ?? '',
|
||||
totalRevenue: parseD(json['totalRevenue']),
|
||||
costOfRevenue: parseD(json['costOfRevenue']),
|
||||
grossProfit: parseD(json['grossProfit']),
|
||||
operatingExpenses: parseD(json['operatingExpenses']),
|
||||
operatingIncome: parseD(json['operatingIncome']),
|
||||
ebitda: parseD(json['ebitda']),
|
||||
netIncome: parseD(json['netIncome']),
|
||||
epsBasic: parseD(json['epsBasic']),
|
||||
epsDiluted: parseD(json['epsDiluted']),
|
||||
cashAndCashEquivalents: parseD(json['cashAndCashEquivalents']),
|
||||
accountsReceivable: parseD(json['accountsReceivable']),
|
||||
inventory: parseD(json['inventory']),
|
||||
totalCurrentAssets: parseD(json['totalCurrentAssets']),
|
||||
totalNonCurrentAssets: parseD(json['totalNonCurrentAssets']),
|
||||
currentLiabilities: parseD(json['currentLiabilities']),
|
||||
longTermDebt: parseD(json['longTermDebt']),
|
||||
totalLiabilities: parseD(json['totalLiabilities']),
|
||||
totalStockholdersEquity: parseD(json['totalStockholdersEquity']),
|
||||
operatingCashFlow: parseD(json['operatingCashFlow']),
|
||||
investingCashFlow: parseD(json['investingCashFlow']),
|
||||
capitalExpenditures: parseD(json['capitalExpenditures']),
|
||||
financingCashFlow: parseD(json['financingCashFlow']),
|
||||
freeCashFlow: parseD(json['freeCashFlow']),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'periodType': periodType,
|
||||
'endDate': endDate,
|
||||
'totalRevenue': totalRevenue,
|
||||
'costOfRevenue': costOfRevenue,
|
||||
'grossProfit': grossProfit,
|
||||
'operatingExpenses': operatingExpenses,
|
||||
'operatingIncome': operatingIncome,
|
||||
'ebitda': ebitda,
|
||||
'netIncome': netIncome,
|
||||
'epsBasic': epsBasic,
|
||||
'epsDiluted': epsDiluted,
|
||||
'cashAndCashEquivalents': cashAndCashEquivalents,
|
||||
'accountsReceivable': accountsReceivable,
|
||||
'inventory': inventory,
|
||||
'totalCurrentAssets': totalCurrentAssets,
|
||||
'totalNonCurrentAssets': totalNonCurrentAssets,
|
||||
'currentLiabilities': currentLiabilities,
|
||||
'longTermDebt': longTermDebt,
|
||||
'totalLiabilities': totalLiabilities,
|
||||
'totalStockholdersEquity': totalStockholdersEquity,
|
||||
'operatingCashFlow': operatingCashFlow,
|
||||
'investingCashFlow': investingCashFlow,
|
||||
'capitalExpenditures': capitalExpenditures,
|
||||
'financingCashFlow': financingCashFlow,
|
||||
'freeCashFlow': freeCashFlow,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
periodType,
|
||||
endDate,
|
||||
totalRevenue,
|
||||
costOfRevenue,
|
||||
grossProfit,
|
||||
operatingExpenses,
|
||||
operatingIncome,
|
||||
ebitda,
|
||||
netIncome,
|
||||
epsBasic,
|
||||
epsDiluted,
|
||||
cashAndCashEquivalents,
|
||||
accountsReceivable,
|
||||
inventory,
|
||||
totalCurrentAssets,
|
||||
totalNonCurrentAssets,
|
||||
currentLiabilities,
|
||||
longTermDebt,
|
||||
totalLiabilities,
|
||||
totalStockholdersEquity,
|
||||
operatingCashFlow,
|
||||
investingCashFlow,
|
||||
capitalExpenditures,
|
||||
financingCashFlow,
|
||||
freeCashFlow,
|
||||
];
|
||||
}
|
||||
|
||||
class ForwardEstimateModel extends Equatable {
|
||||
final String period;
|
||||
final double? expectedRevenue;
|
||||
final double? expectedEps;
|
||||
final double? expectedGrowthRate;
|
||||
|
||||
const ForwardEstimateModel({
|
||||
required this.period,
|
||||
this.expectedRevenue,
|
||||
this.expectedEps,
|
||||
this.expectedGrowthRate,
|
||||
});
|
||||
|
||||
factory ForwardEstimateModel.fromJson(Map<String, dynamic> json) {
|
||||
return ForwardEstimateModel(
|
||||
period: json['period']?.toString() ?? '',
|
||||
expectedRevenue: json['expectedRevenue'] != null ? double.tryParse(json['expectedRevenue'].toString()) : null,
|
||||
expectedEps: json['expectedEps'] != null ? double.tryParse(json['expectedEps'].toString()) : null,
|
||||
expectedGrowthRate: json['expectedGrowthRate'] != null ? double.tryParse(json['expectedGrowthRate'].toString()) : null,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'period': period,
|
||||
'expectedRevenue': expectedRevenue,
|
||||
'expectedEps': expectedEps,
|
||||
'expectedGrowthRate': expectedGrowthRate,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [period, expectedRevenue, expectedEps, expectedGrowthRate];
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
class ManualAnalysisRequestDto {
|
||||
final String isin;
|
||||
final String symbol;
|
||||
final int riskScore;
|
||||
final int minTimeframeValue;
|
||||
final int maxTimeframeValue;
|
||||
final String timeframeUnit;
|
||||
final String instrumentType;
|
||||
final String userNotes;
|
||||
final String headline;
|
||||
|
||||
ManualAnalysisRequestDto({
|
||||
required this.isin,
|
||||
required this.symbol,
|
||||
required this.riskScore,
|
||||
required this.minTimeframeValue,
|
||||
required this.maxTimeframeValue,
|
||||
required this.timeframeUnit,
|
||||
required this.instrumentType,
|
||||
required this.userNotes,
|
||||
required this.headline,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'isin': isin,
|
||||
'symbol': symbol,
|
||||
'riskScore': riskScore,
|
||||
'minTimeframeValue': minTimeframeValue,
|
||||
'maxTimeframeValue': maxTimeframeValue,
|
||||
'timeframeUnit': timeframeUnit,
|
||||
'instrumentType': instrumentType,
|
||||
'userNotes': userNotes,
|
||||
'headline': headline,
|
||||
};
|
||||
}
|
||||
|
||||
factory ManualAnalysisRequestDto.fromJson(Map<String, dynamic> json) {
|
||||
return ManualAnalysisRequestDto(
|
||||
isin: json['isin'] as String,
|
||||
symbol: json['symbol'] as String,
|
||||
riskScore: json['riskScore'] as int,
|
||||
minTimeframeValue: json['minTimeframeValue'] as int,
|
||||
maxTimeframeValue: json['maxTimeframeValue'] as int,
|
||||
timeframeUnit: json['timeframeUnit'] as String,
|
||||
instrumentType: json['instrumentType'] as String,
|
||||
userNotes: json['userNotes'] as String,
|
||||
headline: json['headline'] as String,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
class CandleModel extends Equatable {
|
||||
final DateTime timestamp;
|
||||
final double open;
|
||||
final double high;
|
||||
final double low;
|
||||
final double close;
|
||||
final double volume;
|
||||
|
||||
const CandleModel({
|
||||
required this.timestamp,
|
||||
required this.open,
|
||||
required this.high,
|
||||
required this.low,
|
||||
required this.close,
|
||||
required this.volume,
|
||||
});
|
||||
|
||||
factory CandleModel.fromJson(Map<String, dynamic> json) {
|
||||
return CandleModel(
|
||||
timestamp: DateTime.tryParse(json['timestamp']?.toString() ?? '') ?? DateTime.now(),
|
||||
open: (json['open'] as num?)?.toDouble() ?? 0.0,
|
||||
high: (json['high'] as num?)?.toDouble() ?? 0.0,
|
||||
low: (json['low'] as num?)?.toDouble() ?? 0.0,
|
||||
close: (json['close'] as num?)?.toDouble() ?? 0.0,
|
||||
volume: (json['volume'] as num?)?.toDouble() ?? 0.0,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [timestamp, open, high, low, close, volume];
|
||||
}
|
||||
|
||||
class IndicatorModel extends Equatable {
|
||||
final DateTime timestamp;
|
||||
final double? ema20;
|
||||
final double? sma50;
|
||||
final double? sma200;
|
||||
final double? rsi14;
|
||||
final double? macdLine;
|
||||
final double? macdSignal;
|
||||
final double? macdHistogram;
|
||||
final double? atr14;
|
||||
final double? vwap;
|
||||
final double? supertrendUpper;
|
||||
final double? supertrendLower;
|
||||
final String? supertrendDirection;
|
||||
final double? recommendedStopLoss;
|
||||
|
||||
const IndicatorModel({
|
||||
required this.timestamp,
|
||||
this.ema20,
|
||||
this.sma50,
|
||||
this.sma200,
|
||||
this.rsi14,
|
||||
this.macdLine,
|
||||
this.macdSignal,
|
||||
this.macdHistogram,
|
||||
this.atr14,
|
||||
this.vwap,
|
||||
this.supertrendUpper,
|
||||
this.supertrendLower,
|
||||
this.supertrendDirection,
|
||||
this.recommendedStopLoss,
|
||||
});
|
||||
|
||||
factory IndicatorModel.fromJson(Map<String, dynamic> json) {
|
||||
return IndicatorModel(
|
||||
timestamp: DateTime.tryParse(json['timestamp']?.toString() ?? '') ?? DateTime.now(),
|
||||
ema20: (json['ema20'] as num?)?.toDouble(),
|
||||
sma50: (json['sma50'] as num?)?.toDouble(),
|
||||
sma200: (json['sma200'] as num?)?.toDouble(),
|
||||
rsi14: (json['rsi14'] as num?)?.toDouble(),
|
||||
macdLine: (json['macdLine'] as num?)?.toDouble(),
|
||||
macdSignal: (json['macdSignal'] as num?)?.toDouble(),
|
||||
macdHistogram: (json['macdHistogram'] as num?)?.toDouble(),
|
||||
atr14: (json['atr14'] as num?)?.toDouble(),
|
||||
vwap: (json['vwap'] as num?)?.toDouble(),
|
||||
supertrendUpper: (json['supertrendUpper'] as num?)?.toDouble(),
|
||||
supertrendLower: (json['supertrendLower'] as num?)?.toDouble(),
|
||||
supertrendDirection: json['supertrendDirection']?.toString(),
|
||||
recommendedStopLoss: (json['recommendedStopLoss'] as num?)?.toDouble(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
timestamp, ema20, sma50, sma200, rsi14, macdLine, macdSignal,
|
||||
macdHistogram, atr14, vwap, supertrendUpper, supertrendLower,
|
||||
supertrendDirection, recommendedStopLoss
|
||||
];
|
||||
}
|
||||
|
||||
class StrategySignalModel extends Equatable {
|
||||
final String title;
|
||||
final DateTime date;
|
||||
final double price;
|
||||
final String type; // BUY or SELL
|
||||
|
||||
const StrategySignalModel({
|
||||
required this.title,
|
||||
required this.date,
|
||||
required this.price,
|
||||
required this.type,
|
||||
});
|
||||
|
||||
factory StrategySignalModel.fromJson(Map<String, dynamic> json) {
|
||||
return StrategySignalModel(
|
||||
title: json['title']?.toString() ?? '',
|
||||
date: DateTime.tryParse(json['date']?.toString() ?? '') ?? DateTime.now(),
|
||||
price: (json['price'] as num?)?.toDouble() ?? 0.0,
|
||||
type: json['type']?.toString() ?? 'BUY',
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [title, date, price, type];
|
||||
}
|
||||
|
||||
class TechnicalAnalysisModel extends Equatable {
|
||||
final String symbol;
|
||||
final String trend;
|
||||
final String rsi;
|
||||
final String macd;
|
||||
final String overallSignal;
|
||||
final String sma50;
|
||||
final String sma200;
|
||||
final double vix;
|
||||
final String sp500Trend;
|
||||
final double dxy;
|
||||
final double? stopLossAtr;
|
||||
final List<CandleModel> candles;
|
||||
final List<IndicatorModel> indicators;
|
||||
final List<String> patterns;
|
||||
final List<StrategySignalModel> signals;
|
||||
|
||||
const TechnicalAnalysisModel({
|
||||
required this.symbol,
|
||||
required this.trend,
|
||||
required this.rsi,
|
||||
required this.macd,
|
||||
required this.overallSignal,
|
||||
required this.sma50,
|
||||
required this.sma200,
|
||||
this.vix = 16.5,
|
||||
this.sp500Trend = 'Bullish',
|
||||
this.dxy = 104.2,
|
||||
this.stopLossAtr,
|
||||
this.candles = const [],
|
||||
this.indicators = const [],
|
||||
this.patterns = const [],
|
||||
this.signals = const [],
|
||||
});
|
||||
|
||||
factory TechnicalAnalysisModel.fromJson(Map<String, dynamic> json) {
|
||||
var rawCandles = json['candles'] as List<dynamic>? ?? [];
|
||||
var candlesList = rawCandles.map((c) => CandleModel.fromJson(c as Map<String, dynamic>)).toList();
|
||||
|
||||
var rawIndicators = json['indicators'] as List<dynamic>? ?? [];
|
||||
var indicatorsList = rawIndicators.map((i) => IndicatorModel.fromJson(i as Map<String, dynamic>)).toList();
|
||||
|
||||
var rawSignals = json['signals'] as List<dynamic>? ?? [];
|
||||
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();
|
||||
|
||||
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(),
|
||||
candles: candlesList,
|
||||
indicators: indicatorsList,
|
||||
patterns: patternsList,
|
||||
signals: signalsList,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'symbol': symbol,
|
||||
'trend': trend,
|
||||
'rsi': rsi,
|
||||
'macd': macd,
|
||||
'overallSignal': overallSignal,
|
||||
'sma50': sma50,
|
||||
'sma200': sma200,
|
||||
'vix': vix,
|
||||
'sp500Trend': sp500Trend,
|
||||
'dxy': dxy,
|
||||
'stopLossAtr': stopLossAtr,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
symbol, trend, rsi, macd, overallSignal, sma50, sma200, vix,
|
||||
sp500Trend, dxy, stopLossAtr, candles, indicators, patterns, signals
|
||||
];
|
||||
}
|
||||
Reference in New Issue
Block a user