Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
        }
Пример #5
0
        // ---------------------------------------------------------------------------------------- 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;
        }
Пример #6
0
        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);
        }