# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/yFinance_restructureData.ipynb.

# %% auto 0
__all__ = ['stockDataPlots']

# %% ../nbs/yFinance_restructureData.ipynb 5
import numpy as np
import pandas as pd

from yfinance import *

import os
from pathlib import Path

# %% ../nbs/yFinance_restructureData.ipynb 7
class stockDataPlots:
    
    def __init__(self, 
                 ticker: str):
        
        self.ticker = ticker
        
    #---
    
    def getCurrentYahooData(self):
        
        tickerObject = Ticker(self.ticker)
        
        #---
        
        # Income Statement
        incomeStatement = tickerObject.financials.T
        incomeStatementQuarterly = tickerObject.quarterly_financials.T
        
        incomeStatement.fillna(value = np.nan, inplace = True)
        incomeStatementQuarterly.fillna(value = np.nan, inplace = True)
        
        incomeStatement.reset_index(drop = False, names = 'Date', inplace = True)
        incomeStatement.set_index('Date', drop = False, inplace = True)
        incomeStatement.index.name = None
        
        incomeStatementQuarterly.reset_index(drop = False, names = 'Date', inplace = True)
        incomeStatementQuarterly.set_index('Date', drop = False, inplace = True)
        incomeStatementQuarterly.index.name = None
        
        #---
        
        incomeColsOrdered = ['Date',
                             'Total Revenue',
                             'Cost Of Revenue',
                             'Gross Profit',
                             'Gross Margin',
                             'Selling General Administrative',
                             'Research Development',
                             'Other Items',
                             'Other Operating Expenses',
                             'Total Operating Expenses',
                             'Operating Income',
                             'Operating Margin',
                             'Effect Of Accounting Charges',
                             'Extraordinary Items',
                             'Total Other Income Expense Net',
                             'Ebit',
                             'Interest Expense',
                             'Income Before Tax',
                             'Income Tax Expense',
                             'Net Income',
                             'Net Margin',
                             'Net Income From Continuing Ops',
                             'Non Recurring',
                             'Net Income Applicable To Common Shares',
                             'Minority Interest',
                             'Discontinued Operations'
                            ]
        
        incomeColsMissing = [col for col in incomeColsOrdered if col not in incomeStatement.columns]
        incomeColsMissingQuarterly = [col for col in incomeColsOrdered if col not in incomeStatementQuarterly.columns]
        
        for col in incomeColsMissing:
            incomeStatement[col] = np.nan
        
        for col in incomeColsMissingQuarterly:
            incomeStatementQuarterly[col] = np.nan
            
        #---
        
        incomeStatement['Gross Margin'] = incomeStatement['Gross Profit'] / incomeStatement['Total Revenue']
        incomeStatement['Operating Margin'] = incomeStatement['Operating Income'] / incomeStatement['Total Revenue']
        incomeStatement['Net Margin'] = incomeStatement['Net Income'] / incomeStatement['Total Revenue']
        
        incomeStatementQuarterly['Gross Margin'] = incomeStatementQuarterly['Gross Profit'] / incomeStatementQuarterly['Total Revenue']
        incomeStatementQuarterly['Operating Margin'] = incomeStatementQuarterly['Operating Income'] / incomeStatementQuarterly['Total Revenue']
        incomeStatementQuarterly['Net Margin'] = incomeStatementQuarterly['Net Income'] / incomeStatementQuarterly['Total Revenue']
        
        #---
        
        incomeStatementOrdered = incomeStatement[incomeColsOrdered]
        incomeStatementQuarterlyOrdered = incomeStatementQuarterly[incomeColsOrdered]
        
        self.incomeStatement = incomeStatementOrdered
        self.incomeStatementQuarterly = incomeStatementQuarterlyOrdered
        
        #---
        
        incomeStatementTTM = incomeStatementQuarterlyOrdered.drop('Date', axis = 1).iloc[0:4, :].sum(axis = 0, min_count = 1, numeric_only = None)
        incomeStatementTTM = pd.DataFrame(incomeStatementTTM).T
        
        incomeStatementTTM['Date'] = incomeStatementQuarterly['Date'][0]
        cols = incomeStatementTTM.columns.to_list()
        colsOrdered = cols[-1:] + cols[:-1]
        incomeStatementTTM = incomeStatementTTM[colsOrdered].set_index('Date', drop = False)
        incomeStatementTTM.index.name = None
        
        incomeStatementTTM['Gross Margin'] = incomeStatementTTM['Gross Profit'] / incomeStatementTTM['Total Revenue']
        incomeStatementTTM['Operating Margin'] = incomeStatementTTM['Operating Income'] / incomeStatementTTM['Total Revenue']
        incomeStatementTTM['Net Margin'] = incomeStatementTTM['Net Income'] / incomeStatementTTM['Total Revenue']
        
        self.incomeStatementTTM = incomeStatementTTM
        
        #------------------------------
        
        # Balance Sheet
        
        balanceSheet = tickerObject.balancesheet.T
        balanceSheetQuarterly = tickerObject.quarterly_balancesheet.T
        
        balanceSheet.fillna(value = np.nan, inplace = True)
        balanceSheetQuarterly.fillna(value = np.nan, inplace = True)
        
        balanceSheet.reset_index(drop = False, names = 'Date', inplace = True)
        balanceSheet.set_index('Date', drop = False, inplace = True)
        balanceSheet.index.name = None
        
        balanceSheetQuarterly.reset_index(drop = False, names = 'Date', inplace = True)
        balanceSheetQuarterly.set_index('Date', drop = False, inplace = True)
        balanceSheetQuarterly.index.name = None
        
        #---
        
        balanceColsOrdered = ['Date',
                              'Total Stockholder Equity',
                              'Debt To Equity Ratio',
                              'Adjusted Debt To Equity Ratio',
                              'Current Ratio',
                              'Total Assets',
                              'Total Current Assets',
                              'Cash And Cash Equivalents',
                              'Cash',
                              'Short Term Investments',
                              'Net Receivables',
                              'Inventory',
                              'Other Current Assets',
                              'Total Non Current Assets',
                              'Property Plant Equipment',
                              'Long Term Investments',
                              'Good Will',
                              'Intangible Assets',
                              'Other Assets',
                              'Total Liab',
                              'Total Current Liabilities',
                              'Accounts Payable',
                              'Other Current Liab',
                              'Total Non Current Liabilities',
                              'Long Term Debt',
                              'Deferred Long Term Asset Charges',
                              'Other Liab',
                              'Net Tangible Assets',
                              'Retained Earnings',
                              'Gains Losses Not Affecting Retained Earnings',
                              'Other Stockholder Equity',
                              'Common Stock',
                              'Short Long Term Debt'
                             ]
        
        balanceColsMissing = [col for col in balanceColsOrdered if col not in balanceSheet.columns]
        balanceColsMissingQuarterly = [col for col in balanceColsOrdered if col not in balanceSheetQuarterly.columns]
        
        for col in balanceColsMissing:
            balanceSheet[col] = np.nan
        
        for col in balanceColsMissingQuarterly:
            balanceSheetQuarterly[col] = np.nan
            
        #---
        
        balanceSheet['Total Non Current Assets'] = balanceSheet['Total Assets'] - balanceSheet['Total Current Assets']
        balanceSheet['Total Non Current Liabilities'] = balanceSheet['Total Liab'] - balanceSheet['Total Current Liabilities']
        balanceSheet['Cash And Cash Equivalents'] = balanceSheet['Cash'] + balanceSheet['Short Term Investments']
        balanceSheet['Debt To Equity Ratio'] = balanceSheet['Total Liab'] / balanceSheet['Total Stockholder Equity']
        balanceSheet['Adjusted Debt To Equity Ratio'] = balanceSheet['Total Liab'] / \
                                                        (balanceSheet['Total Stockholder Equity'] - balanceSheet['Good Will'])
        balanceSheet['Current Ratio'] = balanceSheet['Total Current Assets'] / balanceSheet['Total Current Liabilities']
        
        
        balanceSheetQuarterly['Total Non Current Assets'] = balanceSheetQuarterly['Total Assets'] - balanceSheetQuarterly['Total Current Assets']
        balanceSheetQuarterly['Total Non Current Liabilities'] = balanceSheetQuarterly['Total Liab'] - balanceSheetQuarterly['Total Current Liabilities']
        balanceSheetQuarterly['Cash And Cash Equivalents'] = balanceSheetQuarterly['Cash'] + balanceSheetQuarterly['Short Term Investments']
        balanceSheetQuarterly['Debt To Equity Ratio'] = balanceSheetQuarterly['Total Liab'] / balanceSheetQuarterly['Total Stockholder Equity']
        balanceSheetQuarterly['Adjusted Debt To Equity Ratio'] = balanceSheetQuarterly['Total Liab'] / \
                                                        (balanceSheetQuarterly['Total Stockholder Equity'] - balanceSheetQuarterly['Good Will'])
        balanceSheetQuarterly['Current Ratio'] = balanceSheetQuarterly['Total Current Assets'] / balanceSheetQuarterly['Total Current Liabilities']
        
        #---
            
        balanceSheetOrdered = balanceSheet[balanceColsOrdered]
        balanceSheetQuarterlyOrdered = balanceSheetQuarterly[balanceColsOrdered]
        
        balanceColsNewNames = {'Good Will': 'Goodwill',
                               'Total Liab': 'Total Liabilities',
                               'Other Current Liab': 'Other Current Liabilities',
                               'Other Liab': 'Other Liabilities'}
        
        balanceSheetOrdered = balanceSheetOrdered.rename(columns = balanceColsNewNames)
        balanceSheetQuarterlyOrdered = balanceSheetQuarterlyOrdered.rename(columns = balanceColsNewNames)
        
        self.balanceSheet = balanceSheetOrdered
        self.balanceSheetQuarterly = balanceSheetQuarterlyOrdered
        
        #------------------------------
        
        # Cashflow
        
        cashflow = tickerObject.cashflow.T
        cashflowQuarterly = tickerObject.quarterly_cashflow.T
        
        cashflow.fillna(value = np.nan, inplace = True)
        cashflowQuarterly.fillna(value = np.nan, inplace = True)
        
        cashflow.reset_index(drop = False, names = 'Date', inplace = True)
        cashflow.set_index('Date', drop = False, inplace = True)
        cashflow.index.name = None
        
        cashflowQuarterly.reset_index(drop = False, names = 'Date', inplace = True)
        cashflowQuarterly.set_index('Date', drop = False, inplace = True)
        cashflowQuarterly.index.name = None
        
        #---
        
        cashflowColsOrdered = ['Date',
                               'Total Cash From Operating Activities',
                               'Operating Cashflow Ratio',
                               'Capital Expenditures',
                               'Free Cashflow',
                               'Free Cashflow Ratio',
                               'Adjusted Operating Cashflow',
                               'Adjusted Operating Cashflow Ratio',
                               'Adjusted Free Cashflow',
                               'Adjusted Free Cashflow Ratio',
                               'Net Income',
                               'Depreciation',
                               'Change To Account Receivables',
                               'Change To Operating Activities',
                               'Total Cashflows From Investing Activities',
                               'Investments',
                               'Other Cashflows From Investing Activities',
                               'Total Cash From Financing Activities',
                               'Repurchase Of Stock',
                               'Net Borrowings',
                               'Other Cashflows From Financing Activities',
                               'Change In Cash',
                               'Effect Of Exchange Rate',
                               'Change To Liabilities',
                               'Change To Netincome'
                              ]
        
        cashflowColsMissing = [col for col in cashflowColsOrdered if col not in cashflow.columns]
        cashflowColsMissingQuarterly = [col for col in cashflowColsOrdered if col not in cashflowQuarterly.columns]
        
        for col in cashflowColsMissing:
            cashflow[col] = np.nan
        
        for col in cashflowColsMissingQuarterly:
            cashflowQuarterly[col] = np.nan
            
        #---
        
        cashflow['Free Cashflow'] = cashflow['Total Cash From Operating Activities'] + cashflow['Capital Expenditures']
        cashflow['Adjusted Operating Cashflow'] = cashflow['Net Income'] + cashflow['Depreciation']
        cashflow['Operating Cashflow Ratio'] = cashflow['Total Cash From Operating Activities'] / self.incomeStatement['Total Revenue']
        cashflow['Adjusted Operating Cashflow Ratio'] = cashflow['Adjusted Operating Cashflow'] / self.incomeStatement['Total Revenue']
        cashflow['Adjusted Free Cashflow'] = cashflow['Adjusted Operating Cashflow'] + cashflow['Capital Expenditures']
        cashflow['Free Cashflow Ratio'] = cashflow['Free Cashflow'] / self.incomeStatement['Total Revenue']
        cashflow['Adjusted Free Cashflow Ratio'] = cashflow['Adjusted Free Cashflow'] / self.incomeStatement['Total Revenue']
        
        cashflowQuarterly['Free Cashflow'] = cashflowQuarterly['Total Cash From Operating Activities'] + cashflowQuarterly['Capital Expenditures']
        cashflowQuarterly['Adjusted Operating Cashflow'] = cashflowQuarterly['Net Income'] + cashflowQuarterly['Depreciation']
        cashflowQuarterly['Operating Cashflow Ratio'] = cashflowQuarterly['Total Cash From Operating Activities'] / self.incomeStatementQuarterly['Total Revenue']
        cashflowQuarterly['Adjusted Operating Cashflow Ratio'] = cashflowQuarterly['Adjusted Operating Cashflow'] / self.incomeStatementQuarterly['Total Revenue']
        cashflowQuarterly['Adjusted Free Cashflow'] = cashflowQuarterly['Adjusted Operating Cashflow'] + cashflowQuarterly['Capital Expenditures']
        cashflowQuarterly['Free Cashflow Ratio'] = cashflowQuarterly['Free Cashflow'] / self.incomeStatementQuarterly['Total Revenue']
        cashflowQuarterly['Adjusted Free Cashflow Ratio'] = cashflowQuarterly['Adjusted Free Cashflow'] / self.incomeStatementQuarterly['Total Revenue']
        
        #---
        
        cashflowOrdered = cashflow[cashflowColsOrdered]
        cashflowQuarterlyOrdered = cashflowQuarterly[cashflowColsOrdered]
        
        cashflowColsNewNames = {'Total Cash From Operating Activities': 'Operating Cashflow',
                                'Total Cashflows From Investing Activities': 'Investing Cashflow',
                                'Total Cashflows From Financing Activities': 'Financing Cashflow',
                                'Change To Netincome': 'Change To Net Income'}
        
        cashflowOrdered = cashflowOrdered.rename(columns = cashflowColsNewNames)
        cashflowQuarterlyOrdered = cashflowQuarterlyOrdered.rename(columns = cashflowColsNewNames)
        
        self.cashflow = cashflowOrdered
        self.cashflowQuarterly = cashflowQuarterlyOrdered
        
        #---
        
        cashflowTTM = cashflowQuarterlyOrdered.drop('Date', axis = 1).iloc[0:4, :].sum(axis = 0, min_count = 1, numeric_only = None)
        cashflowTTM = pd.DataFrame(cashflowTTM).T
        
        cashflowTTM['Date'] = cashflowQuarterly['Date'][0]
        cols = cashflowTTM.columns.to_list()
        colsOrdered = cols[-1:] + cols[:-1]
        cashflowTTM = cashflowTTM[colsOrdered].set_index('Date', drop = False)
        cashflowTTM.index.name = None
        
        cashflowTTM['Operating Cashflow Ratio'] = cashflowTTM['Operating Cashflow'] / self.incomeStatementTTM['Total Revenue']
        cashflowTTM['Adjusted Operating Cashflow Ratio'] = cashflowTTM['Adjusted Operating Cashflow'] / self.incomeStatementTTM['Total Revenue']
        cashflowTTM['Free Cashflow Ratio'] = cashflowTTM['Free Cashflow'] / self.incomeStatementTTM['Total Revenue']
        cashflowTTM['Adjusted Free Cashflow Ratio'] = cashflowTTM['Adjusted Free Cashflow'] / self.incomeStatementTTM['Total Revenue']
        
        self.cashflowTTM = cashflowTTM
        
        #------------------------------
        
        # Setting other useful attributes as is.
        
        usefulAttributes = ['_base_url', # URL used for scraping 
                            '_options2df', # seems transform data of trading info
                            '_tz', # timezone (but more like city location). Seems to be needed for some functions like _options2df()
                            'actions', # date of stock splits and dividends including the action
                            'analysis', # Df containing Growth estimates over time etc.
                            'calendar', # Future earnings date, seems to be somewhat flawed
                            'dividends', # time series of dividend payments. Empty if no dividends have been payed
                            'earnings', # Just revenue and earnings for whole years (4 years)
                            'earnings_dates', # Past earnings dates with EPS-Estimate vs. Reported-EPS
                            'history', # Historical stock price data on a daily basis
                            'info', # A massive load of information about the company like a business summary, number of employees, KPIs, PE-Ratio etc.
                            'institutional_holders', # Top 10
                            'major_holders', # Stock ownership in terms of Intitutions and Insiders
                            'mutualfund_holders', # Top 10
                            'option_chain', # represents data about the currently traded options. Is its own data-type created by yFinance
                            'quarterly_earnings',
                            'recommendations', # Analyst Ratings
                            'shares', # Share Count at the end of different years
                            'splits', # Series depicting historic stock splits
                           ]
        
        usefulAttributesNewNames = ['baseUrl', # URL used for scraping 
                                    'options2df', # seems transform data of trading info
                                    'timeZone', # timezone (but more like city location). Seems to be needed for some functions like _options2df()
                                    'actions', # date of stock splits and dividends including the action
                                    'analysis', # Df containing Growth estimates over time etc.
                                    'calendar', # Future earnings date, seems to be somewhat flawed
                                    'dividends', # time series of dividend payments. Empty if no dividends have been payed
                                    'earnings', # Just revenue and earnings for whole years (4 years)
                                    'earningsDates', # Past earnings dates with EPS-Estimate vs. Reported-EPS
                                    'history', # Historical stock price data on a daily basis
                                    'info', # A massive load of information about the company like a business summary, number of employees, KPIs, PE-Ratio etc.
                                    'institutionalHolders', # Top 10
                                    'majorHolders', # Stock ownership in terms of Intitutions and Insiders
                                    'mutualfundHolders', # Top 10
                                    'optionChain', # represents data about the currently traded options. Is its own data-type created by yFinance
                                    'quarterlyEarnings',
                                    'analystRatings', # Analyst Ratings
                                    'shares', # Share Count at the end of different years
                                    'splits', # Series depicting historic stock splits
                                   ]
        
        for i in range(len(usefulAttributes)):

            setattr(self, 
                    usefulAttributesNewNames[i], 
                    getattr(tickerObject, usefulAttributes[i]))
            
        #------------------------------
        
        # Short Ratio: Doesn't seem to be fully accurate. Maybe scrape from Marketwatch?
        try:
            self.shortRatio = self.info['sharesShort'] / self.info['sharesOutstanding'] 
        except:
            self.shortRatio = None
        
    #------------------------------
        
    def updateLocalData(self, path):

        pathStockData = path + self.ticker

        financialDataNames = ['incomeStatement',
                              'incomeStatementQuarterly',
                              'incomeStatementTTM',
                              'balanceSheet',
                              'balanceSheetQuarterly',
                              'cashflow',
                              'cashflowQuarterly',
                              'cashflowTTM']

        for name in financialDataNames:
            filePath = pathStockData + '/' + name + '.csv'
            dataNew = getattr(self, name)
            
            # Check if folder for current stock ticker exists. If not, create one.
            try:
                filesInFolder = os.listdir(pathStockData)
                
            except:
                Path(pathStockData).mkdir(exist_ok = True)
                filesInFolder = []
                print(f"New Folder for ticker {self.ticker} has been created at {path}")
            
            if name + '.csv' in filesInFolder:
                dataLocal = pd.read_csv(filePath, parse_dates = ['Date']).set_index('Date', drop = False)
                dataLocal.index.name = False
                
                datesLocal = set(dataLocal['Date'])
                datesNew = set(dataNew['Date'])

                datesToAdd = datesNew.difference(datesLocal)
                
                if len(datesToAdd) > 0:
                    dataToAdd = dataNew[dataNew['Date'] == datesToAdd]
                    dataLocalUpdated = pd.concat([dataLocal, dataToAdd], axis = 0)
                    ipdb.set_trace()
                    dataLocalUpdated.sort_index(axis = 0, ascending = False)
                    dataLocalUpdated.to_csv(filePath, index = False)

                else:
                    print(f"{name} of {self.ticker} is already up to date!")
                        
            else:
                print(f"{name} doesn't exist locally for {self.ticker}! New csv-file is created at {pathStockData}!")
                dataNew.to_csv(filePath, index = False)
        
    #------------------------------

    def getLocalData(self, path):
        
        pathStockData = path + self.ticker
        
        financialDataNames = ['incomeStatement',
                              'incomeStatementQuarterly',
                              'incomeStatementTTM',
                              'balanceSheet',
                              'balanceSheetQuarterly',
                              'cashflow',
                              'cashflowQuarterly',
                              'cashflowTTM']
        
        for name in financialDataNames:
            filePath = pathStockData + '/' + name + '.csv'
            
            try:
                dataLocal = pd.read_csv(filePath, parse_dates = ['Date']).set_index('Date', drop = False)
                setattr(self, name, dataLocal)
            except:
                print(f"{name} isn't available at {pathStockData} for ticker {self.ticker}")
            
            
