def pf_sell_all(self, ref_date="1990-01-01"):
     """
     Sell all holdings on a particular date
     @params:
         ref_date    - Optional  : date YYYY-MM-DD (Str)
     """
     mdb_query = Query()
     #Get link to MongoDB
     #Get date for stock prices
     dayBeforeDate = (pandas.Timestamp(ref_date) +
                      pandas.DateOffset(days=-1)).strftime('%Y-%m-%d')
     #Get existing portfolios
     portfolios = mdb_query.get_portfolios(ref_date)[[
         "portfolioID", "inceptionDate"
     ]]
     #Loop through portfolios
     for portfolio_index, portfolio_row in portfolios.iterrows():
         #Get portfolioID and inceptionDate
         portfolio = portfolio_row['portfolioID']
         #Get holdings table
         holdings = mdb_query.get_holdings(portfolio, ref_date, "on")
         #Get latest prices from dayBeforeDate
         prices = mdb_query.get_chart(holdings['symbol'].tolist(),
                                      dayBeforeDate, 'latest')
         #Merge prices with holdings
         holdings = pandas.merge(holdings,
                                 prices,
                                 how='left',
                                 left_on=['symbol'],
                                 right_on=['symbol'],
                                 sort=False)
         #Remove USD
         holdings = holdings[holdings['symbol'] != 'USD']
         #print( holdings )
         #Build transaction tables which sell the stocks
         transaction_tables = []
         #Loop through stocks to be sold
         for index, stock in holdings.iterrows():
             #Transaction tables: type = sell, date = ref_date, price = close, volume = endOfDayQuantity
             transaction_table = {
                 "portfolioID": portfolio_row.portfolioID,
                 "symbol": stock.symbol,
                 "type": "sell",
                 "date": ref_date,
                 "price": stock.close,
                 "volume": stock.endOfDayQuantity,
                 "commission": 0.0
             }
             transaction_tables.append(transaction_table)
         insert_pf_transactions = True
         if insert_pf_transactions:
             #print( transaction_tables )
             self.db.pf_transactions.insert_many(transaction_tables)
Esempio n. 2
0
    def calculate_top_stocks_old(self, ref_date):
        """
        Calculate ranked list of stocks
        @params:
            ref_date    - Required  : date YYYY-MM-DD (Str)
        """

        mdb_query = Query()
        #Get ranked stock list for given date
        symbols = mdb_query.get_active_companies().tolist()
        print("Query earnings")
        earnings = mdb_query.get_earnings(symbols, ref_date, "latest",
                                          "EPSReportDate")
        earnings = earnings[[
            "EPSReportDate", "actualEPS", "fiscalEndDate", "fiscalPeriod",
            "symbol"
        ]]
        #print( earnings )
        #Get financials within 6 months
        print("Query financials")
        sixMonthsBeforeDate = (
            pandas.Timestamp(ref_date) +
            pandas.DateOffset(months=-6)).strftime('%Y-%m-%d')
        financials = mdb_query.get_financials(symbols, sixMonthsBeforeDate,
                                              "after")
        financials = financials[
            financials['reportDate'] <= earnings['fiscalEndDate'].max()]
        financials = financials[[
            "symbol", "reportDate", "netIncome", "shareholderEquity"
        ]]
        #print( financials )
        #Get prices for inception date
        print("Query prices")
        idx_min = 0
        query_num = 100
        prices = pandas.DataFrame()
        while idx_min < len(symbols):
            idx_max = idx_min + query_num
            if idx_max > len(symbols):
                idx_max = len(symbols)
            symbols_split = symbols[idx_min:idx_max]
            prices_split = mdb_query.get_chart(symbols_split, ref_date,
                                               "latest")
            prices = prices.append(prices_split, ignore_index=True, sort=False)
            idx_min = idx_min + query_num
        prices.reset_index(drop=True, inplace=True)
        #print( prices )
        #Get company data
        company = mdb_query.get_company(symbols)
        company = company[['symbol', 'companyName', 'industry', 'sector']]
        #Merge dataframes together
        print("Merge dataframes")
        merged = pandas.merge(earnings,
                              financials,
                              how='inner',
                              left_on=["symbol", "fiscalEndDate"],
                              right_on=["symbol", "reportDate"],
                              sort=False)
        merged = pandas.merge(merged,
                              prices,
                              how='inner',
                              on="symbol",
                              sort=False)
        merged = pandas.merge(merged,
                              company,
                              how='inner',
                              on='symbol',
                              sort=False)
        #Remove any rows with missing values
        merged = merged.dropna(
            axis=0,
            subset=["netIncome", "actualEPS", "close", "shareholderEquity"])
        #Calculate marketCap value
        # price * netIncome / EPS = price * sharesOutstanding = mcap
        # Actually not 100% accurate, should be netIncome - preferred dividend
        # Doesn't perfectly match IEX value or google - probably good enough
        merged["sharesOutstanding"] = merged.netIncome / merged.actualEPS
        merged["marketCap"] = merged.sharesOutstanding * merged.close
        #Calculate PE, ROE, and ratio
        merged["peRatio"] = merged.close / merged.actualEPS
        merged["returnOnEquity"] = merged.netIncome / merged.shareholderEquity
        merged["peROERatio"] = merged.peRatio / merged.returnOnEquity
        #Count number of stocks above mcap value
        # A useful indicator of how universe compares to S&P500
        print("Universe before cuts...")
        print("mcap > 50M: " +
              str(merged[merged["marketCap"] > 50000000].count()["marketCap"]))
        print(
            "mcap > 100M: " +
            str(merged[merged["marketCap"] > 100000000].count()["marketCap"]))
        print(
            "mcap > 500M: " +
            str(merged[merged["marketCap"] > 500000000].count()["marketCap"]))
        print(
            "mcap > 1B: " +
            str(merged[merged["marketCap"] > 1000000000].count()["marketCap"]))
        print(
            "mcap > 5B: " +
            str(merged[merged["marketCap"] > 5000000000].count()["marketCap"]))
        print("mcap > 10B: " + str(merged[
            merged["marketCap"] > 10000000000].count()["marketCap"]))
        print("mcap > 50B: " + str(merged[
            merged["marketCap"] > 50000000000].count()["marketCap"]))
        print("mcap > 100B: " + str(merged[
            merged["marketCap"] > 100000000000].count()["marketCap"]))
        #Rank stocks
        #Cut negative PE and ROE
        merged = merged[(merged.peRatio > 0) & (merged.returnOnEquity > 0)]
        #Remove invalid stock symbols, and different voting options
        # Do the different voting options affect marketCap?
        #forbidden = [ "#", ".", "-" ]
        #merged = merged[ merged.apply( lambda x: not any( s in x['symbol'] for s in forbidden ), axis=1 ) ]
        #Remove American Depositary Shares
        #ads_str = 'American Depositary Shares'
        #merged = merged[ merged.apply( lambda x: ads_str not in x['companyName'], axis=1 ) ]
        #Remove industries that do not compare well
        # e.g. Companies that have investments as assets
        #forbidden_industry = ['Brokers & Exchanges','REITs','Asset Management','Banks']
        #merged = merged[ ~merged.industry.isin( forbidden_industry ) ]
        #Count number of stocks after cuts
        print("Universe after cuts...")
        print("mcap > 50M: " +
              str(merged[merged["marketCap"] > 50000000].count()["marketCap"]))
        print(
            "mcap > 100M: " +
            str(merged[merged["marketCap"] > 100000000].count()["marketCap"]))
        print(
            "mcap > 500M: " +
            str(merged[merged["marketCap"] > 500000000].count()["marketCap"]))
        print(
            "mcap > 1B: " +
            str(merged[merged["marketCap"] > 1000000000].count()["marketCap"]))
        print(
            "mcap > 5B: " +
            str(merged[merged["marketCap"] > 5000000000].count()["marketCap"]))
        print("mcap > 10B: " + str(merged[
            merged["marketCap"] > 10000000000].count()["marketCap"]))
        print("mcap > 50B: " + str(merged[
            merged["marketCap"] > 50000000000].count()["marketCap"]))
        print("mcap > 100B: " + str(merged[
            merged["marketCap"] > 100000000000].count()["marketCap"]))
        #Order by peROERatio
        merged = merged.sort_values(by="peROERatio",
                                    ascending=True,
                                    axis="index")

        return merged
Esempio n. 3
0
 def insert_prices(self):
     print( "Insert new charts" )
     mdb_query = Query()
     iex = Iex()
     #Get all symbols in MongoDB
     mdb_symbols_full = mdb_query.get_active_companies()
     mdb_symbols_full = mdb_symbols_full[mdb_symbols_full == 'SPY']
     #Get current date
     currDate = datetime.datetime.now().strftime("%Y-%m-%d")
     #Initial call to print 0% progress
     printProgressBar(0, len(mdb_symbols_full.index), prefix = 'Progress:', suffix = '', length = 50)
     idx_min = 0
     query_num = 100
     #flag = False
     while idx_min < len(mdb_symbols_full.index):
         #if idx_min > 1:
         #    break
         idx_max = idx_min + query_num
         if idx_max > len(mdb_symbols_full.index):
             idx_max = len(mdb_symbols_full.index)
         mdb_symbols = mdb_symbols_full.iloc[ idx_min:idx_max ]
         mdb_symbols.reset_index(drop=True, inplace=True)
         #Get latest price in MongoDB for each symbol up to 50 days ago
         mdb_charts = mdb_query.get_chart( mdb_symbols.tolist(), currDate, "latest" )
         #print( mdb_charts )
         #break
         #Loop through symbols
         for index, mdb_symbol in mdb_symbols.iteritems():
             #Get matching chart in MongoDB
             mdb_chart = mdb_charts[ mdb_charts['symbol'] == mdb_symbol ]
             #Get first date to insert
             date = mdb_chart.date.iloc[0]
             date = (pandas.Timestamp(date) + pandas.DateOffset(days=1)).strftime('%Y-%m-%d')
             iex_chart = pandas.DataFrame()
             while date <= currDate:
                 #Get date in correct format for IEX query
                 iex_date = (pandas.Timestamp(date)).strftime('%Y%m%d')
                 #Get IEX chart
                 iex_chart_day = iex.get_chart( mdb_symbol, ref_range=iex_date )
                 iex_chart = iex_chart.append(iex_chart_day, ignore_index=True, sort=False)
                 #Increment date
                 date = (pandas.Timestamp(date) + pandas.DateOffset(days=1)).strftime('%Y-%m-%d')
             #Get 1y of charts from IEX
             #print( mdb_symbol )
             #print( mdb_symbol["symbol"] )
             #if mdb_symbol["symbol"] == "ZZZZZZZZZ":
             #    flag = True
             #if not flag:
             #    continue
             #iex_chart = iex.get_chart( mdb_symbol, ref_range='5d' )
             #Get matching chart in MongoDB
             #mdb_chart = mdb_charts[ mdb_charts['symbol'] == mdb_symbol ]
             #Select charts more recent than MongoDB
             #if not iex_chart.empty and not mdb_chart.empty:
             #    mask = iex_chart['date'] > mdb_chart['date'].iloc[0]
             #    iex_chart = iex_chart.loc[mask]
             #Insert if charts exist
             #print( iex_chart )
             if not iex_chart.empty:
                 #Update progress bar
                 printProgressBar(idx_min+index+1, len(mdb_symbols_full.index), prefix = 'Progress:', suffix = "Inserting chart for " + mdb_symbol + "      ", length = 50)
                 #Print write error if couldn't insert charts
                 try:
                     print( iex_chart )
                     self.db.iex_charts.insert_many( iex_chart.to_dict('records') )
                 except BulkWriteError as bwe:
                     print( bwe.details )
                     raise
             else:
                 #Update progress bar
                 printProgressBar(idx_min+index+1, len(mdb_symbols_full.index), prefix = 'Progress:', suffix = "No new data for " + mdb_symbol + "      ", length = 50)
         idx_min = idx_min + query_num