コード例 #1
0
ファイル: plugin.py プロジェクト: obviyus/Cardinal
    def answer(self, cardinal, user, channel, msg):
        if not (msg.endswith("?") and len(msg.split()) > 1):
            cardinal.sendMsg(channel, "Was that a question?")
            return

        cardinal.sendMsg(
            channel,
            "Let me dig deep into the waters of life, and find your answer."
        )
        yield sleep(2)
        cardinal.sendMsg(channel, "Hmmm...")
        yield sleep(2)
        cardinal.sendMsg(channel, self._get_random_answer())
コード例 #2
0
ファイル: plugin.py プロジェクト: obviyus/Cardinal
    def tick(self):
        """Send a message with daily stock movements"""
        # Start the timer for the next tick -- do this first, as the rest of
        # this function may take time. While that's OK, and it shouldn't take
        # anywhere close to 15 minutes, reloading the plugin during that time
        # could result in close() cancelling the event, and then wait() getting
        # called from the old (reloaded) instance.
        self.wait()

        # If it's after 4pm ET or before 9:30am ET on a weekday, or if it's
        # a weekend (Saturday or Sunday), don't tick, just wait.
        now = est_now()

        # Determine if the market is currently open
        is_market_open = not (
            (now.weekday() >= 5) or
            (now.hour < 9 or now.hour >= 17) or
            (now.hour == 9 and now.minute < 30) or
            (now.hour == 16 and now.minute > 0))

        # Determine if this is the market opening or market closing
        is_open = now.hour == 9 and now.minute == 30
        is_close = now.hour == 16 and now.minute == 0

        # Determine if we should do predictions after sending ticker
        should_do_predictions = True \
            if is_market_open and (is_open or is_close) \
            else False

        # If there are no stocks to send in the ticker, or no channels to send
        # them to, don't tick, just wait.
        should_send_ticker = is_market_open and \
            self.config["channels"] and self.config["stocks"]

        if should_send_ticker:
            yield self.send_ticker()

        if should_do_predictions:
            # Try to avoid hitting rate limiting (5 calls per minute) by giving
            # a minute of buffer after the ticker.
            yield util.sleep(60)
            yield self.do_predictions()
コード例 #3
0
    def make_av_request(self, function, params=None):
        if params is None:
            params = {}
        params['function'] = function
        params['apikey'] = self.config["api_key"]
        params['datatype'] = 'json'

        retries_remaining = MAX_RETRIES
        while retries_remaining > 0:
            retries_remaining -= 1
            try:
                r = yield deferToThread(requests.get,
                                        AV_API_URL,
                                        params=params)
                result = r.json()

                # Detect rate limiting
                if 'Note' in result and 'call frequency' in result['Note']:
                    raise ThrottledException(result['Note'])
            except Exception:
                self.logger.exception(
                    "Failed to make request to AV API - "
                    "retries remaining: {}".format(retries_remaining))

                # Raise the exception if we're out of retries
                if retries_remaining == 0:
                    raise
            # If we succeeded, don't retry
            else:
                break

            # Otherwise, sleep 15 seconds to avoid rate limits before retrying
            yield util.sleep(RETRY_WAIT)
            continue

        defer.returnValue(result)
コード例 #4
0
    def do_predictions(self):
        # Loop each prediction, grouped by symbols to avoid rate limits
        with self.db() as db:
            predicted_symbols = list(db['predictions'].keys())

        for symbol in predicted_symbols:
            try:
                data = yield self.get_daily(symbol)

                actual = data['close']
            except Exception:
                self.logger.exception(
                    "Failed to fetch information for symbol {} -- skipping".
                    format(symbol))
                for channel in self.config["channels"]:
                    self.cardinal.sendMsg(
                        channel,
                        "Error with predictions for symbol {}.".format(symbol))
                continue

            # Loop each nick's prediction, and look for the closest prediction
            # for the current symbol
            closest_prediction = None
            closest_delta = None
            closest_nick = None

            with self.db() as db:
                predictions = db['predictions'][symbol]
                del db['predictions'][symbol]

            for nick, prediction in list(predictions.items()):
                # Check if this is the closest guess for the symbol so far
                delta = abs(actual - prediction['prediction'])
                if not closest_delta or delta < closest_delta:
                    closest_prediction = prediction['prediction']
                    closest_delta = delta
                    closest_nick = nick

                self.send_prediction(
                    nick,
                    symbol,
                    prediction,
                    actual,
                )

            market_open_close = 'open' if market_is_open() else 'close'
            for channel in self.config["channels"]:
                self.cardinal.sendMsg(
                    channel,
                    "{} had the closest guess for \x02{}\x02 out of {} "
                    "predictions with a prediction of {} ({}) "
                    "compared to the actual {} of {} ({}).".format(
                        closest_nick,
                        symbol,
                        len(predictions),
                        closest_prediction,
                        colorize(
                            get_delta(closest_prediction, prediction['base'])),
                        market_open_close,
                        actual,
                        colorize(get_delta(actual, prediction['base'])),
                    ))

            # Try to avoid hitting rate limiting (5 calls per minute) by
            # only checking predictions of 4 symbols per minute
            yield util.sleep(15)
コード例 #5
0
ファイル: plugin.py プロジェクト: obviyus/Cardinal
    def do_predictions(self):
        # Loop each prediction, grouped by symbols to avoid rate limits
        with self.db() as db:
            # TODO will this generator still work if it's iterated outside the
            # context manager?
            predicted_symbols = list(db['predictions'].keys())

        for symbol in predicted_symbols:
            try:
                data = yield self.get_daily(symbol)

                # this is not 100% accurate as to the value at open... it's
                # just a value close to the open, iex cloud doesn't let us get
                # at the true open without paying
                actual = data['price']
            except Exception:
                self.logger.exception(
                    "Failed to fetch information for symbol {} -- skipping"
                    .format(symbol))
                for channel in self.config["channels"]:
                    self.cardinal.sendMsg(
                        channel, "Error with predictions for symbol {}."
                                 .format(symbol))
                continue

            # Loop each nick's prediction, and look for the closest prediction
            # for the current symbol
            closest_prediction = None
            closest_delta = None
            closest_nick = None

            with self.db() as db:
                predictions = db['predictions'][symbol]
                del db['predictions'][symbol]

            for nick, prediction in list(predictions.items()):
                # Check if this is the closest guess for the symbol so far
                delta = abs(actual - prediction['prediction'])
                if not closest_delta or delta < closest_delta:
                    closest_prediction = prediction['prediction']
                    closest_delta = delta
                    closest_nick = nick

                self.send_prediction(
                    nick,
                    symbol,
                    prediction,
                    actual,
                )

            market_open_close = 'open' if market_is_open() else 'close'
            for channel in self.config["channels"]:
                self.cardinal.sendMsg(
                    channel,
                    "{} had the closest guess for {} out of {} "
                    "predictions with a prediction of {:.2f} ({}) "
                    "compared to the actual {} of {:.2f} ({}).".format(
                        closest_nick,
                        F.bold(symbol),
                        len(predictions),
                        closest_prediction,
                        colorize(get_delta(closest_prediction,
                                           prediction['base'])),
                        market_open_close,
                        actual,
                        colorize(get_delta(actual, prediction['base'])),
                    ))

            # Try to avoid hitting rate limiting (5 calls per minute) by
            # only checking predictions of 4 symbols per minute
            yield util.sleep(15)
コード例 #6
0
def test_sleep():
    now = datetime.datetime.now()
    yield util.sleep(1)
    delta = datetime.datetime.now() - now
    assert delta.seconds == 1