public async Task GetPriceHistoryAsync(CancellationToken cancellationToken) { _logger.LogInformation("GetPriceHistoryAsync started {now}", DateTime.Now); long start; long end; DateTime dateTime; int count; StockCandles stockCandle; IAsyncEnumerable <Models.TdAmeritrade.Account.Instrument> instruments; _dataAdapter.JsonSerializerOptions = new(); _dataAdapter.JsonSerializerOptions.PropertyNameCaseInsensitive = true; dateTime = new DateTime(2015, 1, 1); instruments = _dataAdapter.StocksDbContext.Instrument; await foreach (Instrument instrument in instruments) { try { using StocksDbContext stocksDbContext = _dataAdapter.StocksDbContextFactory.CreateDbContext(); count = stocksDbContext.PriceHistory.Count(x => x.Exchange == instrument.Exchange && x.Symbol == instrument.Symbol); start = count > 0 ? new DateTimeOffset(stocksDbContext.PriceHistory.Where(x => x.Exchange == instrument.Exchange && x.Symbol == instrument.Symbol).OrderBy(x => x.DateTime).Last().DateTime.Date).AddDays(1).ToUnixTimeMilliseconds() : new DateTimeOffset(dateTime).ToUnixTimeMilliseconds(); end = DateTimeOffset.Now.ToUnixTimeMilliseconds(); _dataAdapter.Json = await Requester.SendRequestAsync(Enums.HttpVerb.Get, $"{_dataAdapter.Settings["MarketDataUri"]}/{instrument.Symbol}/pricehistory?apikey={_dataAdapter.Settings["ApiKey"]}&periodType=year&frequencyType=daily&startDate={start}&endDate={end}", null, cancellationToken); _dataAdapter.Json = Toolbox.Json.RemoveEntry(_dataAdapter.Json, "NaN"); stockCandle = JsonSerializer.Deserialize <StockCandles>(_dataAdapter.Json, _dataAdapter.JsonSerializerOptions); if (stockCandle.Empty) { _logger.LogInformation("GetPriceHistoryAsync empty {exchange} {symbol}", instrument.Exchange, instrument.Symbol); } else { await stocksDbContext.AddRangeAsync(stockCandle.Candles.Select(x => new PriceHistory() { Symbol = instrument.Symbol, DateTime = DateTime.UnixEpoch.AddMilliseconds(x.DateTime), Exchange = instrument.Exchange, Open = x.Open, Close = x.Close, High = x.High, Low = x.Low, Volume = x.Volume, //Instrument = instrument, Updated = DateTime.UtcNow }).OrderBy(x => x.DateTime), cancellationToken); await stocksDbContext.SaveChangesAsync(cancellationToken); _logger.LogInformation("GetPriceHistoryAsync added {exchange} {symbol}", instrument.Exchange, instrument.Symbol); } } catch (Exception exception) { _logger.LogWarning("GetPriceHistoryAsync {exchange} {symbol} {message}", instrument.Exchange, instrument.Symbol, exception.Message); } } _logger.LogInformation("GetPriceHistoryAsync completed {now}", DateTime.Now); }
public StocksService(StocksDbContext db) { _db = db; }
public async Task GetInstrumentsAsync(CancellationToken cancellationToken) { _logger.LogInformation("GetInstrumentsAsync started {now}", DateTime.Now); Instrument ins; List <char> characters; IAsyncEnumerable <Instrument> instruments; _dataAdapter.JsonSerializerOptions = new(); _dataAdapter.JsonSerializerOptions.PropertyNameCaseInsensitive = true; characters = new(); for (byte i = Convert.ToByte('A'); i <= Convert.ToByte('Z'); i++) { characters.Add(Convert.ToChar(i)); } foreach (char character in characters) { try { using StocksDbContext stocksDbContext = _dataAdapter.StocksDbContextFactory.CreateDbContext(); _dataAdapter.Json = await Requester.SendRequestAsync(Enums.HttpVerb.Get, $"{_dataAdapter.Settings["InstrumentsUri"]}?apikey={_dataAdapter.Settings["ApiKey"]}&symbol={character}.*&projection=symbol-regex", null, cancellationToken); _dataAdapter.Json = Toolbox.Json.RemoveTopLevelKeys(_dataAdapter.Json); instruments = JsonSerializer.Deserialize <IAsyncEnumerable <Instrument> >(_dataAdapter.Json, _dataAdapter.JsonSerializerOptions); await foreach (Instrument instrument in instruments) { try { _logger.LogInformation("GetInstrumentsAsync processing {exchange} {symbol}", instrument.Exchange, instrument.Symbol); ins = await stocksDbContext.FindAsync <Instrument>(new object[] { instrument.Exchange, instrument.Symbol }, cancellationToken); if (ins == null) { await stocksDbContext.AddAsync(instrument, cancellationToken); } else { ins.Cusip = instrument.Cusip; ins.AssetType = instrument.AssetType; ins.Updated = DateTime.UtcNow; stocksDbContext.Update(ins); } await stocksDbContext.SaveChangesAsync(cancellationToken); } catch { _logger.LogError("GetInstrumentsAsync error updaing {symbol}", instrument.Symbol); } finally { _logger.LogInformation("GetInstrumentsAsync processed {exchange} {symbol}", instrument.Exchange, instrument.Symbol); } } } catch (Exception exception) { _logger.LogError("GetInstrumentsAsync {message}", exception.Message); } } _logger.LogInformation("GetInstrumentsAsync completed {now}", DateTime.Now); }
public UsersService(IOptions <AppSettings> appSettings, StocksDbContext db) { _appSettings = appSettings.Value; _db = db; }
public async Task <IReadOnlyCollection <Models.TdAmeritrade.Account.Account> > UpdateAccountAsync(CancellationToken cancellationToken = default) { IReadOnlyCollection <Models.TdAmeritrade.Account.Account> accounts; SecuritiesAccount securitiesAccount; Instrument ins; Position pos; DateTime updated; updated = DateTime.UtcNow; JsonSerializerOptions.PropertyNameCaseInsensitive = true; Json = await Requester.SendRequestAsync(Enums.HttpVerb.Get, $"{Settings["AccountsUri"]}?fields=positions,orders", null, cancellationToken); accounts = JsonSerializer.Deserialize <IReadOnlyCollection <Models.TdAmeritrade.Account.Account> >(Json, JsonSerializerOptions); foreach (Models.TdAmeritrade.Account.Account account in accounts) { securitiesAccount = await StocksDbContext.FindAsync <SecuritiesAccount>(new object[] { account.SecuritiesAccount.AccountId }, cancellationToken); if (securitiesAccount == null) { securitiesAccount = new SecuritiesAccount(StocksDbContext, Settings, account.SecuritiesAccount); await StocksDbContext.AddAsync(securitiesAccount, cancellationToken); } else { securitiesAccount.IsClosingOnlyRestricted = account.SecuritiesAccount.IsClosingOnlyRestricted; securitiesAccount.IsDayTrader = account.SecuritiesAccount.IsDayTrader; securitiesAccount.RoundTrips = account.SecuritiesAccount.RoundTrips; securitiesAccount.Type = account.SecuritiesAccount.Type; securitiesAccount.Updated = updated; securitiesAccount.CurrentBalances.AccruedInterest = account.SecuritiesAccount.CurrentBalances.AccruedInterest; securitiesAccount.CurrentBalances.BondValue = account.SecuritiesAccount.CurrentBalances.BondValue; securitiesAccount.CurrentBalances.CashAvailableForTrading = account.SecuritiesAccount.CurrentBalances.CashAvailableForTrading; securitiesAccount.CurrentBalances.CashAvailableForWithdrawal = account.SecuritiesAccount.CurrentBalances.CashAvailableForWithdrawal; securitiesAccount.CurrentBalances.CashBalance = account.SecuritiesAccount.CurrentBalances.CashBalance; securitiesAccount.CurrentBalances.CashCall = account.SecuritiesAccount.CurrentBalances.CashCall; securitiesAccount.CurrentBalances.CashDebitCallValue = account.SecuritiesAccount.CurrentBalances.CashDebitCallValue; securitiesAccount.CurrentBalances.CashReceipts = account.SecuritiesAccount.CurrentBalances.CashReceipts; securitiesAccount.CurrentBalances.LiquidationValue = account.SecuritiesAccount.CurrentBalances.LiquidationValue; securitiesAccount.CurrentBalances.LongMarketValue = account.SecuritiesAccount.CurrentBalances.LongMarketValue; securitiesAccount.CurrentBalances.LongNonMarginableMarketValue = account.SecuritiesAccount.CurrentBalances.LongNonMarginableMarketValue; securitiesAccount.CurrentBalances.LongOptionMarketValue = account.SecuritiesAccount.CurrentBalances.LongOptionMarketValue; securitiesAccount.CurrentBalances.MoneyMarketFund = account.SecuritiesAccount.CurrentBalances.MoneyMarketFund; securitiesAccount.CurrentBalances.PendingDeposits = account.SecuritiesAccount.CurrentBalances.PendingDeposits; securitiesAccount.CurrentBalances.Savings = account.SecuritiesAccount.CurrentBalances.Savings; securitiesAccount.CurrentBalances.ShortMarketValue = account.SecuritiesAccount.CurrentBalances.ShortMarketValue; securitiesAccount.CurrentBalances.ShortOptionMarketValue = account.SecuritiesAccount.CurrentBalances.ShortOptionMarketValue; securitiesAccount.CurrentBalances.TotalCash = account.SecuritiesAccount.CurrentBalances.TotalCash; securitiesAccount.CurrentBalances.UnsettledCash = account.SecuritiesAccount.CurrentBalances.UnsettledCash; securitiesAccount.CurrentBalances.Updated = updated; securitiesAccount.Positions.Clear(); if (account.SecuritiesAccount.Positions != null) { foreach (Models.TdAmeritrade.Account.Position position in account.SecuritiesAccount.Positions) { ins = await Instrument.GetInstrumentAsync(StocksDbContext, Settings, position.Instrument, cancellationToken); pos = await StocksDbContext.FindAsync <Position>(new object[] { account.SecuritiesAccount.AccountId, ins.Exchange, ins.Symbol }); if (pos == null) { pos = new Position(StocksDbContext, Settings, position, account.SecuritiesAccount.AccountId); } else { pos.AveragePrice = position.AveragePrice; pos.CurrentDayProfitLoss = position.CurrentDayProfitLoss; pos.CurrentDayProfitLossPercentage = position.CurrentDayProfitLossPercentage; pos.Instrument = ins; pos.LongQuantity = position.LongQuantity; pos.MarketValue = position.MarketValue; pos.SettledLongQuantity = position.SettledLongQuantity; pos.SettledShortQuantity = position.SettledShortQuantity; pos.ShortQuantity = position.ShortQuantity; pos.Updated = updated; } securitiesAccount.Positions.Add(pos); } } StocksDbContext.Update(securitiesAccount); } } await StocksDbContext.SaveChangesAsync(cancellationToken); return(accounts); }