public bool UpdateProfile(Data.Entities.Profile editedProfile) { Data.Entities.Profile profileToUpdate = new Data.Entities.Profile(); int updateCount = 0; try { IQueryable <Data.Entities.Profile> existingProfile = _ctx.Profile.Where(p => p.TickerSymbol == editedProfile.TickerSymbol).AsQueryable(); existingProfile.First().TickerDescription = editedProfile.TickerDescription; existingProfile.First().DividendRate = editedProfile.DividendRate; existingProfile.First().DividendYield = editedProfile.DividendYield; existingProfile.First().PERatio = editedProfile.PERatio; existingProfile.First().DividendMonths = editedProfile.DividendMonths; existingProfile.First().DividendPayDay = editedProfile.DividendPayDay; existingProfile.First().UnitPrice = editedProfile.UnitPrice; existingProfile.First().LastUpdate = Convert.ToDateTime(editedProfile.LastUpdate); _ctx.UpdateRange(existingProfile); updateCount = _ctx.SaveChanges(); } catch (Exception) { return(false); } return(updateCount == 1 ? true : false); }
public bool SaveProfile(Data.Entities.Profile newProfile) { // Check for existing Profile first, therefore run through UI 'Asset Profile' // menu option first, utilizing 'Create Profile' button & debug. int savedCount = 0; bool profileSaved = false; try { _ctx.Add(newProfile); savedCount = _ctx.SaveChanges(); profileSaved = savedCount == 1 ? true : false; } catch (Exception ex) { Exception err = ex.InnerException; Log.Error("Error saving Profile data via ProfileDataProcessing.SaveProfile() due to: {0}.", err); } return(profileSaved); }
public ProfileForUpdateVm Process12MosRevenueHistory(string investorId) { // Revenue processing in response to investor-initiated Profile updating. ProfileForUpdateVm vm = new ProfileForUpdateVm(); try { string exceptionTickers = string.Empty; IQueryable <string> currentPositions = _ctx.Position.Where(p => p.PositionAsset.InvestorId == investorId && p.Status == "A") .Select(p => p.PositionAsset.Profile.TickerSymbol) .Distinct() .AsQueryable(); IQueryable <PositionIncomeVm> joinedPositionIncome = _ctx.Position.Where(p => p.PositionAsset.InvestorId == investorId && p.Status == "A") .Join(_ctx.Income, p => p.PositionId, i => i.PositionId, (p, i) => new PositionIncomeVm { ProfileId = p.PositionAsset.Profile.ProfileId, PositionId = p.PositionId, TickerSymbol = p.PositionAsset.Profile.TickerSymbol, Account = p.AccountType.AccountTypeDesc, DateRecvd = i.DateRecvd, DividendYield = Convert.ToDecimal(p.PositionAsset.Profile.DividendYield), TickerDescription = p.PositionAsset.Profile.TickerDescription }) .OrderBy(results => results.TickerSymbol) .ThenBy(results => results.Account) .AsQueryable(); joinedPositionIncome.OrderBy(pi => pi.DateRecvd); // To be initialized return collection. List <Data.Entities.Profile> updateProfileModelList = new List <Data.Entities.Profile>(); foreach (string currentTicker in currentPositions) { // Do we have income data for this position that is greater than or equal to a least a year old, as is necessary // for accurate calculation of both 1) dividend distribution frequency, and 2) dividend payout months values. // Back-dated info is always from the 1st of the calculated year ago month. int olderThanOneYearRevenueCount = joinedPositionIncome .Where(pi => pi.TickerSymbol == currentTicker && pi.DateRecvd <= DateTime.Now.AddMonths(-12).AddDays(-DateTime.Now.Day)).Count(); if (olderThanOneYearRevenueCount > 0) { Data.Entities.Profile updateProfileModel = new Data.Entities.Profile { TickerSymbol = currentTicker }; IQueryable <PositionIncomeVm> withinLastYearData = joinedPositionIncome .Where(pi => pi.TickerSymbol == currentTicker && pi.DateRecvd >= DateTime.Now.AddMonths(-12).AddDays(-DateTime.Now.Day)) .AsQueryable(); // Investor may have same position in multiple accounts, e.g. IRA, Roth-IRA. int dupAcctCount = withinLastYearData.Select(pi => pi.Account).Distinct().Count(); if (dupAcctCount > 1) { IQueryable <PositionIncomeVm> withUniqueAcct = withinLastYearData .Where(pi => pi.Account == withinLastYearData.First().Account).OrderBy(pi => pi.TickerSymbol); updateProfileModel.DividendFreq = CalculateDividendFrequency(withUniqueAcct); updateProfileModel.DividendMonths = updateProfileModel.DividendFreq != "M" ? CalculateDividendMonths(withUniqueAcct) : "N/A"; updateProfileModel.DividendPayDay = CommonSvc.CalculateMedianValue(BuildDivDaysList((withUniqueAcct))); } else { updateProfileModel.DividendFreq = CalculateDividendFrequency(withinLastYearData); updateProfileModel.DividendMonths = updateProfileModel.DividendFreq != "M" ? CalculateDividendMonths(withinLastYearData) : "N/A"; updateProfileModel.DividendPayDay = CommonSvc.CalculateMedianValue(BuildDivDaysList((withinLastYearData))); } // Satisfy 'required' Profile attributes & ProfileId for updating. updateProfileModel.ProfileId = joinedPositionIncome.Where(d => d.TickerSymbol == currentTicker).First().ProfileId; updateProfileModel.DividendYield = joinedPositionIncome.Where(d => d.TickerSymbol == currentTicker).First().DividendYield; updateProfileModel.TickerDescription = joinedPositionIncome.Where(d => d.TickerSymbol == currentTicker).First().TickerDescription; updateProfileModel.LastUpdate = DateTime.Now; updateProfileModelList.Add(updateProfileModel); } else { exceptionTickers += currentTicker + ", "; } } if (exceptionTickers.Length > 0) { exceptionTickers.Trim(); exceptionTickers = exceptionTickers.Remove(exceptionTickers.LastIndexOf(','), 1); } vm.BatchProfilesList = updateProfileModelList; vm.ExceptionTickerSymbols = (exceptionTickers.Length > 0 ? exceptionTickers : ""); vm.UpdateHasErrors = false; } catch (Exception) { vm.UpdateHasErrors = true; } return(vm); }
public Data.Entities.Profile BuildProfile(string ticker) { // Update or initialize Profile data via 3rd party Tiingo service. DateTime cutOffDateTimeForProfileUpdate = DateTime.Now.AddHours(-72); const string BaseTiingoUrl = "https://api.tiingo.com/tiingo/daily/"; const string TiingoAccountToken = "95cff258ce493ec51fd10798b3e7f0657ee37740"; ImportFileProcessing busLayerComponent = new ImportFileProcessing(null, _ctx, null); var updatedOrNewProfile = new Data.Entities.Profile(); // By default, we'll use the last 6 months for pricing history. string priceHistoryStartDate = CalculateStartDate(-180); using (var client = new HttpClient()) { client.BaseAddress = new Uri(BaseTiingoUrl + ticker); // e.g., https://api.tiingo.com/tiingo/daily/IBM client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); client.DefaultRequestHeaders.Add("Authorization", "Bearer " + TiingoAccountToken); string metaDataResponse; JArray jsonTickerPriceData; // Ex: https://api.tiingo.com/tiingo/daily/STK/prices?startDate=2018-3-26&token=95cff258ce493ec51fd10798b3e7f0657ee37740 var url = client.BaseAddress + "/prices?startDate=" + priceHistoryStartDate + "&" + "token=" + TiingoAccountToken; // Using 'Tiingo' end-point service for Profile data retreival. string webResponse = FetchProfileViaWebSync(client, url); if (webResponse == "" || webResponse == null) { return(null); } jsonTickerPriceData = JArray.Parse(webResponse); // Sort Newtonsoft JArray historical results on 'date', e.g., date info gathered. var orderedJsonTickerPriceData = new JArray(jsonTickerPriceData.OrderByDescending(obj => obj["date"])); var sequenceIndex = 0; var divCashGtZero = false; var metaDataInitialized = false; IQueryable <Data.Entities.Profile> existingProfile; // Check for Profile to update, either custom, or standard. The latter will contain // an uninitialized investorLoginName, and is accounted for in FetchDbProfile(). try { existingProfile = FetchDbProfile(ticker, investorLoginName); } catch (Exception) { Log.Error("Error retreiving Db Profile via ProfileDataProcessing.BuildProfile() for ticker: {0}", ticker); return(null); } foreach (JObject objChild in orderedJsonTickerPriceData.Children <JObject>()) { if (existingProfile != null) { // Profile update IF last updated > 72hrs ago. if (Convert.ToDateTime(existingProfile.First().LastUpdate) < cutOffDateTimeForProfileUpdate) { // Due to Tiingo API limitations, update just dividend rate. foreach (var property in objChild.Properties()) { if (property.Name != "divCash") { continue; } var cashValue = decimal.Parse(property.Value.ToString()); if (cashValue <= 0) { break; } existingProfile.First().DividendRate = decimal.Parse(property.Value.ToString()); existingProfile.First().UnitPrice = decimal.Parse(objChild.Properties().ElementAt(1).Value.ToString()); existingProfile.First().DividendYield = busLayerComponent.CalculateDividendYield(existingProfile.First().DividendRate, existingProfile.First().UnitPrice); existingProfile.First().LastUpdate = DateTime.Now; updatedOrNewProfile = existingProfile.First(); return(updatedOrNewProfile); } continue; } } if (divCashGtZero) { break; } // New Profile processing. Capture meta data (name/ticker). if (!metaDataInitialized) { var Uri = client.BaseAddress + "?token=" + TiingoAccountToken; metaDataResponse = FetchProfileViaWebSync(new HttpClient(), Uri); if (metaDataResponse == null || metaDataResponse == string.Empty) { Log.Warning("BadRequest - unable to fetch Profile meta data for: {0}", ticker); return(null); } var responseMetaData = metaDataResponse; // Content.ReadAsStringAsync(); var jsonTickerMetaData = JObject.Parse(responseMetaData); updatedOrNewProfile.TickerDescription = jsonTickerMetaData["name"].ToString().Trim(); updatedOrNewProfile.TickerSymbol = jsonTickerMetaData["ticker"].ToString().Trim(); metaDataResponse = null; metaDataInitialized = true; } // Capture most recent closing price & dividend rate (aka divCash); if (sequenceIndex == 0) { foreach (var property in objChild.Properties()) { if (property.Name != "close") { continue; } // Latest closing price. updatedOrNewProfile.UnitPrice = decimal.Parse(property.Value.ToString()); break; } } else { foreach (var property in objChild.Properties()) { if (property.Name != "divCash") { continue; } var cashValue = decimal.Parse(property.Value.ToString()); if (cashValue <= 0) { continue; } updatedOrNewProfile.DividendRate = decimal.Parse(property.Value.ToString()); updatedOrNewProfile.DividendYield = busLayerComponent.CalculateDividendYield(updatedOrNewProfile.DividendRate, updatedOrNewProfile.UnitPrice); updatedOrNewProfile.DividendPayDay = existingProfile == null ? 15 : existingProfile.First().DividendPayDay; divCashGtZero = true; break; } } sequenceIndex += 1; } // end foreach updatedOrNewProfile.ProfileId = Guid.NewGuid().ToString(); updatedOrNewProfile.CreatedBy = string.Empty; updatedOrNewProfile.EarningsPerShare = 0; updatedOrNewProfile.PERatio = 0; updatedOrNewProfile.ExDividendDate = null; } // end using updatedOrNewProfile.LastUpdate = DateTime.Now; return(updatedOrNewProfile); }
// ---------------------------------------------------------------------------------------- IEnumerable<IPerson> .ToModelCollection() END public static Data.Entities.Profile ToEntity(this Profile profileModel) { var profile = new Data.Entities.Profile(); if (profileModel == null) { return profile; } profile.ProfileId = profileModel.ProfileId; profile.PersonId = profileModel.PersonId; profile.ReceiveEmailNotification = profileModel.ReceiveEmailNotification; profile.IsActive = profileModel.IsActive; profile.IsDisabled = profileModel.IsDisabled; profile.IsValidated = profileModel.IsValidated; profile.UserId = profileModel.UserId; profile.DateModified = profileModel.DateModified; profile.DateCreated = profileModel.DateCreated; if (profileModel.Person != null) { profile.Person = ((Person)profileModel.Person).ToEntity(); } return profile; }
private object MapVmToEntities(dynamic entityToMap) { dynamic currentType = null; switch (entityToMap.GetType().Name) { case "Profile": currentType = new Data.Entities.Profile { ProfileId = entityToMap.ProfileId, CreatedBy = entityToMap.CreatedBy ?? string.Empty, DividendFreq = entityToMap.DividendFreq, DividendMonths = "NA", DividendPayDay = entityToMap.DividendPayDay, DividendRate = entityToMap.DividendRate, DividendYield = entityToMap.DividendYield > 0 ? entityToMap.DividendYield : 0M, EarningsPerShare = entityToMap.EarningsPerShare > 0 ? entityToMap.EarningsPerShare : 0M, LastUpdate = entityToMap.LastUpdate ?? DateTime.Now, PERatio = entityToMap.PERatio > 0 ? entityToMap.PERatio : 0M, TickerDescription = entityToMap.TickerDescription, TickerSymbol = entityToMap.TickerSymbol, UnitPrice = entityToMap.UnitPrice }; break; case "AssetCreationVm": currentType = new Data.Entities.Asset { AssetId = entityToMap.AssetId, AssetClassId = entityToMap.AssetClassId, InvestorId = entityToMap.InvestorId, LastUpdate = entityToMap.LastUpdate ?? DateTime.Now, ProfileId = entityToMap.ProfileId, Positions = new List <Data.Entities.Position>() }; break; case "Position": currentType = new Data.Entities.Position { PositionId = entityToMap.PositionId, AccountTypeId = entityToMap.AccountTypeId, AssetId = entityToMap.AssetId, // value needed Fees = entityToMap.Fees > 0 ? entityToMap.Fees : 0M, LastUpdate = entityToMap.LastUpdate ?? DateTime.Now, PositionDate = entityToMap.PositionDate ?? DateTime.Now, Quantity = entityToMap.Quantity, Status = "A", UnitCost = entityToMap.UnitCost }; break; default: break; } return(currentType); }