def val_signals(self, variant='daily', func=None, shares_index=SHARES_DILUTED): """ Calculate valuation signals such as P/E and P/Sales ratios. :param variant: String with the frequency of the results. Valid options: - 'daily': The result has daily data-points, same as share-prices. - 'latest' The result is only for the latest share-price dates. :param func: Function to apply on a per-stock basis on the financial data, before calculating the valuation signals. This is useful e.g. to calculate multi-year averages of the Net Income and Revenue and use those when calculating P/E and P/Sales ratios. This should be a real function (not a lambda-function) because its name will be used in the cache-filename. Example: `func=sf.avg_ttm_2y` :param shares_index: String with the column-name for the share-counts. SHARES_DILUTED takes the potential diluting impact of stock-options into account, so it results in more conservative valuation ratios than SHARES_BASIC. :return: Pandas DataFrame """ # Load the required datasets. # This is only really necessary if the cache-file needs refreshing, # but it is easier to program like this and the overhead is small. df_prices = self.load_shareprices(variant=variant) df_income_ttm = self.load_income(variant='ttm') df_balance_ttm = self.load_balance(variant='ttm') df_cashflow_ttm = self.load_cashflow(variant='ttm') # List of datasets used to determine if disk-cache must be refreshed. datasets = [('shareprices', variant), ('income', 'ttm'), ('balance', 'ttm'), ('cashflow', 'ttm')] # List of arguments used to uniquely identify the cache-file. cache_ids = [variant, _func_name(func=func), shares_index] # Create dict with disk-cache arguments. cache_args = self._cache_args(datasets=datasets, cache_ids=cache_ids) # Calculate the signals, or load the DataFrame from the disk-cache. df_result = val_signals(df_prices=df_prices, df_income_ttm=df_income_ttm, df_balance_ttm=df_balance_ttm, df_cashflow_ttm=df_cashflow_ttm, shares_index=shares_index, func=func, **self._signal_args, **cache_args) return df_result
def fin_signals(self, variant='daily', func=None): """ Calculate financial signals such as Net Profit Margin, Debt Ratio, etc. :param variant: String with the frequency of the results. Valid options: - 'quarterly': The result has 4 data-points per year. - 'daily': The result has daily data-points, same as share-prices. - 'latest' The result is only for the latest share-price dates. :param func: Function to apply on a per-stock basis after the signals have been calculated, but before they have been reindexed to daily data-points. This is useful e.g. to calculate multi-year averages. This should be a real function (not a lambda-function) because its name will be used in the cache-filename. Example: `func=sf.avg_ttm_2y` to calculate 2-year averages. Example: `func=sf.rel_change_ttm_1y` to calculate 1-year change. :return: Pandas DataFrame """ # Load the required datasets. # This is only really necessary if the cache-file needs refreshing, # but it is easier to program like this and the overhead is small. df_income_ttm = self.load_income(variant='ttm') df_balance_ttm = self.load_balance(variant='ttm') df_cashflow_ttm = self.load_cashflow(variant='ttm') # List of datasets used to determine if disk-cache must be refreshed. datasets = [('income', 'ttm'), ('balance', 'ttm'), ('cashflow', 'ttm')] # Load dataset with shareprices? if variant in ['daily', 'latest']: # Load share-prices for the given variant. df_prices = self.load_shareprices(variant=variant) # Append to the list of datasets we are using here. datasets.append(('shareprices', variant)) elif variant == 'quarterly': # Share-prices are not used to reindex the results. df_prices = None else: # Raise exception. msg = 'invalid arg variant={0}'.format(variant) raise ValueError(msg) # List of arguments used to uniquely identify the cache-file. cache_ids = [variant, _func_name(func=func)] # Create dict with disk-cache arguments. cache_args = self._cache_args(datasets=datasets, cache_ids=cache_ids) # Calculate the signals, or load the DataFrame from the disk-cache. df_result = fin_signals(df_income_ttm=df_income_ttm, df_balance_ttm=df_balance_ttm, df_cashflow_ttm=df_cashflow_ttm, df_prices=df_prices, func=func, **self._signal_args, **cache_args) return df_result