示例#1
0
    def send_notification_email(self, gdax, bitcoin_de, profit_pct):
        try:
            email = EmailBuilder.build_notification_email(
                gdax, bitcoin_de, profit_pct)
            response = self.email_client.send_email(
                Destination={
                    'ToAddresses': [
                        self._recipient,
                    ],
                },
                Message={
                    'Body': {
                        'Text': {
                            'Charset': self._charset,
                            'Data': email['text']
                        },
                    },
                    'Subject': {
                        'Charset': self._charset,
                        'Data': email['subject']
                    },
                },
                Source=self._sender,
            )
            Log.info(
                self.ME,
                'Just sent a notification email. Profit: {} %.'.format(
                    profit_pct))
        except Exception as e:
            Log.error(self.ME,
                      'Unable to send notification email: {}'.format(e))
            return False

        return True
示例#2
0
    def get_gdax_ask(self, pair):
        try:
            gdax_order_book = self.GDAX_CLIENT.get_product_order_book(pair,
                                                                      level=1)
            return self.parse_gdax_order_book(gdax_order_book, pair)
        except Exception as e:
            Log.warn(self.ME,
                     'Unable to fetch new ask from gdax.com: {}'.format(e))

        return None
示例#3
0
    def __init__(self):
        self.fidor_password = os.environ['FIDOR_PASSWORD']
        self.fidor_email = os.environ['FIDOR_EMAIL']

        options = webdriver.ChromeOptions()
        options.add_argument('headless')
        options.add_argument('no-sandbox')

        try:
            self.client = webdriver.Chrome(chrome_options=options)
            Log.debug(self.ME, 'Launched new chromedriver instance.')
        except Exception as e:
            Log.fatal(self.ME, 'Unable to create chrome client: {}'.format(e))
示例#4
0
    def handle(self, *args, **options):
        last_gdax_ask_btc = None
        last_gdax_ask_eth = None
        last_bitcoin_de_ask_btc = None
        while True:
            bitcoin_ask_btc = self.get_bitcoin_ask('BTC')
            if bitcoin_ask_btc is not None:
                bitcoin_ask_btc.save()
                last_bitcoin_de_ask_btc = bitcoin_ask_btc
                Log.info(self.ME,
                         'Fetched new ask: {}'.format(last_bitcoin_de_ask_btc))

            bitcoin_ask_eth = self.get_bitcoin_ask('ETH')
            if bitcoin_ask_eth is not None:
                bitcoin_ask_eth.save()
                last_bitcoin_de_ask_eth = bitcoin_ask_eth
                Log.info(self.ME,
                         'Fetched new ask: {}'.format(last_bitcoin_de_ask_eth))

            gdax_ask_btc = self.get_gdax_ask('BTC-EUR')
            if gdax_ask_btc is not None:
                gdax_ask_btc.save()
                last_gdax_ask_btc = gdax_ask_btc
                Log.info(self.ME,
                         'Fetched new ask: {}'.format(last_gdax_ask_btc))

            gdax_ask_eth = self.get_gdax_ask('ETH-EUR')
            if gdax_ask_eth is not None:
                gdax_ask_eth.save()
                last_gdax_ask_eth = gdax_ask_eth
                Log.info(self.ME,
                         'Fetched new ask: {}'.format(last_gdax_ask_eth))

            pct_profit = self.calc_profit_pct_btc(last_gdax_ask_btc,
                                                  last_bitcoin_de_ask_btc)
            allowed_to_send_email = self.last_notification_email is None or (
                datetime.now() - self.last_notification_email
            ).seconds // 60 > self.NOTIFICATION_EMAIL_PAUSE_MIN

            if pct_profit > self.NOTIFICATION_THRESHOLD_PCT and allowed_to_send_email:
                success = self.send_notification_email(
                    last_gdax_ask_btc, last_bitcoin_de_ask_btc, pct_profit)
                if success:
                    self.last_notification_email = datetime.now()

            # TODO: Fix. Should really fire every minute and not sleep for 60s.
            self.heartbeat()
            time.sleep(60)

        return 0
示例#5
0
    def update_transactions(self):
        """ Keeps turn overs up-to-date """
        TRANSACTIONS_URL = 'https://banking.fidor.de/smart-account/transactions'
        self.client.get(TRANSACTIONS_URL)

        transactions = self.client.find_elements_by_css_selector(
            '#booked-transactions tbody tr')
        new_transactions = []
        for t in transactions:
            cols = t.find_elements_by_tag_name('td')
            try:
                date = datetime.strptime(cols[0].text, '%d.%m.%Y')
                desc = cols[1].text
                amount = float(cols[2].text.strip("€").replace('.',
                                                               '').replace(
                                                                   ',', '.'))
                balance = float(cols[3].text.strip('€').replace('.',
                                                                '').replace(
                                                                    ',', '.'))
                unique = sha256('{}-{}-{}-{}'.format(
                    date, desc, amount, balance).encode('utf-8')).hexdigest()
                result = BankTransaction.objects.filter(unique=unique)
                if result:
                    break

                # Look for open transactions that can be closed
                open_transaction = BankTransaction.objects.filter(
                    amount=amount, finished=False).first()
                if open_transaction:
                    open_transaction.arrived_at = date
                    open_transaction.desc = desc
                    open_transaction.unique = unique
                    open_transaction.finished = True
                    open_transaction.new_balance = balance
                    open_transaction.save()
                    Log.info(
                        self.ME,
                        'A pending SEPA transaction of {} € just arrived. New balance: {} €.'
                        .format(open_transaction.amount,
                                open_transaction.new_balance))
                else:
                    new_transactions.append(
                        BankTransaction(finished=True,
                                        arrived_on=date,
                                        desc=desc,
                                        amount=amount,
                                        new_balance=balance,
                                        unique=unique))
            except Exception as e:
                Log.warn(self.ME,
                         'Unable to store new SEPA transaction: {}'.format(e))

        for t in reversed(new_transactions):
            Log.info(
                self.ME,
                'An unexpected SEPA transaction of {} € just arrived. New balance: {} €.'
                .format(t.amount, t.new_balance))
            t.save()
示例#6
0
    def get_bitcoin_ask(self, coin):
        try:
            if coin == 'BTC':
                self.bitcoin_conn.request('GET', self.BTC_OFFER_RESOURCE, None,
                                          self.CLIENT_HEADER)
                resp = self.bitcoin_conn.getresponse()
                if resp.status == 200:
                    asks = html.fragments_fromstring(resp.read())
                    for a in asks:
                        ask = self.parse_ask_btc(a)
                        if (self.valid(ask)):
                            return ask
                else:
                    Log.warn(
                        self.ME,
                        'Unable to fetch new ask from bitcoin.de: [status={}, reason={}]'
                        .format(resp.status, resp.reason))
            elif coin == 'ETH':
                self.bitcoin_conn.request('GET', self.ETH_OFFER_RESOURCE, None,
                                          self.CLIENT_HEADER_ETH)
                resp = self.bitcoin_conn.getresponse()
                if resp.status == 200:
                    asks = html.fragments_fromstring(resp.read())
                    for a in asks:
                        ask = self.parse_ask_eth(a)
                        if (self.valid(ask)):
                            return ask
                else:
                    Log.warn(
                        self.ME,
                        'Unable to fetch new ask from bitcoin.de: [status={}, reason={}]'
                        .format(resp.status, resp.reason))
        except Exception as e:
            Log.warn(self.ME,
                     'Unable to fetch new ask from bitcoin.de: {}'.format(e))
            self.create_btc_conn()

        return None