Пример #1
0
    def check_alerts(self):
        """Check alerts for all types of assets."""
        self.check_date()

        if self.price_tracker is None:
            self.price_tracker = PriceTracker()
        if self.send_message is None:
            from moontracker.api_keys import twilio_sid, twilio_auth
            twilio_client = TwilioClient(twilio_sid, twilio_auth)
            self.send_message = twilio_client.api.account.messages.create

        for asset in supported_assets:
            for market in supported_assets[asset]["markets"]:
                self.check_alerts_for_coin(asset, market)

        # too many requests per second, keep getting 429 code
        for asset in supported_assets:
            for market in supported_assets[asset]["markets"]:
                # currently only supports 24 hours

                # for time in supported_durations[market]:
                #     self.check_alerts_for_coin_percent(
                #         asset, market, int(time))

                self.check_alerts_for_coin_percent(asset, market,
                                                   supported_times[1][1])
def test_not_implemented_error():
    pt = PriceTracker()

    with pytest.raises(NotImplementedError) as err:
        pt.get_spot_price("BTC", "FAKE")

    with pytest.raises(NotImplementedError) as err:
        pt.get_percent_change("BTC", "FAKE")
Пример #3
0
def test_price_tracker_integration():
    price_tracker = PriceTracker()
    twilio = twilio_fake()
    texter = Texter()
    texter.set_clients(price_tracker, twilio.send_message)
    alert = Alert(symbol='BTC',
                  price=100.0,
                  condition=1,
                  phone_number='555-555-5555',
                  market='coinbase')
    db.session.add(alert)
    db.session.commit()

    texter.check_alerts()
Пример #4
0
class Texter(object):
    """Texting Object."""
    def __init__(self):
        """Object initializer."""
        self.price_tracker = None
        self.send_message = None

    def set_clients(self, price_tracker=None, send_message=None):
        """Set Clients. Used for unit testing.

        Args:
            price_tracker: The price tracking client.
            send_message: The function to send the text message.
        """
        self.price_tracker = price_tracker
        self.send_message = send_message

    def check_alerts(self):
        """Check alerts for all types of assets."""
        self.check_date()

        if self.price_tracker is None:
            self.price_tracker = PriceTracker()
        if self.send_message is None:
            from moontracker.api_keys import twilio_sid, twilio_auth
            twilio_client = TwilioClient(twilio_sid, twilio_auth)
            self.send_message = twilio_client.api.account.messages.create

        for asset in supported_assets:
            for market in supported_assets[asset]["markets"]:
                self.check_alerts_for_coin(asset, market)

        # too many requests per second, keep getting 429 code
        for asset in supported_assets:
            for market in supported_assets[asset]["markets"]:
                # currently only supports 24 hours

                # for time in supported_durations[market]:
                #     self.check_alerts_for_coin_percent(
                #         asset, market, int(time))

                self.check_alerts_for_coin_percent(asset, market,
                                                   supported_times[1][1])

    def check_date(self):
        """Remove alert from database if at or past end date."""
        timestamp = datetime.now().date()
        dateQuery = Alert.query.filter(Alert.end_date < timestamp)

        dateQuery.delete(False)
        db.session.commit()

    def check_alerts_for_coin(self, coin, market):
        """Check for alerts.

        Args:
            coin: The asset to check against.
            market: String of which market to use
        """
        timestamp = datetime.utcnow()

        # Make the request
        price = self.price_tracker.get_spot_price(asset=coin, market=market)

        # Get all of the prices that are less than the current amount
        greater_than_query = Alert.query.filter(
            Alert.symbol == coin, Alert.price < price, Alert.condition == 1,
            ((Alert.market == market) | (Alert.market.is_(None))))
        self.text_greater_than(greater_than_query.all(), price)
        greater_than_query.delete(False)

        less_than_query = Alert.query.filter(
            Alert.symbol == coin, Alert.price > price, Alert.condition == 0,
            ((Alert.market == market) | (Alert.market.is_(None))))
        self.text_less_than(less_than_query.all(), price)
        less_than_query.delete(False)

        last_price = LastPrice(symbol=coin, price=price, timestamp=timestamp)
        db.session.merge(last_price)

        # TODO(Chase): This will cause race condition.
        db.session.commit()

    def check_alerts_for_coin_percent(self, coin, market, duration):
        """Check for alerts.

        Args:
            coin: The asset to check against.
            market: String of which market to use
        """
        # I need to check each supported time
        percent = self.price_tracker.get_percent_change(asset=coin,
                                                        market=market,
                                                        duration=duration)

        if (percent > 0):  # what if 0? did we already check for that?
            # Get all alerts w/ increase less than the current increase
            percent_increase_query = Alert.query.filter(
                Alert.symbol == coin, Alert.percent_duration == duration,
                Alert.percent < percent, Alert.condition == 2,
                ((Alert.market == market) | (Alert.market.is_(None))))
            if percent_increase_query.count() > 0:
                self.text_percent_increase(percent_increase_query.all(),
                                           percent)
            percent_increase_query.delete(False)
        else:
            # Get all alerts w/ decrease smaller in magnitude than
            # the current decrease
            percent_decrease_query = Alert.query.filter(
                Alert.symbol == coin, Alert.percent_duration == duration,
                -Alert.percent > percent, Alert.condition == 3,
                ((Alert.market == market) | (Alert.market.is_(None))))
            if percent_decrease_query.count() > 0:
                self.text_percent_decrease(percent_decrease_query.all(),
                                           percent * -1)
            percent_decrease_query.delete(False)

        # TODO(Chase): This will cause race condition.
        db.session.commit()

    def text_greater_than(self, alerts, price):
        """Send text message for above triggers.

        Args:
            alerts: The alerts to send. Should be type Alert.
            price: The current asset price.
        """
        for alert in alerts:
            # Some logging
            print("Sending text to %s" % alert.phone_number)
            try:
                # Send the text
                self.send_message(
                    to=alert.phone_number,
                    from_="+15072003597",
                    body=("{} price is above your trigger of ${:.2f}. "
                          "Current price is ${:.2f}".format(
                              alert.symbol, alert.price, price)))
            except twilio.base.exceptions.TwilioRestException:
                # Catch errors.
                print("Invalid number:", alert.phone_number)

    def text_less_than(self, alerts, price):
        """Send text message for above triggers.

        Args:
            alerts: The alerts to send. Should be type Alert.
            price: The current asset price.
        """
        for alert in alerts:
            # Some logging
            print("Sending text to %s" % alert.phone_number)
            try:
                # Send the text
                self.send_message(
                    to=alert.phone_number,
                    from_="+15072003597",
                    body=("{} price is below your trigger of ${:.2f}. "
                          "Current price is ${:.2f}".format(
                              alert.symbol, alert.price, price)))
            except twilio.base.exceptions.TwilioRestException:
                print("Invalid number:", alert.phone_number)

    def text_percent_increase(self, alerts, percent):
        """Send text message for percent increase triggers.

        Args:
            alerts: The alerts to send. Should be type Alert.
            price: The current asset price.
            percent:
            percent_duration:
        """
        percent_duration_str = ""
        for time in supported_times:
            if time[1] == alerts[0].percent_duration:
                percent_duration_str = time[0]
                break

        print("percent_duration_str: " + percent_duration_str)

        for alert in alerts:
            print("Sending text to %s" % alert.phone_number)
            try:
                # should switch percent w/ alert.percent
                self.send_message(
                    to=alert.phone_number,
                    from_="+15072003597",
                    body=("{} price has increased by {:.2f}% over {}. ".format(
                        alert.symbol, percent, percent_duration_str)))
            except twilio.base.exceptions.TwilioRestException:
                print("Invalid number:", alert.phone_number)

    def text_percent_decrease(self, alerts, percent):
        """Send text message for percent decrease triggers.

        Args:
            alerts: The alerts to send. Should be type Alert.
            price: The current asset price.
            percent:
            percent_duration:
        """
        percent_duration_str = ""
        for time in supported_times:
            if time[1] == alerts[0].percent_duration:
                percent_duration_str = time[0]
                break

        print("percent_duration_str: " + percent_duration_str)

        for alert in alerts:
            print("Sending text to %s" % alert.phone_number)
            try:
                self.send_message(
                    to=alert.phone_number,
                    from_="+15072003597",
                    body=("{} price has decreased by {:.2f}% over {}. ".format(
                        alert.symbol, percent, percent_duration_str)))
            except twilio.base.exceptions.TwilioRestException:
                print("Invalid number:", alert.phone_number)
def test_btc():
    pt = PriceTracker()
    price = pt.get_spot_price("BTC")
    assert isinstance(price, float)
def test_googl():
    pt = PriceTracker()
    price = pt.get_spot_price("GOOGL")
    assert isinstance(price, float)
def test_aapl():
    pt = PriceTracker()
    price = pt.get_spot_price("AAPL")
    assert isinstance(price, float)
def test_eth():
    pt = PriceTracker()
    price = pt.get_spot_price("ETH")
    assert isinstance(price, float)