feat(Fundamentals): add fundamentals service

This commit is contained in:
2026-08-09 21:01:39 +02:00
parent e0778b88ea
commit 605e41cfeb
21 changed files with 3122 additions and 0 deletions
@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace FinlyticFundamentals.Entities;
/// <summary>
/// Main database table representing global company profile, ownership structure, analyst predictions, and corporate events.
/// </summary>
public class AssetFundamentalsEntity
{
[Key]
[Required]
public string Isin { get; set; } = string.Empty;
[Required]
public string PrimaryTicker { get; set; } = string.Empty;
// --- Static Company Profile Columns ---
[Required]
public string CompanyName { get; set; } = string.Empty;
public string? BusinessSummary { get; set; }
public string? Sector { get; set; }
public string? Industry { get; set; }
public string? Country { get; set; }
public int? Employees { get; set; }
// --- Ownership & Sentiment Data (Company-wide) ---
public decimal? PercentHeldByInstitutions { get; set; }
public decimal? PercentHeldByInsiders { get; set; }
public decimal? ShortRatio { get; set; }
public decimal? ShortPercentOfFloat { get; set; }
// --- Analyst Forecasts & Targets ---
public string? ConsensusRating { get; set; }
public decimal? PriceTargetLow { get; set; }
public decimal? PriceTargetHigh { get; set; }
public decimal? PriceTargetMedian { get; set; }
public decimal? PriceTargetMean { get; set; }
// --- Corporate Calendar / Catalysts ---
public DateTime? ExDividendDate { get; set; }
public DateTime? NextEarningsDate { get; set; }
// --- Cache Control Timestamps ---
public DateTime LastUpdatedAt { get; set; } = DateTime.UtcNow;
public DateTime LastStaticUpdatedAt { get; set; } = DateTime.UtcNow;
// --- Relational Collections ---
public List<CompanyExecutiveEntity> Executives { get; set; } = [];
public List<FinancialStatementEntity> FinancialStatements { get; set; } = [];
public List<ForwardEstimateEntity> Estimates { get; set; } = [];
public List<TickerFundamentalsEntity> TickerFundamentals { get; set; } = [];
}
@@ -0,0 +1,28 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
namespace FinlyticFundamentals.Entities;
/// <summary>
/// Relational executive board table linked to the main fundamentals entity by ISIN.
/// </summary>
public class CompanyExecutiveEntity
{
[Key]
public Guid Id { get; set; } = Guid.NewGuid();
[Required]
public string Isin { get; set; } = string.Empty;
[JsonIgnore]
public AssetFundamentalsEntity? AssetFundamentals { get; set; }
[Required]
public string Name { get; set; } = string.Empty;
[Required]
public string Title { get; set; } = string.Empty;
public int? Age { get; set; }
public decimal? Compensation { get; set; }
}
@@ -0,0 +1,55 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
namespace FinlyticFundamentals.Entities;
/// <summary>
/// Relational statement table linking historical Income Statements, Balance Sheets, and Cash Flow metrics.
/// </summary>
public class FinancialStatementEntity
{
[Key]
public Guid Id { get; set; } = Guid.NewGuid();
[Required]
public string Isin { get; set; } = string.Empty;
[JsonIgnore]
public AssetFundamentalsEntity? AssetFundamentals { get; set; }
[Required]
public string PeriodType { get; set; } = string.Empty; // "Annual" or "Quarterly"
[Required]
public DateTime EndDate { get; set; }
// --- Income Statement Fields ---
public decimal? TotalRevenue { get; set; }
public decimal? CostOfRevenue { get; set; }
public decimal? GrossProfit { get; set; }
public decimal? OperatingExpenses { get; set; }
public decimal? OperatingIncome { get; set; }
public decimal? Ebitda { get; set; }
public decimal? NetIncome { get; set; }
public decimal? EpsBasic { get; set; }
public decimal? EpsDiluted { get; set; }
// --- Balance Sheet Fields ---
public decimal? CashAndCashEquivalents { get; set; }
public decimal? AccountsReceivable { get; set; }
public decimal? Inventory { get; set; }
public decimal? TotalCurrentAssets { get; set; }
public decimal? TotalNonCurrentAssets { get; set; }
public decimal? CurrentLiabilities { get; set; }
public decimal? LongTermDebt { get; set; }
public decimal? TotalLiabilities { get; set; }
public decimal? TotalStockholdersEquity { get; set; }
// --- Cash Flow Fields ---
public decimal? OperatingCashFlow { get; set; }
public decimal? InvestingCashFlow { get; set; }
public decimal? CapitalExpenditures { get; set; }
public decimal? FinancingCashFlow { get; set; }
public decimal? FreeCashFlow { get; set; } // OperatingCashFlow - CapEx
}
@@ -0,0 +1,26 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
namespace FinlyticFundamentals.Entities;
/// <summary>
/// Relational table for analyst consensus revenue and EPS forecasts.
/// </summary>
public class ForwardEstimateEntity
{
[Key]
public Guid Id { get; set; } = Guid.NewGuid();
[Required]
public string Isin { get; set; } = string.Empty;
[JsonIgnore]
public AssetFundamentalsEntity? AssetFundamentals { get; set; }
[Required]
public string Period { get; set; } = string.Empty; // "CurrentQuarter", "NextQuarter", "CurrentYear", "NextYear"
public decimal? ExpectedRevenue { get; set; }
public decimal? ExpectedEps { get; set; }
public decimal? ExpectedGrowthRate { get; set; }
}
@@ -0,0 +1,14 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace FinlyticFundamentals.Entities;
public class FundamentalsSettingsEntity
{
[Key]
public Guid Id { get; set; }
public int CacheTtlHours { get; set; } = 24;
public bool EnableYahooFallback { get; set; } = true;
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
}
@@ -0,0 +1,65 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace FinlyticFundamentals.Entities;
/// <summary>
/// Database table representing dynamic trading data, exchange-dependent valuation ratios, liquidity, and leverage stats for each traded ticker symbol.
/// </summary>
public class TickerFundamentalsEntity
{
[Key]
[Required]
public string Ticker { get; set; } = string.Empty; // Primary key, e.g., "POR.DE"
[Required]
public string Isin { get; set; } = string.Empty;
[ForeignKey("Isin")]
public AssetFundamentalsEntity? AssetFundamentals { get; set; }
public string? Exchange { get; set; }
public string? TradingCurrency { get; set; }
// Real-time & Price Performance
public decimal CurrentPrice { get; set; }
public decimal DayChangeAbsolute { get; set; }
public decimal DayChangePercent { get; set; }
public decimal FiftyTwoWeekHigh { get; set; }
public decimal FiftyTwoWeekLow { get; set; }
// Size & Enterprise Valuation
public decimal MarketCapitalization { get; set; }
public decimal EnterpriseValue { get; set; }
// Valuation Ratios
public decimal? PeRatioTrailing { get; set; }
public decimal? PeRatioForward { get; set; }
public decimal? PegRatio { get; set; }
public decimal? PbRatio { get; set; }
public decimal? PsRatio { get; set; }
public decimal? EvToEbitda { get; set; }
public decimal? EvToRevenue { get; set; }
// Profitability & Return Ratios
public decimal? GrossMargin { get; set; }
public decimal? OperatingMargin { get; set; }
public decimal? NetProfitMargin { get; set; }
public decimal? ReturnOnEquity { get; set; }
public decimal? ReturnOnAssets { get; set; }
public decimal? ReturnOnInvestedCapital { get; set; }
// Financial Health, Solvency & Liquidity
public decimal? DebtToEquity { get; set; }
public decimal? CurrentRatio { get; set; }
public decimal? QuickRatio { get; set; }
public decimal? InterestCoverage { get; set; }
// Dividend Performance Metrics
public decimal? DividendYield { get; set; }
public decimal? PayoutRatio { get; set; }
public DateTime? ExDividendDate { get; set; }
public DateTime LastUpdatedAt { get; set; } = DateTime.UtcNow;
}