From 833f7adbd0232f558fb7f474095cadce5a844f5d Mon Sep 17 00:00:00 2001 From: willthiswork89 Date: Fri, 5 Feb 2021 11:52:07 -0500 Subject: [PATCH] Added new library to handle fundamentals api. This commit focused on the Company Overview and Earnings Calls. --- .../AlphaVantage.Net.Common/ApiFunction.cs | 1 + .../Earnings/EarningsBase.cs | 16 ++++ .../Earnings/EarningsParserBase.cs | 88 ++++++++++++++++++ .../Earnings/EarningsPeriodBase.cs | 12 +++ .../Overview/OverviewBase.cs | 71 +++++++++++++++ .../Overview/OverviewParserBase.cs | 43 +++++++++ .../Parsing/ParsingExtensions.cs | 22 +++++ .../src/AlphaVantage.Net.Core/AssemblyInfo.cs | 1 + .../AlphaVantage.Net.Fundamentals.csproj | 31 +++++++ .../Client/CoreClientExtensions.cs | 20 +++++ .../Client/FundamentalsClient.cs | 20 +++++ .../Client/FundamentalsClientExtensions.cs | 39 ++++++++ .../Data/AnnualEarnings.cs | 13 +++ .../Data/CompanyOverview.cs | 11 +++ .../Data/Earnings.cs | 12 +++ .../Data/QuarterlyEarnings.cs | 21 +++++ .../Parsing/EarningsParser.cs | 75 ++++++++++++++++ .../Parsing/OverviewParser.cs | 90 +++++++++++++++++++ 18 files changed, 586 insertions(+) create mode 100644 AlphaVantage.Net/src/AlphaVantage.Net.Common/Earnings/EarningsBase.cs create mode 100644 AlphaVantage.Net/src/AlphaVantage.Net.Common/Earnings/EarningsParserBase.cs create mode 100644 AlphaVantage.Net/src/AlphaVantage.Net.Common/Earnings/EarningsPeriodBase.cs create mode 100644 AlphaVantage.Net/src/AlphaVantage.Net.Common/Overview/OverviewBase.cs create mode 100644 AlphaVantage.Net/src/AlphaVantage.Net.Common/Overview/OverviewParserBase.cs create mode 100644 AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/AlphaVantage.Net.Fundamentals.csproj create mode 100644 AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Client/CoreClientExtensions.cs create mode 100644 AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Client/FundamentalsClient.cs create mode 100644 AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Client/FundamentalsClientExtensions.cs create mode 100644 AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Data/AnnualEarnings.cs create mode 100644 AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Data/CompanyOverview.cs create mode 100644 AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Data/Earnings.cs create mode 100644 AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Data/QuarterlyEarnings.cs create mode 100644 AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Parsing/EarningsParser.cs create mode 100644 AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Parsing/OverviewParser.cs diff --git a/AlphaVantage.Net/src/AlphaVantage.Net.Common/ApiFunction.cs b/AlphaVantage.Net/src/AlphaVantage.Net.Common/ApiFunction.cs index 790f609..31a7c63 100644 --- a/AlphaVantage.Net/src/AlphaVantage.Net.Common/ApiFunction.cs +++ b/AlphaVantage.Net/src/AlphaVantage.Net.Common/ApiFunction.cs @@ -26,6 +26,7 @@ public enum ApiFunction INCOME_STATEMENT, BALANCE_SHEET, CASH_FLOW, + EARNINGS, LISTING_STATUS, // Forex (FX) diff --git a/AlphaVantage.Net/src/AlphaVantage.Net.Common/Earnings/EarningsBase.cs b/AlphaVantage.Net/src/AlphaVantage.Net.Common/Earnings/EarningsBase.cs new file mode 100644 index 0000000..a43930c --- /dev/null +++ b/AlphaVantage.Net/src/AlphaVantage.Net.Common/Earnings/EarningsBase.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace AlphaVantage.Net.Common.Earnings +{ + public abstract class EarningsBase + where TQuartleryEarnings : EarningsPeriodBase + where TAnnualEarnings : EarningsPeriodBase + { + public string Symbol { get; set; } = String.Empty; + + public ICollection AnnualEarnings { get; set; } = new List(); + public ICollection QuarterlyEarnings { get; set; } = new List(); + } +} diff --git a/AlphaVantage.Net/src/AlphaVantage.Net.Common/Earnings/EarningsParserBase.cs b/AlphaVantage.Net/src/AlphaVantage.Net.Common/Earnings/EarningsParserBase.cs new file mode 100644 index 0000000..027a63c --- /dev/null +++ b/AlphaVantage.Net/src/AlphaVantage.Net.Common/Earnings/EarningsParserBase.cs @@ -0,0 +1,88 @@ +using AlphaVantage.Net.Common.Parsing; +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.Json; + +namespace AlphaVantage.Net.Common.Earnings +{ + public abstract class EarningsParserBase : IAlphaVantageJsonDocumentParser + where TQuarterlyEarnings : EarningsPeriodBase + where TAnnualEarnings : EarningsPeriodBase + where TEarnings : EarningsBase + + { + + public abstract TEarnings CreateEarningsInstance(); + + public abstract TQuarterlyEarnings CreateQuarterlyEarningsInstance(); + + public abstract TAnnualEarnings CreateAnnualEarningsInstance(); + + protected abstract Action? GetAnnualParsingDelegate(string fieldName); + protected abstract Action? GetQuarterlyParsingDelegate(string fieldName); + public TEarnings ParseApiResponse(JsonDocument jsonDocument) + { + var result = CreateEarningsInstance(); + + try + { + result.Symbol = jsonDocument.RootElement.GetProperty("symbol").GetString(); + result.AnnualEarnings = GetAnnualEarningsData(jsonDocument); + result.QuarterlyEarnings = GetQuarterlyEarningsData(jsonDocument); + } + catch(Exception ex) + { + Console.WriteLine(ex.ToString()); + } + + return result; + } + + private List GetAnnualEarningsData(JsonDocument jsonDocument) + { + var result = new List(); + var annualEarningsJson = jsonDocument.RootElement.GetProperty("annualEarnings"); + + foreach (var annualEarningsDataPoint in annualEarningsJson.EnumerateArray()) + { + var annualDataPoint = CreateAnnualEarningsInstance(); + EnrichAnnualEarningsDataPoint(annualDataPoint, annualEarningsDataPoint); + result.Add(annualDataPoint); + } + + return result; + } + private void EnrichAnnualEarningsDataPoint(TAnnualEarnings annualEarningDataPoint, JsonElement annualEarningDataPointFields) + { + foreach (var fieldJson in annualEarningDataPointFields.EnumerateObject()) + { + GetAnnualParsingDelegate(fieldJson.Name)?.Invoke(annualEarningDataPoint, fieldJson.Value.GetString()); + } + } + + private List GetQuarterlyEarningsData(JsonDocument jsonDocument) + { + var result = new List(); + var quarterlyEarningsJson = jsonDocument.RootElement.GetProperty("quarterlyEarnings"); + + foreach (var quarterlyEarningsDataPoint in quarterlyEarningsJson.EnumerateArray()) + { + + System.Diagnostics.Debug.WriteLine(quarterlyEarningsDataPoint.ToString()); + var quarterlyDataPoint = CreateQuarterlyEarningsInstance(); + EnrichQuarterlyEarningsDataPoint(quarterlyDataPoint, quarterlyEarningsDataPoint); + result.Add(quarterlyDataPoint); + } + + return result; + } + private void EnrichQuarterlyEarningsDataPoint(TQuarterlyEarnings quarterlyEarningDataPoint, JsonElement quarterlyEarningDataPointFields) + { + foreach (var fieldJson in quarterlyEarningDataPointFields.EnumerateObject()) + { + GetQuarterlyParsingDelegate(fieldJson.Name)?.Invoke(quarterlyEarningDataPoint, fieldJson.Value.GetString()); + } + } + } +} diff --git a/AlphaVantage.Net/src/AlphaVantage.Net.Common/Earnings/EarningsPeriodBase.cs b/AlphaVantage.Net/src/AlphaVantage.Net.Common/Earnings/EarningsPeriodBase.cs new file mode 100644 index 0000000..8e2b95c --- /dev/null +++ b/AlphaVantage.Net/src/AlphaVantage.Net.Common/Earnings/EarningsPeriodBase.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace AlphaVantage.Net.Common.Earnings +{ + public abstract class EarningsPeriodBase + { + public DateTime FiscalDateEnding { get; set; } + public decimal ReportedEPS { get; set; } + } +} diff --git a/AlphaVantage.Net/src/AlphaVantage.Net.Common/Overview/OverviewBase.cs b/AlphaVantage.Net/src/AlphaVantage.Net.Common/Overview/OverviewBase.cs new file mode 100644 index 0000000..eee2ac0 --- /dev/null +++ b/AlphaVantage.Net/src/AlphaVantage.Net.Common/Overview/OverviewBase.cs @@ -0,0 +1,71 @@ +using AlphaVantage.Net.Common.Currencies; +using System; +using System.Collections.Generic; +using System.Text; + +namespace AlphaVantage.Net.Common.Overview +{ + public abstract class OverviewBase + { + public string Symbol { get; set; } = String.Empty; + public string AssetType { get; set; } = String.Empty;//probably could become an enum + public string Name { get; set; } = String.Empty; + public string Description { get; set; } = String.Empty; + public string Exchange { get; set; } = String.Empty; //probably could become an enum + public PhysicalCurrency PhysicalCurrency { get; set; } + public string Country { get; set; } = String.Empty;//probably could become an enum + + public string Sector { get; set; } = String.Empty; + public string Industry { get; set; } = String.Empty; + public string Address { get; set; } = String.Empty; + public int FullTimeEmployees { get; set; } + public string FiscalYearEnd { get; set; } = String.Empty; + public DateTime LatestQuarter { get; set; } + public long MarketCapitalization { get; set; } + public long EBITDA { get; set; } + public decimal PERatio { get; set; } + public decimal PEGRatio { get; set; } + public decimal BookValue { get; set; } + public decimal DividendPerShare { get; set; } + public decimal DividendYield { get; set; } + public decimal EPS { get; set; } + public decimal RevenuePerShareTTM { get; set; } + public decimal ProfitMargin { get; set; } + public decimal OperatingMarginTTM { get; set; } + public decimal ReturnOnAssetsTTM { get; set; } + public decimal ReturnOnEquityTTM { get; set; } + public long RevenueTTM { get; set; } + public long GrossProfitTTM { get; set; } + public decimal DilutedEPSTTM { get; set; } + public decimal QuarterlyEarningsGrowthYOY { get; set; } + public decimal QuarterlyRevenueGrowthYOY { get; set; } + public decimal AnalystTargetPrice { get; set; } + public decimal TrailingPE { get; set; } + public decimal ForwardPE { get; set; } + public decimal PriceToSalesRatioTTM { get; set; } + public decimal PriceToBookRatio { get; set; } + public decimal EVToRevenue { get; set; } + public decimal EVToEBITDA { get; set; } + public decimal Beta { get; set; } + public decimal FiftyTwoWeekHigh { get; set; } + public decimal FiftyTwoWeekLow { get; set; } + public decimal FiftyDayMovingAverage { get; set; } + public decimal TwoHundredDayMovingAverage { get; set; } + public long SharesOutstanding { get; set; } + public long SharesFloat { get; set; } + public long SharesShort { get; set; } + public long SharesShortPriorMonth { get; set; } + public decimal ShortRatio { get; set; } + public decimal ShortPercentOutstanding { get; set; } + public decimal ShortPercentFloat { get; set; } + public decimal PercentInsiders { get; set; } + public decimal PercentInstitutions { get; set; } + public decimal ForwardAnnualDividendRate { get; set; } + public decimal ForwardAnnualDividendYield { get; set; } + public decimal PayoutRatio { get; set; } + public DateTime DividendDate { get; set; } + public DateTime ExDividendDate { get; set; } + public string LastSplitFactor { get; set; } = String.Empty; + public DateTime LastSplitDate { get; set; } + } +} diff --git a/AlphaVantage.Net/src/AlphaVantage.Net.Common/Overview/OverviewParserBase.cs b/AlphaVantage.Net/src/AlphaVantage.Net.Common/Overview/OverviewParserBase.cs new file mode 100644 index 0000000..5646aef --- /dev/null +++ b/AlphaVantage.Net/src/AlphaVantage.Net.Common/Overview/OverviewParserBase.cs @@ -0,0 +1,43 @@ +using AlphaVantage.Net.Common.Parsing; +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.Json; + +namespace AlphaVantage.Net.Common.Overview +{ + public abstract class OverviewParserBase : IAlphaVantageJsonDocumentParser + where TOverview : OverviewBase + { + public abstract TOverview CreateOverviewInstance(); + + public abstract Action? GetOverviewParsingDelegate(string fieldName); + + public TOverview ParseApiResponse(JsonDocument jsonDocument) + { + var result = CreateOverviewInstance(); + + try + { + EnrichOverviewData(result, jsonDocument); + } + catch(Exception ex) + { + Console.WriteLine(ex.ToString()); + throw; + } + + return result; + } + + private void EnrichOverviewData(TOverview overview, JsonDocument overviewFields) + { + foreach (var fieldJson in overviewFields.RootElement.EnumerateObject()) + { + GetOverviewParsingDelegate(fieldJson.Name)?.Invoke(overview, fieldJson.Value.GetString()); + } + } + + + } +} diff --git a/AlphaVantage.Net/src/AlphaVantage.Net.Common/Parsing/ParsingExtensions.cs b/AlphaVantage.Net/src/AlphaVantage.Net.Common/Parsing/ParsingExtensions.cs index 2426427..2a117ee 100644 --- a/AlphaVantage.Net/src/AlphaVantage.Net.Common/Parsing/ParsingExtensions.cs +++ b/AlphaVantage.Net/src/AlphaVantage.Net.Common/Parsing/ParsingExtensions.cs @@ -1,3 +1,4 @@ +using AlphaVantage.Net.Common.Currencies; using System; using System.Globalization; @@ -5,24 +6,45 @@ namespace AlphaVantage.Net.Common.Parsing { public static class ParsingExtensions { + static readonly string EMPTY_VALUE = "None"; public static decimal ParseToDecimal(this string stringToParse) { + if (stringToParse == EMPTY_VALUE) + return 0; return decimal.Parse(stringToParse, CultureInfo.InvariantCulture); } public static DateTime ParseToDateTime(this string stringToParse) { + if (stringToParse == EMPTY_VALUE) + return DateTime.MinValue; return DateTime.Parse(stringToParse, CultureInfo.InvariantCulture); } public static long ParseToLong(this string stringToParse) { + if (stringToParse == EMPTY_VALUE) + return 0; return long.Parse(stringToParse, CultureInfo.InvariantCulture); } public static int ParseToInt(this string stringToParse) { + if (stringToParse == EMPTY_VALUE) + return 0; return int.Parse(stringToParse, CultureInfo.InvariantCulture); } + + public static PhysicalCurrency ParseToCurrency(this string stringToParse) + { + if (stringToParse == EMPTY_VALUE) + return 0; + PhysicalCurrency result = PhysicalCurrency.AED; + + if (!Enum.TryParse(stringToParse, out result)) + throw new FormatException("The currency code did not match a known currency code"); + + return result; + } } } \ No newline at end of file diff --git a/AlphaVantage.Net/src/AlphaVantage.Net.Core/AssemblyInfo.cs b/AlphaVantage.Net/src/AlphaVantage.Net.Core/AssemblyInfo.cs index fe16c0b..3412ed5 100644 --- a/AlphaVantage.Net/src/AlphaVantage.Net.Core/AssemblyInfo.cs +++ b/AlphaVantage.Net/src/AlphaVantage.Net.Core/AssemblyInfo.cs @@ -2,6 +2,7 @@ [assembly: InternalsVisibleTo("AlphaVantage.Net.Stocks")] [assembly: InternalsVisibleTo("AlphaVantage.Net.Forex")] +[assembly: InternalsVisibleTo("AlphaVantage.Net.Fundamentals")] [assembly: InternalsVisibleTo("AlphaVantage.Net.Crypto")] [assembly: InternalsVisibleTo("AlphaVantage.Net.TechnicalIndicators")] [assembly: InternalsVisibleTo("AlphaVantage.Net.Core.Tests")] \ No newline at end of file diff --git a/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/AlphaVantage.Net.Fundamentals.csproj b/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/AlphaVantage.Net.Fundamentals.csproj new file mode 100644 index 0000000..8b9c97f --- /dev/null +++ b/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/AlphaVantage.Net.Fundamentals.csproj @@ -0,0 +1,31 @@ + + + AlphaVantage.Net.Fundamentals + + Fully typed client for retrieval fundamental data from Alpha Vantage API. Works with newest and fastest parser System.Text.Json under the hood + + 2.0.1 + LutsenkoKirill + https://github.com/LutsenkoKirill/AlphaVantage.Net + true + true + 8 + enable + MIT + logo.jpg + netstandard2.0;netstandard2.1 + + + + + + + + + + + + logo.jpg + + + \ No newline at end of file diff --git a/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Client/CoreClientExtensions.cs b/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Client/CoreClientExtensions.cs new file mode 100644 index 0000000..bade03c --- /dev/null +++ b/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Client/CoreClientExtensions.cs @@ -0,0 +1,20 @@ +using AlphaVantage.Net.Core.Client; +using System; +using System.Collections.Generic; +using System.Text; + +namespace AlphaVantage.Net.Fundamentals.Client +{ + public static class CoreClientExtension + { + /// + /// Return that simplify work with Fundamentals APIs + /// + /// + /// + public static FundamentalsClient Fundamentals(this AlphaVantageClient client) + { + return new FundamentalsClient(client); + } + } +} diff --git a/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Client/FundamentalsClient.cs b/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Client/FundamentalsClient.cs new file mode 100644 index 0000000..228c99a --- /dev/null +++ b/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Client/FundamentalsClient.cs @@ -0,0 +1,20 @@ +using AlphaVantage.Net.Common; +using AlphaVantage.Net.Core.Client; +using AlphaVantage.Net.Fundamentals.Data; +using AlphaVantage.Net.Fundamentals.Parsing; +using JetBrains.Annotations; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace AlphaVantage.Net.Fundamentals.Client +{ + public sealed class FundamentalsClient : TypedAlphaVantageClient + { + internal FundamentalsClient(AlphaVantageClient alphaVantageClient) : base(alphaVantageClient) + { + } + + + + } +} diff --git a/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Client/FundamentalsClientExtensions.cs b/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Client/FundamentalsClientExtensions.cs new file mode 100644 index 0000000..f3e682f --- /dev/null +++ b/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Client/FundamentalsClientExtensions.cs @@ -0,0 +1,39 @@ +using AlphaVantage.Net.Common; +using AlphaVantage.Net.Fundamentals.Data; +using AlphaVantage.Net.Fundamentals.Parsing; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace AlphaVantage.Net.Fundamentals.Client +{ + public static class FundamentalsClientExtensions + { + + public static async Task GetEarningsAsync(this FundamentalsClient fundamentalsClient, string symbol) + { + var parser = new EarningsParser(); + + var query = new Dictionary() + { + {ApiQueryConstants.SymbolQueryVar, symbol}, + }; + + + return await fundamentalsClient.RequestApiAsync(parser, ApiFunction.EARNINGS, query); + } + + public static async Task GetCompanyOverviewAsync(this FundamentalsClient fundamentalsClient, string symbol) + { + var parser = new OverviewParser(); + + var query = new Dictionary() + { + {ApiQueryConstants.SymbolQueryVar, symbol}, + }; + + return await fundamentalsClient.RequestApiAsync(parser, ApiFunction.OVERVIEW, query); + } + } +} diff --git a/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Data/AnnualEarnings.cs b/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Data/AnnualEarnings.cs new file mode 100644 index 0000000..420551c --- /dev/null +++ b/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Data/AnnualEarnings.cs @@ -0,0 +1,13 @@ +using AlphaVantage.Net.Common.Earnings; +using AlphaVantage.Net.Common.TimeSeries; +using System; +using System.Collections.Generic; +using System.Text; + +namespace AlphaVantage.Net.Fundamentals.Data +{ + public class AnnualEarnings : EarningsPeriodBase + { + + } +} diff --git a/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Data/CompanyOverview.cs b/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Data/CompanyOverview.cs new file mode 100644 index 0000000..44fb534 --- /dev/null +++ b/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Data/CompanyOverview.cs @@ -0,0 +1,11 @@ +using AlphaVantage.Net.Common.Overview; +using System; +using System.Collections.Generic; +using System.Text; + +namespace AlphaVantage.Net.Fundamentals.Data +{ + public class CompanyOverview : OverviewBase + { + } +} diff --git a/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Data/Earnings.cs b/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Data/Earnings.cs new file mode 100644 index 0000000..864c76b --- /dev/null +++ b/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Data/Earnings.cs @@ -0,0 +1,12 @@ +using AlphaVantage.Net.Common.Earnings; +using System; +using System.Collections.Generic; +using System.Text; + +namespace AlphaVantage.Net.Fundamentals.Data +{ + public class Earnings : EarningsBase + { + + } +} diff --git a/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Data/QuarterlyEarnings.cs b/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Data/QuarterlyEarnings.cs new file mode 100644 index 0000000..8fbe2c0 --- /dev/null +++ b/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Data/QuarterlyEarnings.cs @@ -0,0 +1,21 @@ +using AlphaVantage.Net.Common.Earnings; +using System; +using System.Collections.Generic; +using System.Text; + +namespace AlphaVantage.Net.Fundamentals.Data +{ + public class QuarterlyEarnings : EarningsPeriodBase + { + public DateTime ReportedDate { get; set; } + public decimal EstimatedEPS { get; set; } + public decimal Surprise { get; set; } + public decimal SurprisePercentage { get; set; } + + + public bool DidMeetExpectedEPS() + { + return ReportedEPS >= EstimatedEPS; + } + } +} diff --git a/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Parsing/EarningsParser.cs b/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Parsing/EarningsParser.cs new file mode 100644 index 0000000..f91bf2f --- /dev/null +++ b/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Parsing/EarningsParser.cs @@ -0,0 +1,75 @@ +using AlphaVantage.Net.Common.Earnings; +using AlphaVantage.Net.Common.Parsing; +using AlphaVantage.Net.Fundamentals.Data; +using System; +using System.Collections.Generic; +using System.Text; + +namespace AlphaVantage.Net.Fundamentals.Parsing +{ + internal sealed class EarningsParser : EarningsParserBase + { + public const string EMPTY_VALUE = "None"; + public override AnnualEarnings CreateAnnualEarningsInstance() + { + return new AnnualEarnings(); + } + + public override Earnings CreateEarningsInstance() + { + return new Earnings(); + } + + public override QuarterlyEarnings CreateQuarterlyEarningsInstance() + { + return new QuarterlyEarnings(); + } + + protected override Action? GetAnnualParsingDelegate(string fieldName) + { + return AnnualParsingDelegates.ContainsKey(fieldName) ? AnnualParsingDelegates[fieldName] : null; + } + + + + protected override Action? GetQuarterlyParsingDelegate(string fieldName) + { + return QuarterlyParsingDelegates.ContainsKey(fieldName) ? QuarterlyParsingDelegates[fieldName] : null; + } + + + private static readonly Dictionary> QuarterlyParsingDelegates = + new Dictionary>() + { + {"fiscalDateEnding", (dataPoint, strValue) => { dataPoint.FiscalDateEnding = strValue.ParseToDateTime(); }}, + {"reportedDate", (dataPoint, strValue) => { dataPoint.ReportedDate = strValue.ParseToDateTime(); }}, + {"reportedEPS", (dataPoint, strValue) => { dataPoint.ReportedEPS = strValue.ParseToDecimal(); }}, + {"estimatedEPS", (dataPoint, strValue) => { + if(strValue == EMPTY_VALUE ) + dataPoint.EstimatedEPS = 0; + else + dataPoint.EstimatedEPS = strValue.ParseToDecimal(); + }}, + {"surprise", (dataPoint, strValue) => { + if(strValue == EMPTY_VALUE ) + dataPoint.Surprise = 0; + else + dataPoint.Surprise = strValue.ParseToDecimal(); + }}, + {"surprisePercentage", (dataPoint, strValue) => { + if(strValue == EMPTY_VALUE ) + dataPoint.SurprisePercentage = 0; + else + dataPoint.SurprisePercentage = strValue.ParseToDecimal(); + }}, + + }; + + private static readonly Dictionary> AnnualParsingDelegates = + new Dictionary>() + { + {"fiscalDateEnding", (dataPoint, strValue) => { dataPoint.FiscalDateEnding = strValue.ParseToDateTime(); }}, + {"reportedEPS", (dataPoint, strValue) => { dataPoint.ReportedEPS = strValue.ParseToDecimal(); }} + }; + } +} diff --git a/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Parsing/OverviewParser.cs b/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Parsing/OverviewParser.cs new file mode 100644 index 0000000..0e48536 --- /dev/null +++ b/AlphaVantage.Net/src/AlphaVantage.Net.Fundamentals/Parsing/OverviewParser.cs @@ -0,0 +1,90 @@ +using AlphaVantage.Net.Common.Currencies; +using AlphaVantage.Net.Common.Overview; +using AlphaVantage.Net.Common.Parsing; +using AlphaVantage.Net.Fundamentals.Data; +using System; +using System.Collections.Generic; +using System.Text; + +namespace AlphaVantage.Net.Fundamentals.Parsing +{ + internal sealed class OverviewParser : OverviewParserBase + { + public override CompanyOverview CreateOverviewInstance() + { + return new CompanyOverview(); + } + + public override Action? GetOverviewParsingDelegate(string fieldName) + { + return OverviewParsingDelegates.ContainsKey(fieldName) ? OverviewParsingDelegates[fieldName] : null; + } + + + public static readonly Dictionary> OverviewParsingDelegates = + new Dictionary>() + { + {"Symbol", (dataPoint, strValue) => { dataPoint.Symbol = strValue; }}, + {"AssetType", (dataPoint, strValue) => { dataPoint.AssetType = strValue; }}, + {"Name", (dataPoint, strValue) => { dataPoint.Name = strValue; }}, + {"Description", (dataPoint, strValue) => { dataPoint.Description = strValue; }}, + {"Exchange", (dataPoint, strValue) => { dataPoint.Exchange = strValue; }}, + {"Currency", (dataPoint, strValue) => { dataPoint.PhysicalCurrency = strValue.ParseToCurrency(); }}, + {"Country", (dataPoint, strValue) => { dataPoint.Country = strValue; }}, + {"Sector", (dataPoint, strValue) => { dataPoint.Sector = strValue; }}, + {"Industry", (dataPoint, strValue) => { dataPoint.Industry = strValue; }}, + {"Address", (dataPoint, strValue) => { dataPoint.Address = strValue; }}, + {"FullTimeEmployees", (dataPoint, strValue) => { dataPoint.FullTimeEmployees = strValue.ParseToInt(); }}, + {"FiscalYearEnd", (dataPoint, strValue) => { dataPoint.FiscalYearEnd = strValue; }}, + {"LatestQuarter", (dataPoint, strValue) => { dataPoint.LatestQuarter = strValue.ParseToDateTime(); }}, + {"MarketCapitalization", (dataPoint, strValue) => { dataPoint.MarketCapitalization = strValue.ParseToLong(); }}, + {"EBITDA", (dataPoint, strValue) => { dataPoint.EBITDA = strValue.ParseToLong(); }}, + {"PERatio", (dataPoint, strValue) => { dataPoint.PERatio = strValue.ParseToDecimal(); }}, + {"PEGRatio", (dataPoint, strValue) => { dataPoint.PEGRatio = strValue.ParseToDecimal(); }}, + {"BookValue", (dataPoint, strValue) => { dataPoint.BookValue = strValue.ParseToDecimal(); }}, + {"DividendPerShare", (dataPoint, strValue) => { dataPoint.DividendPerShare = strValue.ParseToDecimal(); }}, + {"DividendYield", (dataPoint, strValue) => { dataPoint.DividendYield = strValue.ParseToDecimal(); }}, + {"EPS", (dataPoint, strValue) => { dataPoint.EPS = strValue.ParseToDecimal(); }}, + {"RevenuePerShareTTM", (dataPoint, strValue) => { dataPoint.RevenuePerShareTTM = strValue.ParseToDecimal(); }}, + {"ProfitMargin", (dataPoint, strValue) => { dataPoint.ProfitMargin = strValue.ParseToDecimal(); }}, + {"OperatingMarginTTM", (dataPoint, strValue) => { dataPoint.OperatingMarginTTM = strValue.ParseToDecimal(); }}, + {"ReturnOnAssetsTTM", (dataPoint, strValue) => { dataPoint.ReturnOnAssetsTTM = strValue.ParseToDecimal(); }}, + {"ReturnOnEquityTTM", (dataPoint, strValue) => { dataPoint.ReturnOnEquityTTM = strValue.ParseToDecimal(); }}, + {"RevenueTTM", (dataPoint, strValue) => { dataPoint.RevenueTTM = strValue.ParseToLong(); }}, + {"GrossProfitTTM", (dataPoint, strValue) => { dataPoint.GrossProfitTTM = strValue.ParseToLong(); }}, + {"DilutedEPSTTM", (dataPoint, strValue) => { dataPoint.DilutedEPSTTM = strValue.ParseToDecimal(); }}, + {"QuarterlyEarningsGrowthYOY", (dataPoint, strValue) => { dataPoint.QuarterlyEarningsGrowthYOY = strValue.ParseToDecimal(); }}, + {"QuarterlyRevenueGrowthYOY", (dataPoint, strValue) => { dataPoint.QuarterlyRevenueGrowthYOY = strValue.ParseToDecimal(); }}, + {"AnalystTargetPrice", (dataPoint, strValue) => { dataPoint.AnalystTargetPrice = strValue.ParseToDecimal(); }}, + {"TrailingPE", (dataPoint, strValue) => { dataPoint.TrailingPE = strValue.ParseToDecimal(); }}, + {"ForwardPE", (dataPoint, strValue) => { dataPoint.ForwardPE = strValue.ParseToDecimal(); }}, + {"PriceToSalesRatioTTM", (dataPoint, strValue) => { dataPoint.PriceToSalesRatioTTM = strValue.ParseToDecimal(); }}, + {"PriceToBookRatio", (dataPoint, strValue) => { dataPoint.PriceToBookRatio = strValue.ParseToDecimal(); }}, + {"EVToRevenue", (dataPoint, strValue) => { dataPoint.EVToRevenue = strValue.ParseToDecimal(); }}, + {"EVToEBITDA", (dataPoint, strValue) => { dataPoint.EVToEBITDA = strValue.ParseToDecimal(); }}, + {"Beta", (dataPoint, strValue) => { dataPoint.Beta = strValue.ParseToDecimal(); }}, + {"52WeekHigh", (dataPoint, strValue) => { dataPoint.FiftyTwoWeekHigh = strValue.ParseToDecimal(); }}, + {"52WeekLow", (dataPoint, strValue) => { dataPoint.FiftyTwoWeekLow = strValue.ParseToDecimal(); }}, + {"50DayMovingAverage", (dataPoint, strValue) => { dataPoint.FiftyDayMovingAverage = strValue.ParseToDecimal(); }}, + {"200DayMovingAverage", (dataPoint, strValue) => { dataPoint.TwoHundredDayMovingAverage = strValue.ParseToDecimal(); }}, + {"SharesOutstanding", (dataPoint, strValue) => { dataPoint.SharesOutstanding = strValue.ParseToLong(); }}, + {"SharesFloat", (dataPoint, strValue) => { dataPoint.SharesFloat = strValue.ParseToLong(); }}, + {"SharesShort", (dataPoint, strValue) => { dataPoint.SharesShort = strValue.ParseToLong(); }}, + {"SharesShortPriorMonth", (dataPoint, strValue) => { dataPoint.SharesShortPriorMonth = strValue.ParseToLong(); }}, + {"ShortRatio", (dataPoint, strValue) => { dataPoint.ShortRatio = strValue.ParseToDecimal(); }}, + {"ShortPercentOutstanding", (dataPoint, strValue) => { dataPoint.ShortPercentOutstanding = strValue.ParseToDecimal(); }}, + {"ShortPercentFloat", (dataPoint, strValue) => { dataPoint.ShortPercentFloat = strValue.ParseToDecimal(); }}, + {"PercentInsiders", (dataPoint, strValue) => { dataPoint.PercentInsiders = strValue.ParseToDecimal(); }}, + {"PercentInstitutions", (dataPoint, strValue) => { dataPoint.PercentInstitutions = strValue.ParseToDecimal(); }}, + {"ForwardAnnualDividendRate", (dataPoint, strValue) => { dataPoint.ForwardAnnualDividendRate = strValue.ParseToDecimal(); }}, + {"ForwardAnnualDividendYield", (dataPoint, strValue) => { dataPoint.ForwardAnnualDividendYield = strValue.ParseToDecimal(); }}, + {"PayoutRatio", (dataPoint, strValue) => { dataPoint.PayoutRatio = strValue.ParseToDecimal(); }}, + {"DividendDate", (dataPoint, strValue) => { dataPoint.DividendDate = strValue.ParseToDateTime(); }}, + {"ExDividendDate", (dataPoint, strValue) => { dataPoint.ExDividendDate = strValue.ParseToDateTime(); }}, + {"LastSplitFactor", (dataPoint, strValue) => { dataPoint.LastSplitFactor = strValue; }}, + {"LastSplitDate", (dataPoint, strValue) => { dataPoint.LastSplitDate = strValue.ParseToDateTime(); }} + + + }; + } +}