def loop_listen(self) -> None:
     while True:
         data = self.client.recv(self.buffer_size).decode('utf-8')
         if data != '':
             Logger.console_log(message="Received {} of type {}".format(
                 data, type(data)),
                                status=Logger.LogStatus.SUCCESS)
예제 #2
0
    def __init__(self,
                 data_refresh_rate: int = 1800,
                 relative_path_correction: str = "") -> None:
        """
        Constructor.
        :param data_refresh_rate:
        :param relative_path_correction:
        """
        Logger.console_log("Initializing Stock Scraper.",
                           status=Logger.LogStatus.COMMUNICATION)
        self.scrape = True
        self.available_cpus = cpu_count() - 1
        self.threads = {}
        self.mode_lock = Lock()
        self.executive_lock = Lock()
        self.mode = Scraper.ServerModes.INVALID
        self.stock_ticker_letters_to_survey = list(ascii_uppercase)
        self.relative_path_correction = relative_path_correction

        # Initialize Threads
        # Build worker threads for available number of cpus
        self.threads[Scraper.WorkerThread] = []
        for available_cpu_index in range(self.available_cpus):
            self.threads[Scraper.WorkerThread].append(
                Scraper.WorkerThread(thread_id=available_cpu_index,
                                     scraper_server=self))
        # Build Executive Thread
        self.threads[Scraper.ExecutiveThread] = Scraper.ExecutiveThread(
            thread_id=0,
            scraper_server=self,
            worker_threads=self.threads[Scraper.WorkerThread])
예제 #3
0
def survey_market():
    from yahoo_fin.stock_info import get_data

    Logger.console_log("Beginning survey of all possible stock symbols", 1)

    def concatenate_letters(one, two, three, four, five):
        if letter_four is None:
            return letter_one + letter_two + letter_three
        elif five is None:
            return letter_one + letter_two + letter_three + letter_four
        else:
            return letter_one + letter_two + letter_three + letter_four + letter_five

    def log_valid_stock_symbol(symbol):
        log_location = os.getcwd(
        ) + os.path.sep + "Data" + os.path.sep + "valid_stocks.txt"

        with open(log_location, 'a+') as stock_log:
            stock_log.write(symbol + '\n')

    def survey_symbol(symbol):
        try:
            try:
                data = get_data(symbol)
                #                Logger.console_log("Stock for symbol {} exists.".format(symbol), 1)
                log_valid_stock_symbol(symbol)
            except KeyError:
                #                Logger.console_log("Stock for symbol {} produced KeyError on adjclose.".format(symbol), 4)
                pass
            except ValueError:
                Logger.console_log(
                    "ValueError when attempting to retrieve data for stock symbol {}. Retrying..."
                    .format(symbol), Logger.LogStatus.FAIL)
                survey_symbol(symbol)
        except AssertionError:
            #            Logger.console_log("Stock for symbol {} does not exist.".format(symbol), 2)
            pass

    ascii_uppercase_and_none = list(ascii_uppercase)
    ascii_uppercase_and_none.append(None)

    for letter_one in ascii_uppercase[2:]:
        for letter_two in ascii_uppercase:
            for letter_three in ascii_uppercase:
                for letter_four in ascii_uppercase_and_none:
                    if letter_four is None:
                        three_letter_symbol = concatenate_letters(
                            letter_one, letter_two, letter_three, letter_four,
                            None)
                        survey_symbol(three_letter_symbol)
                    else:
                        for letter_five in ascii_uppercase_and_none:
                            four_or_five_letter_symbol = concatenate_letters(
                                letter_one, letter_two, letter_three,
                                letter_four, letter_five)
                            survey_symbol(four_or_five_letter_symbol)
예제 #4
0
 def connection_test(self) -> bool:
     try:
         test_connection = self.create_connection()
         Logger.console_log(message="Connection test with " +
                            self.database + " located at " + self.host +
                            " was a success",
                            status=Logger.LogStatus.SUCCESS)
         return True
     except self.sql_type.value.Error as err:
         Logger.console_log(
             message="Unable to establish connection with database " +
             self.database + ". Error [" + str(err) + "] was returned",
             status=Logger.LogStatus.FAIL)
         return False
예제 #5
0
 def survey_symbol(symbol):
     try:
         try:
             data = get_data(symbol)
             #                Logger.console_log("Stock for symbol {} exists.".format(symbol), 1)
             log_valid_stock_symbol(symbol)
         except KeyError:
             #                Logger.console_log("Stock for symbol {} produced KeyError on adjclose.".format(symbol), 4)
             pass
         except ValueError:
             Logger.console_log(
                 "ValueError when attempting to retrieve data for stock symbol {}. Retrying..."
                 .format(symbol), Logger.LogStatus.FAIL)
             survey_symbol(symbol)
     except AssertionError:
         #            Logger.console_log("Stock for symbol {} does not exist.".format(symbol), 2)
         pass
예제 #6
0
    def survey_ticker(thread: Thread, ticker: str) -> bool:
        """
        Uses Scraper.get_current_ticker_data to survey the given ticker string.  The result is returned.
        :param thread: A Scraper.WorkerThread responsible for carrying out the survey.
        :param ticker: Stock ticker.
        :return: Boolean denoting rather or not the ticker was successfully scraped during the survey.
        """
        try:
            data = Scraper.WebInterface.get_current_ticker_data(ticker=ticker)

            if None in data:
                return False
            else:
                Logger.console_log(
                    "Successful scraping of ticker " + ticker + " from " +
                    str(thread), Logger.LogStatus.SUCCESS)
                return True
        except Exception as e:
            return False
예제 #7
0
    def menu(self) -> None:
        Logger.console_log(message="==== MENU ====",
                           status=Logger.LogStatus.COMMUNICATION)
        Logger.console_log(message="1) send a message",
                           status=Logger.LogStatus.COMMUNICATION)
        Logger.console_log(message="0) end connection",
                           status=Logger.LogStatus.COMMUNICATION)

        response = int(input("What would you like to do: "))

        if response == 1:
            self.prompt_for_message()
        elif response == 0:
            self.end_connection()
        else:
            Logger.console_log(
                message="Invalid menu selection.  Please try again...",
                status=Logger.LogStatus.FAIL)

        return response
예제 #8
0
    def connect(self, ip_address: str, port: int) -> None:
        port_description = (ip_address, port)

        Logger.console_log(
            message="Attempting to bind to port with description: " +
            str(port_description),
            status=Logger.LogStatus.EMPHASIS)

        # Bind to the port description
        try:
            self.sock.connect(port_description)
            Logger.console_log(
                message=
                "Successfully created connection with server @ address {} through port {}"
                .format(ip_address, port),
                status=Logger.LogStatus.SUCCESS)
        except Exception as err:
            Logger.console_log(
                message="Unable to send message due to error: " + str(err),
                status=Logger.LogStatus.FAIL)
    def connect(self, ip_address: str, port: int) -> None:
        port_description = (ip_address, port)

        try:
            # Bind to the port description
            self.sock.bind(port_description)

            # Sets up and start TCP Listener
            self.sock.listen(2)

            # Wait for TCP connection to arrive [Returns client]
            Logger.console_log(message="Waiting for client...",
                               status=Logger.LogStatus.EMPHASIS)
            self.client, client_address = self.sock.accept()
            Logger.console_log(
                message="Creating connection with client from " +
                str(client_address),
                status=Logger.LogStatus.SUCCESS)
        except Exception as err:
            Logger.console_log(
                message="Unable to send message due to error: " + str(err),
                status=Logger.LogStatus.FAIL)
예제 #10
0
def engineer_additional_features(stock_data: pd.DataFrame) -> None:
    intervals = range(6, 21)

    Logger.console_log(
        "Calculating Relative Stock Index over intervals " + str(intervals),
        Logger.LogStatus.EMPHASIS)
    RSI(stock_data, 'close', intervals)
    Logger.console_log(
        "Calculating Williams Percent Range over intervals " + str(intervals),
        Logger.LogStatus.EMPHASIS)
    WilliamsR(stock_data, intervals)
    Logger.console_log(
        "Calculating Weighted Moving Average over intervals " + str(intervals),
        Logger.LogStatus.EMPHASIS)
    WMA(stock_data, 'close', intervals)
    Logger.console_log(
        "Calculating Exponential Moving Average over intervals " +
        str(intervals), Logger.LogStatus.EMPHASIS)
    EMA(stock_data, 'close', intervals)
    Logger.console_log(
        "Calculating Simple Moving Average over intervals " + str(intervals),
        Logger.LogStatus.EMPHASIS)
    SMA(stock_data, 'close', intervals)
    Logger.console_log(
        "Calculating Hull Moving Average over intervals " + str(intervals),
        Logger.LogStatus.EMPHASIS)
    HMA(stock_data, 'close', intervals)
    Logger.console_log(
        "Calculating Triple Exponentially Smoothed Moving Average over intervals "
        + str(intervals), Logger.LogStatus.EMPHASIS)
    TRIX(stock_data, 'close', intervals)
    Logger.console_log(
        "Calculating Commodity Channel Index over intervals " + str(intervals),
        Logger.LogStatus.EMPHASIS)
    CCI(stock_data, intervals)
    Logger.console_log(
        "Calculating Chande Momentum Oscillator over intervals " +
        str(intervals), Logger.LogStatus.EMPHASIS)
    CMO(stock_data, 'close', intervals)
    Logger.console_log(
        "Calculating Moving Average Convergence/Divergence over intervals " +
        str(intervals), Logger.LogStatus.EMPHASIS)
    MACD(stock_data, 'close', intervals)
    Logger.console_log(
        "Calculating Detrended Price Oscillator over intervals " +
        str(intervals), Logger.LogStatus.EMPHASIS)
    DPO(stock_data, 'close', intervals)
    Logger.console_log(
        "Calculating Rate of Change over intervals " + str(intervals),
        Logger.LogStatus.EMPHASIS)
    ROC(stock_data, 'close', intervals)
    Logger.console_log(
        "Calculating Chaikin Money Flow over intervals " + str(intervals),
        Logger.LogStatus.EMPHASIS)
    CMF(stock_data, intervals)
    Logger.console_log(
        "Calculating Average Directional Index over intervals " +
        str(intervals), Logger.LogStatus.EMPHASIS)
    ADX(stock_data, intervals)
    Logger.console_log(
        "Calculating Force Index over intervals " + str(intervals),
        Logger.LogStatus.EMPHASIS)
    ForceIndex(stock_data, intervals)

    stock_data = stock_data.drop(stock_data.index[range(intervals[-1])])
예제 #11
0
def engineer_data_over_single_interval(df: pd.DataFrame,
                                       indicators: list,
                                       ticker: str = "",
                                       rsi_n: int = 14,
                                       cmo_n: int = 7,
                                       macd_fast: int = 12,
                                       macd_slow: int = 26,
                                       macd_sign: int = 9,
                                       roc_n: int = 12,
                                       cci_n: int = 20,
                                       dpo_n: int = 20,
                                       cmf_n: int = 20,
                                       adx_n: int = 14,
                                       mass_index_low: int = 9,
                                       mass_index_high: int = 25,
                                       trix_n: int = 15,
                                       stochastic_oscillator_n: int = 14,
                                       stochastic_oscillator_sma_n: int = 3,
                                       ultimate_oscillator_short_n: int = 7,
                                       ultimate_oscillator_medium_n: int = 14,
                                       ultimate_oscillator_long_n: int = 28,
                                       ao_short_n: int = 5,
                                       ao_long_n: int = 34,
                                       kama_n: int = 10,
                                       tsi_high_n: int = 25,
                                       tsi_low_n: int = 13,
                                       eom_n: int = 14,
                                       force_index_n: int = 13,
                                       ichimoku_low_n: int = 9,
                                       ichimoku_medium_n: int = 26):
    from ta.momentum import rsi, wr, roc, ao, stoch, uo, kama, tsi
    from ta.trend import macd, macd_signal, cci, dpo, adx, mass_index, trix, ichimoku_a
    from ta.volume import chaikin_money_flow, acc_dist_index, ease_of_movement, force_index

    # Momentum Indicators
    if Indicators.RELATIVE_STOCK_INDEX in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.RELATIVE_STOCK_INDEX.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.RELATIVE_STOCK_INDEX.value] = rsi(close=df['close'],
                                                        n=rsi_n)

    if Indicators.WILLIAMS_PERCENT_RANGE in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.WILLIAMS_PERCENT_RANGE.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.WILLIAMS_PERCENT_RANGE.value] = wr(
            df['high'], df['low'], df['close'])

    if Indicators.CHANDE_MOMENTUM_OSCILLATOR in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.CHANDE_MOMENTUM_OSCILLATOR.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.CHANDE_MOMENTUM_OSCILLATOR.
           value] = chande_momentum_oscillator(close_data=df['close'],
                                               period=cmo_n)

    if Indicators.RATE_OF_CHANGE in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.RATE_OF_CHANGE.value + " for stock " +
                           ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.RATE_OF_CHANGE.value] = roc(close=df['close'], n=roc_n)

    if Indicators.STOCHASTIC_OSCILLATOR in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.STOCHASTIC_OSCILLATOR.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.STOCHASTIC_OSCILLATOR.value] = stoch(
            high=df['high'],
            low=df['low'],
            close=df['close'],
            n=stochastic_oscillator_n,
            d_n=stochastic_oscillator_sma_n)

    if Indicators.ULTIMATE_OSCILLATOR in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.ULTIMATE_OSCILLATOR.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.ULTIMATE_OSCILLATOR.value] = uo(
            high=df['high'],
            low=df['low'],
            close=df['close'],
            s=ultimate_oscillator_short_n,
            m=ultimate_oscillator_medium_n,
            len=ultimate_oscillator_long_n)

    if Indicators.AWESOME_OSCILLATOR in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.AWESOME_OSCILLATOR.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.AWESOME_OSCILLATOR.value] = ao(high=df['high'],
                                                     low=df['low'],
                                                     s=ao_short_n,
                                                     len=ao_long_n)

    if Indicators.KAUFMAN_ADAPTIVE_MOVING_AVERAGE in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.KAUFMAN_ADAPTIVE_MOVING_AVERAGE.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.KAUFMAN_ADAPTIVE_MOVING_AVERAGE.value] = kama(
            close=df['close'], n=kama_n)

    if Indicators.TRUE_STRENGTH_INDEX in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.TRUE_STRENGTH_INDEX.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.TRUE_STRENGTH_INDEX.value] = tsi(close=df['close'],
                                                       r=tsi_high_n,
                                                       s=tsi_low_n)

    # Trend Indicator
    if Indicators.MOVING_AVERAGE_CONVERGENCE_DIVERGENCE in indicators:
        Logger.console_log(
            message="Calculating " +
            Indicators.MOVING_AVERAGE_CONVERGENCE_DIVERGENCE.value +
            " for stock " + ticker,
            status=Logger.LogStatus.EMPHASIS)
        df[Indicators.MOVING_AVERAGE_CONVERGENCE_DIVERGENCE.value] = macd(close=df['close'],
                                                                          n_slow=macd_slow,
                                                                          n_fast=macd_fast) - \
                                                                     macd_signal(close=df['close'],
                                                                                 n_slow=macd_slow,
                                                                                 n_fast=macd_fast,
                                                                                 n_sign=macd_sign)

    if Indicators.COMMODITY_CHANNEL_INDEX in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.COMMODITY_CHANNEL_INDEX.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.COMMODITY_CHANNEL_INDEX.value] = cci(high=df['high'],
                                                           low=df['low'],
                                                           close=df['close'],
                                                           n=cci_n)

    if Indicators.DETRENDED_PRICE_OSCILLATOR in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.DETRENDED_PRICE_OSCILLATOR.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.DETRENDED_PRICE_OSCILLATOR.value] = dpo(
            close=df['close'], n=dpo_n)

    if Indicators.AVERAGE_DIRECTIONAL_INDEX in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.AVERAGE_DIRECTIONAL_INDEX.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.AVERAGE_DIRECTIONAL_INDEX.value] = adx(high=df['high'],
                                                             low=df['low'],
                                                             close=df['close'],
                                                             n=adx_n)

    if Indicators.MASS_INDEX in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.MASS_INDEX.value + " for stock " +
                           ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.MASS_INDEX.value] = mass_index(high=df['high'],
                                                     low=df['low'],
                                                     n=mass_index_low,
                                                     n2=mass_index_high)

    if Indicators.TRIPLE_EXPONENTIALLY_SMOOTHED_MOVING_AVERAGE in indicators:
        Logger.console_log(
            message="Calculating " +
            Indicators.TRIPLE_EXPONENTIALLY_SMOOTHED_MOVING_AVERAGE.value +
            " for stock " + ticker,
            status=Logger.LogStatus.EMPHASIS)
        df[Indicators.TRIPLE_EXPONENTIALLY_SMOOTHED_MOVING_AVERAGE.
           value] = trix(close=df['close'], n=trix_n)

    if Indicators.ICHIMOKU_A in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.ICHIMOKU_A.value + " for stock " +
                           ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.ICHIMOKU_A.value] = ichimoku_a(high=df['high'],
                                                     low=df['low'],
                                                     n1=ichimoku_low_n,
                                                     n2=ichimoku_medium_n)

    # Volume Indicator
    if Indicators.CHAIKIN_MONEY_FLOW in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.CHAIKIN_MONEY_FLOW.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.CHAIKIN_MONEY_FLOW.value] = chaikin_money_flow(
            high=df['high'],
            low=df['low'],
            close=df['close'],
            volume=df['volume'],
            n=cmf_n)

    if Indicators.ACCUMULATION_DISTRIBUTION_INDEX in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.ACCUMULATION_DISTRIBUTION_INDEX.value +
                           " for stock " + ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.ACCUMULATION_DISTRIBUTION_INDEX.value] = acc_dist_index(
            high=df['high'],
            low=df['low'],
            close=df['close'],
            volume=df['volume'])

    if Indicators.EASE_OF_MOVEMENT in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.EASE_OF_MOVEMENT.value + " for stock " +
                           ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.EASE_OF_MOVEMENT.value] = ease_of_movement(
            high=df['high'], low=df['low'], volume=df['volume'], n=eom_n)

    if Indicators.FORCE_INDEX in indicators:
        Logger.console_log(message="Calculating " +
                           Indicators.FORCE_INDEX.value + " for stock " +
                           ticker,
                           status=Logger.LogStatus.EMPHASIS)
        df[Indicators.FORCE_INDEX.value] = force_index(close=df['close'],
                                                       volume=df['volume'],
                                                       n=force_index_n)
예제 #12
0
        def run(self) -> None:
            """
            """
            try:
                last_polled_server_mode = Scraper.ServerModes.INVALID
                ticker_survey_list = self.ticker_survey_list
                ticker_monitor_list = self.ticker_monitor_list

                while last_polled_server_mode != Scraper.ServerModes.SHUT_DOWN:
                    if last_polled_server_mode == Scraper.ServerModes.SURVEY_MARKET:
                        # Survey the market, it must be closed.
                        if len(ticker_survey_list) == 0:
                            # No data yet... sleep
                            sleep(5)
                            if self.scraper_server.executive_lock.acquire(
                                    blocking=False):
                                ticker_survey_list = self.ticker_survey_list
                                self.scraper_server.executive_lock.release()
                        else:
                            # Get ticker to survey.
                            ticker = self.ticker_survey_list[0]

                            # Log Result.
                            if Scraper.survey_ticker(thread=self,
                                                     ticker=ticker):
                                self.scraper_server.executive_lock.acquire()
                                Scraper.FileHandler.add_ticker_to_tickers(
                                    ticker=ticker,
                                    relative_path_correction=self.
                                    scraper_server.relative_path_correction)
                                self.scraper_server.executive_lock.release()

                            # remove from survey list.
                            self.ticker_survey_list.remove(ticker)
                    elif last_polled_server_mode == Scraper.ServerModes.RETRIEVE_DATA:
                        # Stock market is open schedule
                        if len(ticker_monitor_list) == 0:
                            # The ticker monitor list is currently empty. Create non blocking check for tickers to monitor.
                            if self.scraper_server.executive_lock.acquire(
                                    blocking=False):
                                ticker_monitor_list = self.ticker_monitor_list
                                self.scraper_server.executive_lock.release()
                        else:
                            # Survey the current ticker_monitor_list
                            for ticker in ticker_monitor_list:
                                try:
                                    ticker_data = Scraper.WebInterface.get_current_ticker_data(
                                        ticker=ticker)
                                    Scraper.FileHandler.store_ticker_data(
                                        ticker=ticker,
                                        data=ticker_data,
                                        relative_path_correction=self.
                                        scraper_server.relative_path_correction
                                    )
                                    Logger.console_log(
                                        message=str(self) +
                                        " was able to retrieve data for ticker: "
                                        + ticker + ".",
                                        status=Logger.LogStatus.SUCCESS)
                                except Exception as e:
                                    Logger.console_log(
                                        message=str(self) +
                                        " was unable to retrieve data for ticker: "
                                        + ticker + " due to exception [" +
                                        str(e) +
                                        "] trying again in 3 seconds.",
                                        status=Logger.LogStatus.FAIL)
                                    sleep(3)
                                    try:
                                        ticker_data = Scraper.WebInterface.get_current_ticker_data(
                                            ticker=ticker)
                                        Scraper.FileHandler.store_ticker_data(
                                            ticker=ticker,
                                            data=ticker_data,
                                            relative_path_correction=self.
                                            scraper_server.
                                            relative_path_correction)
                                        Logger.console_log(
                                            message=str(self) +
                                            " was able to retrieve data for ticker: "
                                            + ticker + ".",
                                            status=Logger.LogStatus.SUCCESS)
                                    except ValueError:
                                        Logger.console_log(
                                            message=str(self) +
                                            " was unable to retrieve data for ticker again: "
                                            + ticker +
                                            " due to ValueError. Will try again later.",
                                            status=Logger.LogStatus.FAIL)
                                    except TypeError:
                                        Logger.console_log(
                                            message=str(self) +
                                            " was unable to retrieve data for ticker again: "
                                            + ticker +
                                            " due to TypeError. It is likely not a valid ticker. Removing"
                                            + "from list of valid tickers.",
                                            status=Logger.LogStatus.FAIL)
                                        Scraper.FileHandler.remove_invalid_ticker(
                                            ticker=ticker,
                                            relative_path_correction=self.
                                            scraper_server.
                                            relative_path_correction)
                                    except Exception as e:
                                        Logger.console_log(
                                            message=str(self) +
                                            " was unable to retrieve data for ticker again: "
                                            + ticker + " due to exception " +
                                            str(e) + ".",
                                            status=Logger.LogStatus.FAIL)

                    # Update the server mode for the next loop
                    if last_polled_server_mode != self.scraper_server.mode:
                        Logger.console_log(
                            str(self) +
                            " has noticed a change in scraper server mode to "
                            + str(self.scraper_server.mode) + " the time is " +
                            str(datetime.now()),
                            status=Logger.LogStatus.COMMUNICATION)
                        # server_mode change.  Time to retrieve processing data.
                        if self.scraper_server.mode == Scraper.ServerModes.SURVEY_MARKET:
                            # Survey the market, it must be closed.
                            self.scraper_server.executive_lock.acquire()
                            ticker_survey_list = self.ticker_survey_list
                            self.scraper_server.executive_lock.release()
                        elif self.scraper_server.mode == Scraper.ServerModes.RETRIEVE_DATA:
                            # Stock market is open schedule
                            self.scraper_server.executive_lock.acquire()
                            ticker_monitor_list = self.ticker_monitor_list
                            self.scraper_server.executive_lock.release()

                    # Update the server mode
                    last_polled_server_mode = self.scraper_server.mode
            except (KeyboardInterrupt, SystemExit):
                self.scraper_server.mode_lock.acquire()
                self.scraper_server.mode = Scraper.ServerModes.SHUT_DOWN
                self.scraper_server.mode_lock.release()
예제 #13
0
        def run(self) -> None:
            """
            """
            try:
                last_polled_server_mode = Scraper.ServerModes.INVALID

                while last_polled_server_mode != Scraper.ServerModes.SHUT_DOWN:

                    # Set the mode of the scraper server
                    self.scraper_server.mode_lock.acquire()
                    self.scraper_server.mode = Scraper.ServerModes.set_mode()

                    # The mode has changed.  It is time to update data for the workers.
                    if last_polled_server_mode != self.scraper_server.mode:
                        Logger.console_log(
                            str(self) +
                            " has updated the scraper server mode to " +
                            str(self.scraper_server.mode) + " the time is " +
                            str(datetime.now()),
                            status=Logger.LogStatus.COMMUNICATION)
                        # The server mode is updated. Time to update the data
                        if self.scraper_server.mode == Scraper.ServerModes.SURVEY_MARKET:
                            # Give workers a list of stocks to monitor Get letters to be surveyed by workers
                            worker_starter_letters = self.scraper_server.stock_ticker_letters_to_survey[:
                                                                                                        self
                                                                                                        .
                                                                                                        scraper_server
                                                                                                        .
                                                                                                        available_cpus]

                            # Remove worker starter letters from survey list
                            for worker_starter_letter in worker_starter_letters:
                                self.scraper_server.stock_ticker_letters_to_survey.remove(
                                    worker_starter_letter)

                            for worker_enum, worker_starter_letter in enumerate(
                                    worker_starter_letters):
                                Logger.console_log(
                                    str(self) + " is asking " +
                                    str(self.worker_threads[worker_enum]) +
                                    " to survey letter " +
                                    worker_starter_letter,
                                    Logger.LogStatus.COMMUNICATION)

                                # Get last surveyed ticker
                                previous_ticker_list = Scraper.FileHandler.load_tickers(
                                    ticker_starting_letter=
                                    worker_starter_letter,
                                    relative_path_correction=self.
                                    scraper_server.relative_path_correction)
                                if len(previous_ticker_list) > 0:
                                    last_surveyed_ticker = previous_ticker_list[
                                        -1]
                                else:
                                    last_surveyed_ticker = None

                                # Get new survey list.
                                ticker_survey_list = Scraper.get_ticker_survey_list(
                                    starting_letter=worker_starter_letter,
                                    last_ticker_surveyed=last_surveyed_ticker)

                                # Give the list to the worker
                                self.scraper_server.executive_lock.acquire()
                                self.worker_threads[
                                    worker_enum].ticker_survey_list = ticker_survey_list
                                self.scraper_server.executive_lock.release()

                        elif self.scraper_server.mode == Scraper.ServerModes.RETRIEVE_DATA:
                            # Get ticker data
                            ticker_list = Scraper.FileHandler.load_all_tickers(
                                relative_path_correction=self.scraper_server.
                                relative_path_correction)
                            ticker_sub_lists = np.array_split(
                                ticker_list,
                                self.scraper_server.available_cpus)

                            # Give the ticker sub lists to workers to monitor for the day.
                            self.scraper_server.executive_lock.acquire()
                            for worker_enum, worker in enumerate(
                                    self.worker_threads):
                                Logger.console_log(
                                    str(self) + " is asking " + str(worker) +
                                    " to monitor tickers: " +
                                    str(ticker_sub_lists[worker_enum]),
                                    Logger.LogStatus.COMMUNICATION)
                                worker.ticker_monitor_list = ticker_sub_lists[
                                    worker_enum]
                            self.scraper_server.executive_lock.release()

                        # Update the mode
                        last_polled_server_mode = self.scraper_server.mode
                        self.scraper_server.mode_lock.release()
                    else:
                        self.scraper_server.mode_lock.release()

                        # Mode has not changed. Make sure the workers have work to do.
                        if last_polled_server_mode == Scraper.ServerModes.SURVEY_MARKET:
                            # Check to see if any of the workers have exhausted their lists
                            for worker in self.worker_threads:
                                if len(worker.ticker_survey_list) == 0:
                                    # wait 2 seconds to make sure the worker is finished
                                    sleep(2)

                                    # Get a new letter
                                    new_letter = self.scraper_server.stock_ticker_letters_to_survey.pop(
                                        0)

                                    # Get a new ticker survey list for the worker thread
                                    self.scraper_server.executive_lock.acquire(
                                    )
                                    Logger.console_log(
                                        message=str(worker) +
                                        " has finished their survey. " +
                                        str(self) +
                                        " is asking it to survey " +
                                        new_letter + " next.",
                                        status=Logger.LogStatus.COMMUNICATION)
                                    worker.ticker_survey_list = Scraper.get_ticker_survey_list(
                                        starting_letter=new_letter,
                                        last_ticker_surveyed=Scraper.
                                        FileHandler.get_last_ticker_surveyed(
                                            ticker_starting_letter=new_letter,
                                            relative_path_correction=self.
                                            scraper_server.
                                            relative_path_correction))
                                    self.scraper_server.executive_lock.release(
                                    )

            except (KeyboardInterrupt, SystemExit):
                Logger.console_log(message="Executive" + str(self.thread_id) +
                                   "shutting down server",
                                   status=Logger.LogStatus.FAIL)
                self.scraper_server.mode_lock.acquire()
                self.scraper_server.mode = Scraper.ServerModes.SHUT_DOWN
                self.scraper_server.mode_lock.release()
 def end_connection(self) -> None:
     Logger.console_log(message="Ending the TCP Connection.",
                        status=Logger.LogStatus.EMPHASIS)
     self.client.close()
예제 #15
0
 def prompt_for_message(self) -> None:
     Logger.console_log(message="", status=Logger.LogStatus.COMMUNICATION)
     message = input('What would you like to send to the server?')
     self.send_message(message=message)