private async Task CalcStockMinuteReturn(int stockId, StockPriceDto stockPriceDto, DateTime savingDate) { //get nearest 1 minute or older price var nearestMinutePrice = await _portfolioContext.PriceRecords .Where(pr => pr.Datetime <= savingDate.AddMinutes(-1)) .Where(pr => pr.StockId == stockId) .OrderByDescending(pr => pr.Datetime) .Select(pr => pr.Price) .FirstAsync(); var existingRecord = await _portfolioContext.MinuteReturns .Where(pr => pr.DateTime == savingDate && pr.StockId == stockId) .FirstOrDefaultAsync(); if (existingRecord != null) { //modify existing record if already exists existingRecord.Return = stockPriceDto.Price - nearestMinutePrice; } else { _portfolioContext.MinuteReturns.Add( new StockMinuteReturn() { DateTime = savingDate, Return = stockPriceDto.Price - nearestMinutePrice, StockId = stockId }); } }
public List <ProfitReport> GroupProfitByTicker(List <TradeHistory> histories) { List <ProfitReport> profitReports = histories.GroupBy ( history => history.Ticker, history => history, (key, group) => { StockPriceDto price = _liveDateRepo.GetLastStockPrice(key); ProfitReport profit = new ProfitReport { Ticker = key, AsOfDate = DateTime.Today, Cost = CalculatePortfolioCost(group.ToList()), Quantity = CalculatePortfolioQuantity(group.ToList()), CurPrice = price.LatestPrice.ClosePrice, PrePrice = price.LatestPrice.PrePrice }; profit.MarketValue = profit.CurPrice * profit.Quantity; profit.DailyProfit = (profit.CurPrice - profit.PrePrice) * profit.Quantity; profit.InceptionProfit = profit.MarketValue != 0 ? profit.MarketValue - profit.Cost : 0; return(profit); } ) .OrderBy(p => p.Ticker) .ToList(); return(profitReports); }
public void Post([FromForm] StockPriceDto stockPriceDto) { //SSV if (ModelState.IsValid) { var isAdded = repository.Add(stockPriceDto); } }
public async Task PutStockPriceChange(int stockid, StockPriceDto stockPriceDto) { //locate stock information var currentStock = await _portfolioContext.Stocks .Where(p => p.StockId == stockid) .FirstAsync(); // format date (strip away seconds, milliseconds, etc) var baseDate = stockPriceDto.DateTime; var savingDate = new DateTime( baseDate.Year, baseDate.Month, baseDate.Day, baseDate.Hour, baseDate.Minute, 0, DateTimeKind.Local); // if current stock price is more recent then ... // update the .. update time and latest price information if (currentStock.LastUpdated <= savingDate) { currentStock.LatestPrice = stockPriceDto.Price; currentStock.LastUpdated = savingDate; } await CreateStockPriceRecord(stockid, stockPriceDto, savingDate); await CalcStockMinuteReturn(stockid, stockPriceDto, savingDate); await CalcStockHourReturn(stockid, stockPriceDto, savingDate); await CalcStockDailyReturn(stockid, stockPriceDto, savingDate); await _portfolioContext.SaveChangesAsync(); Dictionary <int, double> PortfoliosByPrice = await CreateOrUpdatePortfolioPriceRecord(stockid, savingDate); foreach (var portfolioPrice in PortfoliosByPrice) { var dailyReturnTask = CalcPortfolioDailyReturn(portfolioPrice.Key, portfolioPrice.Value, savingDate); var hourReturnTask = CalcPortfolioHourReturn(portfolioPrice.Key, portfolioPrice.Value, savingDate); var minuteReturnTask = CalcPortfolioMinuteReturn(portfolioPrice.Key, portfolioPrice.Value, savingDate); Task.WaitAll(dailyReturnTask, hourReturnTask, minuteReturnTask); } await _portfolioContext.SaveChangesAsync(); await _hubContext.Clients.All.SendAsync("UpdatePortfolio"); }
public IActionResult AddStockPrice(StockPriceDto Obj) { if (ModelState.IsValid == false) { return(BadRequest(ModelState)); } var result = stockPriceService.AddStockPrice(Obj); if (!result) { return(BadRequest("Error saving products")); } //return CreatedAtRoute("GetProductById", new { id = obj.ID }); return(StatusCode(201)); }
public StockPriceDto GetLastStockPrice(string ticker) { try { // -- check if we quote the same ticker price in past 30 seconds if (priceCache.ContainsKey(ticker) && DateTime.Now < priceCache[ticker].QuateTime.AddSeconds(LiveDateCacheIntervalInSecond) && priceCache[ticker].LatestPrice.ClosePrice != 0) { _logger.Info($"price is found in the cache: {JsonConvert.SerializeObject(priceCache[ticker])}"); return(priceCache[ticker]); } string url = new Uri(ALPHA_VANTAGE_BASE_URL + string.Format(GET_LATEST_PRICE_BY_TICKER, ticker)).AbsoluteUri; using (HttpClient http = new HttpClient()) { HttpResponseMessage response = http.GetAsync(url).Result; if (response.StatusCode == HttpStatusCode.OK) { string jsonStr = response.Content.ReadAsStringAsync().Result; StockPriceDto price = JsonConvert.DeserializeObject <StockPriceDto>(jsonStr); _logger.Info($"Get response from [{url}]: status code {response.StatusCode} with result: {JsonConvert.SerializeObject(price)}"); // -- refresh cache price.QuateTime = DateTime.Now; if (priceCache.ContainsKey(ticker)) { priceCache[ticker] = price; } else { priceCache.Add(ticker, price); } return(price); } _logger.Warn($"Get response from [{url}]: status code {response.StatusCode}"); } } catch (Exception ex) { _logger.Error(ex); } return(new StockPriceDto()); }
private async Task CreateStockPriceRecord(int stockId, StockPriceDto stockPriceDto, DateTime savingDate) { // check if record with current date and stock already exists var existingRecord = await _portfolioContext.PriceRecords .Where(pr => pr.Datetime == savingDate && pr.StockId == stockId) .FirstOrDefaultAsync(); if (existingRecord != null) { //modify existing record if already exists existingRecord.Price = stockPriceDto.Price; } else { //add new price record if it doesn´t _portfolioContext.PriceRecords.Add( new StockPriceRecord() { Datetime = savingDate, Price = stockPriceDto.Price, StockId = stockId }); } }
public bool UpdateStockPrice(StockPriceDto stockPrice) { var Obj = mapper.Map <StockPrice>(stockPrice); return(repository.UpdateStockPrice(Obj)); }