Skip to content

Commit 72e51c6

Browse files
authored
Add crypto market, stock screener and social sentiment support. (#43)
* Added crypto market, stock screener and social sentiment support. * Moved symbol to query parameter for social sentiment.
1 parent bdad9f5 commit 72e51c6

19 files changed

+574
-0
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using MatthiWare.FinancialModelingPrep.Model;
2+
using MatthiWare.FinancialModelingPrep.Model.Crypto;
3+
using MatthiWare.FinancialModelingPrep.Model.StockMarket;
4+
using System.Collections.Generic;
5+
using System.Threading.Tasks;
6+
7+
namespace MatthiWare.FinancialModelingPrep.Abstractions.StockMarket
8+
{
9+
public interface ICryptoMarketProvider
10+
{
11+
public Task<ApiResponse<List<CryptoItem>>> GetAvilableCryptocurrencies();
12+
13+
public Task<ApiResponse<List<CryptoHistoricalPricePeriodListing>>> GetHistoricalPrices(string symbol, HistoricalPricingPeriod period);
14+
15+
public Task<ApiResponse<CryptoHistoricalPriceDailyItem>> GetDailyPrices(string symbol);
16+
}
17+
}

FinancialModelingPrepApi/Abstractions/Statistics/IStockStatisticsProvider.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,8 @@ public interface IStockStatisticsProvider
1818
/// <param name="limit">Limts the amount of results</param>
1919
/// <returns></returns>
2020
public Task<ApiResponse<List<AnalystEstimateItem>>> GetAnalystEstimatesAsync(string symbol, Period period = Period.Annual, int? limit = 30);
21+
22+
// Social Sentiment
23+
public Task<ApiResponse<List<SocialSentimentItem>>> GetSocialSentimentAsync(string symbol, int page = 0);
2124
}
2225
}

FinancialModelingPrepApi/Abstractions/StockMarket/IStockMarketProvider.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,8 @@ public interface IStockMarketProvider
1010
public Task<ApiResponse<List<StockMarketSymbolResponse>>> GetMostActiveStocksAsync();
1111
public Task<ApiResponse<List<StockMarketSymbolResponse>>> GetBiggestGainerStocksAsync();
1212
public Task<ApiResponse<List<StockMarketSymbolResponse>>> GetBiggestLoserStocksAsync();
13+
public Task<ApiResponse<List<StockScreenerItem>>> StockScreener(int? marketCapMoreThan = null, int? marketCapLowerThan = null, decimal? priceMoreThan = null, decimal? priceLowerThan = null,
14+
decimal? betaMoreThan = null, decimal? betaLowerThan = null, int? volumeMoreThan = null, int? volumeLowerThan = null, bool? isEtf = null, bool? isActivelyTraded = null,
15+
Sector? sector = null, Industry? industry = null, Country? country = null, Exchange? exchange = null, int? limit = 30);
1316
}
1417
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
using MatthiWare.FinancialModelingPrep.Abstractions.StockMarket;
2+
using MatthiWare.FinancialModelingPrep.Core.Http;
3+
using MatthiWare.FinancialModelingPrep.Model;
4+
using MatthiWare.FinancialModelingPrep.Model.Crypto;
5+
using MatthiWare.FinancialModelingPrep.Model.StockMarket;
6+
using System.Collections.Generic;
7+
using System.Collections.Specialized;
8+
using System.Threading.Tasks;
9+
10+
namespace MatthiWare.FinancialModelingPrep.Core.StockMarket
11+
{
12+
public sealed class CryptoMarketProvider : ICryptoMarketProvider
13+
{
14+
private readonly FinancialModelingPrepHttpClient client;
15+
16+
public CryptoMarketProvider(FinancialModelingPrepHttpClient client)
17+
{
18+
this.client = client ?? throw new System.ArgumentNullException(nameof(client));
19+
}
20+
21+
public Task<ApiResponse<List<CryptoItem>>> GetAvilableCryptocurrencies()
22+
{
23+
24+
const string url = "[version]/symbol/available-cryptocurrencies";
25+
26+
var pathParams = new NameValueCollection()
27+
{
28+
{ "version", ApiVersion.v3.ToString() }
29+
};
30+
31+
return client.GetJsonAsync<List<CryptoItem>>(url, pathParams, null);
32+
}
33+
34+
public Task<ApiResponse<CryptoHistoricalPriceDailyItem>> GetDailyPrices(string symbol)
35+
{
36+
const string url = "[version]/historical-price-full/[symbol]";
37+
38+
var pathParams = new NameValueCollection()
39+
{
40+
{ "version", ApiVersion.v3.ToString() },
41+
{ "symbol", symbol }
42+
};
43+
44+
return client.GetJsonAsync<CryptoHistoricalPriceDailyItem>(url, pathParams, null);
45+
}
46+
47+
public Task<ApiResponse<List<CryptoHistoricalPricePeriodListing>>> GetHistoricalPrices(string symbol, HistoricalPricingPeriod period)
48+
{
49+
const string url = "[version]/historical-chart/[pricePeriod]/[symbol]";
50+
51+
string pricePeriod = EnumMappings.HistoricalPrices[period];
52+
53+
var pathParams = new NameValueCollection()
54+
{
55+
{ "version", ApiVersion.v3.ToString() },
56+
{ "symbol", symbol },
57+
{ "pricePeriod", pricePeriod }
58+
};
59+
60+
var queryString = new QueryStringBuilder();
61+
62+
return client.GetJsonAsync<List<CryptoHistoricalPricePeriodListing>>(url, pathParams, queryString);
63+
}
64+
}
65+
}

FinancialModelingPrepApi/Core/Statistics/StockStatisticsProvider.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,20 @@ public Task<ApiResponse<List<AnalystEstimateItem>>> GetAnalystEstimatesAsync(str
4242
return client.GetJsonAsync<List<AnalystEstimateItem>>(url, pathParams, queryString);
4343
}
4444

45+
public Task<ApiResponse<List<SocialSentimentItem>>> GetSocialSentimentAsync(string symbol, int page = 0)
46+
{
47+
const string url = "[version]/historical/social-sentiment/";
48+
49+
var pathParams = new NameValueCollection()
50+
{
51+
{ "version", ApiVersion.v4.ToString() }
52+
};
53+
54+
var queryString = new QueryStringBuilder();
55+
queryString.Add("symbol", symbol);
56+
queryString.Add("page", page.ToString());
57+
58+
return client.GetJsonAsync<List<SocialSentimentItem>>(url, pathParams, queryString);
59+
}
4560
}
4661
}

FinancialModelingPrepApi/Core/StockMarket/StockMarketProvider.cs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,86 @@ public StockMarketProvider(FinancialModelingPrepHttpClient client)
2121
this.client = client ?? throw new System.ArgumentNullException(nameof(client));
2222
}
2323

24+
public Task<ApiResponse<List<StockScreenerItem>>> StockScreener(int? marketCapMoreThan = null, int? marketCapLowerThan = null, decimal? priceMoreThan = null, decimal? priceLowerThan = null,
25+
decimal? betaMoreThan = null, decimal? betaLowerThan = null, int? volumeMoreThan = null, int? volumeLowerThan = null, bool? isEtf = null, bool? isActivelyTraded = null,
26+
Sector? sector = null, Industry? industry = null, Country? country = null, Exchange? exchange = null, int? limit = 30)
27+
{
28+
29+
const string url = "[version]/stock-screener";
30+
31+
var pathParams = new NameValueCollection()
32+
{
33+
{ "version", ApiVersion.v3.ToString() }
34+
};
35+
36+
var queryString = new QueryStringBuilder();
37+
38+
if (marketCapMoreThan.HasValue)
39+
{
40+
queryString.Add("marketCapMoreThan", marketCapMoreThan.Value.ToString());
41+
}
42+
43+
if (marketCapLowerThan.HasValue)
44+
{
45+
queryString.Add("marketCapLowerThan", marketCapLowerThan.Value.ToString());
46+
}
47+
48+
if (priceMoreThan.HasValue)
49+
{
50+
queryString.Add("priceMoreThan", priceMoreThan.Value.ToString());
51+
}
52+
53+
if (priceLowerThan.HasValue)
54+
{
55+
queryString.Add("priceLowerThan", priceLowerThan.Value.ToString());
56+
}
57+
58+
if (betaMoreThan.HasValue)
59+
{
60+
queryString.Add("betaMoreThan", betaMoreThan.Value.ToString());
61+
}
62+
63+
if (betaLowerThan.HasValue)
64+
{
65+
queryString.Add("betaLowerThan", betaLowerThan.Value.ToString());
66+
}
67+
68+
if (volumeMoreThan.HasValue)
69+
{
70+
queryString.Add("volumeMoreThan", volumeMoreThan.Value.ToString());
71+
}
72+
73+
if (isEtf.HasValue)
74+
{
75+
queryString.Add("isEtf", isEtf.Value.ToString());
76+
}
77+
78+
if (sector.HasValue)
79+
{
80+
queryString.Add("sector", EnumMappings.Sectors[sector.Value]);
81+
}
82+
83+
if (industry.HasValue)
84+
{
85+
queryString.Add("industry", EnumMappings.Industries[industry.Value]);
86+
}
87+
88+
if (country.HasValue)
89+
{
90+
queryString.Add("country", country.Value.ToString());
91+
}
92+
93+
if (exchange.HasValue)
94+
{
95+
queryString.Add("exchange", exchange.Value.ToString().ToLower());
96+
}
97+
98+
queryString.Add("limit", limit.Value.ToString());
99+
100+
101+
return client.GetJsonAsync<List<StockScreenerItem>>(url, pathParams, queryString);
102+
}
103+
24104
public Task<ApiResponse<List<StockMarketSymbolResponse>>> GetBiggestGainerStocksAsync()
25105
=> GetStockMarketData(GainersEndpoint);
26106

FinancialModelingPrepApi/DependencyInjectionExtensions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public static void AddFinancialModelingPrepApiClient(this IServiceCollection ser
4949
services.TryAddTransient<IInstitutionalFundProvider, InstitutionalFundProvider>();
5050
services.TryAddTransient<IStockTimeSeriesProvider, StockTimeSeriesProvider>();
5151
services.TryAddTransient<IStockMarketProvider, StockMarketProvider>();
52+
services.TryAddTransient<ICryptoMarketProvider, CryptoMarketProvider>();
5253
services.TryAddTransient<IStockStatisticsProvider, StockStatisticsProvider>();
5354
}
5455
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Text.Json.Serialization;
6+
using System.Threading.Tasks;
7+
8+
namespace MatthiWare.FinancialModelingPrep.Model.Crypto
9+
{
10+
public class CryptoHistoricalPriceDailyItem
11+
{
12+
[JsonPropertyName("symbol")]
13+
public string Symbol { get; set; }
14+
15+
[JsonPropertyName("historical")]
16+
public List<CyptoHistoricalPriceDailyListing> HistoricalPrices { get; set; }
17+
}
18+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Text.Json.Serialization;
6+
using System.Threading.Tasks;
7+
8+
namespace MatthiWare.FinancialModelingPrep.Model.Crypto
9+
{
10+
public class CryptoItem
11+
{
12+
[JsonPropertyName("symbol")]
13+
public string Symbol { get; set; }
14+
15+
[JsonPropertyName("name")]
16+
public string Name { get; set; }
17+
18+
[JsonPropertyName("currency")]
19+
public string Currency { get; set; }
20+
21+
[JsonPropertyName("stockExchange")]
22+
public string StockExchange { get; set; }
23+
24+
[JsonPropertyName("exchangeShortName")]
25+
public string ExchangeShortName { get; set; }
26+
27+
}
28+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Text.Json.Serialization;
6+
using System.Threading.Tasks;
7+
8+
namespace MatthiWare.FinancialModelingPrep.Model.Crypto
9+
{
10+
public class CryptoHistoricalPricePeriodListing
11+
{
12+
[JsonPropertyName("date")]
13+
public string Date { get; set; }
14+
15+
[JsonPropertyName("open")]
16+
public decimal Open { get; set; }
17+
18+
[JsonPropertyName("high")]
19+
public decimal High { get; set; }
20+
21+
[JsonPropertyName("low")]
22+
public decimal Low { get; set; }
23+
24+
[JsonPropertyName("close")]
25+
public decimal Close { get; set; }
26+
27+
[JsonPropertyName("volume")]
28+
public long Volume { get; set; }
29+
}
30+
31+
public class CyptoHistoricalPriceDailyListing
32+
{
33+
[JsonPropertyName("date")]
34+
public DateTime Date { get; set; }
35+
36+
[JsonPropertyName("open")]
37+
public decimal Open { get; set; }
38+
39+
[JsonPropertyName("high")]
40+
public decimal High { get; set; }
41+
42+
[JsonPropertyName("low")]
43+
public decimal Low { get; set; }
44+
45+
[JsonPropertyName("close")]
46+
public decimal Close { get; set; }
47+
48+
[JsonPropertyName("adjClose")]
49+
public decimal AdjClose { get; set; }
50+
51+
[JsonPropertyName("volume")]
52+
public double Volume { get; set; }
53+
54+
[JsonPropertyName("unadjustedVolume")]
55+
public double UnadjustedVolume { get; set; }
56+
57+
[JsonPropertyName("change")]
58+
public decimal Change { get; set; }
59+
60+
[JsonPropertyName("changePercent")]
61+
public decimal ChangePercent { get; set; }
62+
63+
[JsonPropertyName("vwap")]
64+
public decimal VWAP { get; set; }
65+
66+
[JsonPropertyName("label")]
67+
public string Label { get; set; }
68+
69+
[JsonPropertyName("changeOvertime")]
70+
public double ChangeOvertime { get; set; }
71+
}
72+
}

0 commit comments

Comments
 (0)