11using DatabaseProjectAPI . DataContext ;
22using DatabaseProjectAPI . Entities ;
3+ using DatabaseProjectAPI . Helpers ;
34
45namespace DatabaseProjectAPI . Services
56{
@@ -16,67 +17,103 @@ public StockQuoteBackgroundService(IServiceProvider serviceProvider, ILogger<Sto
1617
1718 protected override async Task ExecuteAsync ( CancellationToken stoppingToken )
1819 {
20+ _logger . LogInformation ( "StockQuoteBackgroundService started at: {time}" , DateTime . UtcNow ) ;
21+
1922 while ( ! stoppingToken . IsCancellationRequested )
2023 {
2124 var now = DateTime . UtcNow ;
2225
23- if ( IsMarketOpenTime ( now ) || IsMarketCloseTime ( now ) )
26+ using ( var scope = _serviceProvider . CreateScope ( ) )
2427 {
25- using ( var scope = _serviceProvider . CreateScope ( ) )
28+ var dbContext = scope . ServiceProvider . GetRequiredService < DpapiDbContext > ( ) ;
29+ var apiRequestLogger = scope . ServiceProvider . GetRequiredService < IApiRequestLogger > ( ) ;
30+
31+ // Check if API call has already been made today for market open or close
32+ if ( IsMarketOpenTime ( now ) && ! await apiRequestLogger . HasMadeApiCallToday ( "MarketOpen" , "AAPL" ) )
33+ {
34+ await FetchAndSaveStockData ( dbContext , apiRequestLogger , "MarketOpen" , "AAPL" ) ;
35+ }
36+ else if ( IsMarketCloseTime ( now ) && ! await apiRequestLogger . HasMadeApiCallToday ( "MarketClose" , "AAPL" ) )
2637 {
27- var stockService = scope . ServiceProvider . GetRequiredService < IAlphaVantageService > ( ) ;
28- var dbContext = scope . ServiceProvider . GetRequiredService < DpapiDbContext > ( ) ;
29-
30- try
31- {
32- var stockQuote = await stockService . GetStockQuote ( "AAPL" ) ;
33-
34- var stock = await dbContext . Stocks
35- . FirstOrDefaultAsync ( s => s . Symbol == stockQuote . Symbol , stoppingToken ) ;
36-
37- if ( stock == null )
38- {
39- _logger . LogWarning ( "Stock not found in the database. Symbol: {Symbol}" , stockQuote . Symbol ) ;
40- continue ;
41- }
42-
43- var stockHistory = new StockHistory
44- {
45- StockId = stock . StockId ,
46- Timestamp = stockQuote . LatestTradingDay ,
47- OpenedValue = stockQuote . Open ,
48- ClosedValue = stockQuote . Price
49- } ;
50-
51-
52- dbContext . StockHistories . Add ( stockHistory ) ;
53- await dbContext . SaveChangesAsync ( stoppingToken ) ;
54-
55- _logger . LogInformation ( "Stock history saved successfully for {Symbol} at {Timestamp}" , stock . Symbol , stockHistory . Timestamp ) ;
56- }
57- catch ( Exception ex )
58- {
59- _logger . LogError ( ex , "Error occurred while fetching and saving stock history data." ) ;
60- }
38+ await FetchAndSaveStockData ( dbContext , apiRequestLogger , "MarketClose" , "AAPL" ) ;
6139 }
6240 }
6341
64- await Task . Delay ( TimeSpan . FromMinutes ( 60 ) , stoppingToken ) ; // Check every hour
42+ await Task . Delay ( TimeSpan . FromMinutes ( 60 ) , stoppingToken ) ; // Delay for 1 hour
43+ }
44+ }
45+ private async Task FetchAndSaveStockData ( DpapiDbContext dbContext , IApiRequestLogger apiRequestLogger , string callType , string symbol )
46+ {
47+ using ( var scope = _serviceProvider . CreateScope ( ) )
48+ {
49+ var stockService = scope . ServiceProvider . GetRequiredService < IAlphaVantageService > ( ) ;
50+
51+ try
52+ {
53+ var stockQuote = await stockService . GetStockQuote ( symbol ) ;
54+
55+ // Find stock by symbol
56+ var stock = await dbContext . Stocks . FirstOrDefaultAsync ( s => s . Symbol == stockQuote . Symbol ) ;
57+
58+ if ( stock == null )
59+ {
60+ _logger . LogWarning ( "Stock not found in the database. Symbol: {Symbol}" , stockQuote . Symbol ) ;
61+ return ;
62+ }
63+
64+ var stockHistory = new StockHistory
65+ {
66+ StockId = stock . StockId ,
67+ Timestamp = stockQuote . LatestTradingDay ,
68+ OpenedValue = stockQuote . Open ,
69+ ClosedValue = stockQuote . Price
70+ } ;
71+
72+ dbContext . StockHistories . Add ( stockHistory ) ;
73+ await dbContext . SaveChangesAsync ( ) ;
74+
75+ // Log that an API call was made
76+ await apiRequestLogger . LogApiCall ( callType , symbol ) ;
77+
78+ _logger . LogInformation ( "Stock history saved successfully for {Symbol} at {Timestamp}" , stock . Symbol , stockHistory . Timestamp ) ;
79+ }
80+ catch ( Exception ex )
81+ {
82+ _logger . LogError ( ex , "Error occurred while fetching and saving stock history data." ) ;
83+ }
6584 }
6685 }
86+
6787
6888 private bool IsMarketOpenTime ( DateTime currentTime )
6989 {
70- TimeZoneInfo est = TimeZoneInfo . FindSystemTimeZoneById ( "Eastern Standard Time" ) ;
71- var marketOpenTime = TimeZoneInfo . ConvertTimeFromUtc ( new DateTime ( currentTime . Year , currentTime . Month , currentTime . Day , 9 , 30 , 0 ) , est ) ;
90+ TimeZoneInfo easternTime = GetEasternTimeZone ( ) ;
91+ var marketOpenTime = TimeZoneInfo . ConvertTimeFromUtc ( new DateTime ( currentTime . Year , currentTime . Month , currentTime . Day , 9 , 30 , 0 ) , easternTime ) ;
7292 return currentTime >= marketOpenTime && currentTime < marketOpenTime . AddMinutes ( 1 ) ; // Within 1 minute of market opening
7393 }
7494
7595 private bool IsMarketCloseTime ( DateTime currentTime )
7696 {
77- TimeZoneInfo est = TimeZoneInfo . FindSystemTimeZoneById ( "Eastern Standard Time" ) ;
78- var marketCloseTime = TimeZoneInfo . ConvertTimeFromUtc ( new DateTime ( currentTime . Year , currentTime . Month , currentTime . Day , 16 , 0 , 0 ) , est ) ;
97+ TimeZoneInfo easternTime = GetEasternTimeZone ( ) ;
98+ var marketCloseTime = TimeZoneInfo . ConvertTimeFromUtc ( new DateTime ( currentTime . Year , currentTime . Month , currentTime . Day , 16 , 0 , 0 ) , easternTime ) ;
7999 return currentTime >= marketCloseTime && currentTime < marketCloseTime . AddMinutes ( 1 ) ; // Within 1 minute of market closing
80100 }
101+ private TimeZoneInfo GetEasternTimeZone ( )
102+ {
103+ try
104+ {
105+ return TimeZoneInfo . FindSystemTimeZoneById ( "Eastern Standard Time" ) ;
106+ }
107+ catch ( TimeZoneNotFoundException )
108+ {
109+ return TimeZoneInfo . FindSystemTimeZoneById ( "America/New_York" ) ;
110+ }
111+ catch ( InvalidTimeZoneException )
112+ {
113+ throw new Exception ( "Unable to determine the Eastern Time zone." ) ;
114+ }
115+ }
116+
81117 }
118+
82119}
0 commit comments