예제 #1
0
    def Implement_RSI(self,
                      sec_id='AAPL',
                      qty=10,
                      period=14,
                      start_date="2018-10-30"):

        # Get real time data from Interactive Broker
        user1 = DataAPI()
        df = user1.yahoo_pricing_data(sec_id, start_date=start_date)

        # Check the signal
        # -- sma --
        BT_user1 = Backtesting(df)
        df = BT_user1.RSI_single_stock(period=14)

        print('signal: {}'.format(df.loc[df.shape[0] - 1, 'signal']))
        # check the most recent signal

        if df.loc[df.shape[0] - 1, 'signal'] == 'buy':

            self.submit_buy_order(sec_id, qty)
            self.Email_client.send_buy_notification(self.email_add, sec_id)

        elif df.loc[df.shape[0] - 1, 'signal'] == 'sell':

            self.submit_sell_order(sec_id, qty)
            self.Email_client.send_sell_notification(self.email_add, sec_id)
class Analysis_report:

    def __init__(self, sec_id: str = 'AAPL'):
        
        self.sec_id = sec_id
        self.sf_data_client = DataAPI(which_API = 'SimFin')
        self.yh_data_client = DataAPI(which_API = 'yahoo')
        self.period = 'annual'
        self.market = 'us'
        self.IS_revenue = None

    def stock_report(self, File_path):
        
        #// Retrive pricing data from yahoo finance
        df_pricing = self.yh_data_client.yahoo_pricing_data(sec_id = self.sec_id)
        
        #// Retrieve Income Statement
        df_income = self.sf_data_client.SF_income_statement(sec_id = self.sec_id, period = self.period, market = self.market )
        #// Retrieve Balance Sheet Data
        df_bs = self.sf_data_client.SF_balance_sheet(sec_id = self.sec_id, period = self.period, market = self.market )
        #// Retrieve Cash Flow Statement
        df_cf = self.sf_data_client.SF_cashflow_statment(sec_id = self.sec_id, period = self.period, market = self.market )
        #// Retrieve Ratios
        df_ratios = self.sf_data_client.SF_Derived_Ratios(sec_id = self.sec_id, period = self.period, market= self.market )
        
        #// Plot pricing chart
        self.plotly_stock_price(df_pricing)
        
        
        #// Balance Sheet

        df_bs = df_bs.T
        #// Balance Sheet commonsize
        df_BS_common_size = self.balance_sheet_commonsize(df_bs.T)
    
        #// Income Statement Common Size
        df_IS_common_size = self.income_statment_common_size(df_income)
        
        #// Cash flow statement 
        df_cf = df_cf.T
        
        #// Ratio
        df_ratios = self.ratios_yoy(df_ratios)

        #// write data to an excel file
        with pd.ExcelWriter(File_path) as writer:  
            df_bs.to_excel(writer, sheet_name = "Balance Sheet")
            df_BS_common_size.to_excel(writer, sheet_name = "Balance Sheet Commonsize")
            df_IS_common_size.to_excel(writer, sheet_name='Income Statement')
            df_cf.to_excel(writer, sheet_name = "Cash Flow Statement")
            df_ratios.to_excel(writer, sheet_name = "Ratios")
            df_pricing.to_excel(writer, sheet_name = "Historical_price")
            
    def plotly_stock_price(self, df):
        fig = go.Figure(data=[go.Candlestick(x=df['date'],
                        open=df['open'],
                        high=df['high'],
                        low=df['low'],
                        close=df['close'])])
        fig.layout.xaxis.type = 'category'
        fig.show()
        
    def income_statment_common_size(self, df):
        
        dfT = df.T
        
        Row_Revenue = dfT.index.get_loc('Revenue') + 1

        Row_lis = dfT.index[Row_Revenue:]
        
        self.IS_revenue = dfT.loc['Revenue']
        df_temp = dfT.iloc[:Row_Revenue, :]
        
        for i in Row_lis:
            
            S_lis = self.IS_add_yoy_rows(dfT.loc[i])
            df_temp = df_temp.append(dfT.loc[i].map(lambda x:  '{:,} M'.format(x/1000000)), ignore_index = False)
            df_temp = df_temp.append(S_lis, ignore_index = False)
        
        return df_temp

    def IS_add_yoy_rows(self, row_series):
        
        #// Add yoy pct change, commonsize, yoy_commonsize rows into Income Stetement
        row_index_name = row_series.name
        YOY_name = "YOY_" + row_index_name
        S_YOY_name = pd.Series(self.yoy_pct_change(row_series), name = YOY_name)
        
        CommonSize_Name= "CommonSize_" + row_index_name
        S_CommonSize_Name = pd.Series(row_series/self.IS_revenue, name = CommonSize_Name)
        
        YOY_CommonSize_Name = "YOY_CommonSize_" + row_index_name
        S_YOY_CommonSize_Name = pd.Series(self.yoy_pct_change(S_CommonSize_Name), name = YOY_CommonSize_Name)
        
        S_lis = [S_YOY_name, S_CommonSize_Name, S_YOY_CommonSize_Name]
        
        return S_lis
        
    def yoy_pct_change(self, col_series):
        
        #// replace pct_change function as it is not accurate when numbers are negative
        S_pct_change = (col_series - col_series.shift(1))/col_series.shift(1).map(lambda x: x if x >= 0 else -x)
        S_pct_change = S_pct_change.map(lambda x: '{:.2%}'.format(x))

        return S_pct_change


    def balance_sheet_yoy(self, df):
        
        dfT = df.T
        
        Ros_shares = dfT.index.get_loc('Shares (Diluted)') + 1
        Row_lis = dfT.index[Ros_shares:]
        
        df_temp = dfT.iloc[:Ros_shares, :]
        
        for i in Row_lis:
            
            S_yoy_col = self.BS_add_yoy_rows(dfT.loc[i])
            df_temp = df_temp.append(dfT.loc[i].map(lambda x:  '{:,} M'.format(x/1000000)), ignore_index = False)
            df_temp = df_temp.append(S_yoy_col, ignore_index = False)
        
        return df_temp

    def BS_add_yoy_rows(self, row_series):
        
        #// Add yoy pct change, commonsize, yoy_commonsize rows into Income Stetement
        row_index_name = row_series.name
        YOY_name = "YOY_" + row_index_name
        S_YOY_name = pd.Series(self.yoy_pct_change(row_series), name = YOY_name)

        return S_YOY_name
        
    def yoy_pct_change(self, col_series):
        
        #// replace pct_change function as it is not accurate when numbers are negative
        col_shift_1 = col_series.shift(1).map(lambda x: x + 0.0001 if x >= 0 else -x)
        S_pct_change = (col_series - col_series.shift(1))/col_shift_1
        S_pct_change = S_pct_change.map(lambda x: '{:.2%}'.format(x))

        return S_pct_change



    def balance_sheet_commonsize(self, df):
        
        #// transpose to date as columns
        df = df.T
        
        #// categorize index names into asset and liabilities
        lis_asset = ['Cash, Cash Equivalents & Short Term Investments', 'Accounts & Notes Receivable', 'Inventories',
                'Property, Plant & Equipment, Net', 'Long Term Investments & Receivables', 'Other Long Term Assets',
                'Total Noncurrent Assets']
        total_asset = 'Total Assets'
        lis_liability = ['Payables & Accruals','Short Term Debt', 'Total Current Liabilities', 
                        'Long Term Debt','Total Noncurrent Liabilities']
        total_liability = 'Total Liabilities'
        lis_equity = ['Share Capital & Additional Paid-In Capital', 'Treasury Stock','Retained Earnings']
        total_equity = 'Total Equity'
        total_liabilityNequity = 'Total Liabilities & Equity'

        df.loc[lis_asset] = df.loc[lis_asset]/df.loc[total_asset]
        df.loc[lis_liability] = df.loc[lis_liability]/df.loc[total_liabilityNequity]
        df.loc[lis_equity] = df.loc[lis_equity]/df.loc[total_liabilityNequity]
        
        lis_a = lis_asset + lis_liability + lis_equity
        lis_b = [total_asset, total_liability, total_equity, total_liabilityNequity, 'Total Current Assets']
        
        df.loc[lis_a] = df.loc[lis_a].applymap(lambda x: '{:.2%}'.format(x))
        df.loc[lis_b] = df.loc[lis_b].applymap(lambda x: '{:,} M'.format(x/1000000))

        return df

    def ratios_yoy(self, df):
        
        df = df.T
        
        lis = ['EBITDA', 'Total Debt', 'Free Cash Flow',
        'Gross Profit Margin', 'Operating Margin', 'Net Profit Margin',
        'Return on Equity', 'Return on Assets', 'Free Cash Flow to Net Income',
        'Current Ratio', 'Liabilities to Equity Ratio', 'Debt Ratio',
        'Earnings Per Share, Basic', 'Earnings Per Share, Diluted',
        'Sales Per Share', 'Equity Per Share', 'Free Cash Flow Per Share',
        'Dividends Per Share']
        
        Row_Ebida = df.index.get_loc('EBITDA')
        df_temp = df.iloc[:Row_Ebida, :]

        for i in lis:
            
            row_index_name = df.loc[i].name
            YOY_name = "YOY_" + row_index_name
            S_YOY_name = pd.Series(self.yoy_pct_change(df.loc[i]), name = YOY_name)
            
            df_temp = df_temp.append(df.loc[i])
            df_temp = df_temp.append(S_YOY_name, ignore_index = False)
            
        
        lis_dollar_Form = ['EBITDA', 'Total Debt', 'Free Cash Flow']
        lis_pct_form = ['Gross Profit Margin', 'Operating Margin', 'Net Profit Margin',
        'Return on Equity', 'Return on Assets', 'Free Cash Flow to Net Income',
        'Current Ratio', 'Liabilities to Equity Ratio', 'Debt Ratio']
        
        
        df_temp.loc[lis_pct_form] = df_temp.loc[lis_pct_form].applymap(lambda x: '{:.2%}'.format(x))
        df_temp.loc[lis_dollar_Form] = df_temp.loc[lis_dollar_Form].applymap(lambda x: '{:,} M'.format(x/1000000))

        
        return df_temp
예제 #3
0
from data import DataAPI
from backtesting import Backtesting
from Visualization import Visualization
import pandas as pd 
import matplotlib.pyplot as plt



user1 = DataAPI("yahoo")


df = user1.yahoo_pricing_data('AAPL', start_date= "2015-10-30")

# -- sma --
# bt1 = Backtesting(df)
# df1 = bt1.backtesting_sma_single_stock(sma_short=5, sma_long=30)
# v1 = Visualize(df1)
# v1.sma_plot_result()

# -- rsi --

# bt1 = Backtesting(df)
# df1 = bt1.RSI_single_stock(period= 28)
# v1 = Visualize(df1)
# v1.sma_plot_result()

# path = r'D:\K\HU\HU - Courses\CISC 695 Research Methodology and Writing\Assignments\sample_data\rsi_aapl_data.csv'
# df1.to_csv(path)


#// test sma_backtesting bulk 
예제 #4
0
 def get_data(self):
     
     df = DataAPI.yahoo_pricing_data('AAPL', start_date='2019-01-01', end_date= '2020-10-30')
     return df
예제 #5
0
    def test_yahoo_pricing_data(self):

        usr = DataAPI(which_API='yahoo')
        result = usr.yahoo_pricing_data('AAPL', start_date='2018-01-01', end_date= '2020-10-30')
        self.assertIsInstance(result, pd.DataFrame)