示例#1
0
 private static void UpdateAnalysis(PiotroskiScore newValue, int year, int rating, float ebitda)
 {
     newValue.FYear   = year;
     newValue.Rating  = rating;
     newValue.EBITDA  = (long)ebitda;
     newValue.Revenue = null;
 }
        public async Task <string> GetCompanyFundamentals(string companyName)
        {
            _logger.LogTrace("Starting fundamental details");
            var tickersToUse = await _resolveCompanyName.ResolveCompanyNameOrTicker(companyName);

            if (tickersToUse.IsNullOrWhiteSpace())
            {
                return($"We could not resolve ticker/company Name {companyName}; possible reason Google registered name is Alphabet Inc.\n\n" +
                       $"Hint: try with symbol or ticker");
            }
            var fulfillmentText = new StringBuilder();

            try
            {
                int counter = 0;
                foreach (var ticker in tickersToUse.Split(','))
                {
                    var ratingsMd = _connectionHandlerCF.Get().Where(x => x.Ticker.ToLower().Equals(ticker.ToLower()))
                                    .OrderByDescending(x => x.FYear).FirstOrDefault();
                    PiotroskiScore computedRating = null;

                    if (ratingsMd != null && DateTime.Now.Year - ratingsMd.FYear <= 2)
                    {
                        computedRating = _mapper.Map <PiotroskiScore>(ratingsMd);
                    }
                    fulfillmentText.Append(await BuildCompanyProfile(ticker, computedRating));
                    if (++counter >= 2)
                    {
                        break;
                    }
                }
                if (counter >= 2)
                {
                    fulfillmentText.Append($"Limiting result set as the search term {companyName} resolved to too many results.\n");
                }
            }
            catch (Exception ex)
            {
                _logger.LogCritical($"Error while processing Get Company Fundamentals; \n{ex.Message}");
                return("");
            }
            if (fulfillmentText.ToString().Contains("Piotroski"))
            {
                fulfillmentText.Append("\nNote: Piotroski F-Score is based on company fundamentals; " +
                                       "a rating greater than 6 indicates strong fundamentals.");
            }
            return(fulfillmentText.ToString());
        }
        private string BuildCommonStockMessage(PiotroskiScore computedRating, string symbol)
        {
            var returnText = new StringBuilder();

            if (computedRating == null)
            {
                returnText.Append($" We do not have any additional details about {symbol} at this time.\n");
                return(returnText.ToString());
            }
            returnText.Append($"Additional details about {symbol} using its SEC filings.\n");
            returnText.Append($" Revenues {((decimal)computedRating.Revenue).ToKMB()}.\n");
            returnText.Append($" EBITDA {((decimal)(computedRating.EBITDA)).ToKMB()}. \n");
            returnText.Append($" Gross Margin {computedRating.ProfitablityRatios["Gross Margin"]}%.\n");
            returnText.Append($" Operating Margin {computedRating.ProfitablityRatios["Operating Margin"]}%.\n");
            returnText.Append($" Net Profit Margin {computedRating.ProfitablityRatios["Net Profit Margin"]}%.\n");
            returnText.Append($" Return on Equity {computedRating.ProfitablityRatios["Return on Equity"]}%.\n");
            returnText.Append($" Return on Assets {computedRating.ProfitablityRatios["Return on Assets"]}%.\n");
            if (computedRating.Rating != 0)
            {
                returnText.Append($" Piotroski F-Score ratings for {symbol} is {computedRating.Rating}.  \n");
            }
            return(returnText.ToString());
        }
        private async Task <string> BuildCompanyProfile(string ticker, PiotroskiScore computedRating)
        {
            var symbol          = Regex.Replace(ticker, ".{1}", "$0 ");
            var companyOverview = await ObtainCompanyOverview(ticker);

            var companyStats = await ObtainCompanyStats(ticker);

            companyStats.ttmDividendRate = companyStats.ttmDividendRate == null ? 0 :
                                           companyStats.ttmDividendRate;
            companyStats.ttmEPS = companyStats.ttmEPS == null ? 0 :
                                  companyStats.ttmEPS;
            var returnText = new StringBuilder();

            if (companyOverview == null || string.IsNullOrWhiteSpace(companyOverview.Symbol))
            {
                returnText.Append($" No basic information about {symbol} found at this time\n");
            }
            else
            {
                returnText.Append($"Basic information about {companyOverview.CompanyName} trading with symbol {symbol}.\n");
                returnText.Append($" {(companyOverview.Description.IsNullOrWhiteSpace() ? "This information is not available now" : companyOverview.Description.TruncateAtWord(175))}\n");
                if (companyOverview.Description.Length >= 175)
                {
                    returnText.Append("\n\n..... more removed. ....\n\n");
                }
                returnText.Append($" Its industry sector is {companyOverview.Sector} and falls under {companyOverview.Industry}.\n\n ");
                returnText.Append($" {companyOverview.CompanyName} has a market cap of {((decimal)companyStats.marketcap).ToKMB()}, " +
                                  $" TTM E P S of about {((decimal)companyStats.ttmEPS).ToKMB()}, and  divident rate around {((decimal)companyStats.ttmDividendRate).ToKMB()}.\n");
            }
            switch (companyOverview.IssueType.ToLower())
            {
            case "cs":
                returnText.Append(BuildCommonStockMessage(computedRating, symbol));
                //1returnText.Append(await BuildAnalystsRatings(ticker));
                break;

            case "ad":
                returnText.Append($" {symbol} is an American Depositary Receipt: ADR");
                break;

            case "re":
                returnText.Append($" {symbol} is a Real estate investment trust: REIT");
                break;

            case "ce":
            case "cef":
                returnText.Append($" {symbol} is a closed end fund");
                break;

            case "si":
                returnText.Append($" {symbol} is a secondary issue");
                break;

            case "et":
            case "etf":
                returnText.Append($" {symbol} is a exchange traded fund; ETF");
                break;

            case "ps":
            case "wt":
                returnText.Append($" {symbol} is a preferred stock or warrant; individuals do not trade these!");
                break;

            default:
                returnText.Append($" No additional information is available for {symbol}");
                break;
            }
            return(returnText.ToString());
        }
示例#5
0
        public async Task <WebhookResponse> GetCompanyRatings(GoogleCloudDialogflowV2WebhookRequest ratingsParameters)
        {
            _log.LogTrace("Start obtain fundamentals");
            var companyNameToResolve = ratingsParameters.QueryResult.Parameters[companyName].ToString();
            var tickersToUse         = await _obtainCompanyDetails.ResolveCompanyNameOrTicker(companyNameToResolve);

            if (string.IsNullOrWhiteSpace(tickersToUse))
            {
                return(new WebhookResponse
                {
                    FulfillmentText = $"Could not resolve {companyNameToResolve}"
                });
            }

            var fulfillmentText = new StringBuilder();

            try
            {
                int counter = 0;
                foreach (var ticker in tickersToUse.Split(','))
                {
                    var computedRatingMd = _connectionHandlerCF.Get().Where(x => x.Ticker.ToLower().Equals(ticker.ToLower()) &&
                                                                            x.FYear == DateTime.Now.Year).FirstOrDefault();
                    if (computedRatingMd == null)
                    {
                        computedRatingMd = _connectionHandlerCF.Get().Where(x => x.Ticker.ToLower().Equals(ticker.ToLower()) &&
                                                                            x.FYear == DateTime.Now.Year - 1).FirstOrDefault();
                    }
                    PiotroskiScore computedRating = null;
                    if (computedRatingMd != null)
                    {
                        computedRating = Mapper.Map <PiotroskiScore>(computedRatingMd);
                    }
                    fulfillmentText.Append(await BuildCompanyProfile(ticker, computedRating));
                    if (++counter >= 2)
                    {
                        break;
                    }
                }
                if (counter >= 2)
                {
                    fulfillmentText.Append($"Limiting result set as the search term {companyNameToResolve} resolved to too many results.\n");
                }
            }
            catch (Exception ex)
            {
                _log.LogCritical($"Error while processing Getting Company Ratings; \n{ex.Message}");
                return(new WebhookResponse
                {
                    FulfillmentText = Utilities.ErrorReturnMsg() + Utilities.EndOfCurrentRequest()
                });
            }
            if (fulfillmentText.ToString().Contains("Piotroski"))
            {
                fulfillmentText.Append("Note: Piotroski F-Score is based on company fundamentals; " +
                                       "a rating greater than 6 indicates strong fundamentals");
            }
            var webhookResponse = new WebhookResponse
            {
                FulfillmentText = fulfillmentText.ToString()
            };

            _log.LogTrace("End obtain fundamentals");
            return(webhookResponse);
        }
示例#6
0
        public async Task UpdateAnalysis()
        {
            var ac = await _hcl.GetAllCompaniesFromDbAsync();

            try
            {
                await _dfr.ParseKeyFinanceFromS3(ServiceExtensions.BucketName, ServiceExtensions.Region, "1. Key Ratios.xlsx");
            }
            catch (Exception ex)
            {
                _logger.LogError($"Error while reading excel file\n{ex.Message}");
                return;
            }
            var result = await _dbpiScore.RemoveAll();

            _logger.LogDebug($"Excel file contains {_dfr.dataCollection.Count}");
            List <DataCollection> dcl          = _dfr.dataCollection;
            List <CompanyDetail>  allCompanies = await _hcl.GetAllCompaniesFromDbAsync();

            var counter    = 0;
            var newValues  = new List <PiotroskiScoreMd>();
            var updateTime = DateTime.Now;

            foreach (var dc in dcl)
            {
                if (string.IsNullOrWhiteSpace(dc.CompanyName) || string.IsNullOrWhiteSpace(dc.Ticker))
                {
                    _logger.LogDebug($"Skipping {dc.CompanyName} => {dc.Ticker} due to missing details");
                    continue;
                }
                var selected = (from comp in allCompanies
                                where (comp.Ticker == dc.Ticker && comp.Name == dc.CompanyName)
                                select comp).FirstOrDefault();
                if (selected == null)
                {
                    _logger.LogDebug("Referential integrity error");
                    _logger.LogDebug($"Did not find {dc.CompanyName} => {dc.Ticker} in Company Details");
                    continue;
                }

                var ProfitablityRatios = new Dictionary <string, decimal>
                {
                    { "Gross Margin", (decimal)dc.GrossMargin },
                    { "Operating Margin", (decimal)dc.OperatingMargin },
                    { "Net Profit Margin", (decimal)dc.NetMargin },
                    { "Return on Equity", (decimal)dc.ReturnOnEquity },
                    { "Return on Assets", (decimal)dc.ReturnOnAssets }
                };
                var newValue = new PiotroskiScore
                {
                    SimId              = selected.SimId,
                    FYear              = DateTime.Now.Year,
                    Rating             = dc.PiotroskiScoreCurrent,
                    EBITDA             = (long)dc.EbitdaCurrent,
                    LastUpdate         = DateTime.Now,
                    ProfitablityRatios = ProfitablityRatios,
                    Revenue            = dc.Revenue,
                    Ticker             = dc.Ticker
                };
                newValues.Add(Mapper.Map <PiotroskiScoreMd>(newValue));
                newValue.ProfitablityRatios.Clear();
                UpdateAnalysis(newValue, DateTime.Now.Year - 1, dc.PiotroskiScore1YrAgo, dc.Ebitda1YrAgo);
                newValues.Add(Mapper.Map <PiotroskiScoreMd>(newValue));
                UpdateAnalysis(newValue, DateTime.Now.Year - 2, dc.PiotroskiScore2YrAgo, dc.Ebitda2YrAgo);
                newValues.Add(Mapper.Map <PiotroskiScoreMd>(newValue));
                UpdateAnalysis(newValue, DateTime.Now.Year - 3, dc.PiotroskiScore3YrAgo, dc.Ebitda3YrAgo);
                newValues.Add(Mapper.Map <PiotroskiScoreMd>(newValue));
                selected.LastUpdate = updateTime;
                await _hcl.UpdateCompanyDetailAsync(selected.SimId, dc.Sector, updateTime);

                if (++counter % 500 == 0)
                {
                    Console.WriteLine($"Updated {counter} firms {DateTime.Now}");
                    _logger.LogDebug($"Updated {counter} firms");
                    await _dbpiScore.Create(newValues);

                    newValues.Clear();
                }
            }
            if (newValues.Any())
            {
                Console.WriteLine($"Updated {counter} firms");
                _logger.LogDebug($"Updated {counter} firms");
                await _dbpiScore.Create(newValues);
            }
        }