feat(Core): update DTOs and shared models

This commit is contained in:
2026-08-09 21:01:38 +02:00
parent 6337e63a77
commit 5475c3ac51
58 changed files with 3418 additions and 30 deletions
@@ -0,0 +1,281 @@
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace FinlyticCore.Dtos.Fundamentals;
/// <summary>
/// Data transfer object representing the complete fundamental analysis dataset of an asset.
/// </summary>
public record AssetFundamentalsDto
{
[JsonPropertyName("isin")]
public string Isin { get; init; } = string.Empty;
[JsonPropertyName("primaryTicker")]
public string PrimaryTicker { get; init; } = string.Empty;
[JsonPropertyName("ticker")]
public string Ticker { get; init; } = string.Empty;
[JsonPropertyName("companyName")]
public string CompanyName { get; init; } = string.Empty;
[JsonPropertyName("exchange")]
public string? Exchange { get; init; }
[JsonPropertyName("tradingCurrency")]
public string? TradingCurrency { get; init; }
[JsonPropertyName("businessSummary")]
public string? BusinessSummary { get; init; }
[JsonPropertyName("sector")]
public string? Sector { get; init; }
[JsonPropertyName("industry")]
public string? Industry { get; init; }
[JsonPropertyName("country")]
public string? Country { get; init; }
[JsonPropertyName("employees")]
public int? Employees { get; init; }
// Valuation Metrics (derived from Primary Ticker)
[JsonPropertyName("currentPrice")]
public decimal CurrentPrice { get; init; }
[JsonPropertyName("dayChangeAbsolute")]
public decimal DayChangeAbsolute { get; init; }
[JsonPropertyName("dayChangePercent")]
public decimal DayChangePercent { get; init; }
[JsonPropertyName("fiftyTwoWeekHigh")]
public decimal FiftyTwoWeekHigh { get; init; }
[JsonPropertyName("fiftyTwoWeekLow")]
public decimal FiftyTwoWeekLow { get; init; }
[JsonPropertyName("marketCapitalization")]
public decimal MarketCapitalization { get; init; }
[JsonPropertyName("enterpriseValue")]
public decimal EnterpriseValue { get; init; }
[JsonPropertyName("peRatioTrailing")]
public decimal? PeRatioTrailing { get; init; }
[JsonPropertyName("peRatioForward")]
public decimal? PeRatioForward { get; init; }
[JsonPropertyName("pegRatio")]
public decimal? PegRatio { get; init; }
[JsonPropertyName("pbRatio")]
public decimal? PbRatio { get; init; }
[JsonPropertyName("psRatio")]
public decimal? PsRatio { get; init; }
[JsonPropertyName("evToEbitda")]
public decimal? EvToEbitda { get; init; }
[JsonPropertyName("evToRevenue")]
public decimal? EvToRevenue { get; init; }
// Financial Health & Leverage
[JsonPropertyName("grossMargin")]
public decimal? GrossMargin { get; init; }
[JsonPropertyName("operatingMargin")]
public decimal? OperatingMargin { get; init; }
[JsonPropertyName("netProfitMargin")]
public decimal? NetProfitMargin { get; init; }
[JsonPropertyName("returnOnEquity")]
public decimal? ReturnOnEquity { get; init; }
[JsonPropertyName("returnOnAssets")]
public decimal? ReturnOnAssets { get; init; }
[JsonPropertyName("returnOnInvestedCapital")]
public decimal? ReturnOnInvestedCapital { get; init; }
[JsonPropertyName("debtToEquity")]
public decimal? DebtToEquity { get; init; }
[JsonPropertyName("currentRatio")]
public decimal? CurrentRatio { get; init; }
[JsonPropertyName("quickRatio")]
public decimal? QuickRatio { get; init; }
[JsonPropertyName("interestCoverage")]
public decimal? InterestCoverage { get; init; }
// Dividends & Ownership
[JsonPropertyName("dividendYield")]
public decimal? DividendYield { get; init; }
[JsonPropertyName("payoutRatio")]
public decimal? PayoutRatio { get; init; }
[JsonPropertyName("exDividendDate")]
public DateTime? ExDividendDate { get; init; }
[JsonPropertyName("nextEarningsDate")]
public DateTime? NextEarningsDate { get; init; }
[JsonPropertyName("percentHeldByInstitutions")]
public decimal? PercentHeldByInstitutions { get; init; }
[JsonPropertyName("percentHeldByInsiders")]
public decimal? PercentHeldByInsiders { get; init; }
[JsonPropertyName("shortRatio")]
public decimal? ShortRatio { get; init; }
[JsonPropertyName("shortPercentOfFloat")]
public decimal? ShortPercentOfFloat { get; init; }
// Forecasts
[JsonPropertyName("consensusRating")]
public string? ConsensusRating { get; init; }
[JsonPropertyName("priceTargetLow")]
public decimal? PriceTargetLow { get; init; }
[JsonPropertyName("priceTargetHigh")]
public decimal? PriceTargetHigh { get; init; }
[JsonPropertyName("priceTargetMedian")]
public decimal? PriceTargetMedian { get; init; }
[JsonPropertyName("priceTargetMean")]
public decimal? PriceTargetMean { get; init; }
// Timestamps
[JsonPropertyName("lastUpdatedAt")]
public DateTime LastUpdatedAt { get; init; }
// Relational Collections
[JsonPropertyName("executives")]
public List<CompanyExecutiveDto> Executives { get; init; } = [];
[JsonPropertyName("financialStatements")]
public List<FinancialStatementDto> FinancialStatements { get; init; } = [];
[JsonPropertyName("estimates")]
public List<ForwardEstimateDto> Estimates { get; init; } = [];
[JsonPropertyName("availableTickers")]
public List<TickerDto> AvailableTickers { get; init; } = [];
}
public record CompanyExecutiveDto
{
[JsonPropertyName("name")]
public string Name { get; init; } = string.Empty;
[JsonPropertyName("title")]
public string Title { get; init; } = string.Empty;
[JsonPropertyName("age")]
public int? Age { get; init; }
[JsonPropertyName("compensation")]
public decimal? Compensation { get; init; }
}
public record FinancialStatementDto
{
[JsonPropertyName("periodType")]
public string PeriodType { get; init; } = string.Empty; // "Annual" or "Quarterly"
[JsonPropertyName("endDate")]
public DateTime EndDate { get; init; }
// Income Statement
[JsonPropertyName("totalRevenue")]
public decimal? TotalRevenue { get; init; }
[JsonPropertyName("costOfRevenue")]
public decimal? CostOfRevenue { get; init; }
[JsonPropertyName("grossProfit")]
public decimal? GrossProfit { get; init; }
[JsonPropertyName("operatingExpenses")]
public decimal? OperatingExpenses { get; init; }
[JsonPropertyName("operatingIncome")]
public decimal? OperatingIncome { get; init; }
[JsonPropertyName("ebitda")]
public decimal? Ebitda { get; init; }
[JsonPropertyName("netIncome")]
public decimal? NetIncome { get; init; }
[JsonPropertyName("epsBasic")]
public decimal? EpsBasic { get; init; }
[JsonPropertyName("epsDiluted")]
public decimal? EpsDiluted { get; init; }
// Balance Sheet
[JsonPropertyName("cashAndCashEquivalents")]
public decimal? CashAndCashEquivalents { get; init; }
[JsonPropertyName("accountsReceivable")]
public decimal? AccountsReceivable { get; init; }
[JsonPropertyName("inventory")]
public decimal? Inventory { get; init; }
[JsonPropertyName("totalCurrentAssets")]
public decimal? TotalCurrentAssets { get; init; }
[JsonPropertyName("totalNonCurrentAssets")]
public decimal? TotalNonCurrentAssets { get; init; }
[JsonPropertyName("currentLiabilities")]
public decimal? CurrentLiabilities { get; init; }
[JsonPropertyName("longTermDebt")]
public decimal? LongTermDebt { get; init; }
[JsonPropertyName("totalLiabilities")]
public decimal? TotalLiabilities { get; init; }
[JsonPropertyName("totalStockholdersEquity")]
public decimal? TotalStockholdersEquity { get; init; }
// Cash Flow Statement
[JsonPropertyName("operatingCashFlow")]
public decimal? OperatingCashFlow { get; init; }
[JsonPropertyName("investingCashFlow")]
public decimal? InvestingCashFlow { get; init; }
[JsonPropertyName("capitalExpenditures")]
public decimal? CapitalExpenditures { get; init; }
[JsonPropertyName("financingCashFlow")]
public decimal? FinancingCashFlow { get; init; }
[JsonPropertyName("freeCashFlow")]
public decimal? FreeCashFlow { get; init; } // OperatingCashFlow - CapEx
}
public record ForwardEstimateDto
{
[JsonPropertyName("period")]
public string Period { get; init; } = string.Empty; // "CurrentQuarter", "NextQuarter", "CurrentYear", "NextYear"
[JsonPropertyName("expectedRevenue")]
public decimal? ExpectedRevenue { get; init; }
[JsonPropertyName("expectedEps")]
public decimal? ExpectedEps { get; init; }
[JsonPropertyName("expectedGrowthRate")]
public decimal? ExpectedGrowthRate { get; init; }
}
public record TickerDto
{
[JsonPropertyName("ticker")]
public string Ticker { get; init; } = string.Empty;
[JsonPropertyName("exchange")]
public string? Exchange { get; init; }
[JsonPropertyName("tradingCurrency")]
public string? TradingCurrency { get; init; }
[JsonPropertyName("currentPrice")]
public decimal CurrentPrice { get; init; }
[JsonPropertyName("dayChangeAbsolute")]
public decimal DayChangeAbsolute { get; init; }
[JsonPropertyName("dayChangePercent")]
public decimal DayChangePercent { get; init; }
[JsonPropertyName("fiftyTwoWeekHigh")]
public decimal FiftyTwoWeekHigh { get; init; }
[JsonPropertyName("fiftyTwoWeekLow")]
public decimal FiftyTwoWeekLow { get; init; }
[JsonPropertyName("marketCapitalization")]
public decimal MarketCapitalization { get; init; }
[JsonPropertyName("enterpriseValue")]
public decimal EnterpriseValue { get; init; }
[JsonPropertyName("peRatioTrailing")]
public decimal? PeRatioTrailing { get; init; }
[JsonPropertyName("peRatioForward")]
public decimal? PeRatioForward { get; init; }
[JsonPropertyName("pegRatio")]
public decimal? PegRatio { get; init; }
[JsonPropertyName("pbRatio")]
public decimal? PbRatio { get; init; }
[JsonPropertyName("psRatio")]
public decimal? PsRatio { get; init; }
[JsonPropertyName("evToEbitda")]
public decimal? EvToEbitda { get; init; }
[JsonPropertyName("evToRevenue")]
public decimal? EvToRevenue { get; init; }
[JsonPropertyName("grossMargin")]
public decimal? GrossMargin { get; init; }
[JsonPropertyName("operatingMargin")]
public decimal? OperatingMargin { get; init; }
[JsonPropertyName("netProfitMargin")]
public decimal? NetProfitMargin { get; init; }
[JsonPropertyName("returnOnEquity")]
public decimal? ReturnOnEquity { get; init; }
[JsonPropertyName("returnOnAssets")]
public decimal? ReturnOnAssets { get; init; }
[JsonPropertyName("returnOnInvestedCapital")]
public decimal? ReturnOnInvestedCapital { get; init; }
[JsonPropertyName("debtToEquity")]
public decimal? DebtToEquity { get; init; }
[JsonPropertyName("currentRatio")]
public decimal? CurrentRatio { get; init; }
[JsonPropertyName("quickRatio")]
public decimal? QuickRatio { get; init; }
[JsonPropertyName("interestCoverage")]
public decimal? InterestCoverage { get; init; }
[JsonPropertyName("dividendYield")]
public decimal? DividendYield { get; init; }
[JsonPropertyName("payoutRatio")]
public decimal? PayoutRatio { get; init; }
[JsonPropertyName("exDividendDate")]
public DateTime? ExDividendDate { get; init; }
}
@@ -0,0 +1,25 @@
using System;
using System.Text.Json.Serialization;
namespace FinlyticCore.Dtos.Fundamentals;
/// <summary>
/// DTO representing a scheduled corporate event (e.g. Earnings, Ex-Dividend, Dividend Payout).
/// </summary>
public record CorporateEventDto
{
[JsonPropertyName("isin")]
public string Isin { get; init; } = string.Empty;
[JsonPropertyName("ticker")]
public string Ticker { get; init; } = string.Empty;
[JsonPropertyName("companyName")]
public string CompanyName { get; init; } = string.Empty;
[JsonPropertyName("eventType")]
public string EventType { get; init; } = string.Empty; // "Quartalsergebnis", "Ex-Dividendentag", "Dividenden-Zahltag"
[JsonPropertyName("date")]
public DateTime Date { get; init; }
}
+130
View File
@@ -0,0 +1,130 @@
using System.Text.Json.Serialization;
namespace FinlyticCore.Dtos;
/// <summary>
/// Generic request payload carrying only a limit parameter (e.g. news_GetPending).
/// </summary>
public record LimitRequest(
[property: JsonPropertyName("limit")] int Limit
);
/// <summary>
/// Generic request payload for paginated queries with optional ISIN filter.
/// </summary>
public record PaginatedRequest(
[property: JsonPropertyName("limit")] int Limit,
[property: JsonPropertyName("offset")] int Offset,
[property: JsonPropertyName("isin")] string? Isin = null
);
/// <summary>
/// Request payload for daily-news queries with optional filters.
/// </summary>
public record DailyNewsRequest(
[property: JsonPropertyName("limit")] int Limit,
[property: JsonPropertyName("offset")] int Offset,
[property: JsonPropertyName("isin")] string? Isin = null,
[property: JsonPropertyName("date")] string? Date = null,
[property: JsonPropertyName("status")] string? Status = null,
[property: JsonPropertyName("query")] string? Query = null,
[property: JsonPropertyName("hasSentiment")] bool? HasSentiment = null
);
/// <summary>
/// Request payload for fetching fundamentals or technical-analysis data by ISIN.
/// </summary>
public record IsinRequest(
[property: JsonPropertyName("isin")] string Isin,
[property: JsonPropertyName("ticker")] string? Ticker = "",
[property: JsonPropertyName("forceRefresh")] bool ForceRefresh = false
);
/// <summary>
/// Request payload for fetching trades filtered by ISIN and/or status.
/// </summary>
public record GetTradesRequest(
[property: JsonPropertyName("isin")] string? Isin = null,
[property: JsonPropertyName("status")] string? Status = null,
[property: JsonPropertyName("userId")] string? UserId = null
);
/// <summary>
/// Request payload for fetching sentiment by article ID.
/// </summary>
public record ArticleRequest(
[property: JsonPropertyName("articleId")] string ArticleId,
[property: JsonPropertyName("id")] string? Id = null
);
/// <summary>
/// Request payload for triggering a manual sentiment analysis for an article or ISIN.
/// </summary>
public record AnalyzeSentimentRequest(
[property: JsonPropertyName("articleId")] string? ArticleId = null,
[property: JsonPropertyName("isin")] string? Isin = null,
[property: JsonPropertyName("forceReload")] bool ForceReload = false
);
/// <summary>
/// Empty request payload for MQTT RPCs that require no parameters (e.g. events_GetAll).
/// </summary>
public record EmptyRequest;
/// <summary>
/// Request payload for triggering a manual AI analysis.
/// </summary>
public record ManualAnalysisRpcRequest(
[property: JsonPropertyName("isin")] string Isin,
[property: JsonPropertyName("symbol")] string Symbol,
[property: JsonPropertyName("sector")] string Sector,
[property: JsonPropertyName("headline")] string Headline,
[property: JsonPropertyName("currentPrice")] decimal CurrentPrice,
[property: JsonPropertyName("riskScore")] int RiskScore,
[property: JsonPropertyName("minTimeframeValue")] int MinTimeframeValue,
[property: JsonPropertyName("maxTimeframeValue")] int MaxTimeframeValue,
[property: JsonPropertyName("timeframeUnit")] string TimeframeUnit,
[property: JsonPropertyName("instrumentType")] string InstrumentType,
[property: JsonPropertyName("userNotes")] string UserNotes,
[property: JsonPropertyName("taData")] FinlyticCore.Dtos.TechnicalAnalysis.TechnicalAnalysisDto? TaData,
[property: JsonPropertyName("fundamentalsData")] FinlyticCore.Dtos.Fundamentals.AssetFundamentalsDto? FundamentalsData,
[property: JsonPropertyName("sentimentData")] FinlyticCore.Dtos.Sentiment.IsinSentimentSummaryDto? SentimentData
);
/// <summary>
/// Response payload returned by microservice health pings over MQTT.
/// </summary>
public record ServiceHealthResponse(
[property: JsonPropertyName("serviceName")] string ServiceName,
[property: JsonPropertyName("status")] string Status,
[property: JsonPropertyName("timestamp")] DateTime Timestamp,
[property: JsonPropertyName("dbStatus")] string DbStatus
);
/// <summary>
/// Response payload for assets_FetchLogo RPC request.
/// </summary>
public record FetchLogoResponse(
[property: JsonPropertyName("isin")] string? Isin,
[property: JsonPropertyName("path")] string? Path,
[property: JsonPropertyName("success")] bool Success
);
/// <summary>
/// Payload published to MQTT when the Admin Panel updates a microservice's configuration.
/// Replaces the anonymous type to be compatible with AOT/source-gen JSON serialization.
/// </summary>
public record ServiceConfigUpdatePayload(
[property: JsonPropertyName("serviceName")] string ServiceName,
[property: JsonPropertyName("timestamp")] DateTime Timestamp,
[property: JsonPropertyName("settings")] Dictionary<string, string> Settings
);
/// <summary>
/// Payload published to MQTT when a live market tick is received.
/// </summary>
public record TickMessageDto(
[property: JsonPropertyName("price")] decimal Price
);
@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace FinlyticCore.Dtos.News;
/// <summary>
/// Represents a news article discovered by a feed/page scanner, carrying parsed metadata such as title, summary, publication date, language, and associated ISINs.
/// </summary>
public record DiscoveredArticle(
[property: JsonPropertyName("url")]
string Url,
[property: JsonPropertyName("isins")]
List<string>? Isins = null,
[property: JsonPropertyName("title")]
string? Title = null,
[property: JsonPropertyName("summary")]
string? Summary = null,
[property: JsonPropertyName("publishedAt")]
DateTime? PublishedAt = null,
[property: JsonPropertyName("language")]
string? Language = null,
[property: JsonPropertyName("sourceName")]
string? SourceName = null
);
+22
View File
@@ -0,0 +1,22 @@
using System.Text.Json.Serialization;
namespace FinlyticCore.Dtos.News;
/// <summary>
/// Data transfer object representing a financial asset matched inside an article.
/// </summary>
public record MatchedAssetDto
{
/// <summary>
/// Gets or sets the name of the matched asset.
/// </summary>
[JsonPropertyName("name")]
public string Name { get; init; } = string.Empty;
/// <summary>
/// Gets or sets the ISIN (International Securities Identification Number) of the matched asset.
/// </summary>
[JsonPropertyName("isin")]
public string Isin { get; init; } = string.Empty;
}
+43
View File
@@ -0,0 +1,43 @@
using System.Text.Json.Serialization;
namespace FinlyticCore.Dtos.News;
/// <summary>
/// Payload representing the pre-filtered asset configuration dispatched to n8n.
/// </summary>
public record FilteredAssetPayload(
[property: JsonPropertyName("Name")] string Name,
[property: JsonPropertyName("Isin")] string Isin
);
/// <summary>
/// Webhook payload structure dispatched to the n8n workflow.
/// </summary>
public record N8nRequestPayload(
[property: JsonPropertyName("article")] string Article,
[property: JsonPropertyName("filtered_assets")] List<FilteredAssetPayload> FilteredAssets
);
/// <summary>
/// Matched asset returned by the n8n AI workflow classification.
/// </summary>
public record N8nMatchedAssetPayload(
[property: JsonPropertyName("ticker")] string? Ticker,
[property: JsonPropertyName("name")] string Name,
[property: JsonPropertyName("confidence_score")] double ConfidenceScore
);
/// <summary>
/// Enriched response payload returned by the n8n workflow webhook.
/// </summary>
public record N8nResponsePayload(
[property: JsonPropertyName("title")] string Title,
[property: JsonPropertyName("author")] string? Author,
[property: JsonPropertyName("published_at")] string? PublishedAt,
[property: JsonPropertyName("scraped_at")] string? ScrapedAt,
[property: JsonPropertyName("source_url")] string SourceUrl,
[property: JsonPropertyName("summary")] string? Summary,
[property: JsonPropertyName("content_raw")] string ContentRaw,
[property: JsonPropertyName("language")] string? Language,
[property: JsonPropertyName("matched_assets")] List<N8nMatchedAssetPayload> MatchedAssets
);
+101
View File
@@ -0,0 +1,101 @@
using System.Text.Json.Serialization;
using FinlyticCore.Dtos.Sentiment;
namespace FinlyticCore.Dtos.News;
/// <summary>
/// Data transfer object representing a parsed and enriched news article with bundled sentiment metrics.
/// </summary>
public record NewsArticleDto
{
/// <summary>
/// Gets or sets the unique article identifier.
/// </summary>
[JsonPropertyName("id")]
public Guid Id { get; init; }
/// <summary>
/// Gets or sets the title of the article.
/// </summary>
[JsonPropertyName("title")]
public string Title { get; init; } = string.Empty;
/// <summary>
/// Gets or sets the author of the article.
/// </summary>
[JsonPropertyName("author")]
public string? Author { get; init; }
/// <summary>
/// Gets or sets a brief summary of the article content.
/// </summary>
[JsonPropertyName("summary")]
public string? Summary { get; init; }
/// <summary>
/// Gets or sets the raw extracted text content of the article.
/// </summary>
[JsonPropertyName("contentRaw")]
public string ContentRaw { get; init; } = string.Empty;
/// <summary>
/// Gets or sets the language of the article (e.g. "en", "de").
/// </summary>
[JsonPropertyName("language")]
public string? Language { get; init; }
/// <summary>
/// Gets or sets the unique source URL of the article.
/// </summary>
[JsonPropertyName("sourceUrl")]
public string SourceUrl { get; init; } = string.Empty;
/// <summary>
/// Gets or sets the timestamp when the article was scraped.
/// </summary>
[JsonPropertyName("scrapedAt")]
public DateTime ScrapedAt { get; init; }
/// <summary>
/// Gets or sets the publication timestamp of the article.
/// </summary>
[JsonPropertyName("publishedAt")]
public DateTime PublishedAt { get; init; }
/// <summary>
/// Gets or sets the list of classified assets referenced in the article.
/// </summary>
[JsonPropertyName("matchedAssets")]
public List<MatchedAssetDto> MatchedAssets { get; init; } = [];
/// <summary>
/// Gets or sets the processing lifecycle state (e.g. "Pending", "Completed", "Analyzed").
/// </summary>
[JsonPropertyName("status")]
public string Status { get; init; } = "Completed";
/// <summary>
/// Gets or sets the classified sentiment label ("POSITIVE", "NEGATIVE", "NEUTRAL").
/// </summary>
[JsonPropertyName("sentiment")]
public string? Sentiment { get; init; }
/// <summary>
/// Gets or sets the compound sentiment score (-1.0 to +1.0).
/// </summary>
[JsonPropertyName("sentimentScore")]
public double? SentimentScore { get; init; }
/// <summary>
/// Gets or sets the FinBERT classification confidence score (0.0 to 1.0).
/// </summary>
[JsonPropertyName("confidence")]
public double? Confidence { get; init; }
/// <summary>
/// Gets or sets the detailed FinBERT result breakdown.
/// </summary>
[JsonPropertyName("finbertResult")]
public FinBertResultDto? FinbertResult { get; init; }
}
+20
View File
@@ -0,0 +1,20 @@
using System.Text.Json.Serialization;
namespace FinlyticCore.Dtos.News;
/// <summary>
/// Request payload sent by downstream services (e.g., FinlyticSentiment) to update the processing status of a news article.
/// </summary>
public record UpdateNewsStatusRequest(
[property: JsonPropertyName("id")] Guid Id,
[property: JsonPropertyName("status")] string Status
);
/// <summary>
/// Response payload returned to verify the success of the status update operation.
/// </summary>
public record UpdateNewsStatusResponse(
[property: JsonPropertyName("success")] bool Success,
[property: JsonPropertyName("message")] string? Message = null
);
@@ -0,0 +1,63 @@
using System.Text.Json.Serialization;
namespace FinlyticCore.Dtos.Sentiment;
/// <summary>
/// Probabilities dictionary containing positive, negative, and neutral softmax scores.
/// </summary>
public record FinBertProbabilities
{
/// <summary>
/// Gets or sets the positive probability score (0.0 to 1.0).
/// </summary>
[JsonPropertyName("positive")]
public double Positive { get; init; }
/// <summary>
/// Gets or sets the negative probability score (0.0 to 1.0).
/// </summary>
[JsonPropertyName("negative")]
public double Negative { get; init; }
/// <summary>
/// Gets or sets the neutral probability score (0.0 to 1.0).
/// </summary>
[JsonPropertyName("neutral")]
public double Neutral { get; init; }
}
/// <summary>
/// Data transfer object holding the result of a FinBERT sentiment analysis.
/// </summary>
public record FinBertResultDto
{
/// <summary>
/// Gets or sets the dominant sentiment label ("POSITIVE", "NEGATIVE", "NEUTRAL").
/// </summary>
[JsonPropertyName("label")]
public string Label { get; init; } = "NEUTRAL";
/// <summary>
/// Gets or sets the compound score (-1.0 to +1.0).
/// </summary>
[JsonPropertyName("compoundScore")]
public double CompoundScore { get; init; }
/// <summary>
/// Gets or sets the highest confidence score (0.0 to 1.0).
/// </summary>
[JsonPropertyName("confidence")]
public double Confidence { get; init; }
/// <summary>
/// Gets or sets the probability breakdown.
/// </summary>
[JsonPropertyName("probabilities")]
public FinBertProbabilities Probabilities { get; init; } = new();
/// <summary>
/// Gets or sets the short summary snippet highlighting the impact of the article.
/// </summary>
[JsonPropertyName("summarySnippet")]
public string? SummarySnippet { get; init; }
}
@@ -0,0 +1,147 @@
using System.Text.Json.Serialization;
namespace FinlyticCore.Dtos.Sentiment;
/// <summary>
/// Article metadata referenced inside an ISIN analysis event.
/// </summary>
public record IsinAnalysisArticleRef
{
/// <summary>
/// Gets or sets the article identifier.
/// </summary>
[JsonPropertyName("articleId")]
public string ArticleId { get; init; } = string.Empty;
/// <summary>
/// Gets or sets the article title.
/// </summary>
[JsonPropertyName("title")]
public string Title { get; init; } = string.Empty;
/// <summary>
/// Gets or sets the article source name.
/// </summary>
[JsonPropertyName("source")]
public string Source { get; init; } = string.Empty;
/// <summary>
/// Gets or sets the publication timestamp in ISO-8601 format.
/// </summary>
[JsonPropertyName("publishedAt")]
public string PublishedAt { get; init; } = string.Empty;
}
/// <summary>
/// Individual chronological analysis entry inside an ISIN summary file.
/// </summary>
public record IsinAnalysisEntry
{
/// <summary>
/// Gets or sets the unique analysis ID (e.g. "sent_20260722_001").
/// </summary>
[JsonPropertyName("analysisId")]
public string AnalysisId { get; init; } = string.Empty;
/// <summary>
/// Gets or sets the analysis timestamp in ISO-8601 format.
/// </summary>
[JsonPropertyName("timestamp")]
public string Timestamp { get; init; } = string.Empty;
/// <summary>
/// Gets or sets the referenced article details.
/// </summary>
[JsonPropertyName("article")]
public IsinAnalysisArticleRef Article { get; init; } = new();
/// <summary>
/// Gets or sets the FinBERT analysis result.
/// </summary>
[JsonPropertyName("finbertResult")]
public FinBertResultDto FinbertResult { get; init; } = new();
/// <summary>
/// Gets or sets the summary snippet.
/// </summary>
[JsonPropertyName("summarySnippet")]
public string SummarySnippet { get; init; } = string.Empty;
}
/// <summary>
/// Current summary aggregate header inside an ISIN sentiment summary file.
/// </summary>
public record IsinCurrentSummary
{
/// <summary>
/// Gets or sets the average compound score (-1.0 to +1.0).
/// </summary>
[JsonPropertyName("compoundScore")]
public double CompoundScore { get; init; }
/// <summary>
/// Gets or sets the overall sentiment label ("POSITIVE", "NEGATIVE", "NEUTRAL").
/// </summary>
[JsonPropertyName("sentimentLabel")]
public string SentimentLabel { get; init; } = "NEUTRAL";
/// <summary>
/// Gets or sets the average confidence across analyzed articles.
/// </summary>
[JsonPropertyName("avgConfidence")]
public double AvgConfidence { get; init; }
/// <summary>
/// Gets or sets the total number of articles analyzed for this ISIN.
/// </summary>
[JsonPropertyName("totalArticlesAnalyzed")]
public int TotalArticlesAnalyzed { get; init; }
/// <summary>
/// Gets or sets the overall synthesized sentiment text overview.
/// </summary>
[JsonPropertyName("text")]
public string Text { get; init; } = string.Empty;
}
/// <summary>
/// Data transfer object for an ISIN sentiment summary file (stored in data/summaries/isin/ISIN.json).
/// </summary>
public record IsinSentimentSummaryDto
{
/// <summary>
/// Gets or sets the ISIN code.
/// </summary>
[JsonPropertyName("isin")]
public string Isin { get; init; } = string.Empty;
/// <summary>
/// Gets or sets the company name.
/// </summary>
[JsonPropertyName("companyName")]
public string CompanyName { get; init; } = string.Empty;
/// <summary>
/// Gets or sets the sector name.
/// </summary>
[JsonPropertyName("sector")]
public string Sector { get; init; } = string.Empty;
/// <summary>
/// Gets or sets the last updated timestamp in ISO-8601 format.
/// </summary>
[JsonPropertyName("lastUpdated")]
public string LastUpdated { get; init; } = string.Empty;
/// <summary>
/// Gets or sets the current summary metrics and overview.
/// </summary>
[JsonPropertyName("currentSummary")]
public IsinCurrentSummary CurrentSummary { get; init; } = new();
/// <summary>
/// Gets or sets the list of historical analysis entries.
/// </summary>
[JsonPropertyName("analyses")]
public List<IsinAnalysisEntry> Analyses { get; init; } = [];
}
@@ -0,0 +1,99 @@
using System.Text.Json.Serialization;
namespace FinlyticCore.Dtos.Sentiment;
/// <summary>
/// Individual analysis entry inside a Sector sentiment summary file.
/// </summary>
public record SectorAnalysisEntry
{
/// <summary>
/// Gets or sets the unique analysis ID.
/// </summary>
[JsonPropertyName("analysisId")]
public string AnalysisId { get; init; } = string.Empty;
/// <summary>
/// Gets or sets the timestamp in ISO-8601 format.
/// </summary>
[JsonPropertyName("timestamp")]
public string Timestamp { get; init; } = string.Empty;
/// <summary>
/// Gets or sets the related asset ISIN.
/// </summary>
[JsonPropertyName("relatedIsin")]
public string RelatedIsin { get; init; } = string.Empty;
/// <summary>
/// Gets or sets the article ID.
/// </summary>
[JsonPropertyName("articleId")]
public string ArticleId { get; init; } = string.Empty;
/// <summary>
/// Gets or sets the FinBERT analysis result.
/// </summary>
[JsonPropertyName("finbertResult")]
public FinBertResultDto FinbertResult { get; init; } = new();
}
/// <summary>
/// Current summary aggregate header inside a Sector sentiment summary file.
/// </summary>
public record SectorCurrentSummary
{
/// <summary>
/// Gets or sets the sector compound score (-1.0 to +1.0).
/// </summary>
[JsonPropertyName("compoundScore")]
public double CompoundScore { get; init; }
/// <summary>
/// Gets or sets the overall sector sentiment label ("POSITIVE", "NEGATIVE", "NEUTRAL").
/// </summary>
[JsonPropertyName("sentimentLabel")]
public string SentimentLabel { get; init; } = "NEUTRAL";
/// <summary>
/// Gets or sets the list of active asset ISINs influencing the sector.
/// </summary>
[JsonPropertyName("activeIsins")]
public List<string> ActiveIsins { get; init; } = [];
/// <summary>
/// Gets or sets the overview text for the sector.
/// </summary>
[JsonPropertyName("text")]
public string Text { get; init; } = string.Empty;
}
/// <summary>
/// Data transfer object for a Sector sentiment summary file (stored in data/summaries/sectors/SectorName.json).
/// </summary>
public record SectorSentimentSummaryDto
{
/// <summary>
/// Gets or sets the sector name.
/// </summary>
[JsonPropertyName("sector")]
public string Sector { get; init; } = string.Empty;
/// <summary>
/// Gets or sets the last updated timestamp in ISO-8601 format.
/// </summary>
[JsonPropertyName("lastUpdated")]
public string LastUpdated { get; init; } = string.Empty;
/// <summary>
/// Gets or sets the current sector summary metrics and overview.
/// </summary>
[JsonPropertyName("currentSummary")]
public SectorCurrentSummary CurrentSummary { get; init; } = new();
/// <summary>
/// Gets or sets the list of historical sector analysis entries.
/// </summary>
[JsonPropertyName("analyses")]
public List<SectorAnalysisEntry> Analyses { get; init; } = [];
}
@@ -0,0 +1,15 @@
using System;
using System.Text.Json.Serialization;
namespace FinlyticCore.Dtos.TechnicalAnalysis;
public record CandleDto(
[property: JsonPropertyName("timestamp")] DateTime Timestamp,
[property: JsonPropertyName("open")] decimal Open,
[property: JsonPropertyName("high")] decimal High,
[property: JsonPropertyName("low")] decimal Low,
[property: JsonPropertyName("close")] decimal Close,
[property: JsonPropertyName("volume")] long Volume,
[property: JsonPropertyName("bid")] decimal? Bid = null,
[property: JsonPropertyName("ask")] decimal? Ask = null
);
@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace FinlyticCore.Dtos.TechnicalAnalysis;
public record PatternPointDto(
[property: JsonPropertyName("time")] DateTime Time,
[property: JsonPropertyName("price")] decimal Price
);
public record BreakoutSignalDto(
[property: JsonPropertyName("time")] DateTime Time,
[property: JsonPropertyName("direction")] string Direction, // "BUY" or "SELL"
[property: JsonPropertyName("triggerPrice")] decimal TriggerPrice,
[property: JsonPropertyName("targetPrice")] decimal TargetPrice,
[property: JsonPropertyName("potentialPercent")] decimal? PotentialPercent = null
);
public record ChartPatternDto(
[property: JsonPropertyName("type")] string Type, // "AscendingTriangle", "DescendingTriangle", "SymmetricalTriangle", "DoubleBottom", "DoubleTop", "HeadAndShoulders"
[property: JsonPropertyName("description")] string? Description,
[property: JsonPropertyName("upperLine")] List<PatternPointDto> UpperLine,
[property: JsonPropertyName("lowerLine")] List<PatternPointDto> LowerLine,
[property: JsonPropertyName("apexTime")] DateTime? ApexTime,
[property: JsonPropertyName("breakoutSignal")] BreakoutSignalDto? BreakoutSignal,
[property: JsonPropertyName("confidencePercent")] decimal? ConfidencePercent = null
);
@@ -0,0 +1,21 @@
using System;
using System.Text.Json.Serialization;
namespace FinlyticCore.Dtos.TechnicalAnalysis;
public record IndicatorValuesDto(
[property: JsonPropertyName("timestamp")] DateTime Timestamp,
[property: JsonPropertyName("ema20")] decimal? Ema20,
[property: JsonPropertyName("sma50")] decimal? Sma50,
[property: JsonPropertyName("sma200")] decimal? Sma200,
[property: JsonPropertyName("rsi14")] decimal? Rsi14,
[property: JsonPropertyName("macdLine")] decimal? MacdLine,
[property: JsonPropertyName("macdSignal")] decimal? MacdSignal,
[property: JsonPropertyName("macdHistogram")] decimal? MacdHistogram,
[property: JsonPropertyName("atr14")] decimal? Atr14,
[property: JsonPropertyName("vwap")] decimal? Vwap,
[property: JsonPropertyName("supertrendUpper")] decimal? SupertrendUpper,
[property: JsonPropertyName("supertrendLower")] decimal? SupertrendLower,
[property: JsonPropertyName("supertrendDirection")] string? SupertrendDirection,
[property: JsonPropertyName("recommendedStopLoss")] decimal? RecommendedStopLoss
);
@@ -0,0 +1,16 @@
using System.Text.Json.Serialization;
namespace FinlyticCore.Dtos.TechnicalAnalysis;
public record LivePriceDto(
[property: JsonPropertyName("isin")]
string Isin,
[property: JsonPropertyName("currentPrice")]
decimal CurrentPrice,
[property: JsonPropertyName("dailyChangePercent")]
decimal DailyChangePercent,
[property: JsonPropertyName("bid")]
decimal? Bid,
[property: JsonPropertyName("ask")]
decimal? Ask
);
@@ -0,0 +1,12 @@
using System.Text.Json.Serialization;
namespace FinlyticCore.Dtos.TechnicalAnalysis;
public record MarketRegimeDto(
[property: JsonPropertyName("vixValue")] decimal VixValue,
[property: JsonPropertyName("vixRegime")] string VixRegime, // "LowVolatility", "Moderate", "HighVolatility" (>25)
[property: JsonPropertyName("marketTrend")] string MarketTrend, // "Bullish", "Bearish"
[property: JsonPropertyName("dxyValue")] decimal DxyValue,
[property: JsonPropertyName("dxyState")] string DxyState, // "DollarStrengthening", "DollarWeakening"
[property: JsonPropertyName("summaryText")] string SummaryText
);
@@ -0,0 +1,12 @@
using System;
using System.Text.Json.Serialization;
namespace FinlyticCore.Dtos.TechnicalAnalysis;
public record StrategySignalDto(
[property: JsonPropertyName("type")] string Type, // "GoldenCross", "DeathCross", "RsiDivergenceBullish", "RsiDivergenceBearish", "Breakout"
[property: JsonPropertyName("timestamp")] DateTime Timestamp,
[property: JsonPropertyName("direction")] string Direction, // "BUY", "SELL", "NEUTRAL"
[property: JsonPropertyName("price")] decimal Price,
[property: JsonPropertyName("description")] string Description
);
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace FinlyticCore.Dtos.TechnicalAnalysis;
public record TechnicalAnalysisDto(
[property: JsonPropertyName("isin")] string Isin,
[property: JsonPropertyName("ticker")] string Ticker,
[property: JsonPropertyName("companyName")] string CompanyName,
[property: JsonPropertyName("lastUpdated")] DateTime LastUpdated,
[property: JsonPropertyName("candles")] List<CandleDto> Candles,
[property: JsonPropertyName("indicators")] List<IndicatorValuesDto> Indicators,
[property: JsonPropertyName("patterns")] List<ChartPatternDto> Patterns,
[property: JsonPropertyName("signals")] List<StrategySignalDto> Signals,
[property: JsonPropertyName("marketRegime")] MarketRegimeDto MarketRegime,
[property: JsonPropertyName("currency")] string Currency = "EUR"
);
+66
View File
@@ -0,0 +1,66 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace FinlyticCore.Dtos.Yahoo;
/// <summary>
/// Response object for Yahoo Finance chart API (/v8/finance/chart/{symbol}).
/// </summary>
public record YahooChartResponseDto(
[property: JsonPropertyName("chart")] YahooChartResultWrapperDto? Chart
);
public record YahooChartResultWrapperDto(
[property: JsonPropertyName("result")] List<YahooChartResultDto>? Result,
[property: JsonPropertyName("error")] object? Error
);
public record YahooChartResultDto(
[property: JsonPropertyName("meta")] YahooChartMetaDto? Meta,
[property: JsonPropertyName("timestamp")] List<long>? Timestamp,
[property: JsonPropertyName("indicators")] YahooChartIndicatorsDto? Indicators
);
public record YahooChartMetaDto(
[property: JsonPropertyName("currency")] string? Currency,
[property: JsonPropertyName("symbol")] string? Symbol,
[property: JsonPropertyName("exchangeName")] string? ExchangeName,
[property: JsonPropertyName("fullExchangeName")] string? FullExchangeName,
[property: JsonPropertyName("instrumentType")] string? InstrumentType,
[property: JsonPropertyName("firstTradeDate")] long? FirstTradeDate,
[property: JsonPropertyName("regularMarketTime")] long? RegularMarketTime,
[property: JsonPropertyName("hasPrePostMarketData")] bool? HasPrePostMarketData,
[property: JsonPropertyName("gmtoffset")] int? GmtOffset,
[property: JsonPropertyName("timezone")] string? Timezone,
[property: JsonPropertyName("exchangeTimezoneName")] string? ExchangeTimezoneName,
[property: JsonPropertyName("regularMarketPrice")] double? RegularMarketPrice,
[property: JsonPropertyName("fiftyTwoWeekHigh")] double? FiftyTwoWeekHigh,
[property: JsonPropertyName("fiftyTwoWeekLow")] double? FiftyTwoWeekLow,
[property: JsonPropertyName("regularMarketDayHigh")] double? RegularMarketDayHigh,
[property: JsonPropertyName("regularMarketDayLow")] double? RegularMarketDayLow,
[property: JsonPropertyName("regularMarketVolume")] long? RegularMarketVolume,
[property: JsonPropertyName("chartPreviousClose")] double? ChartPreviousClose,
[property: JsonPropertyName("previousClose")] double? PreviousClose,
[property: JsonPropertyName("scale")] int? Scale,
[property: JsonPropertyName("priceHint")] int? PriceHint,
[property: JsonPropertyName("dataGranularity")] string? DataGranularity,
[property: JsonPropertyName("range")] string? Range,
[property: JsonPropertyName("validRanges")] List<string>? ValidRanges
);
public record YahooChartIndicatorsDto(
[property: JsonPropertyName("quote")] List<YahooChartQuoteDto>? Quote,
[property: JsonPropertyName("adjclose")] List<YahooChartAdjCloseDto>? AdjClose
);
public record YahooChartQuoteDto(
[property: JsonPropertyName("open")] List<double?>? Open,
[property: JsonPropertyName("high")] List<double?>? High,
[property: JsonPropertyName("low")] List<double?>? Low,
[property: JsonPropertyName("close")] List<double?>? Close,
[property: JsonPropertyName("volume")] List<long?>? Volume
);
public record YahooChartAdjCloseDto(
[property: JsonPropertyName("adjclose")] List<double?>? AdjClose
);
+64
View File
@@ -0,0 +1,64 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace FinlyticCore.Dtos.Yahoo;
/// <summary>
/// Response object for Yahoo Finance quick quotes API (/v7/finance/quote?symbols=...).
/// </summary>
public record YahooQuoteResponseDto(
[property: JsonPropertyName("quoteResponse")] YahooQuoteResultWrapperDto? QuoteResponse
);
public record YahooQuoteResultWrapperDto(
[property: JsonPropertyName("result")] List<YahooQuoteItemDto>? Result,
[property: JsonPropertyName("error")] object? Error
);
public record YahooQuoteItemDto(
[property: JsonPropertyName("language")] string? Language,
[property: JsonPropertyName("region")] string? Region,
[property: JsonPropertyName("quoteType")] string? QuoteType,
[property: JsonPropertyName("typeDisp")] string? TypeDisp,
[property: JsonPropertyName("quoteSourceName")] string? QuoteSourceName,
[property: JsonPropertyName("triggerable")] bool? Triggerable,
[property: JsonPropertyName("customPriceAlertConfidence")] string? CustomPriceAlertConfidence,
[property: JsonPropertyName("currency")] string? Currency,
[property: JsonPropertyName("marketState")] string? MarketState,
[property: JsonPropertyName("exchange")] string? Exchange,
[property: JsonPropertyName("shortName")] string? ShortName,
[property: JsonPropertyName("longName")] string? LongName,
[property: JsonPropertyName("messageBoardId")] string? MessageBoardId,
[property: JsonPropertyName("exchangeTimezoneName")] string? ExchangeTimezoneName,
[property: JsonPropertyName("exchangeTimezoneShortName")] string? ExchangeTimezoneShortName,
[property: JsonPropertyName("gmtOffSetMilliseconds")] long? GmtOffSetMilliseconds,
[property: JsonPropertyName("market")] string? Market,
[property: JsonPropertyName("esgPopulated")] bool? EsgPopulated,
[property: JsonPropertyName("regularMarketChangePercent")] double? RegularMarketChangePercent,
[property: JsonPropertyName("regularMarketPrice")] double? RegularMarketPrice,
[property: JsonPropertyName("regularMarketChange")] double? RegularMarketChange,
[property: JsonPropertyName("regularMarketTime")] long? RegularMarketTime,
[property: JsonPropertyName("regularMarketDayHigh")] double? RegularMarketDayHigh,
[property: JsonPropertyName("regularMarketDayRange")] string? RegularMarketDayRange,
[property: JsonPropertyName("regularMarketDayLow")] double? RegularMarketDayLow,
[property: JsonPropertyName("regularMarketVolume")] long? RegularMarketVolume,
[property: JsonPropertyName("regularMarketPreviousClose")] double? RegularMarketPreviousClose,
[property: JsonPropertyName("bid")] double? Bid,
[property: JsonPropertyName("ask")] double? Ask,
[property: JsonPropertyName("bidSize")] long? BidSize,
[property: JsonPropertyName("askSize")] long? AskSize,
[property: JsonPropertyName("fullExchangeName")] string? FullExchangeName,
[property: JsonPropertyName("financialCurrency")] string? FinancialCurrency,
[property: JsonPropertyName("regularMarketOpen")] double? RegularMarketOpen,
[property: JsonPropertyName("averageDailyVolume3Month")] long? AverageDailyVolume3Month,
[property: JsonPropertyName("averageDailyVolume10Day")] long? AverageDailyVolume10Day,
[property: JsonPropertyName("fiftyTwoWeekLowChange")] double? FiftyTwoWeekLowChange,
[property: JsonPropertyName("fiftyTwoWeekLowChangePercent")] double? FiftyTwoWeekLowChangePercent,
[property: JsonPropertyName("fiftyTwoWeekRange")] string? FiftyTwoWeekRange,
[property: JsonPropertyName("fiftyTwoWeekHighChange")] double? FiftyTwoWeekHighChange,
[property: JsonPropertyName("fiftyTwoWeekHighChangePercent")] double? FiftyTwoWeekHighChangePercent,
[property: JsonPropertyName("fiftyTwoWeekLow")] double? FiftyTwoWeekLow,
[property: JsonPropertyName("fiftyTwoWeekHigh")] double? FiftyTwoWeekHigh,
[property: JsonPropertyName("marketCap")] double? MarketCap,
[property: JsonPropertyName("symbol")] string Symbol = ""
);
@@ -0,0 +1,282 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace FinlyticCore.Dtos.Yahoo;
/// <summary>
/// Root response object for Yahoo Finance quoteSummary API (/v10/finance/quoteSummary/{symbol}).
/// </summary>
public record YahooQuoteSummaryResponseDto(
[property: JsonPropertyName("quoteSummary")] YahooQuoteSummaryResultDto? QuoteSummary
);
public record YahooQuoteSummaryResultDto(
[property: JsonPropertyName("result")] List<YahooQuoteSummaryModulesDto>? Result,
[property: JsonPropertyName("error")] object? Error
);
/// <summary>
/// Contains module blocks requested via the modules query parameter.
/// </summary>
public record YahooQuoteSummaryModulesDto(
[property: JsonPropertyName("assetProfile")] YahooAssetProfileDto? AssetProfile,
[property: JsonPropertyName("financialData")] YahooFinancialDataDto? FinancialData,
[property: JsonPropertyName("defaultKeyStatistics")] YahooDefaultKeyStatisticsDto? DefaultKeyStatistics,
[property: JsonPropertyName("summaryDetail")] YahooSummaryDetailDto? SummaryDetail,
[property: JsonPropertyName("incomeStatementHistory")] YahooFinancialStatementHistoryDto? IncomeStatementHistory,
[property: JsonPropertyName("incomeStatementHistoryQuarterly")] YahooFinancialStatementHistoryDto? IncomeStatementHistoryQuarterly,
[property: JsonPropertyName("balanceSheetHistory")] YahooFinancialStatementHistoryDto? BalanceSheetHistory,
[property: JsonPropertyName("balanceSheetHistoryQuarterly")] YahooFinancialStatementHistoryDto? BalanceSheetHistoryQuarterly,
[property: JsonPropertyName("cashflowStatementHistory")] YahooFinancialStatementHistoryDto? CashflowStatementHistory,
[property: JsonPropertyName("cashflowStatementHistoryQuarterly")] YahooFinancialStatementHistoryDto? CashflowStatementHistoryQuarterly,
[property: JsonPropertyName("calendarEvents")] YahooCalendarEventsDto? CalendarEvents
);
#region Module DTOs
/// <summary>
/// Asset profile details including address, industry, sector, officers, and corporate governance risks.
/// </summary>
public record YahooAssetProfileDto(
[property: JsonPropertyName("address1")] string? Address1,
[property: JsonPropertyName("address2")] string? Address2,
[property: JsonPropertyName("city")] string? City,
[property: JsonPropertyName("state")] string? State,
[property: JsonPropertyName("zip")] string? Zip,
[property: JsonPropertyName("country")] string? Country,
[property: JsonPropertyName("phone")] string? Phone,
[property: JsonPropertyName("website")] string? Website,
[property: JsonPropertyName("industry")] string? Industry,
[property: JsonPropertyName("industryKey")] string? IndustryKey,
[property: JsonPropertyName("industryDisp")] string? IndustryDisp,
[property: JsonPropertyName("sector")] string? Sector,
[property: JsonPropertyName("sectorKey")] string? SectorKey,
[property: JsonPropertyName("sectorDisp")] string? SectorDisp,
[property: JsonPropertyName("longBusinessSummary")] string? LongBusinessSummary,
[property: JsonPropertyName("fullTimeEmployees")] int? FullTimeEmployees,
[property: JsonPropertyName("companyOfficers")] List<YahooCompanyOfficerDto>? CompanyOfficers,
[property: JsonPropertyName("auditRisk")] int? AuditRisk,
[property: JsonPropertyName("boardRisk")] int? BoardRisk,
[property: JsonPropertyName("compensationRisk")] int? CompensationRisk,
[property: JsonPropertyName("shareHolderRightsRisk")] int? ShareHolderRightsRisk,
[property: JsonPropertyName("overallRisk")] int? OverallRisk,
[property: JsonPropertyName("governanceEpochDate")] long? GovernanceEpochDate,
[property: JsonPropertyName("compensationAsOfEpochDate")] long? CompensationAsOfEpochDate
);
public record YahooCompanyOfficerDto(
[property: JsonPropertyName("name")] string? Name,
[property: JsonPropertyName("age")] int? Age,
[property: JsonPropertyName("title")] string? Title,
[property: JsonPropertyName("yearBorn")] int? YearBorn,
[property: JsonPropertyName("fiscalYear")] int? FiscalYear,
[property: JsonPropertyName("totalPay")] YahooValueDto? TotalPay,
[property: JsonPropertyName("exercisedValue")] YahooValueDto? ExercisedValue,
[property: JsonPropertyName("unexercisedValue")] YahooValueDto? UnexercisedValue
);
/// <summary>
/// Financial metrics including target prices, debt to equity, margins, and cash flow indicators.
/// </summary>
public record YahooFinancialDataDto(
[property: JsonPropertyName("currentPrice")] YahooValueDto? CurrentPrice,
[property: JsonPropertyName("targetHighPrice")] YahooValueDto? TargetHighPrice,
[property: JsonPropertyName("targetLowPrice")] YahooValueDto? TargetLowPrice,
[property: JsonPropertyName("targetMeanPrice")] YahooValueDto? TargetMeanPrice,
[property: JsonPropertyName("targetMedianPrice")] YahooValueDto? TargetMedianPrice,
[property: JsonPropertyName("recommendationMean")] YahooValueDto? RecommendationMean,
[property: JsonPropertyName("recommendationKey")] string? RecommendationKey,
[property: JsonPropertyName("numberOfAnalystOpinions")] YahooValueDto? NumberOfAnalystOpinions,
[property: JsonPropertyName("totalCash")] YahooValueDto? TotalCash,
[property: JsonPropertyName("totalCashPerShare")] YahooValueDto? TotalCashPerShare,
[property: JsonPropertyName("ebitda")] YahooValueDto? Ebitda,
[property: JsonPropertyName("totalDebt")] YahooValueDto? TotalDebt,
[property: JsonPropertyName("quickRatio")] YahooValueDto? QuickRatio,
[property: JsonPropertyName("currentRatio")] YahooValueDto? CurrentRatio,
[property: JsonPropertyName("totalRevenue")] YahooValueDto? TotalRevenue,
[property: JsonPropertyName("debtToEquity")] YahooValueDto? DebtToEquity,
[property: JsonPropertyName("revenuePerShare")] YahooValueDto? RevenuePerShare,
[property: JsonPropertyName("returnOnAssets")] YahooValueDto? ReturnOnAssets,
[property: JsonPropertyName("returnOnEquity")] YahooValueDto? ReturnOnEquity,
[property: JsonPropertyName("grossProfits")] YahooValueDto? GrossProfits,
[property: JsonPropertyName("freeCashflow")] YahooValueDto? FreeCashflow,
[property: JsonPropertyName("operatingCashflow")] YahooValueDto? OperatingCashflow,
[property: JsonPropertyName("revenueGrowth")] YahooValueDto? RevenueGrowth,
[property: JsonPropertyName("grossMargins")] YahooValueDto? GrossMargins,
[property: JsonPropertyName("ebitdaMargins")] YahooValueDto? EbitdaMargins,
[property: JsonPropertyName("operatingMargins")] YahooValueDto? OperatingMargins,
[property: JsonPropertyName("profitMargins")] YahooValueDto? ProfitMargins,
[property: JsonPropertyName("financialCurrency")] string? FinancialCurrency
);
/// <summary>
/// Key statistics including valuation ratios (P/E, Enterprise Value, Short Ratio, Shares Outstanding).
/// </summary>
public record YahooDefaultKeyStatisticsDto(
[property: JsonPropertyName("priceToBook")] YahooValueDto? PriceToBook,
[property: JsonPropertyName("enterpriseValue")] YahooValueDto? EnterpriseValue,
[property: JsonPropertyName("forwardPE")] YahooValueDto? ForwardPE,
[property: JsonPropertyName("profitMargins")] YahooValueDto? ProfitMargins,
[property: JsonPropertyName("floatShares")] YahooValueDto? FloatShares,
[property: JsonPropertyName("sharesOutstanding")] YahooValueDto? SharesOutstanding,
[property: JsonPropertyName("sharesShort")] YahooValueDto? SharesShort,
[property: JsonPropertyName("sharesShortPriorMonth")] YahooValueDto? SharesShortPriorMonth,
[property: JsonPropertyName("sharesShortPreviousMonthDate")] YahooValueDto? SharesShortPreviousMonthDate,
[property: JsonPropertyName("dateShortInterest")] YahooValueDto? DateShortInterest,
[property: JsonPropertyName("sharesPercentSharesOut")] YahooValueDto? SharesPercentSharesOut,
[property: JsonPropertyName("heldPercentInsiders")] YahooValueDto? HeldPercentInsiders,
[property: JsonPropertyName("heldPercentInstitutions")] YahooValueDto? HeldPercentInstitutions,
[property: JsonPropertyName("shortRatio")] YahooValueDto? ShortRatio,
[property: JsonPropertyName("shortPercentOfFloat")] YahooValueDto? ShortPercentOfFloat,
[property: JsonPropertyName("beta")] YahooValueDto? Beta,
[property: JsonPropertyName("category")] string? Category,
[property: JsonPropertyName("bookValue")] YahooValueDto? BookValue,
[property: JsonPropertyName("priceToSalesTrailing12Months")] YahooValueDto? PriceToSalesTrailing12Months,
[property: JsonPropertyName("lastFiscalYearEnd")] YahooValueDto? LastFiscalYearEnd,
[property: JsonPropertyName("nextFiscalYearEnd")] YahooValueDto? NextFiscalYearEnd,
[property: JsonPropertyName("mostRecentQuarter")] YahooValueDto? MostRecentQuarter,
[property: JsonPropertyName("earningsQuarterlyGrowth")] YahooValueDto? EarningsQuarterlyGrowth,
[property: JsonPropertyName("netIncomeToCommon")] YahooValueDto? NetIncomeToCommon,
[property: JsonPropertyName("trailingEps")] YahooValueDto? TrailingEps,
[property: JsonPropertyName("forwardEps")] YahooValueDto? ForwardEps,
[property: JsonPropertyName("pegRatio")] YahooValueDto? PegRatio,
[property: JsonPropertyName("enterpriseToRevenue")] YahooValueDto? EnterpriseToRevenue,
[property: JsonPropertyName("enterpriseToEbitda")] YahooValueDto? EnterpriseToEbitda,
[property: JsonPropertyName("52WeekChange")] YahooValueDto? FiftyTwoWeekChange,
[property: JsonPropertyName("SandP52WeekChange")] YahooValueDto? SandP52WeekChange
);
/// <summary>
/// Summary details including dividends, 52-week ranges, and market capitalization.
/// </summary>
public record YahooSummaryDetailDto(
[property: JsonPropertyName("maxAge")] long? MaxAge,
[property: JsonPropertyName("priceHint")] YahooValueDto? PriceHint,
[property: JsonPropertyName("previousClose")] YahooValueDto? PreviousClose,
[property: JsonPropertyName("open")] YahooValueDto? Open,
[property: JsonPropertyName("dayLow")] YahooValueDto? DayLow,
[property: JsonPropertyName("dayHigh")] YahooValueDto? DayHigh,
[property: JsonPropertyName("regularMarketPreviousClose")] YahooValueDto? RegularMarketPreviousClose,
[property: JsonPropertyName("regularMarketOpen")] YahooValueDto? RegularMarketOpen,
[property: JsonPropertyName("regularMarketDayLow")] YahooValueDto? RegularMarketDayLow,
[property: JsonPropertyName("regularMarketDayHigh")] YahooValueDto? RegularMarketDayHigh,
[property: JsonPropertyName("dividendRate")] YahooValueDto? DividendRate,
[property: JsonPropertyName("dividendYield")] YahooValueDto? DividendYield,
[property: JsonPropertyName("exDividendDate")] YahooValueDto? ExDividendDate,
[property: JsonPropertyName("payoutRatio")] YahooValueDto? PayoutRatio,
[property: JsonPropertyName("fiveYearAvgDividendYield")] YahooValueDto? FiveYearAvgDividendYield,
[property: JsonPropertyName("beta")] YahooValueDto? Beta,
[property: JsonPropertyName("trailingPE")] YahooValueDto? TrailingPE,
[property: JsonPropertyName("forwardPE")] YahooValueDto? ForwardPE,
[property: JsonPropertyName("volume")] YahooValueDto? Volume,
[property: JsonPropertyName("regularMarketVolume")] YahooValueDto? RegularMarketVolume,
[property: JsonPropertyName("averageVolume")] YahooValueDto? AverageVolume,
[property: JsonPropertyName("averageVolume10days")] YahooValueDto? AverageVolume10days,
[property: JsonPropertyName("averageDailyVolume10Day")] YahooValueDto? AverageDailyVolume10Day,
[property: JsonPropertyName("bid")] YahooValueDto? Bid,
[property: JsonPropertyName("ask")] YahooValueDto? Ask,
[property: JsonPropertyName("bidSize")] YahooValueDto? BidSize,
[property: JsonPropertyName("askSize")] YahooValueDto? AskSize,
[property: JsonPropertyName("marketCap")] YahooValueDto? MarketCap,
[property: JsonPropertyName("fiftyTwoWeekLow")] YahooValueDto? FiftyTwoWeekLow,
[property: JsonPropertyName("fiftyTwoWeekHigh")] YahooValueDto? FiftyTwoWeekHigh,
[property: JsonPropertyName("priceToSalesTrailing12Months")] YahooValueDto? PriceToSalesTrailing12Months,
[property: JsonPropertyName("currency")] string? Currency
);
/// <summary>
/// Historical financial statements container.
/// </summary>
public record YahooFinancialStatementHistoryDto(
[property: JsonPropertyName("incomeStatementHistory")] List<YahooIncomeStatementDto>? IncomeStatementHistory,
[property: JsonPropertyName("balanceSheetStatements")] List<YahooBalanceSheetStatementDto>? BalanceSheetStatements,
[property: JsonPropertyName("cashflowStatements")] List<YahooCashflowStatementDto>? CashflowStatements
);
public record YahooIncomeStatementDto(
[property: JsonPropertyName("endDate")] YahooValueDto? EndDate,
[property: JsonPropertyName("totalRevenue")] YahooValueDto? TotalRevenue,
[property: JsonPropertyName("costOfRevenue")] YahooValueDto? CostOfRevenue,
[property: JsonPropertyName("grossProfit")] YahooValueDto? GrossProfit,
[property: JsonPropertyName("researchDevelopment")] YahooValueDto? ResearchDevelopment,
[property: JsonPropertyName("sellingGeneralAdministrative")] YahooValueDto? SellingGeneralAdministrative,
[property: JsonPropertyName("totalOperatingExpenses")] YahooValueDto? TotalOperatingExpenses,
[property: JsonPropertyName("operatingIncome")] YahooValueDto? OperatingIncome,
[property: JsonPropertyName("totalOtherIncomeExpenseNet")] YahooValueDto? TotalOtherIncomeExpenseNet,
[property: JsonPropertyName("ebit")] YahooValueDto? Ebit,
[property: JsonPropertyName("interestExpense")] YahooValueDto? InterestExpense,
[property: JsonPropertyName("incomeBeforeTax")] YahooValueDto? IncomeBeforeTax,
[property: JsonPropertyName("incomeTaxExpense")] YahooValueDto? IncomeTaxExpense,
[property: JsonPropertyName("netIncome")] YahooValueDto? NetIncome,
[property: JsonPropertyName("netIncomeApplicableToCommonShares")] YahooValueDto? NetIncomeApplicableToCommonShares
);
public record YahooBalanceSheetStatementDto(
[property: JsonPropertyName("endDate")] YahooValueDto? EndDate,
[property: JsonPropertyName("cash")] YahooValueDto? Cash,
[property: JsonPropertyName("shortTermInvestments")] YahooValueDto? ShortTermInvestments,
[property: JsonPropertyName("netReceivables")] YahooValueDto? NetReceivables,
[property: JsonPropertyName("inventory")] YahooValueDto? Inventory,
[property: JsonPropertyName("otherCurrentAssets")] YahooValueDto? OtherCurrentAssets,
[property: JsonPropertyName("totalCurrentAssets")] YahooValueDto? TotalCurrentAssets,
[property: JsonPropertyName("longTermInvestments")] YahooValueDto? LongTermInvestments,
[property: JsonPropertyName("propertyPlantEquipment")] YahooValueDto? PropertyPlantEquipment,
[property: JsonPropertyName("goodWill")] YahooValueDto? GoodWill,
[property: JsonPropertyName("intangibleAssets")] YahooValueDto? IntangibleAssets,
[property: JsonPropertyName("otherAssets")] YahooValueDto? OtherAssets,
[property: JsonPropertyName("totalAssets")] YahooValueDto? TotalAssets,
[property: JsonPropertyName("accountsPayable")] YahooValueDto? AccountsPayable,
[property: JsonPropertyName("shortLongTermDebt")] YahooValueDto? ShortLongTermDebt,
[property: JsonPropertyName("otherCurrentLiabilities")] YahooValueDto? OtherCurrentLiabilities,
[property: JsonPropertyName("totalCurrentLiabilities")] YahooValueDto? TotalCurrentLiabilities,
[property: JsonPropertyName("longTermDebt")] YahooValueDto? LongTermDebt,
[property: JsonPropertyName("otherLiabilities")] YahooValueDto? OtherLiabilities,
[property: JsonPropertyName("totalLiab")] YahooValueDto? TotalLiab,
[property: JsonPropertyName("commonStock")] YahooValueDto? CommonStock,
[property: JsonPropertyName("retainedEarnings")] YahooValueDto? RetainedEarnings,
[property: JsonPropertyName("treasuryStock")] YahooValueDto? TreasuryStock,
[property: JsonPropertyName("otherStockholderEquity")] YahooValueDto? OtherStockholderEquity,
[property: JsonPropertyName("totalStockholderEquity")] YahooValueDto? TotalStockholderEquity
);
public record YahooCashflowStatementDto(
[property: JsonPropertyName("endDate")] YahooValueDto? EndDate,
[property: JsonPropertyName("netIncome")] YahooValueDto? NetIncome,
[property: JsonPropertyName("depreciation")] YahooValueDto? Depreciation,
[property: JsonPropertyName("changeToNetincome")] YahooValueDto? ChangeToNetincome,
[property: JsonPropertyName("changeToAccountReceivables")] YahooValueDto? ChangeToAccountReceivables,
[property: JsonPropertyName("changeToLiabilities")] YahooValueDto? ChangeToLiabilities,
[property: JsonPropertyName("changeToInventory")] YahooValueDto? ChangeToInventory,
[property: JsonPropertyName("changeToOperatingActivities")] YahooValueDto? ChangeToOperatingActivities,
[property: JsonPropertyName("totalCashFromOperatingActivities")] YahooValueDto? TotalCashFromOperatingActivities,
[property: JsonPropertyName("capitalExpenditures")] YahooValueDto? CapitalExpenditures,
[property: JsonPropertyName("investments")] YahooValueDto? Investments,
[property: JsonPropertyName("otherCashflowsFromInvestingActivities")] YahooValueDto? OtherCashflowsFromInvestingActivities,
[property: JsonPropertyName("totalCashflowsFromInvestingActivities")] YahooValueDto? TotalCashflowsFromInvestingActivities,
[property: JsonPropertyName("dividendsPaid")] YahooValueDto? DividendsPaid,
[property: JsonPropertyName("netBorrowings")] YahooValueDto? NetBorrowings,
[property: JsonPropertyName("otherCashflowsFromFinancingActivities")] YahooValueDto? OtherCashflowsFromFinancingActivities,
[property: JsonPropertyName("totalCashFromFinancingActivities")] YahooValueDto? TotalCashFromFinancingActivities,
[property: JsonPropertyName("changeInCashAndCashEquivalents")] YahooValueDto? ChangeInCashAndCashEquivalents
);
/// <summary>
/// Corporate calendar dates including upcoming earnings calls and ex-dividend dates.
/// </summary>
public record YahooCalendarEventsDto(
[property: JsonPropertyName("earnings")] YahooEarningsCalendarDto? Earnings,
[property: JsonPropertyName("exDividendDate")] YahooValueDto? ExDividendDate,
[property: JsonPropertyName("dividendDate")] YahooValueDto? DividendDate
);
public record YahooEarningsCalendarDto(
[property: JsonPropertyName("earningsDate")] List<YahooValueDto>? EarningsDate,
[property: JsonPropertyName("earningsAverage")] YahooValueDto? EarningsAverage,
[property: JsonPropertyName("earningsLow")] YahooValueDto? EarningsLow,
[property: JsonPropertyName("earningsHigh")] YahooValueDto? EarningsHigh,
[property: JsonPropertyName("revenueAverage")] YahooValueDto? RevenueAverage,
[property: JsonPropertyName("revenueLow")] YahooValueDto? RevenueLow,
[property: JsonPropertyName("revenueHigh")] YahooValueDto? RevenueHigh
);
#endregion
@@ -0,0 +1,73 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace FinlyticCore.Dtos.Yahoo;
/// <summary>
/// Root DTO response returned by https://query2.finance.yahoo.com/v1/finance/search
/// </summary>
public class YahooSearchResponseDto
{
[JsonPropertyName("count")]
public int Count { get; set; }
[JsonPropertyName("quotes")]
public List<YahooSearchQuoteDto> Quotes { get; set; } = new();
[JsonPropertyName("totalTime")]
public int TotalTime { get; set; }
[JsonPropertyName("timeTakenForQuotes")]
public int TimeTakenForQuotes { get; set; }
}
/// <summary>
/// Represents an individual quote item returned within the Yahoo Finance search results.
/// </summary>
public class YahooSearchQuoteDto
{
[JsonPropertyName("symbol")]
public string Symbol { get; set; } = string.Empty;
[JsonPropertyName("shortname")]
public string? ShortName { get; set; }
[JsonPropertyName("longname")]
public string? LongName { get; set; }
[JsonPropertyName("exchange")]
public string? Exchange { get; set; }
[JsonPropertyName("exchDisp")]
public string? ExchDisp { get; set; }
[JsonPropertyName("quoteType")]
public string? QuoteType { get; set; }
[JsonPropertyName("typeDisp")]
public string? TypeDisp { get; set; }
[JsonPropertyName("index")]
public string? Index { get; set; }
[JsonPropertyName("score")]
public double Score { get; set; }
[JsonPropertyName("sector")]
public string? Sector { get; set; }
[JsonPropertyName("sectorDisp")]
public string? SectorDisp { get; set; }
[JsonPropertyName("industry")]
public string? Industry { get; set; }
[JsonPropertyName("industryDisp")]
public string? IndustryDisp { get; set; }
[JsonPropertyName("dispSecIndFlag")]
public bool DispSecIndFlag { get; set; }
[JsonPropertyName("isYahooFinance")]
public bool IsYahooFinance { get; set; }
}
+36
View File
@@ -0,0 +1,36 @@
using System.Text.Json.Serialization;
namespace FinlyticCore.Dtos.Yahoo;
/// <summary>
/// Represents a Yahoo Finance value wrapper containing raw numerical data alongside formatted strings.
/// </summary>
public record YahooValueDto
{
[JsonPropertyName("raw")]
public double? Raw { get; init; }
[JsonPropertyName("fmt")]
public string? Fmt { get; init; }
[JsonPropertyName("longFmt")]
public string? LongFmt { get; init; }
/// <summary>
/// Helper property to retrieve Raw as double (or fallback 0.0).
/// </summary>
[JsonIgnore]
public double DoubleValue => Raw ?? 0.0;
/// <summary>
/// Helper property to retrieve Raw as decimal (or fallback 0m).
/// </summary>
[JsonIgnore]
public decimal DecimalValue => Raw.HasValue ? (decimal)Raw.Value : 0m;
/// <summary>
/// Helper property to retrieve Raw as long (or fallback 0L).
/// </summary>
[JsonIgnore]
public long LongValue => Raw.HasValue ? (long)Raw.Value : 0L;
}