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);
        }
Example #2
0
 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);
        }
Example #4
0
 public UsersService(IOptions <AppSettings> appSettings, StocksDbContext db)
 {
     _appSettings = appSettings.Value;
     _db          = db;
 }
Example #5
0
        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);
        }