示例#1
0
 def __init__(self):
     self.engine = create_engine('postgresql://*****:*****@localhost:5432/nyse_financials')
     self.api = al.alpaca2Login().getApi()
     self.fin_db = "financials"
     self.earnings_db = "earning_dates"
     self.sentiment_db = "sentiment"
     self.nothingToGet = True
     self.db = Database()
示例#2
0
文件: sl.py 项目: 4crash/4crash
 def __init__(self):
     self.db = Database()
     self.symbols = self.db.get_symbols(TableName.DAY)
     self.sectors = self.db.get_sectors(TableName.DAY)
     self.sm = StockMess()
     self.ss = SectorStats()
     self.app = self.get_home_page()
     self.submit = None
示例#3
0
    def __init__(self):

        self.db = Database()
        self.sectors_trend = []
        self.spy_trend = []
        self.last_date = None
        self.spy = None
        self.stocks = None
        self.in_day_stocks = None
        self.trend_data = None
示例#4
0
    def __init__(self):

        self.db = Database()
        self.ss = SectorStats()

        self.last_date = None
        self.financials = None
        self.earnings = None
        self.sentiment = None
        self.spy = None
        self.stocks = None
        self.in_day_stocks = None
        self.trend_data = None
示例#5
0
    def __init__(self,
                 trading_provider: Optional[TradingProviders] = None,
                 trading_strategy: Optional[TradingStrategies] = None,
                 fill_open_trades=OpenTradesSource.DB,
                 table_name="buy_sell_bt"):

        if trading_provider == TradingProviders.ALPACA:
            self.trading_provider = TradingProvider(name=trading_provider,
                                                    instance=AlpacaBuySell())

        self.trading_strategy = trading_strategy
        # self.credit["start_amount"] = 1000
        # self.credit['curr_amount'] = credit['start_amount']
        self.buyed_stocks = pd.DataFrame()
        # self.stock_stats = Sdf()
        # self.startCredit = 10000
        self.credit = {'curr_amount': 10000, "start_amount": 10000}

        self.money: float = 100000
        self.prev_stock = None
        self.buyed_stocks = 0
        self.first_stock = pd.DataFrame()
        self.buy_marks = pd.DataFrame()
        self.sell_marks = pd.DataFrame()
        self.top_stocks_list = pd.DataFrame()
        self.last_buyed_stock = Optional[dict]
        self.first_buyed_price = 0.0
        self.profit_perc = 0.0
        self.profit_perc_all = 0.0
        self.transactions = 0
        self.buy_sell_closed = pd.DataFrame()
        self.share_amount = 1
        self.close_alpaca_postition = False
        self.db = Database()
        self.shares_amount = 1
        self.startCredit = 10000
        self.table_name = table_name
        # self.tv = TradingVars()
        if fill_open_trades == OpenTradesSource.DB:
            self.buy_sell_open = self.fill_open_trades_from_db()
        elif fill_open_trades == OpenTradesSource.ALPACA:
            # FIX DOESNT WORK
            self.buy_sell_open = self.fill_trades_from_alpaca()
示例#6
0
class getData():
    def __init__(self):
        self.engine = create_engine('postgresql://*****:*****@localhost:5432/nyse_financials')
        self.api = al.alpaca2Login().getApi()
        self.fin_db = "financials"
        self.earnings_db = "earning_dates"
        self.sentiment_db = "sentiment"
        self.nothingToGet = True
        self.db = Database()
        # df = pd.DataFrame()
        

    def  get_bars(self, symbol, interval, limit, after):
        # print(after.isoformat())
        data = self.api.get_barset(symbol, interval, limit, after=after.isoformat())
        data =  data.df[symbol]
        print(data)
        return data
        
    def get_sentiment(self, days_before=0, days_after=30):
        from stocknews import StockNews
        self.get_sentiment_from_csv()
        symbols = self.db.get_symbols()
        # print(symbols)
        sn = StockNews(symbols, wt_key='0d57e2849d73713e95f395c7440380ff')
        df_sum, r_count = sn.summarize()
        print("rows: " + str(r_count))
        self.save_sentiment(df_sum)
        print("get sentiment ends")
        # print(df_new)
        return df_sum
    
    def get_sentiment_from_csv(self):
        df = pd.read_csv("./data/data.csv", sep=";")
        print(df)
        self.save_sentiment(df)
    
    def save_sentiment(self, df_sum):
        """[summary]
         !!!! WARNING this method ends with exiting whole script
        Args:
            df_sum ([type]): [description]
        """
        try:
            dfdb = pd.read_sql(self.sentiment_db, con=self.engine)
            df_new = df_sum.append(dfdb, ignore_index=True)
        except:
            df_new = df_sum
            print("Database sentiment doesnt exists")
            
        try:    
            df_new.drop(columns=['index','open','close','high','low','volume','change'], inplace=True)
        except KeyError :
            print("some columns to drop hasnt been found")
            
        df_new.drop_duplicates(
            subset=["id","stock", "news_dt"], inplace=True, keep="first")
        
        df_new.to_sql(self.sentiment_db, con=self.engine,
                      if_exists='replace', index=True)
        
        print("Sentiment saved")
        exit()
        # return df_new
    
    def get_earnings(self, days_before = 0, days_after = 30):
        from yahoo_earnings_calendar import YahooEarningsCalendar
      
        dfdb = pd.read_sql(self.earnings_db, con=self.engine)
        yec = YahooEarningsCalendar()
        dfd = pd.DataFrame(yec.earnings_between(
            datetime.now() - timedelta(days=days_before), datetime.now() + timedelta(days=days_after)))
        
        df_new = dfd.append(dfdb, ignore_index=True)
        df_new.drop_duplicates(subset=["ticker","startdatetime","startdatetimetype"], inplace=True, keep="first")
        #save DATAFRAME to database
        df_new.to_sql(self.earnings_db, con=self.engine,
                   if_exists='replace', index=False)
        print(df_new)

        return df_new
    # def convertUnixTimeToDate(columns,df):
    #     for col in columns:
    #         df[col] = pd.to_datetime(df[col],unit="s")
    #     return df

    def fill_database(self, dfs,interval, limit, table_name, after):
        self.nothingToGet = True
        for row in dfs['Symbol']:
            if row:
                row = str.strip(row)
                print(row)
                
                # check last date for specific symbol
                dfp = pd.read_sql('select MAX("index") as last_time from '+ table_name + ' where sym = \'' + row + '\' ', con=self.engine)
                
                if dfp.iloc[0].last_time is not None:
                    after = dfp.iloc[0].last_time

                # get data from ALPACA
                df = self.get_bars(row, interval, limit, after)
                
                if len(df) > 0:
                    self.nothingToGet = False
                   
                    # add symbol
                    df["sym"] = row
                    
                    #add sector
                    # dff = pd.read_sql('select sector from '+ self.fin_db + ' where symbol = \'' + row + '\' and sector is not null limit 1', con=self.engine)
                    # if len(dff) > 0 and dff.iloc[0].sector:
                    #     df["sector"] = dff.iloc[0].sector

                    df.index.rename('index', inplace = True)
                  
                    #save DATAFRAME to database
                    df.to_sql(table_name, con=self.engine, if_exists='append', index = True)
                    if table_name == TableName.MIN15:
                        self.save_bar_as_last_in_day(df)

    def get_last_working_day(self):
        
        offset = max(0, (datetime.today().weekday() + 6) % 7 - 3)
        timedelta2 = timedelta(offset)
        # most_recent = datetime.today().replace(hour=0, minute=0, second=0, microsecond=0) - timedelta2
        most_recent = datetime.today() - timedelta2
        return most_recent

    def save_bar_as_last_in_day(self,last_bar:pd.DataFrame):
        last_day = self.db.get_last_n_days(
            sym=last_bar.iloc[-1].sym, n_days_back=1, table=TableName.DAY)
        last_day.iloc[-1].close = last_bar.iloc[-1].close
        last_day.iloc[-1].high = last_day.iloc[-1].high if last_day.iloc[-1].high > last_bar.iloc[-1].high else last_bar.iloc[-1].high
        last_day.iloc[-1].low = last_day.iloc[-1].low if last_day.iloc[-1].low < last_bar.iloc[-1].low else last_bar.iloc[-1].low

        last_day.to_sql(TableName.DAY, con=self.engine,
                       if_exists='replace', index=False)
    
    # param interval could be 1,5,15, 0 - for day
    def start_download(self, min_interval, start_date, infinity = False):
        
        dfs = pd.read_csv("./datasets/RevolutStock.csv", delimiter="|")
        print(start_date)
        min_interval = int(min_interval)

        if min_interval > 0:
            db_name = 'p_'+ str(min_interval) +'min'
        else:
            db_name = 'p_day'
        
        while True:
           
            try:
                if min_interval > 0:
                    self.fill_database(dfs,str(min_interval) + "Min",1000, 'p_'+ str(min_interval) +'min', start_date)
                else:
                    self.fill_database(dfs,"day",1000, 'p_day', start_date)
                
                if infinity and self.nothingToGet:
                    break
                
                Utils.countdown(60)
            except KeyboardInterrupt:
                print("END by keybord interruption")
                exit()
            except: 
                print("Unexpected error:", sys.exc_info()[0])
                print("Waiting 3 minutes and try it again")
                Utils.countdown(60)

        
        print("DONE")    
示例#7
0
class BuySell():
    trading_provider: TradingProvider

    # buyed_titles = [{"buy_price","sell_price", "sym", "shares_amount", "buy_date", "sell_date", "profit", "remain_credit"}]
    # credit = {"start_amount", "curr_amount"}

    def __init__(self,
                 trading_provider: Optional[TradingProviders] = None,
                 trading_strategy: Optional[TradingStrategies] = None,
                 fill_open_trades=OpenTradesSource.DB,
                 table_name="buy_sell_bt"):

        if trading_provider == TradingProviders.ALPACA:
            self.trading_provider = TradingProvider(name=trading_provider,
                                                    instance=AlpacaBuySell())

        self.trading_strategy = trading_strategy
        # self.credit["start_amount"] = 1000
        # self.credit['curr_amount'] = credit['start_amount']
        self.buyed_stocks = pd.DataFrame()
        # self.stock_stats = Sdf()
        # self.startCredit = 10000
        self.credit = {'curr_amount': 10000, "start_amount": 10000}

        self.money: float = 100000
        self.prev_stock = None
        self.buyed_stocks = 0
        self.first_stock = pd.DataFrame()
        self.buy_marks = pd.DataFrame()
        self.sell_marks = pd.DataFrame()
        self.top_stocks_list = pd.DataFrame()
        self.last_buyed_stock = Optional[dict]
        self.first_buyed_price = 0.0
        self.profit_perc = 0.0
        self.profit_perc_all = 0.0
        self.transactions = 0
        self.buy_sell_closed = pd.DataFrame()
        self.share_amount = 1
        self.close_alpaca_postition = False
        self.db = Database()
        self.shares_amount = 1
        self.startCredit = 10000
        self.table_name = table_name
        # self.tv = TradingVars()
        if fill_open_trades == OpenTradesSource.DB:
            self.buy_sell_open = self.fill_open_trades_from_db()
        elif fill_open_trades == OpenTradesSource.ALPACA:
            # FIX DOESNT WORK
            self.buy_sell_open = self.fill_trades_from_alpaca()

    def fill_trades_from_alpaca(self):
        positions = self.trading_provider.instance.get_positions()
        # logger.debug(positions['symbol'])
        # todo parse this m**********r to buy:sell structure
        for item in positions:
            print(item)
        return positions

    def fill_open_trades_from_db(self):
        sql_string = f"select * from {self.table_name} where state='open'"
        logger.info(sql_string)
        try:
            return pd.read_sql(sql_string, con=self.db.engine)
        except:
            return pd.DataFrame()

    def fill_closed_trades_from_db(self):
        sql_string = f"select * from {self.table_name} where state='closed'"
        logger.info(sql_string)
        return pd.read_sql(sql_string, con=self.db.engine)

    # def sell_stock(self, stock:Union[pd.DataFrame,StockDataFrame],  sell_price: float= None, table_name: str= "buy_sell_bt",  shares_amount:float = 1)->None:
    #     """DEPRECATED

    #     Args:
    #         stock (Union[pd.DataFrame,StockDataFrame]): [description]
    #         sell_price (float, optional): [description]. Defaults to None.
    #         table_name (str, optional): [description]. Defaults to "buy_sell_bt".
    #         shares_amount (float, optional): [description]. Defaults to 1.
    #     """
    #     sell_price = sell_price if sell_price else stock["close"]
    #     self.profit_perc += round((sell_price - self.last_buyed_stock['buy']) / (
    #         self.last_buyed_stock['buy']/100), 2)

    #     self.buyed_stocks -= shares_amount
    #     self.money = self.money + (sell_price * shares_amount)

    #     buy_sell_stock = pd.DataFrame()
    #     buy_sell_stock.append(stock)
    #     buy_sell_stock["sell"] = sell_price
    #     buy_sell_stock["buy"] = self.last_buyed_stock['buy']
    #     buy_sell_stock["buy_date"] = self.last_buyed_stock.index
    #     buy_sell_stock["shares_amount"] = shares_amount
    #     buy_sell_stock["state"] = "closed"

    #     self.buy_sell_open = self.buy_sell_open.append(buy_sell_stock)

    #     logger.info("selling: " + str(stock['sym']) + " " +
    #           str(stock.name) + ' -- ' + str((sell_price * shares_amount)))

    #     if table_name:
    #         self.db.save_data(table_name=table_name,
    #                           data=self.buy_sell_open, if_exists="replace")

    # def buy_stock(self, stock: Union[pd.DataFrame, StockDataFrame], buy_price: float=None, table_name:str="buy_sell_bt", shares_amount:float=1, process_live:bool=False,  profit_loss:float=None):
    #     """DEPRECATED

    #     Args:
    #         stock (Union[pd.DataFrame, StockDataFrame]): [description]
    #         buy_price (float, optional): [description]. Defaults to None.
    #         table_name (str, optional): [description]. Defaults to "buy_sell_bt".
    #         shares_amount (float, optional): [description]. Defaults to 1.
    #         process_live (bool, optional): [description]. Defaults to False.
    #         profit_loss (float, optional): [description]. Defaults to None.
    #     """
    #     buy_price = buy_price if buy_price else stock["close"]
    #     if self.transactions == 0:
    #         self.first_buyed_price = buy_price

    #     self.buyed_stocks += shares_amount
    #     self.money = self.money - (buy_price * shares_amount)
    #     self.transactions += 1
    #     buy_sell_stock = pd.DataFrame()
    #     buy_sell_stock.append(stock)
    #     buy_sell_stock["buy"] = buy_price
    #     buy_sell_stock["shares_amount"] = shares_amount
    #     buy_sell_stock["state"] = "open"
    #     if profit_loss:
    #         buy_sell_stock["profit"] = profit_loss["profit"]
    #         buy_sell_stock["loss"] = profit_loss["loss"]

    #     logger.info("buying: " + str(stock['sym']) + " " +
    #           str(stock.name) + ' -- ' + str((buy_price * shares_amount)))

    #     self.buy_sell_open = self.buy_sell_open.append(buy_sell_stock)
    #     self.last_buyed_stock = buy_sell_stock

    def sell_stock_t(self,
                     sym: str,
                     price: float,
                     table_name: str = "buy_sell_close",
                     qty: Optional[float] = 1,
                     sell_date: datetime = None,
                     stock: pd.DataFrame = None) -> Optional[pd.DataFrame]:

        if stock is not None:
            sell_date = stock.index[0]
            price = stock.close

        buyed_stock = self.buy_sell_open[self.buy_sell_open["sym"] == sym]
        #sell only if some buyed stocks exist
        if buyed_stock is not None and len(buyed_stock) == 1:

            buyed_stock = buyed_stock.iloc[0]
            self.profit_perc += round((price - self.last_buyed_stock['buy']) /
                                      (self.last_buyed_stock['buy'] / 100), 2)

            if qty is None:
                qty = buyed_stock.shares_amount

            self.buyed_stocks = self.buyed_stocks - \
                qty if buyed_stock.shares_amount >= qty else self.buyed_stocks - buyed_stock.shares_amount
            self.money = self.money + (price * qty)

            buyed_stock.sell = price
            buyed_stock.sell_date = sell_date
            buyed_stock.shares_amount = (
                buyed_stock.shares_amount -
                qty) if buyed_stock.shares_amount - qty > 0 else 0
            buyed_stock.profit = buyed_stock.sell - buyed_stock.buy
            # print(buyed_stock.buy)
            # print(buyed_stock.sell)
            buyed_stock.perc_profit = Utils.calc_perc(buyed_stock.buy,
                                                      buyed_stock.sell, 2)
            if buyed_stock.shares_amount == 0:
                buyed_stock.state = "closed"
                self.buy_sell_open.drop(
                    self.buy_sell_open[self.buy_sell_open["sym"] == sym].index,
                    inplace=True)

            # self.buy_sell = self.buy_sell.append(buy_sell_stock)

            logging.info("selling: " + str(buyed_stock.sell_date))

            self.buy_sell_closed = self.buy_sell_closed.append(buyed_stock)
            self.db.save_data(table_name=table_name,
                              data=self.buy_sell_closed,
                              if_exists="replace")
        # sell stocks on provider platform
        if self.trading_provider is not None and self.trading_provider.name == TradingProviders.ALPACA:

            if self.close_alpaca_postition == False:
                self.trading_provider.instance.submitOrder(qty, sym, "sell")
            else:
                self.trading_provider.instance.close_postions(sym)

            return buyed_stock
        else:
            return None

    def buy_stock_t(self,
                    stock: pd.DataFrame,
                    price: float = None,
                    table_name: str = "buy_sell_bt",
                    qty: float = 1,
                    process_live: bool = False,
                    profit_loss: Dict = None,
                    buy_already_buyed: bool = False) -> pd.DataFrame:

        buy_sell_stock: pd.DataFrame = None
        price = price if price else stock["close"]
        if self.transactions == 0:
            self.first_buyed_price = price

        logger.warning(self.buy_sell_open)

        money: float = (self.money - (price * qty))

        already_buyed:Bool = (buy_already_buyed is True or \
            (buy_already_buyed is False and stock.sym not in self.buy_sell_open ))

        if money <= 0:
            logger.warning("not enough money")
        if already_buyed:
            logger.warning("symbol is already buyed")
        logger.info(money)
        logger.debug(already_buyed)
        if money > 0 and already_buyed:
            logger.debug(
                "MOENY OK........................ ALREADY_BUUYED................OK"
            )
            self.money = money
            self.buyed_stocks += qty

            self.transactions += 1
            # buy_sell_stock = pd.DataFrame()
            buy_sell_stock = stock.copy()

            buy_sell_stock["buy"] = price
            buy_sell_stock["shares_amount"] = qty
            buy_sell_stock["state"] = "open"
            buy_sell_stock["sell"] = None
            buy_sell_stock["sell_date"] = None
            buy_sell_stock["profit"] = None
            buy_sell_stock["perc_profit"] = None
            buy_sell_stock["strategy"] = self.trading_strategy
            if profit_loss:
                buy_sell_stock["est_profit"] = profit_loss["profit"]
                buy_sell_stock["est_loss"] = profit_loss["loss"]

            logger.info("buying: " + str(buy_sell_stock))
            self.buy_sell_open = self.buy_sell_open.append(buy_sell_stock)
            self.last_buyed_stock = buy_sell_stock
            logger.debug(self.trading_provider)
            logger.debug("TRADIGN PROVIDER")
            # buy stocks on provider platform
            if self.trading_provider is not None and self.trading_provider.name == TradingProviders.ALPACA:
                logger.debug("BUYIIIIIIIIIIIIIIIIIIIIIIIIIIIING ON ALPACA")
                self.trading_provider.instance.submitOrder(
                    qty,
                    stock.tail(1)["sym"], "buy")
                time.sleep(5)

            try:
                self.db.save_data(table_name=table_name,
                                  data=self.buy_sell_open,
                                  if_exists="replace")
            except Exception as e:
                logger.error("Database save failed:" + str(e))

        return buy_sell_stock

    def close_all_alpaca_postitions(self):
        self.trading_provider.instance.close_all_postions()

    def clean_all_db_postitions(self):
        # self.buy_sell_closed = self.fill_closed_trades_from_db()

        self.db.save_data(table_name=self.table_name,
                          data=pd.DataFrame(),
                          if_exists="append")

        # self.db.save_data(table_name=self.table_name,
        #                   data=self.buy_sell_closed, if_exists="replace")

    def get_buyed_symbols_on_alpaca(self):

        buyed_stocks_table = "buyed_stocks"

        try:
            #get buyed stocks on alpaca
            abs = AlpacaBuySell()
            alp_pos, alp_orders = abs.get_positions()
            symbols = list()

            for position in alp_pos:
                symbols.append(position.symbol)

            for position in alp_orders:
                symbols.append(position.symbol)
                #------------------------------------------------

            df_sym = pd.DataFrame(symbols, columns=['sym'])
            self.db.save_data(buyed_stocks_table, df_sym, "replace")

        except Exception as e:
            logger.error("loading buyed symbols from localDB | Err: " + str(e))
            symbols = self.db.get_data(buyed_stocks_table)
            symbols = symbols.sym.tolist()

        return symbols

    def check_credit(self, price_sum):
        if self.credit["curr_amount"] is not None and self.credit[
                "curr_amount"] >= price_sum:
            return True
        else:
            return False

    def get_credit(self):
        """
        return available credit
        """
        pass
        # return credit["curr_amount"]

    # def show_stats(self, symbol):
    #     print(" ---------SUMMARY--------------- ")
    #     print("STOCKS: " + str(symbol))
    #     print("Stocks in buy: " + str(self.buyed_stocks) + " | Last price: " + str(self.prev_stock.close)+ " | Last buyed price: " + str(self.last_buyed_stock['close']))

    #     afterSellingStockMoney = round(self.money + (self.buyed_stocks * self.last_buyed_stock['close']),2)
    #     # profit = afterSellingStockMoney - self.startCredit;
    #     # tradingGainPercent = (afterSellingStockMoney - self.startCredit) / ( self.startCredit/100)/self.share_amount
    #     tradingGainPercent = (afterSellingStockMoney - self.first_buyed_price) / ( self.first_buyed_price/100)/self.share_amount
    #     tradingGainPercentCurrentPrice = (round(self.money + (self.buyed_stocks * self.prev_stock.close), 2) -
    #                                       self.credit["start_amount"]) / (self.credit["start_amount"]/100)/self.share_amount
    #     gainWithoutTradingPerc = (self.last_buyed_stock['close'] - self.first_stock.close) / (self.first_stock.close/100)
    #     afterSellingStockMoneyLastPrice = round(self.money + (self.buyed_stocks * self.last_buyed_stock['close']),2)
    #     gainWithoutTradingPercLastPrice = (self.prev_stock.close - self.first_stock.close) / (self.first_stock.close/100)

    #     if self.buyed_stocks > 0:
    #         self.sell_stock(self.prev_stock)

    #     # calculate average perc profit
    #     perc_divider = 1
    #     if self.profit_perc_all > 0:
    #         perc_divider = 2
    #     self.profit_perc_all = round((self.profit_perc_all+self.profit_perc)/perc_divider,2)

    #     # print("Money: " + str(self.money))

    #     # print("After selling remaining stocks for last buyed price: "  + str(afterSellingStockMoney) + " |  "  + str(round(afterSellingStockMoney-self.startCredit,2)) + " | " + str(round(tradingGainPercent,2)) + "%")
    #     # print("After selling remaining stocks for current price: "  + str(afterSellingStockMoney) + " |  "  + str(round(afterSellingStockMoney-self.startCredit,2)) + " | " + str(round(tradingGainPercentCurrentPrice,2)) + "%")
    #     print("First stock p.: " + str(self.first_stock.close) + " | Last stock p. : " +str(self.prev_stock.close) + " | Last buyed stock p. : " +str(self.last_buyed_stock['close']))
    #     print("Profit from " + str(symbol) +"  trade: " + str(self.profit_perc) + '%')
    #     print("Profit from all trades: " + str(self.profit_perc_all) + '%')
    #     print("Profit without trading: " + str(round(gainWithoutTradingPercLastPrice,2)) + "%")
    #     # print("Gain without trading last buyed price: " + str(round(self.last_buyed_stock['close'] - self.first_stock.close, 2)*self.share_amount) + " | " + str(round(gainWithoutTradingPerc,2)) + "%")
    #     # print("Profit without trading: " + str(round(self.prev_stock.close - self.first_stock.close, 2)*self.share_amount) + " | " + str(round(gainWithoutTradingPercLastPrice,2)) + "%")

    #     print("transactions: " + str(self.transactions))
    #     print("best settings" + str(self.best_settings))

    def trading_results(self, show=True) -> Union[None, pd.DataFrame]:
        res: pd.DataFrame = self.buy_sell_closed.copy()
        if len(res) > 0:
            res["profit_money"] = res.buy
            res["profit_percents"] = round((res.buy) / (res.buy / 100), 2)
            res["sum_profit_money"] = res["profit_money"].sum()
            res["sum_profit_percents"] = res["profit_percents"].sum()

            if show:
                logger.info("Profit money: ")
                logger.info(res["profit_money"])

                logger.info("Profit percents: ")
                logger.info(res["profit_percents"])

                logger.info("SUM Profit money: ")
                logger.info(res["sum_profit_money"][0])

                logger.info("SUM Profit percents: ")
                logger.info(res["sum_profit_percents"][0])

            return res
        else:
            return None

    def trading_stats(self, symbol: str, bt_stocks: pd.DataFrame) -> str:
        stats_mess: str = ""
        stats_mess += ("Last Buyed Stocks: " + str(self.last_buyed_stock))
        stats_mess += ("buy sell dataframe : " + str(self.buy_sell_open))
        stats_mess += (" ---------SUMMARY--------------- ")
        stats_mess += ("STOCKS: " + str(symbol))
        stats_mess += ("Stocks in buy: " + str(self.buyed_stocks) +
                       " | Last price: " + str(bt_stocks.iloc[-1].close) +
                       " | Last buyed price: " +
                       str(self.last_buyed_stock.buy))

        afterSellingStockMoney = round(
            self.money + (self.buyed_stocks * self.last_buyed_stock.buy), 2)
        # profit = afterSellingStockMoney - self.startCredit;
        # tradingGainPercent = (afterSellingStockMoney - self.startCredit) / ( self.startCredit/100)/self.share_amount
        tradingGainPercent = (afterSellingStockMoney - self.first_buyed_price
                              ) / (self.first_buyed_price /
                                   100) / self.shares_amount
        tradingGainPercentCurrentPrice = (
            round(self.money +
                  (self.buyed_stocks * bt_stocks.iloc[-1].close), 2) -
            self.startCredit) / (self.startCredit / 100) / self.shares_amount
        gainWithoutTradingPerc = (self.last_buyed_stock.buy -
                                  bt_stocks.iloc[0].close) / (
                                      bt_stocks.iloc[0].close / 100)
        # afterSellingStockMoneyLastPrice = round(self.money + (self.buyed_stocks * self.last_buyed_stock['close']),2)
        gainWithoutTradingPercLastPrice = (bt_stocks.iloc[-1].close -
                                           bt_stocks.iloc[0].close) / (
                                               bt_stocks.iloc[0].close / 100)

        if self.buyed_stocks > 0:
            self.sell_stock(bt_stocks.iloc[-1])

        # calculate average perc profit
        perc_divider = 1
        if self.profit_perc_all > 0:
            perc_divider = 2
        self.profit_perc_all = round(
            (self.profit_perc_all + self.profit_perc) / perc_divider, 2)

        # stats_mess +=("Money: " + str(self.money))

        # stats_mess +=("After selling remaining stocks for last buyed price: "  + str(afterSellingStockMoney) + " |  "  + str(round(afterSellingStockMoney-self.startCredit,2)) + " | " + str(round(tradingGainPercent,2)) + "%")
        # stats_mess +=("After selling remaining stocks for current price: "  + str(afterSellingStockMoney) + " |  "  + str(round(afterSellingStockMoney-self.startCredit,2)) + " | " + str(round(tradingGainPercentCurrentPrice,2)) + "%")
        print(self.last_buyed_stock)
        stats_mess += ("First stock p.: " + str(bt_stocks.iloc[0].close) +
                       " | Last stock p. : " + str(bt_stocks.iloc[-1].close) +
                       " | Last buyed stock p. : "
                       )  #+ str(self.last_buyed_stock['close']))
        stats_mess += ("Profit from " + str(symbol) + "  trade: " +
                       str(self.profit_perc) + '%')
        stats_mess += ("Profit from all trades: " + str(self.profit_perc_all) +
                       '%')
        stats_mess += ("Price change : " +
                       str(round(gainWithoutTradingPercLastPrice, 2)) + "%")
        # stats_mess +=("Gain without trading last buyed price: " + str(round(self.last_buyed_stock['close'] - bt_stocks.iloc[0].close, 2)*self.share_amount) + " | " + str(round(gainWithoutTradingPerc,2)) + "%")
        # stats_mess +=("Profit without trading: " + str(round(bt_stocks.iloc[-1].close - bt_stocks.iloc[0].close, 2)*self.share_amount) + " | " + str(round(gainWithoutTradingPercLastPrice,2)) + "%")

        stats_mess += ("transactions: " + str(self.transactions))
        self.show_sym_bs_stats(symbol)
        return stats_mess

    def show_sym_bs_stats(self, sym: str):

        self.db.limit = None
        dfp, financials, sentiment, earnings, spy = self.db.get_all_data(
            self.db.time_from, sym)
        dfp = FinI.add_indicators(dfp)
        dfp = FinI.add_fib(dfp, last_rows=10)
        # print(dfp)
        # last 5 financials
        financials = financials.tail(5)
        days_to_earnings = FinI.days_to_earnings(earnings)
        # print(earnings)
        if days_to_earnings is None:
            earnings = None
        fig, axs = plt.subplots(2, 1, figsize=(16, 16))
        PlotI.set_margins(plt)

        PlotI.plot_spy(axs[0], spy.loc[spy.index.isin(dfp.index)])
        axsp = PlotI.plot_stock_prices(axs[0].twinx(), dfp, sym, 0.5)
        axsp = PlotI.plot_sma(axsp, dfp, ["sma9", "sma50"])
        axsp.xaxis.set_major_formatter(plt.NullFormatter())
        axsp = PlotI.plot_candles(dfp,
                                  axsp,
                                  body_w=0.5,
                                  shadow_w=0.1,
                                  alpha=0.5)
        axsp = PlotI.plot_fib(dfp, axsp, alpha=0.4)
        axsp = PlotI.plot_fib(dfp, axsp, alpha=0.4, fib_name="fb_mid")
        axsp = PlotI.plot_fib(dfp, axsp, alpha=0.4, fib_name="fb_bot")
        axsp = PlotI.plot_weeks(axsp, dfp)

        PlotI.plot_boll(axsp, dfp, sym)

        axsp2 = PlotI.plot_volume_bars(axsp.twinx(), dfp)

        axsp2 = PlotI.plot_rsi(axs[1], dfp)
        axsp2 = PlotI.plot_macd_boll(axs[1].twinx(), dfp)
        # ax_macd = PlotI.plot_macd(ax_macd,dfp)
        axsp2 = PlotI.plot_volume_bars(axs[1].twinx(), dfp)

        if self.buy_sell_closed is not None and len(self.buy_sell_closed) > 0:
            axsp = PlotI.plot_bs(axsp, self.buy_sell_closed)
            axsp2 = PlotI.plot_bs(axsp2.twinx(), self.buy_sell_closed)

        plt.show()
示例#8
0
        train, test = dataset[0:train_size, :], dataset[
            train_size:len(dataset), :]
        print(len(train), len(test))
        return train, test

    # convert an array of values into a dataset matrix

    def create_dataset(self,
                       dataset: list,
                       look_back=1) -> Tuple[numpy.array, numpy.array]:
        dataX, dataY = [], []
        for i in range(len(dataset) - look_back - 1):
            a = dataset[i:(i + look_back), 0]
            dataX.append(a)
            dataY.append(dataset[i + look_back, 0])
        return numpy.array(dataX), numpy.array(dataY)


# Manual run from command line
for arg in args:
    if arg == "run":
        db = Database()
        m_df = db.load_data(table_name=TableName.DAY,
                            time_from="-380d",
                            symbols=["TSLA"])
        m_df_spy = db.load_data(table_name=TableName.DAY,
                                time_from="-380d",
                                symbols=["SPY"])

        lstm = MarketLSTM(m_df_spy[["close"]])
示例#9
0
class StockMess():
    def __init__(self):

        self.db = Database()
        self.ss = SectorStats()

        self.last_date = None
        self.financials = None
        self.earnings = None
        self.sentiment = None
        self.spy = None
        self.stocks = None
        self.in_day_stocks = None
        self.trend_data = None

    async def mail_stats(self, data, subject, last_date=None, spy=None):
        # print(data)
        if spy is None:
            spy = sdf.retype(
                self.db.load_data(TableName.DAY, ["spy"],
                                  time_from="-60d",
                                  time_to="0d"))

        for key, value in data.iterrows():

            if "flpd" in value:
                subject_flpd = subject + " " + str(round(value.flpd,
                                                         2)) + "% | "

            try:
                sym = value.sym

            except AttributeError:
                sym = key

            self.set_fundamentals(sym=sym)
            self.set_prices(sym=sym)
            self.mail_sym_stats(sym, subject_flpd, last_date=last_date)

    def a_mail_sym_stats(self, sym, subject, last_date=None):
        self.mail_sym_stats(sym, subject, last_date=None)

    def mail_sym_stats(self, sym, subject, last_date=None):

        # self.db.last_date = last_date
        # if self.spy is None:
        #     self.spy = sdf.retype(self.db.load_data(
        #         TableName.DAY, ["spy"], time_from="-60d", time_to="0d"))

        # self.stocks = sdf.retype(self.db.load_data(TableName.DAY, sym, time_from="-60d", time_to = "0d"))

        # self.stocks = FinI.add_indicators(self.stocks)
        # time_to = last_date
        # self.earnings, self.sentiment, self.financials = self.db.get_fundamentals(self.stocks.iloc[-1]["sym"],
        #                                     tf={"e": "-5d",
        #                                         "s": "-20d",
        #                                         "f":  "-14d"},
        #                                     tt={"e": "30d", "s": "0d", "f": "0d"})

        mess, curr_price, days_to_earnings = self.get_subj_mess(subject,
                                                                sym=sym)

        details = self.get_fund_mess(self.financials, curr_price,
                                     self.earnings, self.sentiment,
                                     days_to_earnings, self.stocks)

        plt = self.show_sym_stats(sym, True)

        Utils.send_mm_mail(mess, details, plt)

    def get_subj_mess(self, subject, sym=None):

        mess = ""

        if self.stocks is None or sym != self.stocks.iloc[0].sym:
            self.stocks = self.ss.get_trend_slice(table_name=None,
                                                  time_from="-120d",
                                                  time_to="0d",
                                                  symbol=sym)

        curr_price = self.stocks.iloc[-1].close

        # print(self.stocks)

        days_to_earnings = FinI.days_to_earnings(self.earnings)
        sector_mess, spy_mess, vol_mess = self.get_common_mess(self.stocks)

        mess = subject + " " + str(sym) + \
            self.subject_fund_info(self.financials, self.sentiment,
                                   self.earnings, days_to_earnings = days_to_earnings)

        mess += str(sector_mess)
        mess += str(spy_mess)
        mess += str(vol_mess)

        self.stocks = FinI.add_levels(self.stocks)
        # hl = FinI.get_fib_hl(self.stocks,  self.stocks.iloc[-1].close)
        pl = self.stocks.price_level.dropna()
        low, high = FinI.get_nearest_values(pl, curr_price)
        mess += " Price: " + str(curr_price)
        mess += " | Loss: " + str(Utils.calc_perc(
            curr_price,
            low[0])) + "%, " if low is not None and len(low) > 0 else ""
        mess += " " + "Prof.: " + str(Utils.calc_perc(
            curr_price,
            high[0])) + "% " if high is not None and len(high) > 0 else " | "

        print("get_subj_mess() - done")
        return mess, curr_price, days_to_earnings

    @staticmethod
    def get_fib_mess(df, close_price):
        mess = ""
        last_fib = -1
        for col in df:
            if col.startswith('fb'):
                if close_price > last_fib and close_price < df.iloc[-1][col]:
                    mess += str(Utils.calc_perc(close_price, last_fib)) + "% | " \
                        "Price: " + str(close_price) + \
                        " | " + str(Utils.calc_perc(close_price,
                                                  df.iloc[-1][col])) + "% \n\r"

                mess += str(col) + ": " + str(round(df.iloc[0][col],
                                                    2)) + "\n\r"

                last_fib = df.iloc[-1][col]
        return mess

    def show_sym_stats(self, sym, save_img=False):

        # last  financials
        if self.financials is not None and len(self.financials) > 0:
            self.financials = self.financials.tail(5)
        days_to_earnings = FinI.days_to_earnings(self.earnings)
        # print(earnings)
        if days_to_earnings is None:
            self.earnings = None
        plots_num = 4 if save_img else 5

        fig, axs = plt.subplots(plots_num, 1, figsize=(16, 18))
        PlotI.set_margins(plt)

        if self.spy is not None:
            PlotI.plot_spy(
                axs[0], self.spy.loc[self.spy.index.isin(self.stocks.index)])

        axsp = PlotI.plot_stock_prices(axs[0].twinx(),
                                       self.stocks,
                                       sym,
                                       alpha=0.3)
        axsp = PlotI.plot_sma(axsp, self.stocks, ["sma9", "sma50"])
        axsp = PlotI.plot_candles(self.stocks,
                                  axsp,
                                  body_w=0.5,
                                  shadow_w=0.1,
                                  alpha=0.5)
        axsp = PlotI.plot_fib(self.stocks, axsp, alpha=0.4)
        axsp = PlotI.plot_fib(self.stocks, axsp, alpha=0.4, fib_name="fb_mid")
        axsp = PlotI.plot_fib(self.stocks, axsp, alpha=0.4, fib_name="fb_bot")

        PlotI.plot_boll(axsp, self.stocks, sym)
        PlotI.plot_weeks(axsp, self.stocks)

        PlotI.plot_rsi(axs[1], self.stocks)
        ax_macd = PlotI.plot_macd_boll(axs[1].twinx(), self.stocks)
        # ax_macd = PlotI.plot_macd(ax_macd,dfp)

        PlotI.plot_volume_bars(axs[1].twinx(), self.stocks)

        if self.in_day_stocks is None:
            self.in_day_stocks = sdf.retype(
                self.db.load_data(TableName.MIN15,
                                  sym,
                                  time_from="-1d",
                                  time_to="0d"))
            if len(self.in_day_stocks) < 1:
                self.in_day_stocks = sdf.retype(
                    self.db.load_data(TableName.MIN15, sym, limit=20))

        # self.plot_volume(axs[2], last_prices)

        ax = PlotI.plot_candlesticks2(axs[2], self.in_day_stocks)
        self.in_day_stocks = FinI.add_fib_from_day_df(self.in_day_stocks,
                                                      self.stocks)
        ax = PlotI.plot_fib(self.in_day_stocks,
                            axs[2],
                            alpha=0.4,
                            fib_name="fb_mid")
        # PlotI.plot_boll(ax, last_prices, sym)

        sectors = self.ss.sectors_day_stats()
        PlotI.plot_sector_stats(axs[3], sectors, self.stocks.iloc[0].sector)
        if (save_img):
            return plt

        # self.plot_spy(axs[2], self.spy)
        #self.plot_yahoo_candles(last_prices)
        # self.plot_volume(axs[2], last_prices)
        # set rotation of tick labels

        axs[3].text(0.02,
                    0.9,
                    str(self.financials.beta.name) + ' | ' +
                    str(self.financials.beta.to_list()),
                    fontsize=8)
        axs[3].text(
            0.02,
            0.8,
            str(self.financials.priceToSalesTrailing12Months.name) + ' | ' +
            str(self.financials.priceToSalesTrailing12Months.to_list()),
            fontsize=8)
        axs[3].text(0.02,
                    0.7,
                    str(self.financials.enterpriseToRevenue.name) + ' | ' +
                    str(self.financials.enterpriseToRevenue.to_list()),
                    fontsize=8)
        axs[3].text(0.02,
                    0.6,
                    str(self.financials.profitMargins.name) + ' | ' +
                    str(self.financials.profitMargins.to_list()),
                    fontsize=8)
        axs[3].text(0.02,
                    0.5,
                    str(self.financials.enterpriseToEbitda.name) + ' | ' +
                    str(self.financials.enterpriseToEbitda.to_list()),
                    fontsize=8)
        axs[3].text(0.02,
                    0.4,
                    str(self.financials.trailingEps.name) + ' | ' +
                    str(self.financials.trailingEps.to_list()),
                    fontsize=8)
        axs[3].text(0.02,
                    0.3,
                    str(self.financials.forwardEps.name) + ' | ' +
                    str(self.financials.forwardEps.to_list()),
                    fontsize=8)
        axs[3].text(0.02,
                    0.2,
                    str(self.financials.priceToBook.name) + ' | ' +
                    str(self.financials.priceToBook.to_list()),
                    fontsize=8)
        axs[3].text(0.02,
                    0.1,
                    str(self.financials.bookValue.name) + ' | ' +
                    str(self.financials.bookValue.to_list()),
                    fontsize=8)
        axs[3].text(0.4,
                    0.9,
                    str(self.financials.shortRatio.name) + ' | ' +
                    str(self.financials.shortRatio.to_list()),
                    fontsize=8)
        axs[3].text(0.4,
                    0.8,
                    str(self.financials.sharesShortPriorMonth.name) + ' | ' +
                    str(self.financials.sharesShortPriorMonth.to_list()),
                    fontsize=8)
        axs[3].text(0.4,
                    0.7,
                    str(self.financials.pegRatio.name) + ' | ' +
                    str(self.financials.pegRatio.to_list()),
                    fontsize=8)
        axs[3].text(0.4,
                    0.6,
                    str(self.financials.earningsQuarterlyGrowth.name) + ' | ' +
                    str(self.financials.earningsQuarterlyGrowth.to_list()),
                    fontsize=8)
        axs[3].text(0.4,
                    0.5,
                    str(self.financials.bid.name) + ' | ' +
                    str(self.financials.bid.to_list()),
                    fontsize=8)
        axs[3].text(0.4,
                    0.4,
                    str(self.financials.trailingPE.name) + ' | ' +
                    str(self.financials.trailingPE.to_list()),
                    fontsize=8)
        axs[3].text(0.4,
                    0.3,
                    str(self.financials.forwardPE.name) + ' | ' +
                    str(self.financials.forwardPE.to_list()),
                    fontsize=8)
        axs[3].text(0.4,
                    0.2,
                    str(self.financials.industry.to_list()) + ' | ' +
                    str(self.financials.sector.to_list()),
                    fontsize=8)
        axs[3].text(0.4,
                    0.1,
                    str(self.financials.heldPercentInstitutions.name) + ' | ' +
                    str(self.financials.heldPercentInstitutions.to_list()) +
                    ' ||| ' + str(self.financials.heldPercentInsiders.name) +
                    ' | ' + str(self.financials.heldPercentInsiders.to_list()),
                    fontsize=8)
        axs[3].text(0.6,
                    0.9,
                    str(self.financials.fiftyDayAverage.name) + ' | ' +
                    str(self.financials.fiftyDayAverage.to_list()),
                    fontsize=8)
        axs[3].text(0.6,
                    0.7,
                    str("Last CLose Price: ") + ' | ' +
                    str(self.in_day_stocks.iloc[-1].close),
                    fontsize=8)
        axs[3].text(
            0.6,
            0.5,
            str("Days to earn.: ") + ' | ' + str(days_to_earnings.days) +
            " D" if self.earnings is not None else str("Days to earn.: NaN "),
            fontsize=8)
        axs[3].text(0.6,
                    0.4,
                    str("Earn. est. | act. | surp.:  ") +
                    str(self.earnings.iloc[-1].epsestimate) + ' | ' +
                    str(self.earnings.iloc[-1].epsactual) + ' | ' +
                    str(self.earnings.iloc[-1].epssurprisepct)
                    if self.earnings is not None else str("Earn est.: NaN "),
                    fontsize=8)
        axs[3].text(0.6,
                    0.3,
                    str("  Sentiment article/title: ") +
                    str(self.sentiment.sentiment_summary_avg.to_list()) + '/' +
                    str(self.sentiment.sentiment_title_avg.to_list())
                    if self.sentiment is not None and len(self.sentiment) > 0
                    else str("  Sentiment: NaN "),
                    fontsize=8)

        axs[3].text(0.02,
                    0.01,
                    str(self.financials.longBusinessSummary.to_list()),
                    fontsize=8)

        # self.plot_candlesticks(last_prices)
        # axs[3].plot([2], [1], 'o')
        # plt.text()

        # plt.show()
        return plt

    def subject_fund_info(self,
                          financials,
                          sentiment,
                          earnings,
                          days_to_earnings=None):

        mess = ""
        if len(financials) > 0:
            eps, pe = chi.eps_pe(financials)
            mess += ''.join([
                " | ShortR: ",
                str(financials.iloc[-1].shortRatio), " | TrEps/FwdEps: ",
                str(eps) + "%", " | TrPE/FwdPE: ",
                str(pe) + "%", " | 50_DA_move: ",
                str(
                    Utils.calc_perc(financials.iloc[0].fiftyDayAverage,
                                    financials.iloc[-1].fiftyDayAverage)) +
                "%", " | Beta: ",
                str(financials.iloc[0].beta), " | PriceToBook: ",
                str(financials.iloc[0].priceToBook), " | DividRate: ",
                str(financials.iloc[0].dividendRate)
            ])

        if earnings is not None and len(earnings) > 0:
            mess += ''.join([
                str(" | Earn. est./act./surp.:  "),
                str(earnings.iloc[-1].epsestimate), '/',
                str(earnings.iloc[-1].epsactual) + '/',
                str(earnings.iloc[-1].epssurprisepct), ""
            ])
        if days_to_earnings is not None:
            days_to_earnings = str(days_to_earnings).split(",")
            mess += ''.join([" | Earn :", str(days_to_earnings[0])])
        if sentiment is not None and len(sentiment) > 0:
            mess += ''.join([
                str(" | Sentiment article/title: "),
                str(sentiment.iloc[-1].sentiment_summary_avg), '/',
                str(sentiment.iloc[-1].sentiment_title_avg)
                if sentiment is not None and len(sentiment) > 0 else
                str("Sentiment: NaN ")
            ])

        return mess

    # def plot_sectors(self, plt):
    #     data = self.sectors_uptrend_by_month(yf=2021,yt=2021, show_chart = False)
    #     plt = self.sector_stats_to_plt(self,plt, data)
    #     return plt

    # def classify_sectors(self, time_from = "7d", table_name = "p_day", loosers = False):
    #     stocks = self.classify_sectors_uptrend(table_name)
    #     stocks = stocks.sort_values(by='flpd', ascending=loosers)
    #     return stocks

    def create_sectors_trend_mess(self, sector):

        sector_mess = ""

        # if self.sectors_trend is None and len(self.sectors_trend) < 1:
        self.ss.set_spy_sectors_trend()

        sector0 = self.ss.sectors_trend[0][self.ss.sectors_trend[0].index ==
                                           sector]
        sector1 = self.ss.sectors_trend[1][self.ss.sectors_trend[1].index ==
                                           sector]

        if len(sector0) > 0 and len(sector1) > 0:
            sector_mess = " | " + str(sector) + ": " + str(
                round(sector0.iloc[0].flpd, 1)) + "% -> " + str(
                    round(sector1.iloc[0].flpd, 1)) + "%"
        print("create_sectors_trend_mess() - done")

        return sector_mess

    def create_spy_trend_mess(self):
        spy_mess = ""
        if self.ss.spy_trend is not None and \
            self.ss.spy_trend[0] is not None and \
            len(self.ss.spy_trend) > 2 and \
            len(self.ss.spy_trend[0]) > 0 and \
            len(self.ss.spy_trend[1]) > 0:

            print(self.ss.spy_trend[0])
            spy_mess = " | SPY: " + str(
                round(self.ss.spy_trend[0].flpd.mean(), 2)) + "% -> " + str(
                    round(self.ss.spy_trend[1].flpd.mean(), 2)) + "%"
        else:
            spy_mess = "No Data"
        return spy_mess

    def get_common_mess(self, stocks):
        # print(stocks.iloc[0].sector)
        vol_mess = vol_perc = spy_mess = sector_mess = ""
        if stocks is not None and len(stocks) > 0:
            sector_mess = self.create_sectors_trend_mess(stocks.iloc[0].sector)

        if stocks is not None and "boll" in stocks:
            vol_perc = Utils.calc_perc(stocks.iloc[-1].boll,
                                       stocks.iloc[-1].boll_ub)
            vol_mess = " | Vlt: " + str(vol_perc) + "% "
        else:
            vol_perc = 0

        spy_mess = self.create_spy_trend_mess()

        print("get_common_mess() - done")
        return sector_mess, spy_mess, vol_mess

    def get_fund_mess(self,
                      financials,
                      curr_price,
                      earnings,
                      sentiment,
                      days_to_earnings,
                      day_stocks=None):
        mess = ""
        mess += ''.join("Detail | ")
        financials.sort_values(by=["date"], inplace=True, ascending=True)
        if len(financials) > 0:
            cols = [
                "date", "shortRatio", "sharesShortPriorMonth",
                "fiftyDayAverage", "beta", "dividendRate", "exDividendDate",
                "priceToSalesTrailing12Months", "enterpriseToRevenue",
                "profitMargins", "enterpriseToEbitda", "trailingEps",
                "forwardEps", "priceToBook", "bookValue", "pegRatio",
                "earningsQuarterlyGrowth", "bid", "volume", "trailingPE",
                "forwardPE", "heldPercentInstitutions", "heldPercentInsiders"
            ]

            mess += ''.join([
                "T_EPS->F_EPS: ",
                str(
                    Utils.calc_perc(financials.iloc[0].trailingEps,
                                    financials.iloc[0].forwardEps)), "%\n\r",
                "T_PE->F_PE: ",
                str(
                    Utils.calc_perc(financials.iloc[0].trailingPE,
                                    financials.iloc[0].forwardPE)) + "%\n\r"
            ])

            for item in cols:

                # financials[item].dropna(inplace=True)

                first = financials.iloc[0][item]
                last = financials.iloc[-1][item]

                mess += ''.join([
                    item + ": ",
                    str(Utils.human_format(first)),
                    " -> ",
                    str(Utils.human_format(last)),
                    " | ",
                    str(Utils.calc_perc(first, last)),
                    "%\n\r",
                ])

            mess += ''.join([
                str(financials.iloc[0].sector), ' | ',
                str(financials.iloc[0].industry), "\n\r",
                str("Current Price: "), ' | ',
                str(curr_price), "\n\r",
                str("Days to earn.: "), ' | ',
                str(days_to_earnings), " D", "\n\r"
            ])

        if earnings is not None and len(earnings) > 0:
            mess += str("Earn. est. | act. | surp.:  ") + str(earnings.iloc[-1].epsestimate) + \
                ' | ' + str(earnings.iloc[-1].epsactual) + \
                ' | ' + str(earnings.iloc[-1].epssurprisepct) + "\n\r"
        if sentiment is not None and len(sentiment) > 0:
            mess += str("Sentiment article/title: ") + str(sentiment.sentiment_summary_avg.to_list()) + \
                '/' + str(sentiment.sentiment_title_avg.to_list()) if sentiment is not None and len(sentiment)>0 else str("Sentiment: NaN ") + "\n\r"
        if financials is not None and len(financials) > 0:
            mess += str(financials.iloc[0].longBusinessSummary) + "\n\r"

        sector_mess, spy_mess, vol_mess = self.get_common_mess(self.stocks)
        mess += "\n\r" + sector_mess
        mess += "\n\r" + spy_mess
        mess += "\n\r" + vol_mess

        hl = FinI.get_fib_hl(self.stocks, curr_price)
        mess += "\n\r" + "Loss: " + str(Utils.calc_perc(curr_price, hl["l"])) + "% " + "  " + str(hl['l']) +" | "+\
            " Price: " + str(curr_price) + \
            " | " + "Profit: " + str(hl['h']) + \
            "  " + str(Utils.calc_perc(curr_price, hl["h"])) + "% \n\r"

        mess += self.get_fib_mess(self.stocks, curr_price) + "\n\r"
        print("get_fund_mess() - done")
        return mess

    def set_fundamentals(self,
                         sym,
                         last_date=None,
                         tf={
                             "e": "-5d",
                             "s": "-20d",
                             "f": "-30d"
                         },
                         tt={
                             "e": "14d",
                             "s": "2d",
                             "f": "0d"
                         }):

        if last_date:
            self.db.last_date = last_date
        print("set_fund_mess() - done")
        self.earnings, self.sentiment, self.financials = self.db.get_fundamentals(
            sym=sym, tf=tf, tt=tt)

    def set_prices(self,
                   sym=None,
                   last_date=None,
                   time_from="-90d",
                   time_to="0d"):
        if last_date:
            self.db.last_date = last_date

        self.in_day_stocks = sdf.retype(self.db.get_last_n_days(sym))

        self.stocks = sdf.retype(
            self.db.load_data(TableName.DAY,
                              sym,
                              time_from=time_from,
                              time_to=time_to))

        self.stocks = FinI.add_indicators(sdf.retype(self.stocks))

        self.stocks = FinI.add_fib(self.stocks, last_rows=10)

        self.spy = sdf.retype(
            self.db.load_data(TableName.DAY, ["SPY"],
                              time_from=time_from,
                              time_to=time_to))
        print("set_prices() - done")
示例#10
0
class SlBt():
    selected_stock = None
    timetick = None
    time_from = None
    time_to = None
    selected = {}
    action_type = None
    types = ["sector-stats", "stock-detail", "stocks-stats"]
    bs = BuySell()
    db = Database()
    sm = StockMess()
    sw = StockWhisperer()
    submit = None
    warning_check_list = []
    bt_day_gain = {}
    dft = pd.DataFrame()

    def __init__(self):
        self.symbols = self.db.get_symbols(TableName.DAY)
        self.sectors = self.db.get_sectors(TableName.DAY)
        self.app = self.get_home_page()

        # self.fig = None
        # logging.info(self.df)

    # def load_data(self, option, time_from = "-180d", time_to = None):
    #     df =  self.db.load_data(
    #         "p_day", symbols=option, time_from=time_from, time_to = time_to)
    #     df = FinI.add_indicators(sdf.retype(df))
    #     return df

    def testing_mess(self):
        self.sm.stocks = self.db.load_data(
            table_name=TableName.DAY,
            symbols=["PLUG"],
            time_from=self.time_from,
            time_to=self.time_to,
        )
        self.sm.get_subj_mess("Base Fund: ", "PLUG")

    def get_home_page(self):
        # logging.info(st)
        st.set_page_config(layout="wide")
        self.hide_footer()
        self.left_menu()
        # self.testing_mess()

        self.action_router()

    def left_menu(self):

        self.time_from = st.sidebar.text_input("Time from now -1m, -1h, -1d,",
                                               value="-120d")
        self.time_to = st.sidebar.text_input("Time to 1m, 1h, 1d,")

        self.portfolio = st.sidebar.text_input(
            'Portfolio', value='GPS,FCX,CYH,VALE,F,AMAT,MU,ABT,HIMX,SBSW')

        self.selected_stock = st.sidebar.selectbox('Select stock',
                                                   self.symbols)

        # if self.selected_stock == 0:
        #     self.selected_stock = "TSLA"

    def action_router(self):

        if st.sidebar.button('test buy'):
            self.buy_alg()

        if st.sidebar.button('Machine learning'):
            self.prepare_data_for_ml()

        if st.sidebar.button('Portfolio opt'):
            self.portfolio_opt()

        if st.sidebar.button('Up-down stats'):
            self.up_down_stats()

        if st.sidebar.button('Logistic regresion'):
            self.logistic_regresion()

        if st.sidebar.button('L.R. Find Best Buy Candidate'):
            self.lr_best_candidate()

    def lr_best_candidate(self):
        df_best_buy = pd.DataFrame()
        symbols = self.db.get_symbols()
        for sym in symbols:
            try:
                st.write(f"filling: {sym}")
                df_lr_raw = self.logistic_regression_raw(sym)
                df_best_buy = df_best_buy.append(df_lr_raw.tail(1))
            except Exception as e:
                st.write(e)

        st.dataframe(df_best_buy.sort_values(by="prob_1"))

    def logistic_regression_raw(self, symbol="SPY"):
        #TODO finish thos functioo for find best buy for stock with best Linear Regression probability params
        df = self.db.load_data(table_name=TableName.DAY,
                               time_from=self.time_from,
                               symbols=[symbol])

        # m_df_spy = self.db.load_data(
        #     table_name=TableName.DAY,  time_from=self.time_from, symbols=["SPY"])

        df['open-close'] = df['close'] - df['open'].shift(1)
        df['close-close'] = df['close'].shift(-1) - df['close']
        # wrong close close only for research
        df['close-close-prev'] = df['close'] - df['close'].shift(1)

        df['S_9'] = df['close'].rolling(window=9).mean()
        df['S_20'] = df['close'].rolling(window=20).mean()
        # df['S_50'] = df['close'].rolling(window=50).mean()
        # df['S_200'] = df['close'].rolling(window=200).mean()
        df['Corr_9'] = df['close'].rolling(window=9).corr(df['S_9'])
        df['Corr_20'] = df['close'].rolling(window=9).corr(df['S_20'])
        df['RSI'] = ta.momentum.rsi(close=df['close'])

        y = np.where(df['close'].shift(-1) > df['close'], 1, -1)
        df = df[["Corr_9", "open-close", "close-close-prev", "RSI", "S_9"]]
        df = df.dropna()
        X = df.iloc[:, :30]
        # st.write(len(y))
        # st.write(len(X))
        split = int(0.7 * len(df))

        X_train, X_test, y_train, y_test = X[:split], X[split:], y[:split], y[
            split:]

        # We will instantiate the logistic regression in Python using ‘LogisticRegression’
        # function and fit the model on the training dataset using ‘fit’ function.
        model = LogisticRegression()
        model = model.fit(X_train, y_train)

        # Examine coeficients
        # pd.DataFrame(zip(X.columns, np.transpose(model.coef_)))
        # st.write("Examine The Coefficients")
        # st.write(pd.DataFrame(zip(X.columns, np.transpose(model.coef_))))

        #We will calculate the probabilities of the class for the test dataset using ‘predict_proba’ function.
        probability = model.predict_proba(X_test)
        df['Predicted_Signal'] = model.predict(X)
        df = df.tail(len(probability))
        df["prob_0"] = probability[:, 0]
        df["prob_1"] = probability[:, 1]
        df["sym"] = symbol
        return df

    def logistic_regresion(self, symbols=None):

        if symbols is None:
            symbols = [self.selected_stock]
        # LOGISTIC REGRESSION  sucesfully finish this logic
        st.write(f"Logistic regression: {self.selected_stock}")

        df = self.db.load_data(table_name=TableName.DAY,
                               time_from=self.time_from,
                               symbols=symbols)

        m_df_spy = self.db.load_data(table_name=TableName.DAY,
                                     time_from=self.time_from,
                                     symbols=["SPY"])

        df_best_buy = pd.DataFrame()
        df_lr_raw = self.logistic_regression_raw()
        st.write("logistic regression RAW SPY")
        st.dataframe(df_lr_raw)

        # remove volume, industry, symbol cols
        # df = df.iloc[:,:4]
        # df =  df.dropna()
        # df = df.iloc[:, :4]
        # df = df.retype(spy)
        df['open-close'] = df['close'] - df['open'].shift(1)
        df['close-close'] = df['close'].shift(-1) - df['close']
        # wrong close close only for research
        df['close-close-prev'] = df['close'] - df['close'].shift(1)
        # df['close-close-1'] = df['close'] - df['close'].shift(1)
        # df['close-close-2'] = df['close'].shift(1) - df['close'].shift(2)
        # df['close-close-3'] = df['close'].shift(2) - df['close'].shift(3)
        # df['close-close-4'] = df['close'].shift(3)- df['close'].shift(4)
        df, m_df_spy = FinI.get_sizes(df, m_df_spy)
        # df = FinI.add_weekday(df)
        # df = FinI.add_week_of_month(df)
        df = FinI.add_yearweek(df)

        # df = FinI.add_levels(df)
        # only first nine rows be aware of this

        # df = FinI.add_indicators(df)
        # df["MACD"] = ta.trend.macd(close=df['close'])
        # df['S_9'] = df['close'].rolling(window=9).mean()
        # df['S_20'] = df['close'].rolling(window=20).mean()
        # df['S_50'] = df['close'].rolling(window=50).mean()

        # df['Corr'] = df['close'].rolling(window=10).corr(df['S_9'])
        # df['RSI'] = ta.momentum.rsi(close= df['close'], n=9)
        # Initialize Bollinger Bands Indicator

        # Add Bollinger Bands features
        # df['bb_bbm'] = indicator_bb.bollinger_mavg()
        # df['bb_bbh'] = indicator_bb.bollinger_hband()
        # df['bb_bbl'] = indicator_bb.bollinger_lband()

        df['S_9'] = df['close'].rolling(window=9).mean()
        df['S_20'] = df['close'].rolling(window=20).mean()
        # df['S_50'] = df['close'].rolling(window=50).mean()
        # df['S_200'] = df['close'].rolling(window=200).mean()
        df['Corr_9'] = df['close'].rolling(window=9).corr(df['S_9'])
        df['Corr_20'] = df['close'].rolling(window=9).corr(df['S_20'])
        df['RSI'] = ta.momentum.rsi(close=df['close'])
        # df["MACD"] = ta.trend.macd(close=df['close'])
        df = df.fillna(0)
        st.write("Correlation Matrix - Heatmap")
        self.get_heatmap(df)
        # remove open, high, low
        # df = df.iloc[:,3:]
        y = np.where(df['close'].shift(-1) > df['close'], 1, -1)
        st.write("Rows:")
        st.write(len(df))
        # df = df.drop(columns= ["date",
        #                        "yearweek",
        #                        "size_boll_ub",
        #                        "size_boll_lb",
        #                        "size_boll",
        #                        "up_down_row",
        #                        "green_red_row",
        #                        "price_level",
        #                        "weekday",
        #                        "boll",
        #                        "sma9",
        #                        "close_20_sma",
        #                        "size_top",
        #                        "size_btm",
        #                        "close_20_mstd",
        #                        "size_top-2",
        #                        "size_top-1",
        #                        "size_btm-2",
        #                        "size_btm-1",
        #                        "boll_ub",
        #                        "boll_lb",
        #                        "size_btm-3",
        #                        "size_top-3",
        #                        "size_sma9",
        #                        "size_sma20",
        #                         "sma20",
        #                        "open",
        #                        "close",
        #                        "high",
        #                        "low",
        #                        "size_body-1",
        #                        "size_body-2",
        #                        "size_body-3",
        #                        "week_in_month",
        #                        "size_body",
        #                        "size_prev_chng",
        #                        "symbol",
        #                        "sector",
        #                        "sym",
        #                        "industry",
        #                        "amount",
        #                        "volume",
        #  "open-close",
        # "close-close"
        #                        ])
        df_strategy = df.copy()

        # relatively good negative prediction
        # df = df[["size_sma9"]]
        # values by corelation matrix
        # df = df[["size_sma20","size_sma9","up_down_row"]]
        # df = df[["green_red_row", "size_sma9", "up_down_row", "size_body"]]
        # df = df[["green_red_row", "size_sma9", "up_down_row", "size_body","volume"]]
        # origin
        # df = df[["Corr_9","Corr_20", "open-close", "close-close-prev", "RSI","sma9"]]
        df = df[["Corr_9", "open-close", "close-close-prev", "RSI", "sma9"]]
        # overnight, negative precision
        # df = df[["green_red_row", "size_body-1","size_body-2","size_body-3", "size_prev_chng","weekday"]]

        # df = df[["close", "sma9", "sma20"]]
        st.write("Dataframe")
        st.dataframe(df)
        X = df.iloc[:, :30]
        st.write(len(y))
        st.write(len(X))
        # split to test dataset

        split = int(0.7 * len(df))

        X_train, X_test, y_train, y_test = X[:split], X[split:], y[:split], y[
            split:]

        # We will instantiate the logistic regression in Python using ‘LogisticRegression’
        # function and fit the model on the training dataset using ‘fit’ function.
        model = LogisticRegression()
        model = model.fit(X_train, y_train)

        # Examine coeficients
        pd.DataFrame(zip(X.columns, np.transpose(model.coef_)))
        st.write("Examine The Coefficients")
        st.write(pd.DataFrame(zip(X.columns, np.transpose(model.coef_))))

        #We will calculate the probabilities of the class for the test dataset using ‘predict_proba’ function.
        st.write("probability")
        probability = model.predict_proba(X_test)
        st.write(probability)

        st.write("predicted")
        predicted = model.predict(X_test)
        st.write(predicted)

        st.write("Y test")
        st.write(y_test)
        st.write(len(X_test))
        st.write("Confusion matrix")
        conf_matrix = metrics.confusion_matrix(y_test, predicted)
        st.write(conf_matrix)

        st.write("classification report")
        st.write(metrics.classification_report(y_test, predicted))

        st.write("model accuracy")
        st.write(model.score(X_test, y_test))

        st.write("cross validation accuracy")
        cross_val = cross_val_score(LogisticRegression(),
                                    X,
                                    y,
                                    scoring='accuracy',
                                    cv=10)
        st.write(cross_val)
        st.write(cross_val.mean())

        st.write("Trading Strategy")

        df['Predicted_Signal'] = model.predict(X)
        st.write("Predicted signals")
        st.dataframe(df)

        #STRARTEGY count
        st.dataframe(df_strategy)

        # df_strategy = df_strategy.tail(len(df_strategy) - split)
        df_strategy["Predicted_Signal"] = model.predict(X)
        price_change = df_strategy.iloc[len(df_strategy) -
                                        1].close - df_strategy.iloc[0].close

        st.write("Perfect gain")
        df_strategy["perfect_gain"] = df_strategy["close-close"].where(
            df_strategy["close-close"] > 0).sum()
        st.write(df_strategy["perfect_gain"].iloc[0])

        st.write("Invest Gain")
        st.write(price_change)

        st.write("L.G. gain")
        df_strategy["lg_gain"] = df_strategy["close-close"].where(
            df_strategy["Predicted_Signal"] > 0).sum()
        st.write(df_strategy["lg_gain"].iloc[0])

        gap = -2
        st.write("sma9 gain: " + str(gap))
        df_strategy["sma9_gain"] = df_strategy["close-close"].where(
            df_strategy["size_sma9"] > gap).sum()
        st.write(df_strategy["sma9_gain"].iloc[0])

        st.write("sma9 gain 0")
        df_strategy["sma9_gain"] = df_strategy["close-close"].where(
            df_strategy["size_sma9"] > 0).sum()
        st.write(df_strategy["sma9_gain"].iloc[0])

        st.write("sma20 gain")
        df_strategy["sma20_gain"] = df_strategy["close-close"].where(
            df_strategy["size_sma20"] > -2).sum()
        st.write(df_strategy["sma20_gain"].iloc[0])
        # df['Nifty_returns'] = np.log(df['close']/df['close'].shift(1))
        # Cumulative_Nifty_returns = np.cumsum(df[split:]['Nifty_returns'])

        # df['Startegy_returns'] = df['Nifty_returns']* df['Predicted_Signal'].shift(1)
        # Cumulative_Strategy_returns = np.cumsum(df[split:]['Startegy_returns'])

        # st.line_chart(Cumulative_Nifty_returns)
        # st.line_chart(Cumulative_Strategy_returns)

    def up_down_stats(self):

        m_df = self.db.load_data(table_name=TableName.DAY,
                                 time_from=self.time_from,
                                 symbols=[self.selected_stock])

        m_df_spy = self.db.load_data(table_name=TableName.DAY,
                                     time_from=self.time_from,
                                     symbols=["SPY"])

        m_df, m_df_spy = FinI.get_sizes(m_df, m_df_spy)

        self.candle_chart(m_df, m_df_spy)
        # above_sma9, under_sma9, above_boll,under_boll = {"1":0,"2":0,"3":0,"4":0,"5":0,"6":0}
        ind = pd.DataFrame()
        ws = pd.DataFrame()
        u = 0
        pred = pd.DataFrame()

        for index, row in m_df.iterrows():

            if row.weekday == 0:
                i = 1

                while m_df.iloc[
                        m_df.index.get_loc(index) +
                        i].weekday == m_df.iloc[m_df.index.get_loc(index) + 1 +
                                                i].weekday - 1:
                    rw = m_df.iloc[m_df.index.get_loc(index) + i]

                    st.write(str(rw.date) + " - " + str(rw.size_body))
                    i += 1
            st.write(row.week_in_month)

            if True or row.size_sma9 > 0 and row.size_boll > 0:
                if row.size_body > 0:
                    # st.write(u)
                    if u < 0:
                        ind = ind.append([u])
                        u = 0

                    u += 1
                elif row.size_body < 0:
                    if u > 0:
                        ind = ind.append([u])
                        #   st.write(ind)
                        u = 0

                    u -= 1
        #
        st.dataframe(ind)
        st.dataframe(ind.groupby(ind.columns[0]).size())

    # def get_size_data(self, stocks = None):

    #     if stocks is None:
    #         stocks = self.selected_stock
    #     m_df = self.db.load_data(
    #         table_name=TableName.DAY,  time_from=self.time_from, symbols=[stocks])

    #     m_df_spy = self.db.load_data(
    #         table_name=TableName.DAY,  time_from=self.time_from, symbols=["SPY"])
    #     m_df_spy["oc_mean"] = ((m_df_spy.close + m_df_spy.open)/2)
    #     m_df = sdf.retype(m_df)
    #     m_df.get("boll")
    #     m_df = FinI.add_sma(9, m_df)
    #     m_df = FinI.add_weekday(m_df)
    #     m_df = FinI.add_week_of_month(m_df)
    #     m_df = FinI.add_levels(m_df)

    #     m_df["size_top"] = m_df.apply(lambda row: Utils.calc_perc(
    #         row.open, row.high) if row.open > row.close else Utils.calc_perc(row.close, row.high), axis=1)

    #     m_df["size_btm"] = m_df.apply(lambda row: Utils.calc_perc(
    #         row.low, row.close) if row.open > row.close else Utils.calc_perc(row.low, row.open), axis=1)

    #     m_df["size_body"] = m_df.apply(lambda row: Utils.calc_perc(row.open, row.close), axis=1)
    #     m_df["size_sma9"] = m_df.apply(lambda row: Utils.calc_perc(row.sma9, row.close), axis=1)
    #     m_df["size_boll"] = m_df.apply(
    #         lambda row: Utils.calc_perc(row.boll, row.close), axis=1)
    #     m_df["size_boll_ub"] = m_df.apply(
    #         lambda row: Utils.calc_perc(row.boll_ub, row.close), axis=1)
    #     m_df["size_boll_lb"] = m_df.apply(
    #         lambda row: Utils.calc_perc(row.boll_lb, row.close), axis=1)

    #     m_df["size_top-1"] = m_df.shift(1).size_top

    #     m_df["size_btm-1"] = m_df.shift(1).size_btm

    #     m_df["size_body-1"] = m_df.shift(1).size_body

    #     m_df["size_top-2"] = m_df.shift(2).size_top

    #     m_df["size_btm-2"] = m_df.shift(2).size_btm

    #     m_df["size_body-2"] = m_df.shift(2).size_body

    #     m_df["size_top-3"] = m_df.shift(3).size_top

    #     m_df["size_btm-3"] = m_df.shift(3).size_btm

    #     m_df["size_body-3"] = m_df.shift(3).size_body

    #     m_df["size_prev_chng"] = (
    #         m_df.open - m_df.shift(1).close) / (m_df.shift(1).close/100)

    #     return m_df, m_df_spy

    def prepare_data_for_ml(self):

        m_df = self.db.load_data(table_name=TableName.DAY,
                                 time_from=self.time_from,
                                 symbols=[self.selected_stock])

        m_df_spy = self.db.load_data(table_name=TableName.DAY,
                                     time_from=self.time_from,
                                     symbols=["SPY"])

        m_df, m_df_spy = FinI.get_sizes(m_df, m_df_spy)

        st.dataframe(m_df)
        self.process_data(m_df)
        self.candle_chart(m_df, m_df_spy)
        self.show_sizes(m_df)
        self.get_heatmap(m_df)
        self.nn_pred(m_df)

    def show_sizes(self, df):

        sets = [{
            'x': df.index,
            'y': df.size_body,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 1,
                'color': 'blue'
            },
            'name': 'body'
        }]
        sets += [{
            'x': df.index,
            'y': df.size_prev_chng,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 1,
                'color': 'green'
            },
            'name': 'prev day'
        }]
        sets += [{
            'x': df.index,
            'y': df.weekday,
            'type': 'scatter',
            'mode': 'lines+markers',
            'line': {
                'width': 1,
                'color': 'brown'
            },
            'name': 'weeks'
        }]
        sets += [{
            'x': df.index,
            'y': df.week_in_month,
            'type': 'scatter',
            'mode': 'lines+markers',
            'line': {
                'width': 1,
                'color': 'orange'
            },
            'name': 'weeks'
        }]

        fig = make_subplots(rows=1,
                            cols=1,
                            shared_xaxes=True,
                            vertical_spacing=0.009,
                            horizontal_spacing=0.009,
                            row_width=[0.5],
                            specs=[[{
                                "secondary_y": True
                            }]])
        fig.add_traces(data=sets, cols=1, rows=1)

        fig.update_yaxes(showgrid=True,
                         zeroline=False,
                         showticklabels=True,
                         showspikes=True,
                         spikemode='across',
                         spikesnap='cursor',
                         showline=True,
                         spikedash='dash',
                         spikethickness=0.5)

        fig.update_xaxes(showgrid=True,
                         zeroline=False,
                         rangeslider_visible=False,
                         showticklabels=True,
                         showspikes=True,
                         showline=True,
                         spikemode='across',
                         spikesnap='cursor',
                         spikedash='dash',
                         spikethickness=0.5)

        fig.update_layout(autosize=True,
                          height=600,
                          hoverdistance=1,
                          hovermode='x',
                          spikedistance=1000)
        st.plotly_chart(
            fig,
            use_container_width=True,
            use_container_height=True,
            template="plotly_dark",
        )

    def get_heatmap(self, df):
        # fig = px.imshow( df,
        #     x= ["size_body", "size_btm", "size_top", "size_body-1", "size_top-1",  "size_btm-1", "size_prev_chng"],
        #     y=["size_body", "size_btm", "size_top", "size_body-1", "size_top-1",  "size_btm-1", "size_prev_chng"],
        #     )
        # fig = px.scatter_matrix(df)
        # fig.show()

        df_c = pd.DataFrame(
            df,
            columns=[
                "size_body", "size_prev_chng", "weekday", "week_in_month",
                "size_btm", "size_top", "size_body-1", "size_top-1",
                "size_btm-1", "size_body-2", "size_top-2", "size_btm-2",
                "size_body-3", "size_top-3", "size_btm-3", "size_sma9",
                "size_sma20", "size_boll", "size_boll_ub", "size_boll_lb",
                "green_red_row", "up_down_row"
            ])
        st.write(df_c.corr())

    def portfolio_opt(self):
        portfolio = self.portfolio.split(",")
        df = self.db.load_data(TableName.DAY,
                               time_from=self.time_from,
                               symbols=portfolio)
        # df = FinI.add_date_col(df)
        df = df[["close", "sym"]]
        df2 = df.copy()
        df2 = df2.drop(columns=["close", "sym"])
        for sym in portfolio:
            df2[sym] = df[df["sym"] == sym]["close"]

        df2 = df2.drop_duplicates()

        # df = df.transpose()
        # df.index = pd.to_datetime(df['date']).astype(int) / 10**9
        st.write(df2)
        # Calculate expected returns and sample covariance
        mu = expected_returns.mean_historical_return(df2)
        S = risk_models.sample_cov(df2)

        # Optimize for maximal Sharp ratio
        ef = EfficientFrontier(mu, S)
        raw_weights = ef.max_sharpe()
        cleaned_weights = ef.clean_weights()
        # ef.save_weights_to_file("weights.csv")  # saves to file
        st.write(cleaned_weights)
        mu, sigma, sharpe = ef.portfolio_performance(verbose=True)
        st.write("Expected annual return: {:.1f}%".format(100 * mu))
        st.write("Annual volatility: {:.1f}%".format(100 * sigma))
        st.write("Sharpe Ratio: {:.2f}".format(sharpe))

    def process_data(self, m_df):
        from sklearn import datasets
        from sklearn.neighbors import KNeighborsClassifier
        knn = KNeighborsClassifier(n_neighbors=6)
        # knn.fit(m_df.iloc[0,len(m_df/2)], m_df[len(m_df)/2,len(m_df)])

    def nn_pred(self, df):
        # st.dataframe(df[["close"]])
        #Number of neurons in the input, output, and hidden layers

        stock_data = df[["close"]]
        lstm = MarketLSTM(stock_data)

        # stock_data["seconds"] = stock_data.apply(lambda row: row.index.astype(int) / 10**9)
        # stock_data = stock_data[["seconds", "close"]]
        # stock_data = scale(stock_data)
        # #gets the price and dates from the matrix
        # prices = stock_data[:, 1].reshape(-1, 1)
        # dates = stock_data[:, 0].reshape(-1, 1)

        # chart_data = pd.DataFrame([dates[:,0],prices[:,0]])
        # chart_data = chart_data.transpose()
        # self.nn_train(dates,prices)

    def nn_train(self, dates, prices):
        pass

    def nn_train_OLD(self, dates, prices):
        input = 1
        output = 1
        hidden = 50
        #array of layers, 3 hidden and 1 output, along with the tanh activation function
        layers = [('F', hidden), ('AF', 'tanh'), ('F', hidden), ('AF', 'tanh'),
                  ('F', hidden), ('AF', 'tanh'), ('F', output)]
        #construct the model and dictate params
        mlpr = ANNR([input],
                    layers,
                    batchSize=256,
                    maxIter=20000,
                    tol=0.2,
                    reg=1e-4,
                    verbose=True)

        #number of days for the hold-out period used to access progress
        holdDays = 5
        totalDays = len(dates)
        #fit the model to the data "Learning"
        mlpr.fit(dates[0:(totalDays - holdDays)],
                 prices[0:(totalDays - holdDays)])

        # stocks_day["sym"] = stocks_day["sym"].astype('category')

    def candle_chart(self, df, m_df_spy):
        sets = [{
            'x': df.index,
            'open': df.open,
            'close': df.close,
            'yaxis': "y1",
            'high': df.high,
            'low': df.low,
            "hovertext": "",
            'type': 'candlestick',
            "opacity": 1,
            'line': {
                'width': 0.5,
            }
        }]
        sets += [{
            'x': df.index,
            'y': df.boll_ub,
            'type': 'scatter',
            'yaxis': "y1",
            'mode': 'lines',
            'line': {
                'width': 1,
                'color': 'green'
            },
            'name': 'Boll UP'
        }]
        sets += [{
            'x': df.index,
            'y': df.boll,
            'yaxis': "y1",
            'type': 'scatter',
            "fill": 'tonexty',
            'line': {
                'width': 0,
            },
            "fillcolor": 'rgba(128, 255, 128,0.2)'
        }]
        sets += [{
            'x': df.index,
            'y': df.boll_lb,
            'type': 'scatter',
            'yaxis': "y1",
            'mode': 'lines',
            'line': {
                'width': 1,
                'color': 'green'
            },
            'name': 'Boll Down'
        }]
        sets += [{
            'x': df.index,
            'y': df.boll,
            'yaxis': "y1",
            'type': 'scatter',
            "fill": 'tonexty',
            'line': {
                'width': 0,
            },
            "fillcolor": 'rgba(255, 128, 128,0.2)'
        }]

        sets += [{
            'x': df.index,
            'y': df.boll_ub,
            'type': 'scatter',
            'yaxis': "y1",
            'mode': 'lines',
            'line': {
                'width': 1,
                'color': 'green'
            },
            'name': 'Boll UP'
        }]
        sets += [{
            'x': df.index,
            'y': df.sma9,
            'type': 'scatter',
            'yaxis': "y1",
            'mode': 'lines',
            'line': {
                'width': 1,
                'color': 'blue'
            },
            'name': 'Boll Down'
        }]

        for i, r in df.iterrows():
            if r.price_level is not None:
                sets += [{
                    'x': [r.date, df.iloc[-1].date],
                    'y': [r.price_level, r.price_level],
                    'type': 'scatter',
                    'yaxis': "y1",
                    'mode': 'lines',
                    'line': {
                        'width': 1,
                        'color': 'brown',
                        "dash": "dot"
                    },
                    'name': ''
                }]

        fig = make_subplots(rows=2,
                            cols=1,
                            shared_xaxes=True,
                            vertical_spacing=0.009,
                            horizontal_spacing=0.009,
                            row_width=[0.1, 0.5],
                            specs=[[{
                                "secondary_y": True
                            }], [{
                                "secondary_y": True
                            }]])
        fig.add_traces(data=sets, cols=1, rows=1)

        # sets = []

        fig.add_trace(
            {
                'x': m_df_spy.index,
                'y': m_df_spy.oc_mean,
                'type': 'scatter',
                'yaxis': "y2",
                'mode': 'lines',
                'line': {
                    'width': 1,
                    'color': 'red'
                },
                'name': 'SPY'
            },
            1,
            1,
            secondary_y=True,
        )

        df.loc[df.open > df.close, "vol_color"] = "red"
        df.loc[df.open <= df.close, "vol_color"] = "green"
        fig.add_trace(
            {
                'x': df.index,
                'y': df.volume,
                'type': 'bar',
                'name': 'Volume',
                'marker_color': df.vol_color
            },
            2,
            1,
            secondary_y=False,
        )

        fig.update_yaxes(showgrid=True,
                         zeroline=False,
                         showticklabels=True,
                         showspikes=True,
                         spikemode='across',
                         spikesnap='cursor',
                         showline=True,
                         spikedash='dash',
                         spikethickness=0.5)

        fig.update_xaxes(showgrid=True,
                         zeroline=False,
                         rangeslider_visible=False,
                         showticklabels=True,
                         showspikes=True,
                         showline=True,
                         spikemode='across',
                         spikesnap='cursor',
                         spikedash='dash',
                         spikethickness=0.5)

        fig.update_layout(autosize=True,
                          height=600,
                          hoverdistance=1,
                          hovermode='y',
                          spikedistance=10000)
        st.plotly_chart(
            fig,
            use_container_width=True,
            use_container_height=True,
            template="plotly_dark",
        )

    def buy_alg(self, stats_time=None):

        if stats_time is None:
            stats_time = "-60d"
        backtest_time = "-14d"

        self.db.last_date = self.db.get_date_format(backtest_time)
        spy = self.db.load_data(table_name=TableName.DAY_FS,
                                symbols=["SPY"],
                                time_from=stats_time)
        # spy = sdf.retype(spy)
        # spy = FinI.add_indicators(spy)

        stocks_day = self.db.load_data(table_name=TableName.DAY_FS,
                                       time_from=stats_time)
        stocks_day["sym"] = stocks_day["sym"].astype('category')

        stocks_15 = self.db.load_data(table_name=TableName.MIN15,
                                      time_from=backtest_time)
        stocks_15["sym"] = stocks_15["sym"].astype('category')
        spy_15 = stocks_15[stocks_15["sym"] == "SPY"]

        # logging.info(spy)
        symbols = self.db.get_symbols()

        # for testing performance reason here are only few stocks
        symbols = [
            "INTC", "BYND", "ZM", "NKE", "HIMX", "JKS", "ENPH", "DUK", "GE",
            "DIS", "LEVI", "NVAX", "SLCA", "GPS"
        ]
        # iterate over days in market
        spy2 = spy.tail(20)

        # retype to stocks dataframe
        if not isinstance(stocks_day, sdf):
            stocks_day = sdf.retype(stocks_day)

        for index, spy_row_day in spy2.iterrows():
            st.write("spy: " + str(spy_row_day))
            st.write("DATE" + str(index))

            for symbol in symbols:
                # load stocks for stats
                stocks_day_sym = stocks_day[stocks_day["sym"] == symbol]
                # stocks_day_sym = FinI.add_indicators(stocks_day_sym)
                # stocks_day_sym = FinI.add_sma(9, stocks_day_sym)
                # stocks_day_sym = FinI.add_sma(50, stocks_day_sym)
                # stocks_day_sym.get('boll')
                # stocks_day_sym.get('volume_delta')
                # stocks_day_sym.get('macd')
                # stocks_day_sym.get('kdjk')
                # stocks_day_sym.get('open_-2_r')
                # logging.info(" -------------------------------------------------  --------------")
                # logging.info(stocks_day_sym)
                # stocks_day_sym = FinI.add_day_types(stocks_day_sym)
                # stocks_day_sym = FinI.add_levels(stocks_day_sym)
                stocks_15_sym = stocks_15[stocks_15["sym"] == symbol]
                stock_rows15 = stocks_15_sym.loc[
                    stocks_15_sym.index <= pytz.utc.localize(index)]
                # logging.info(stock_rows15.iloc[-1].sym + " | " + str(stock_rows15.index[-1]))

                if len(stock_rows15) > 1:
                    self.back_buy_best_stock(stocks_day_sym, index)
                    # st.write((stock_rows15.iloc[-1].sym + " | " + str(stock_rows15.index[-1])))
                    logging.info(stock_rows15.iloc[-1].sym + " | " +
                                 str(stock_rows15.index[-1]))
                    self.buy_sell(stocks_day_sym, stock_rows15, spy, spy_15,
                                  spy_row_day)

            st.write(self.dft)

    def back_buy_best_stock(self, df, index, days_back=-2):
        # self.bt_day_gain[index]
        df2 = pd.DataFrame()
        if df is not None and len(df) > 0:
            dff = df[df.index <= index]
            if len(dff) > 1:
                gain = Utils.calc_perc(dff.iloc[days_back].close,
                                       dff.iloc[-1].close)
                df2 = dff.iloc[days_back]
                df2["gain"] = gain
                df2["days_back"] = days_back

                self.dft = self.dft.append(df2)
                # st.write(self.dft)

    def set_mess_data(self, fin=None, sen=None, earn=None, spy=None, stc=None):
        if earn is not None:
            self.sm.earnings = earn
        if fin is not None:
            self.sm.financials = fin
        if sen is not None:
            self.sm.sentiment = sen
        if spy is not None:
            self.sm.spy = spy
        # if stc_d is not None:
        #     self.sm.in_day_stocks
        if stc is not None:
            self.sm.stocks = stc

    def buy_sell(self, stocks_day, stocks_15, spy, spy_row15, spy_row_day):
        """ By sell backtrading simaltion with specific strategy

        Args:
            stocks_day ([type]): [description]
            stocks_15 ([type]): [description]
            spy ([type]): [description]
            spy_row15 ([type]): [description]
            spy_row_day ([type]): [description]
        """

        # self.stocks = self.stocks.append(stocks_day.iloc[-1])
        self.db.last_date = stocks_15.iloc[-1].name
        logging.info(self.db.last_date)
        sym = stocks_day.iloc[-1].sym
        # send only one buy suggestion per day
        hash_warn = hash(sym + str(stocks_15.index[-1].strftime("%d/%m/%Y")))

        hl = FinI.get_fib_hl(stocks_day, stocks_day.iloc[-1].close)

        # logging.info(str(stocks_day))
        if len(stocks_day) > 1:
            # stocks_day = sdf.retype(stocks_day)
            # stocks_day = FinI.add_indicators(stocks_day)
            stocks_day.sort_index(ascending=True, inplace=True)
            stocks_day["flpd"] = Utils.calc_flpd(stocks_day)
            hl = FinI.get_fib_hl(stocks_day, stocks_15.iloc[-1].close)
            #OLD CHECK SELL moved to this Fce
            # self.check_sell(stocks_15.iloc[-1])

            earnings, sentiment, financials = self.db.get_fundamentals(
                stocks_day.iloc[-1]["sym"])
            self.set_mess_data(fin=financials,
                               sen=sentiment,
                               earn=earnings,
                               spy=spy,
                               stc=stocks_day)

            # st.write("BUYSELL OPEN trades amount:" + str(len(self.bs.buy_sell_open)))
            #-----------------------------SELL------------------------------------------
            if len(self.bs.buy_sell_open) > 0:

                logging.info("not selled stocks:" + str(self.bs.buy_sell_open[
                    self.bs.buy_sell_open.state == "open"]))
                logging.info("Current SYM: " + str(stocks_15.iloc[-1].sym))

                bs = self.bs.buy_sell_open[self.bs.buy_sell_open.sym ==
                                           stocks_15.iloc[-1].sym]

                if len(bs) > 0:
                    st.write(
                        "--------------------SELLING----------------------------"
                    )
                    for index, row in bs.iterrows():
                        if Utils.calc_perc(stocks_15.iloc[-1].close, hl["h"], 2) <= 1 or \
                                chi.check_sma9(stocks=stocks_day, live_stocks=stocks_15, buy=False):

                            # self.bs.buy_sell_open[(self.bs.buy_sell_open.sym == stocks_15.iloc[-1].sym) & (self.bs.buy_sell_open.state == "open")] = self.bs.sell_stock_t(stocks_15.iloc[-1],  sell_price=stocks_15.iloc[-1].close,
                            sold_stock = self.bs.sell_stock_t(
                                sym=stocks_15.iloc[-1].sym,
                                price=stocks_15.iloc[-1].close,
                                sell_date=stocks_15.iloc[-1].name)
                            st.write(sold_stock)
                            # st.write(sym + " | Selling Profit: " + str(stocks_15.iloc[-1].sym) + " | " + str(stocks_15.index[-1]) + " | " +
                            #                                      " | B.S.:" + str(row["buy"]) + "/" + str(stocks_15.iloc[-1].close) +
                            #                                      " | " + str(Utils.calc_perc(row["buy"], stocks_15.iloc[-1].close)) +
                            #                                      "% | " + str(stocks_15.iloc[-1].name) +
                            #                                      " | ", stocks_15.iloc[-1].name)

                            # asyncio.run(self.sm.a_mail_sym_stats(sym, "Selling Profit: " + str(stocks_15.iloc[-1].sym) + " | " + str(stocks_15.index[-1]) + " | " +
                            #                                      " | B.S.:" + str(row["buy"]) + "/" + str(stocks_15.iloc[-1].close) +
                            #                                      " | " + str(Utils.calc_perc(row["buy"], stocks_15.iloc[-1].close)) +
                            #                                      "% | " + str(stocks_15.iloc[-1].name) +
                            #                                      " | ", stocks_15.iloc[-1].name), debug=True)

            #------------------------------------------------------------BUY---------------------------------------------
            if hash_warn not in self.warning_check_list \
                    and stocks_day.iloc[-1]["flpd"] > 0 \
                    and chi.check_financials(financials) \
                    and (len(self.bs.buy_sell_open) == 0 or stocks_15.iloc[-1].sym not in self.bs.buy_sell_open[self.bs.buy_sell_open.state == "open"].sym)  \
                    and chi.check_pre_sma9(stocks_day, live_stocks=stocks_15):

                # and chi.check_sentiment(sentiment) \
                # and chi.check_financials(financials) \

                self.warning_check_list.append(hash_warn)
                self.bs.buy_stock_t(stocks_15.iloc[-1],
                                    stocks_15.iloc[-1].close,
                                    table_name="buy_sell_lt",
                                    profit_loss={
                                        "profit": hl["h"],
                                        "loss": hl["l"]
                                    })

                st.write(
                    "---------------------------BUYiNG-------------------------------"
                )
                # logging.info(self.bs.buy_sell)

                st.write(
                    sym + " | Buy: " + str(stocks_15.iloc[-1].sym) + " | " +
                    str(stocks_15.index[-1]) + " | " +
                    str(stocks_15.iloc[-1].close) + " | " + str(hl),
                    stocks_15.iloc[-1].name)
                # asyncio.run(self.sm.a_mail_sym_stats(sym, "Buy: " +
                #                                      str(stocks_15.iloc[-1].sym) + " | " + str(stocks_15.index[-1]) + " | " +
                #                                      str(stocks_15.iloc[-1].close) + " | " +
                #                                      str(hl), stocks_15.iloc[-1].name))

    def set_time_to(self):
        if self.time_from is None:
            time_from = "-180d"
        else:
            time_from = self.time_from

        return time_from

    def hide_footer(self):

        hide_streamlit_style = """
            <style>
            #MainMenu {visibility: visible;}
            footer {visibility: hidden;}
            </style>
            """
        st.markdown(hide_streamlit_style, unsafe_allow_html=True)

    def _max_width_(self):
        max_width_str = f"max-width: 2000px;max-height:1000px;"
        st.markdown(
            f"""
        <style>
        .reportview-container .main .block-container{{
            {max_width_str}
        }}
        </style>
        """,
            unsafe_allow_html=True,
        )
示例#11
0
文件: sl.py 项目: 4crash/4crash
class RunData():
    selected_stock = None
    timetick = None
    time_from = None
    time_to = None
    selected = {}
    action_type = None
    types = ["sector-stats", "stock-detail", "stocks-stats"]
    sw = StockWhisperer()
    inday_days = 2

    def __init__(self):
        self.db = Database()
        self.symbols = self.db.get_symbols(TableName.DAY)
        self.sectors = self.db.get_sectors(TableName.DAY)
        self.sm = StockMess()
        self.ss = SectorStats()
        self.app = self.get_home_page()
        self.submit = None

        # self.fig = None
        # print(self.df)

    # def load_data(self, option, time_from = "-180d", time_to = None):
    #     df =  self.db.load_data(
    #         "p_day", symbols=option, time_from=time_from, time_to = time_to)
    #     df = FinI.add_indicators(sdf.retype(df))
    #     return df

    def testing_mess(self):
        self.sm.stocks = self.db.load_data(
            table_name=TableName.DAY,
            symbols=["PLUG"],
            time_from=self.time_from,
            time_to=self.time_to,
        )
        self.sm.get_subj_mess("Base Fund: ", "PLUG")

    def get_home_page(self):

        query_params = st.experimental_get_query_params()
        if len(query_params) > 0 and query_params.get("type")[0] == "detail":
            st.set_page_config(initial_sidebar_state="collapsed",
                               page_title=query_params.get("sym")[0],
                               layout="wide")
        else:
            st.set_page_config(layout="wide")

        self.hide_footer()
        self.left_menu()
        # self.testing_mess()

        self.action_router(query_params)

    async def prepare_detail_tasks(self, sym=None):
        tasks = []

        tasks.append(asyncio.ensure_future(self.get_price_detail(sym=sym)))
        tasks.append(asyncio.ensure_future(
            self.get_inday_price_graph(sym=sym)))
        tasks.append(asyncio.ensure_future(self.get_fund_detail(sym=sym)))

        await asyncio.gather(*tasks, return_exceptions=True)

    def left_menu(self):

        self.time_from = st.sidebar.text_input("Time from now -1m, -1h, -1d,",
                                               value="-120d")
        self.time_to = st.sidebar.text_input("Time to 1m, 1h, 1d,")

        self.selected_sector = st.sidebar.selectbox('Select sector',
                                                    self.sectors)

        self.selected_stock = st.sidebar.selectbox('Select stock',
                                                   self.symbols)

        self.inday_days = st.sidebar.number_input('inday chart days', value=2)

        if self.selected_stock == 0:
            self.selected_stock = "TSLA"

        # loop = asyncio.get_event_loop()
        # task = None
        # try:
        #     task = loop.create_task(self.watch())
        # except KeyboardInterrupt:
        #     task.cancel()

        # print('after async')
        # st.sidebar.text_area("websocket",self.timetick)

        # self.action_type = st.sidebar.selectbox(
        #     'Seeect Type',
        #     self.types)

        # self.submit = st.sidebar.button("Submit", "submit")

    def action_router(self, query_params=None):

        if st.sidebar.button('stock-detail') or (
                len(query_params) > 0
                and query_params.get("type")[0] == "detail"):

            asyncio.new_event_loop().run_until_complete(
                self.prepare_detail_tasks(sym=query_params.get("sym")[0]
                                          if len(query_params) > 0 else None))

        if st.sidebar.button('top-sectors'):
            self.top_sectors(time_from=self.time_from, time_to=self.time_to)
        if st.sidebar.button('top-industries'):
            self.top_sectors(time_from=self.time_from,
                             time_to=self.time_to,
                             is_industries=True)

        if st.sidebar.button('top-stocks'):
            self.top_stocks(time_from=self.time_from, time_to=self.time_to)

        if st.sidebar.button('bottom-stocks'):
            self.top_stocks(time_from=self.time_from,
                            time_to=self.time_to,
                            ascending=True)

        if st.sidebar.button("find-stocks-to-buy"):
            self.find_stocks_to_buy()

        if st.sidebar.button("Last-Financials"):
            self.last_financials()

    def last_financials(self):

        df = self.db.get_last_financials()
        df.dropna(inplace=True, axis='columns', how="all")
        df.drop(columns=['zip','city','phone','longBusinessSummary','companyOfficers','maxAge','address1','previousClose', \
            'regularMarketOpen','regularMarketDayHigh','navPrice','totalAssets','regularMarketPreviousClose','open','yield', \
                         'priceHint', 'currency', 'dayLow', 'ask', 'askSize','website','longName', \
                             'exchange'], inplace=True)
        df.set_index(df.symbol, inplace=True)
        st.dataframe(df, height=2000)

    def find_stocks_to_buy(self):
        st.title("Stocks to buy")
        self.sw.time_from = self.time_from
        if self.sectors is not None:
            self.sw.sectors = [self.sectors]

        self.sw = StockWhisperer()

        try:
            output = self.sw.find_stocks(TableName.DAY, False)
        except KeyboardInterrupt:
            st.write("stopped by keyboard")

        stocks = output[[
            "close", "open", "high", "low", "volume", "amount", "flpd", "sym"
        ]]
        # print(stocks)
        self.print_stocks_list(stocks, True, from_top=0, show_stocks_num=50)

    def show_sectors(self, stocks, is_industries=False):

        fig = px.bar(stocks, y='flpd', x=stocks.index)
        # fig.update_traces(texttemplate=stocks.sector, textposition='inside')
        fig.update_layout(uniformtext_minsize=8,
                          uniformtext_mode='hide',
                          barmode='group')

        st.plotly_chart(
            fig,
            use_container_width=True,
            use_container_height=True,
            template="plotly_dark",
        )
        # st.bar_chart(stocks)

    def top_sectors(self,
                    ascending=False,
                    time_from=None,
                    time_to=None,
                    is_industries=False):
        # st.write(time_to)
        # st.write(time_from)
        title = "Top industries" if is_industries else "Top sectors"
        separator = " | "
        st.title(title + str(time_from))

        if not time_from:
            time_from = "-7d"

        table = TableName.DAY
        if time_from.find("m") > -1 or time_from.find("m") > -1:
            table = TableName.MIN15

        stocks = self.ss.classify_sectors_uptrend(table_name=table,
                                                  time_from=time_from,
                                                  time_to=time_to,
                                                  from_db=True,
                                                  is_industries=is_industries,
                                                  separator=separator)
        if stocks is not None and len(stocks) > 0:
            stocks = stocks.sort_values(by='flpd', ascending=ascending)

            stocks.drop(
                columns=["close", "open", "high", "low", "volume", "amount"],
                inplace=True)
            self.show_sectors(stocks, is_industries=is_industries)

            for idx, row in stocks.iterrows():
                st.write(str(idx) + ": " + str(round(row.flpd, 2)) + "%")
                self.top_stocks(group=idx,
                                ascending=ascending,
                                time_from=time_from,
                                time_to=time_to,
                                table=table,
                                is_industries=is_industries,
                                separator=separator)
        else:
            st.write("No data")

    def top_stocks(self,
                   group=None,
                   ascending=False,
                   time_from=None,
                   time_to=None,
                   table=None,
                   from_top=0,
                   show_stocks_num=20,
                   is_industries=False,
                   separator=None):
        st.empty()
        table = TableName.DAY
        if time_from.find("m") > -1:
            table = TableName.MIN15

        subject = "Loosers: " if ascending else "Gainers: "
        if isinstance(group, str):
            industry = str.split(group, separator)
            group = industry[1] if len(industry) > 1 else industry[0]
            group = [group]
        if is_industries:

            stocks = self.db.load_data(
                table_name=table,
                industries=group,
                time_from=time_from,
                time_to=time_to,
            )
        else:
            stocks = self.db.load_data(
                table_name=table,
                sectors=group,
                time_from=time_from,
                time_to=time_to,
            )

        # self.stocks = FinI.add_change(self.stocks)
        stocks = Utils.add_first_last_perc_diff(stocks)
        self.print_stocks_list(stocks,
                               ascending,
                               from_top=from_top,
                               show_stocks_num=show_stocks_num)

    def print_stocks_list(self,
                          stocks,
                          ascending,
                          from_top=0,
                          show_stocks_num=20):
        if stocks is not None and len(stocks) > 0:

            stocks = stocks.groupby(by="sym").mean()
            stocks = stocks.sort_values(by='flpd', ascending=ascending)

            top_stocks = stocks.iloc[from_top:(from_top + show_stocks_num)]
            top_stocks = self.fill_with_mess(top_stocks)
            reduced_top_stocks = top_stocks.drop(
                columns=["open", "high", "low", "amount"])
            reduced_top_stocks["detail"] = '<a href="/?type=detail&sym=' + \
                reduced_top_stocks.index + '" target="_blank"> ' + \
                    reduced_top_stocks.index + '</a>'
            reduced_top_stocks["news"] = '<a href="https://finance.yahoo.com/quote/' + \
                reduced_top_stocks.index + '" target="_blank"> yahoo </a>'
            reduced_top_stocks["rating"] = '<a href="https://zacks.com/stock/quote/' + \
                reduced_top_stocks.index + '" target="_blank"> zacks </a>'

            st.write(reduced_top_stocks.to_html(escape=False, index=False),
                     unsafe_allow_html=True)

            # selected_indices = st.multiselect('Select rows:', stocks.index)
            # selected_rows = stocks.loc[selected_indices]
            # self.top_stocks_list = top_stocks.index.tolist()
            # self.draw_chart_values(top_stocks)

            #send_mails
            # asyncio.run(self.sm.mail_stats(top_stocks, subject))
        else:
            print('No stocks has been found')

    def fill_with_mess(self, stocks):
        mess_block = []
        for index, row in stocks.iterrows():
            self.sm.set_fundamentals(index)
            # st.write(index)
            mess, curr_price, days_to_earnings = self.sm.get_subj_mess(
                "", index)
            mess_block.append(mess)
            # print(stocks.loc[index])

        stocks["fund"] = mess_block
        return stocks

    def set_time_to(self):
        if self.time_from is None:
            time_from = "-180d"
        else:
            time_from = self.time_from

        return time_from

    async def get_inday_price_graph(self, sym=None):

        if sym is None:
            sym = self.selected_stock

        inday_df = self.db.get_last_n_days(sym,
                                           n_days_back=self.inday_days,
                                           table=TableName.MIN15)

        inday_df = FinI.add_indicators(sdf.retype(inday_df))

        await self.inday_price_graph(sym, inday_df)

    async def get_price_detail(self, sym=None):

        if sym is None:
            sym = self.selected_stock
        time_from = self.set_time_to()
        df = self.db.load_data(
            table_name=TableName.DAY,
            symbols=sym,
            time_from=time_from,
            time_to=self.time_to,
        )
        m_df_spy = self.db.load_data(table_name=TableName.DAY,
                                     time_from=time_from,
                                     time_to=self.time_to,
                                     symbols=["SPY"])
        m_df_spy["oc_mean"] = (m_df_spy.close + m_df_spy.open) / 2
        # self.stocks = FinI.add_change(self.stocks)
        df = FinI.add_indicators(sdf.retype(df))
        await self.price_graph(sym, df, m_df_spy=m_df_spy)

        # self.macd_rsi_graph(option, df)
        self._max_width_()
        # await asyncio.sleep(0.001)

    async def get_fund_detail(self, sym=None):
        if sym is None:
            sym = self.selected_stock
        self.sm.set_fundamentals(sym)

        time_from = self.set_time_to()
        self.sm.stocks = self.db.load_data(
            table_name=TableName.DAY,
            symbols=sym,
            time_from=time_from,
            time_to=self.time_to,
        )

        mess, curr_price, days_to_earnings = self.sm.get_subj_mess(
            "Base Fund: ", sym)
        st.write(mess)

        await st.write(
            self.sm.get_fund_mess(self.sm.financials, curr_price,
                                  self.sm.earnings, self.sm.sentiment,
                                  days_to_earnings, self.sm.stocks))

    def macd_rsi_graph(self, option, df):

        data = PlotP.plot_rsi(df, ax="y")
        data += PlotP.plot_macd_boll(df=df, ax="y2")

        fig = go.Figure(data=data)

        fig.update_layout(autosize=True,
                          height=400,
                          yaxis=dict(title="RSI",
                                     titlefont=dict(color="green"),
                                     tickfont=dict(color="green")),
                          yaxis2=dict(title="macd",
                                      titlefont=dict(color="#8888ff"),
                                      tickfont=dict(color="#8888ff"),
                                      anchor="free",
                                      overlaying="y",
                                      side="left",
                                      position=0))

        # Create figure with secondary y-axis
        st.plotly_chart(fig, use_container_width=True)

    def gainers(self):
        pass

    def hide_footer(self):

        hide_streamlit_style = """
            <style>
            #MainMenu {visibility: visible;}
            footer {visibility: hidden;}
            </style>
            """
        st.markdown(hide_streamlit_style, unsafe_allow_html=True)

    # def sector_stats(self, time_from, time_to, loosers):
    #     stocks = self.ss.classify_sectors_uptrend(table_name =TableName.DAY)
    #     stocks = stocks.sort_values(by='flpd', ascending=loosers)

    #     if False:
    #         self.sw.sectors = [self.sw.stocks.iloc[:-1].index[0]]
    #         self.sw.top_stocks(table_name=None, top_losers=loosers)

    def inday_price_graph(self, option, df, ax="y2"):
        st.write("In day chart: -" + str(self.inday_days) + "d")

        sets = [{
            'x': df["index"],
            'open': df.open,
            'close': df.close,
            'high': df.high,
            'low': df.low,
            'yaxis': ax,
            "hovertext": "",
            'type': 'candlestick'
        }]

        sets += [{
            'x': df["index"],
            'y': df.boll,
            'yaxis': ax,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 1,
                'color': 'green'
            },
            'name': 'Boll'
        }]

        sets += [{
            'x': df["index"],
            'y': df.boll + df.boll_2,
            'yaxis': ax,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 0.3,
                'color': 'green',
                "dash": "dot"
            },
            'name': '-'
        }]

        sets += [{
            'x': df["index"],
            'y': df.boll + df.boll_3,
            'yaxis': ax,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 0.3,
                'color': 'green',
                "dash": "dot"
            },
            'name': '-'
        }]

        # sets += [{'x': df["index"], 'y': df.boll + df.boll_5, 'yaxis':  ax, 'type': 'scatter',
        #           'mode': 'lines', 'line': {'width': 0.3, 'color': 'green'}, 'name': '-'}]

        sets += [{
            'x': df["index"],
            'y': df.boll + df.boll_6,
            'yaxis': ax,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 0.3,
                'color': 'green',
                "dash": "dot"
            },
            'name': '-'
        }]

        sets += [{
            'x': df["index"],
            'y': df.boll - df.boll_2,
            'yaxis': ax,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 0.3,
                'color': 'green',
                "dash": "dot"
            },
            'name': '-'
        }]

        sets += [{
            'x': df["index"],
            'y': df.boll - df.boll_3,
            'yaxis': ax,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 0.3,
                'color': 'green',
                "dash": "dot"
            },
            'name': '-'
        }]

        # sets += [{'x': df["index"], 'y': df.boll - df.boll_5, 'yaxis':  ax, 'type': 'scatter',
        #           'mode': 'lines', 'line': {'width': 0.3, 'color': 'green'}, 'name': '-'}]

        sets += [{
            'x': df["index"],
            'y': df.boll - df.boll_6,
            'yaxis': ax,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 0.3,
                'color': 'green',
                "dash": "dot"
            },
            'name': '-'
        }]

        sets += [{
            'x': df["index"],
            'y': df.boll_ub,
            'yaxis': ax,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 1,
                'color': 'green'
            },
            'name': 'Boll UP'
        }]
        sets += [{
            'x': df["index"],
            'y': df.boll,
            'yaxis': ax,
            'type': 'scatter',
            "fill": 'tonexty',
            'line': {
                'width': 0,
            },
            "fillcolor": 'rgba(128, 255, 128,0.2)'
        }]
        sets += [{
            'x': df["index"],
            'y': df.boll_lb,
            'yaxis': ax,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 1,
                'color': 'green'
            },
            'name': 'Boll Down'
        }]
        sets += [{
            'x': df["index"],
            'y': df.boll,
            'yaxis': ax,
            'type': 'scatter',
            "fill": 'tonexty',
            'line': {
                'width': 0,
            },
            "fillcolor": 'rgba(128, 255, 128,0.2)'
        }]

        sets += [{
            'x': df["index"],
            'y': df.sma9,
            'yaxis': ax,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 1,
                'color': 'blue'
            },
            'name': 'sma9'
        }]

        sets += [{
            'x': df["index"],
            'y': df.sma50,
            'yaxis': ax,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 1,
                'color': 'darkblue'
            },
            'name': 'sma50'
        }]

        sets += [{
            'x': df["index"],
            'y': df.sma100,
            'yaxis': ax,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 1,
                'color': 'orange'
            },
            'name': 'sma100'
        }]

        df = FinI.add_levels(df)
        for i, r in df.iterrows():
            if r.price_level is not None:
                sets += [{
                    'x': [r["index"], df.iloc[-1]["index"]],
                    'y': [r.price_level, r.price_level],
                    'yaxis': ax,
                    'type': 'scatter',
                    'mode': 'lines',
                    'line': {
                        'width': 1,
                        'color': 'brown',
                        "dash": "dot"
                    },
                    'name': ''
                }]
        # print(levels)
        # sets += [{'x': df["index"], 'y': df.price_level, 'yaxis':  ax, 'type': 'scatter',
        #           'mode': 'lines', 'line': {'width': 1, 'color': 'orange'}, 'name': 'sma100'}]

        # data += PlotP.plot_rsi(df, ax="y2")
        # data += PlotP.plot_macd_boll(df=df, ax="y3")
        # st.area(df, x=df["index"], y=df.boll, color="continent",
        #         line_group="country")
        # fig = go.Figure(data=sets)
        fig = make_subplots(rows=2,
                            cols=1,
                            shared_xaxes=True,
                            vertical_spacing=0.009,
                            horizontal_spacing=0.009,
                            row_width=[0.1, 0.5],
                            specs=[[{
                                "secondary_y": True
                            }], [{
                                "secondary_y": True
                            }]])
        fig.add_traces(data=sets, cols=1, rows=1)

        # data = PlotP.plot_rsi(df, ax="y")
        # fig.add_traces(data, 3, 1)
        # data = PlotP.plot_macd_boll(df=df, ax="y2")
        # fig.add_traces(data, 3, 1)
        df.loc[df.open > df.close, "vol_color"] = "red"
        df.loc[df.open <= df.close, "vol_color"] = "green"
        # print(df.vol_color)
        fig.add_trace(
            {
                'x': df["index"],
                'y': df.volume,
                'type': 'bar',
                'name': 'Volume',
                'marker_color': df.vol_color
            },
            2,
            1,
            secondary_y=False,
        )

        # fig['layout']['margin'] = {'l': 30, 'r': 10, 'b': 50, 't': 25}
        fig.update_yaxes(showgrid=True,
                         zeroline=False,
                         showticklabels=True,
                         showspikes=True,
                         spikemode='across',
                         spikesnap='cursor',
                         showline=True,
                         spikedash='dash',
                         spikethickness=0.5)

        fig.update_xaxes(showgrid=True,
                         zeroline=False,
                         rangeslider_visible=False,
                         showticklabels=True,
                         showspikes=True,
                         showline=True,
                         spikemode='across',
                         spikesnap='cursor',
                         spikedash='dash',
                         spikethickness=0.5)

        fig.update_layout(autosize=True,
                          height=600,
                          hoverdistance=1,
                          hovermode='y',
                          spikedistance=10000)
        st.plotly_chart(
            fig,
            use_container_width=True,
            use_container_height=True,
            template="plotly_dark",
        )

        # st.line_chart(df.close)

    def price_graph(self, option, df, m_df_spy=None, ax="y2"):
        st.write("Days chart: " + str(self.time_from))

        sets = [{
            'x': df.index,
            'open': df.open,
            'close': df.close,
            'high': df.high,
            'low': df.low,
            'yaxis': ax,
            "hovertext": "",
            'type': 'candlestick'
        }]

        sets += [{
            'x': df.index,
            'y': df.boll,
            'yaxis': ax,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 1,
                'color': 'green'
            },
            'name': 'Boll'
        }]

        sets += [{
            'x': df.index,
            'y': df.boll + df.boll_2,
            'yaxis': ax,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 0.3,
                'color': 'green',
                "dash": "dot"
            },
            'name': '-'
        }]

        sets += [{
            'x': df.index,
            'y': df.boll + df.boll_3,
            'yaxis': ax,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 0.3,
                'color': 'green',
                "dash": "dot"
            },
            'name': '-'
        }]

        # sets += [{'x': df.index, 'y': df.boll + df.boll_5, 'yaxis':  ax, 'type': 'scatter',
        #           'mode': 'lines', 'line': {'width': 0.3, 'color': 'green'}, 'name': '-'}]

        sets += [{
            'x': df.index,
            'y': df.boll + df.boll_6,
            'yaxis': ax,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 0.3,
                'color': 'green',
                "dash": "dot"
            },
            'name': '-'
        }]

        sets += [{
            'x': df.index,
            'y': df.boll - df.boll_2,
            'yaxis': ax,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 0.3,
                'color': 'green',
                "dash": "dot"
            },
            'name': '-'
        }]

        sets += [{
            'x': df.index,
            'y': df.boll - df.boll_3,
            'yaxis': ax,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 0.3,
                'color': 'green',
                "dash": "dot"
            },
            'name': '-'
        }]

        # sets += [{'x': df.index, 'y': df.boll - df.boll_5, 'yaxis':  ax, 'type': 'scatter',
        #           'mode': 'lines', 'line': {'width': 0.3, 'color': 'green'}, 'name': '-'}]

        sets += [{
            'x': df.index,
            'y': df.boll - df.boll_6,
            'yaxis': ax,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 0.3,
                'color': 'green',
                "dash": "dot"
            },
            'name': '-'
        }]

        sets += [{
            'x': df.index,
            'y': df.boll_ub,
            'yaxis': ax,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 1,
                'color': 'green'
            },
            'name': 'Boll UP'
        }]
        sets += [{
            'x': df.index,
            'y': df.boll,
            'yaxis': ax,
            'type': 'scatter',
            "fill": 'tonexty',
            'line': {
                'width': 0,
            },
            "fillcolor": 'rgba(128, 255, 128,0.2)'
        }]
        sets += [{
            'x': df.index,
            'y': df.boll_lb,
            'yaxis': ax,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 1,
                'color': 'green'
            },
            'name': 'Boll Down'
        }]
        sets += [{
            'x': df.index,
            'y': df.boll,
            'yaxis': ax,
            'type': 'scatter',
            "fill": 'tonexty',
            'line': {
                'width': 0,
            },
            "fillcolor": 'rgba(255, 128, 128,0.2)'
        }]

        sets += [{
            'x': df.index,
            'y': df.sma9,
            'yaxis': ax,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 1,
                'color': 'blue'
            },
            'name': 'sma9'
        }]

        sets += [{
            'x': df.index,
            'y': df.sma50,
            'yaxis': ax,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 1,
                'color': 'darkblue'
            },
            'name': 'sma50'
        }]

        sets += [{
            'x': df.index,
            'y': df.sma100,
            'yaxis': ax,
            'type': 'scatter',
            'mode': 'lines',
            'line': {
                'width': 1,
                'color': 'orange'
            },
            'name': 'sma100'
        }]

        df = FinI.add_levels(df)
        for i, r in df.iterrows():
            if r.price_level is not None:
                sets += [{
                    'x': [i, df.iloc[-1].name],
                    'y': [r.price_level, r.price_level],
                    'yaxis': ax,
                    'type': 'scatter',
                    'mode': 'lines',
                    'line': {
                        'width': 1,
                        'color': 'brown',
                        "dash": "dot"
                    },
                    'name': ''
                }]
        # print(levels)
        # sets += [{'x': df.index, 'y': df.price_level, 'yaxis':  ax, 'type': 'scatter',
        #           'mode': 'lines', 'line': {'width': 1, 'color': 'orange'}, 'name': 'sma100'}]

        # data += PlotP.plot_rsi(df, ax="y2")
        # data += PlotP.plot_macd_boll(df=df, ax="y3")
        # st.area(df, x=df.index, y=df.boll, color="continent",
        #         line_group="country")
        # fig = go.Figure(data=sets)
        fig = make_subplots(rows=3,
                            cols=1,
                            shared_xaxes=True,
                            vertical_spacing=0.009,
                            horizontal_spacing=0.009,
                            row_width=[0.2, 0.1, 0.5],
                            specs=[[{
                                "secondary_y": True
                            }], [{
                                "secondary_y": True
                            }], [{
                                "secondary_y": True
                            }]])
        fig.add_traces(data=sets, cols=1, rows=1)
        if m_df_spy is not None:
            fig.add_trace(
                {
                    'x': m_df_spy.index,
                    'y': m_df_spy.oc_mean,
                    'type': 'scatter',
                    'yaxis': "y",
                    'mode': 'lines',
                    'line': {
                        'width': 1,
                        'color': 'red'
                    },
                    'name': 'SPY'
                },
                1,
                1,
                secondary_y=True,
            )

        # data = PlotP.plot_rsi(df, ax="y")
        # fig.add_traces(data, 3, 1)
        mb = PlotP.plot_macd_boll(df=df, ax="y")
        fig.add_traces(
            data=mb,
            rows=3,
            cols=1,
        )

        rsi = PlotP.plot_rsi(df=df, ax="y3")
        fig.add_traces(data=rsi,
                       rows=3,
                       cols=1,
                       secondary_ys=[True, True, True, True, True])

        df.loc[df.open > df.close, "vol_color"] = "red"
        df.loc[df.open <= df.close, "vol_color"] = "green"
        # print(df.vol_color)

        fig.add_trace(
            {
                'x': df.index,
                'y': df.volume,
                'type': 'bar',
                'name': 'Volume',
                'marker_color': df.vol_color
            },
            2,
            1,
            secondary_y=False,
        )

        # fig['layout']['margin'] = {'l': 30, 'r': 10, 'b': 50, 't': 25}
        fig.update_yaxes(showgrid=True,
                         zeroline=False,
                         showticklabels=True,
                         showspikes=True,
                         spikemode='across',
                         spikesnap='cursor',
                         showline=True,
                         spikedash='dash',
                         spikethickness=0.5)

        fig.update_xaxes(showgrid=True,
                         zeroline=False,
                         rangeslider_visible=False,
                         showticklabels=True,
                         showspikes=True,
                         showline=True,
                         spikemode='across',
                         spikesnap='cursor',
                         spikedash='dash',
                         spikethickness=0.5)

        fig.update_layout(
            autosize=True,
            height=600,
            hoverdistance=1,
            hovermode='y',
            spikedistance=10000,
        )
        st.plotly_chart(
            fig,
            use_container_width=True,
            use_container_height=True,
            template="plotly_dark",
        )

        # st.line_chart(df.close)

    def _max_width_(self):
        max_width_str = f"max-width: 2000px;max-height:1000px;"
        st.markdown(
            f"""
        <style>
        .reportview-container .main .block-container{{
            {max_width_str}
        }}
        </style>
        """,
            unsafe_allow_html=True,
        )
示例#12
0
class SectorStats():
    def __init__(self):

        self.db = Database()
        self.sectors_trend = []
        self.spy_trend = []
        self.last_date = None
        self.spy = None
        self.stocks = None
        self.in_day_stocks = None
        self.trend_data = None

    def show_sectors_stats(self, data, save_image=False, plt=None):
        if plt is None:
            return False

        fig, axs = plt.subplots(len(data))
        fig.suptitle('Sector overview')
        # print(axs)
        plt = self.sector_stats_to_plt(plt, data, axs)
        if save_image:
            return plt
        else:
            plt.show()

    def sector_stats_to_plt(self, plt, data, axs):

        i = 0
        for key in data.keys():
            plotdata = data[key]

            # plt.subplots(len(data))
            # axs.bar(plotdata, height = 2)
            plotdata.plot(kind="bar", ax=axs[i])

            axs[i].set_title("Year " + str(key))
            axs[i].grid(True)
            # plt.title("Year " + str(key))
            plt.xticks(rotation=45)

            plt.xlabel("Sector")
            plt.ylabel("Change")
            axs[i].legend().set_visible(False)

            # for i, j in zip(data[key].index, data[key].flpd):
            #     axs[i].annotate(str(j), xy=(i, j))
            i += 1

        return plt

    def sectors_day_stats(self,
                          table_name=TableName.DAY,
                          time_from="-180d",
                          time_to="0d"):
        # technical, healthcare, financials etc.

        sectors = sdf.retype(
            self.db.load_data(table_name, time_from=time_from,
                              time_to=time_to))
        sectors = sdf.retype(sectors)
        # normalize data
        sectors["date"] = sectors.index

        # print(sectors)
        # sectors.get('close_-1_r')

        # sectors = Utils.add_first_last_perc_diff(sectors)
        sectors = sectors.groupby(by=["sector", "date"]).mean()
        # for item in sectors
        # sectors = sectors.sort_(by = ["sector","date"])
        # print(sectors.where(cond=sectors.index.name == "Basic Materials"))
        res = sdf()
        for index in sectors.index.unique('sector'):
            sec = sectors.iloc[sectors.index.get_level_values('sector') ==
                               index]
            sec = sdf.retype(sec)
            sec['close_n'] = (sec.close - sec.close.min()) / (sec.close.max() -
                                                              sec.close.min())
            sec.get('close_-1_r')
            sec.get('volume_-1_r')
            # print(sec)
            res = res.append(sec)
        # self.show_sec_day_stats(res)
        # print(res)
        return res
        # print(self.stocks.head())

    def get_trend_slice(self,
                        table_name=None,
                        time_from=None,
                        time_to=None,
                        symbol=None,
                        from_db=False):

        if time_to is None:
            time_to = "0d"
        if time_from is None:
            time_from = "-14d"

        # print(time_from + " --- " + time_to)
        if self.trend_data is None or from_db:
            tn = table_name if table_name else TableName.DAY
            self.trend_data = sdf.retype(
                self.db.load_data(table_name=tn,
                                  time_from=time_from,
                                  time_to=time_to))
            print("--------filling trend_data------------")

        print("get_trend_slice() - done")
        stocks = self.trend_data.copy()

        stocks = stocks[stocks.index.to_series().between(
            self.db.get_date_format(time_from),
            self.db.get_date_format(time_to))]

        # print(str(symbol) + "   SYMBOOOOOL")
        if symbol is not None:

            stocks = stocks[stocks.sym == symbol.upper()]
            # print(stocks)
        # print(self.trend_data)

        if stocks is not None and len(stocks) > 0:
            return stocks
        else:
            return None

    # def get_splited_spy_sectors_uptrends(self, table_name=None, time_from=None, time_to=None):

    #     stocks = self.get_trend_slice(full_stock=True)
    #     df1 = stocks.iloc[:, :round(len(stocks)/2, 0)]
    #     df2 = stocks.iloc[:, round(len(stocks)/2, 0):]

    #     self.sectors_trend.append(self.classify_sectors_uptrend(
    #          table_name=table_name, time_from="-14d", time_to="-7d"))
    #     self.sectors_trend.append(self.classify_sectors_uptrend(table_name=table_name, time_from="-7d", time_to="0d"))

    #     # ----------------------------set spy trend-----------------------------

    #     self.spy_trend.append(self.get_trend_slice(
    #         table_name=table_name, time_from="-14d", time_to="-7d", symbol="SPY"))
    #     self.spy_trend[0] = Utils.add_first_last_perc_diff(self.spy_trend[0])

    #     self.spy_trend.append(sdf.retype(self.get_trend_slice(
    #         table_name=table_name, time_from="-7d", time_to="0d", symbol="SPY")))
    #     self.spy_trend[1] = Utils.add_first_last_perc_diff(self.spy_trend[1])
    #     # print(self.spy_trend)

    def classify_sectors_uptrend(self,
                                 table_name=None,
                                 time_from=None,
                                 time_to=None,
                                 stocks=None,
                                 from_db=False,
                                 is_industries=False,
                                 separator=""):
        # print(self.trend_data)
        if stocks is None:
            stocks = self.get_trend_slice(table_name=table_name,
                                          time_from=time_from,
                                          time_to=time_to,
                                          from_db=from_db)
        # technical, healthcare, financials etc.
        # print(stocks)
        if stocks is not None:
            stocks = Utils.add_first_last_perc_diff(stocks)
            stocks[
                "industry"] = stocks["sector"] + separator + stocks["industry"]
            group_by = "sector" if is_industries is False else "industry"
            stocks = stocks.groupby(by=group_by).mean()

            return stocks
        else:
            return stocks

        # print(self.stocks.head())

    def sectors_uptrend_by_month(self, yf=2017, yt=None, show_chart=True):
        # technical, healthcare, financials etc.
        sectors = self.db.get_sectors()
        sectors_month_stats = pd.DataFrame()
        sec_year_stats = {}
        # print(sectors)
        # self.sectors = [sec]
        stocks = sdf.retype(self.db.load_data(TableName.DAY))
        stocks.index = pd.to_datetime(stocks.index, utc=True)
        stocks['month'] = stocks.index.to_series().dt.month
        stocks['year'] = stocks.index.to_series().dt.year

        if not yt:
            max_year = stocks.year.max()
        else:
            max_year = yt
        # data contain more sectors since 2016
        for year in range(yf, max_year + 1):
            one_year_stocks = stocks.where(
                cond=stocks['year'] == year).dropna()
            sectors_month_stats = pd.DataFrame()
            # print(one_year_stocks)

            min_month = one_year_stocks.month.min()
            max_month = one_year_stocks.month.max()

            for month in range(int(min_month), int(max_month) + 1):
                one_month_stocks = one_year_stocks.where(
                    cond=one_year_stocks['month'] == month).dropna()
                one_month_stocks = Utils.add_first_last_perc_diff(
                    one_month_stocks)

                sectors_data = one_month_stocks.groupby(
                    by=one_month_stocks['sector']).mean()

                sectors_month_stats["sector"] = sectors_data.index
                sectors_month_stats[month] = sectors_data.flpd.tolist()
                sectors_month_stats.set_index('sector', inplace=True)

            sec_year_stats[year] = sectors_month_stats.copy()

        if show_chart:
            self.show_sectors_stats(sec_year_stats, False, plt)
        return sectors_month_stats

    def set_spy_sectors_trend(self):
        table_name = TableName.DAY
        if self.trend_data is None:
            self.classify_sectors_uptrend(table_name=table_name,
                                          time_from="-14d",
                                          time_to="0")

        df1 = self.trend_data.iloc[0:int(round(len(self.trend_data) / 2, 0))]
        df2 = self.trend_data.iloc[int(round(len(self.trend_data) /
                                             2, 0)):len(self.trend_data)]

        # ---------------------------set sectors trend --------------------
        self.sectors_trend.append(self.classify_sectors_uptrend(stocks=df1))
        self.sectors_trend.append(self.classify_sectors_uptrend(stocks=df2))

        # ----------------------------set spy trend-----------------------------
        dfs1 = df1[df1.sym == "SPY"]
        dfs2 = df2[df2.sym == "SPY"]
        self.spy_trend.append(Utils.add_first_last_perc_diff(dfs1))
        self.spy_trend.append(Utils.add_first_last_perc_diff(dfs2))

        print("set_spy_sectors_trend() - done")