Esempio n. 1
0
def bitcoin_rebalance(db, exchange_data, algo, execute=False):
    algo.log('------- Bitcoin Balancer Report -----------', (), 'yellow')

    if exchange_data.name not in conf.withdrawals_enabled:
        algo.log('Withdrawals not enabled for %s, not balancing',
                 exchange_data.name, 'yellow')
        return

    exchanges = get_deposit_enabled_exchanges(db)

    destination_exchange_data = get_destination_exchange(
        algo, exchange_data, exchanges)

    if destination_exchange_data is None:
        return
    elif destination_exchange_data == exchange_data:
        algo.log('%s not sending to self', exchange_data.name, 'yellow')
        return

    source_exchange = make_exchange_from_key(exchange_data.name)
    destination_exchange = make_exchange_from_key(
        destination_exchange_data.name)

    transfer_amount = TRANSFER_UNIT + create_uniquifier()

    algo.log(
        'Sending %s from %s to %s',
        (transfer_amount, source_exchange.name, destination_exchange.name),
        'yellow')

    if execute:
        # Send the bitcoins and record the transactions.

        deposit_address, transaction_hash, exchange_withdrawal_id = send_btc_to_exchange(
            source_exchange, destination_exchange, transfer_amount)

        transactions = exchange_data.record_withdrawal(
            destination_exchange_data,
            transfer_amount,
            deposit_address,
            transaction_hash,
            exchange_withdrawal_id,
        )

        commit_mysql_session(db)
    else:
        algo.log('Not Sending Because of NO EXECUTE', (), 'yellow')
Esempio n. 2
0
def main(exchanges, execute):
    exchanges = configuration.parse_configurable_as_list(exchanges)
    db = session.get_a_trading_db_mysql_session()

    for exchange_name in exchanges:
        exchange_wrapper = exchange_factory.make_exchange_from_key(
            exchange_name)
        initialize_exchange_ledger(db, exchange_wrapper)

    if execute is True:
        db.commit()
Esempio n. 3
0
def export_ledger_for_exchange(exchange_name, start_time, end_time):
    exchange_obj = exchange_factory.make_exchange_from_key(exchange_name)

    lines = 'Description, %s Credit, %s Debit, BTC Credit, BTC Debit, BTC Balance, %s Balance, Date (UTC)\n' % (
        exchange_obj.currency, exchange_obj.currency, exchange_obj.currency)

    _, _, ledger_table = get_ledger_table_for_time(exchange_name, start_time,
                                                   end_time)

    for table_entry in ledger_table:
        fiat_debit = ''
        btc_debit = ''
        fiat_credit = ''
        btc_credit = ''

        if 'debit' in table_entry:
            if table_entry['debit'].currency == 'BTC':
                btc_debit = table_entry['debit'].amount
            else:
                fiat_debit = table_entry['debit'].amount

        if 'credit' in table_entry:
            if table_entry['credit'].currency == 'BTC':
                btc_credit = table_entry['credit'].amount
            else:
                fiat_credit = table_entry['credit'].amount

        btc_balance = table_entry['balance']['BTC'].amount

        fiat_balance = table_entry['balance'][exchange_obj.currency].amount

        date = table_entry.get('date')

        lines += '"%s",%s,%s,"%s","%s","%s","%s",%s\n' % (
            table_entry.get('description', ''),
            fiat_credit,
            fiat_debit,
            btc_credit,
            btc_debit,
            btc_balance,
            fiat_balance,
            date,
        )

    filename = '%s_ledger_%s_%s.csv' % (
        exchange_name.lower(),
        start_time.strftime('%Y-%m-%d'),
        end_time.strftime('%Y-%m-%d'),
    )

    f = open(filename, 'w')
    f.write(lines)
    f.close()
Esempio n. 4
0
def withdraw(exchange_name, target_exchange_name, amount_str):
    db = session.get_a_trading_db_mysql_session()
    try:
        exchange_data = make_exchange_data_from_key(exchange_name, db)
        target_exchange_data = make_exchange_data_from_key(target_exchange_name, db)
        target_exchange = make_exchange_from_key(target_exchange_name)
        amount = Money.loads(amount_str)
        
        addr = target_exchange.current_deposit_address
        exchange_data.record_withdrawal(target_exchange_data, amount, addr)
        session.commit_mysql_session(db)
        logger.info(tc.colored("Recorded %s withdrawal from %s" % (amount, exchange_name), "green"))
    finally:
        db.remove()
Esempio n. 5
0
def get_pl_from_open_orders(position_trades, exchange_name, open_orders):
    """
    Given our current position, and the open orders on an exchange, what would our
    realized p&l be if a market order came in and consumed our order entirely?

    Details: we naively assume that our order is sized such that it would completely
    close our position. If there is no open order on that exchange, we return None.
    """

    bids = open_orders['bids']
    asks = open_orders['asks']

    pl = Money('0', 'USD')

    open_position = positions.position_delta(position_trades)
    unmatched_fees = revenue_lib.all_fees(position_trades)[0].to('USD')

    fiat_position = open_position['fiat'].to('USD')
    btc_position = open_position['BTC']

    value_of_btc = Money(0, 'USD')

    if btc_position > 0 and len(asks) > 0:
        close_order = asks[
            0]  # Naively assume the first order is what we care about.

        close_price = Money(close_order[0], 'USD')

        value_of_btc = close_price * btc_position.amount
    elif btc_position <= 0 and len(bids) > 0:
        close_order = bids[0]

        close_price = Money(close_order[0], 'USD')

        value_of_btc = close_price * btc_position.amount
    else:
        return Money(0, 'USD'), Money(0, 'USD')

    revenue = fiat_position + unmatched_fees + value_of_btc.to('USD')

    exchange = exchange_factory.make_exchange_from_key(exchange_name)
    new_fee = exchange.limit_order_fee * abs(value_of_btc.to('USD'))

    fees = unmatched_fees + new_fee

    return revenue, fees
Esempio n. 6
0
def get_pl_from_limit_order(position_trades, orderbook, exchange_name):
    """
    Given our current position and an exchange orderbook, what would our realized p&l
    be on that position if we were the top order on this exchange, in the amount and
    side that would exactly close our position, and a market order came through and took
    the whole order?
    """
    pl = Money('0', 'USD')

    open_position = positions.position_delta(position_trades)
    unmatched_fees = revenue_lib.all_fees(position_trades)[0].to('USD')

    fiat_position = open_position['fiat'].to('USD')
    btc_position = open_position['BTC']

    value_of_btc = Money(0, 'USD')

    if btc_position > 0:
        # Then we're in a long position, we want to sell, so place an order in front
        # of the top ask.
        top_ask = orderbook['asks'][0]

        close_price = top_ask.price - Money('0.01', top_ask.price.currency)

        value_of_btc = close_price * btc_position.amount
    else:
        # Then we're in a long position, we want to sell, so place an order in front
        # of the top bid.
        top_bid = orderbook['bids'][0]

        close_price = top_bid.price + Money('0.01', top_bid.price.currency)

        value_of_btc = close_price * btc_position.amount

    revenue = fiat_position + unmatched_fees + value_of_btc.to('USD')

    exchange = exchange_factory.make_exchange_from_key(exchange_name)
    new_fee = exchange.market_order_fee * abs(value_of_btc.to('USD'))

    fees = unmatched_fees + new_fee

    return revenue, fees
Esempio n. 7
0
    def configure(self, configuration):
        self.init_configurable('price_currency', configuration)
        self.init_configurable('volume_currency', configuration)
        self.init_configurable('infinitisimal', configuration)
        self.init_configurable('infinity', configuration)
        self.init_configurable('zero', configuration)
        self.init_configurable('trading_pairs', configuration)
        self.init_configurable('DEFAULT_WIDTH', configuration)
        self.init_configurable('pair_name', configuration)

        # Parse as list and turn exchange names into exchange connections.
        self.trading_pair_names = config_lib.parse_configurable_as_list(
            self.trading_pairs, )

        self.trading_pair_names = [t.upper() for t in self.trading_pair_names]

        self.trading_pairs = []

        for trading_pair_name in self.trading_pair_names:
            e = exchange_factory.make_exchange_from_key(trading_pair_name)
            self.trading_pairs.append(e)
Esempio n. 8
0
def fix_balance_issues_for_exchange(exchange_name, execute=False):
    db = session.get_a_trading_db_mysql_session()
    exchange = exchange_factory.make_exchange_from_key(exchange_name)

    if not exchange:
        raise Exception('No exchange %s' % exchange_name)

    exchange_balance = exchange.get_balance()

    reset_balance_for_exchange_in_currency(
        db,
        exchange,
        exchange_balance,
        exchange.currency,
        execute,
    )

    reset_balance_for_exchange_in_currency(
        db,
        exchange,
        exchange_balance,
        exchange.volume_currency,
        execute,
    )
Esempio n. 9
0
def get_pl_from_market_order(position_trades, orderbook, exchange_name):
    """
    Given our current position and an exchange orderbook, what would our realized p&l
    be if we closed that position right now with a market order?
    """
    pl = Money('0', 'USD')

    open_position = positions.position_delta(position_trades)
    unmatched_fees = revenue_lib.all_fees(position_trades)[0].to('USD')

    fiat_position = open_position['fiat'].to('USD')
    btc_position = open_position['BTC']

    value_of_btc = Money(0, 'BTC')

    if btc_position > 0:
        value_of_btc = quote_lib.price_quote_from_orderbook(
            orderbook,
            Order.ASK,
            btc_position,
        )['total_price']
    else:
        value_of_btc = quote_lib.price_quote_from_orderbook(
            orderbook,
            Order.BID,
            btc_position,
        )['total_price']

    revenue = fiat_position + unmatched_fees + value_of_btc.to('USD')

    exchange = exchange_factory.make_exchange_from_key(exchange_name)
    new_fee = exchange.market_order_fee * abs(value_of_btc.to('USD'))

    fees = unmatched_fees + new_fee

    return revenue, fees
Esempio n. 10
0
    def audit_orderbook(self, orderbook, orderbook_timestamp):
        orderbook_timestamp_early = orderbook_timestamp - timedelta(seconds=5)
        orderbook_timestamp_late = orderbook_timestamp + timedelta(seconds=5)

        result = yield self.engine.execute(
            orderbook_table.select(orderbook_table).where(
                and_(
                    orderbook_table.c.exchange == self.exchange_name,
                    orderbook_table.c.timestamp.between(
                        orderbook_timestamp_early, orderbook_timestamp_late))))

        our_orderbooks = yield result.fetchall()

        # Non Blocking ^^^
        # Potentially Blocking vvv

        start_time = Delorean().epoch
        audit_successful = 'SOFT'
        change_dict = {}
        fundamental_values = {}

        exchange_object = exchange_factory.make_exchange_from_key(
            self.exchange_name)

        price_limit = Money(ORDERBOOK_PRICE_LIMIT, exchange_object.currency)

        http_orderbook = exchange_object.parse_orderbook(
            orderbook,
            price_limit=price_limit,
        )

        http_fundamental_value = self.fundamental_value(http_orderbook)
        indexed_http_ob = self.index_orderbook(http_orderbook)

        for our_ob in our_orderbooks:
            raw_db_orderbook = {
                'bids': json.loads(our_ob.bids),
                'asks': json.loads(our_ob.asks),
            }

            db_orderbook = exchange_object.parse_orderbook(
                raw_db_orderbook,
                price_limit=price_limit,
                cached_orders=True,
            )

            # Check for soft falilures
            db_fundamental_value = self.fundamental_value(db_orderbook)

            fund_value_closeness = (
                abs(db_fundamental_value - http_fundamental_value) /
                http_fundamental_value)

            indexed_db_ob = self.index_orderbook(db_orderbook)

            ask_diffs = DictDiffer(indexed_db_ob['asks'],
                                   indexed_http_ob['asks'])
            bid_diffs = DictDiffer(indexed_db_ob['bids'],
                                   indexed_http_ob['bids'])

            changes = (list(ask_diffs.added()) + list(ask_diffs.removed()) +
                       list(ask_diffs.changed()) + list(bid_diffs.added()) +
                       list(bid_diffs.removed()) + list(bid_diffs.changed()))

            total_changes = len(changes)

            change_dict[total_changes] = changes
            fundamental_values[fund_value_closeness] = {
                'db_fundamental_value': db_fundamental_value,
                'http_fundamental_value': http_fundamental_value,
            }

            hard_failure_fund_value_closeness = 10

            if (total_changes < self.acceptable_changes_threshold
                    and fund_value_closeness <
                    self.acceptable_fund_value_threshold):
                audit_successful = 'SUCCESSFUL'

            # Check for hard failures.
            if self.detect_orderbook_cross(db_orderbook):
                audit_successful = 'HARD'

                log.err('%s Auditor Detects Cross -  Bids:%s, Asks:%s' %
                        (self.exchange_name, db_orderbook['bids'][:3],
                         db_orderbook['asks'][:3]))

                break

            if fund_value_closeness > hard_failure_fund_value_closeness:
                audit_successful = 'HARD'

                log.err(
                    'Funamental Value difference is more than %s% its:' %
                    (hard_failure_fund_value_closeness, fund_value_closeness))

                break

        if not audit_successful == 'SUCCESSFUL':
            log.msg('%s Orderbook Auditor Soft Failure Report:' %
                    self.exchange_name)

            if not our_orderbooks:
                log.msg('No orderbooks to audit against')

            for key, value in fundamental_values.iteritems():
                log.msg(
                    '------ Fundamental Value Closeness:%.6f, DBfv:%s, HTTPfv:%s'
                    % (key, value['db_fundamental_value'],
                       value['http_fundamental_value']))

            for key, value in change_dict.iteritems():
                log.msg('------ Change Count: %s' % key)

        log.msg('Time Elapsed Auditing %s Orderbook: %s' % (
            self.exchange_name,
            Delorean().epoch - start_time,
        ))

        defer.returnValue(audit_successful)
Esempio n. 11
0
    def get_ledger_table_for_time(self,
                                  exchange_name,
                                  start_time,
                                  end_time,
                                  currency=None):
        if currency:
            currency = currency.upper()

        exchange_name = exchange_name.capitalize()
        exchange = exchange_factory.make_exchange_from_key(exchange_name)
        exchange_data = exchange_factory.make_exchange_data_from_key(
            exchange_name,
            self.trading_db,
        )

        if exchange:
            # Normal bitcoin exchange.
            fiat_currency = exchange.currency
        else:
            # Bank Accounts don't have exchange objects.
            fiat_currency = self.currency_for_bank_account(exchange_name)

            # Bank Accounts only have one currency, so we set a currency filter by
            # default. It just makes the UI look nicer instead of having an empty BTC
            # column.
            currency = fiat_currency

        ledger = exchange_data.ledger(
            start_time=start_time,
            end_time=end_time,
            currency=currency,
        )

        # ledger is empty for this time period.
        if len(ledger) == 0:
            return fiat_currency, currency, []

        # get the exchange balance from before these ledger entries started
        oldest_entry = ledger[-1]
        oldest_time = oldest_entry.time_created

        # There can be multiple entries at the same time
        entries_at_oldest_time = []

        for entry in ledger:
            if isinstance(entry, Trade) and entry.time_created == oldest_time:
                entries_at_oldest_time.append(entry)
            elif isinstance(
                    entry,
                    Transaction) and entry.time_completed == oldest_time:
                entries_at_oldest_time.append(entry)

        oldest_time = pytz.utc.localize(oldest_time)
        balance_at_oldest_time = exchange_data.ledger_balance(
            end_time=oldest_time)

        # balance_at_oldest_time includes all the entries_at_oldest_time
        # so we need to remove them to get the pre-ledger balance
        pre_ledger_balance = balance_at_oldest_time

        for entry in entries_at_oldest_time:
            pre_ledger_balance -= entry.position

        starting_ledger_balance = exchange_data.ledger_balance(
            end_time=start_time)

        ledger_table = []

        for entry in ledger:
            if isinstance(entry, Trade):
                table_entries = self.table_entries_from_trade(entry)
            elif isinstance(entry, Transaction):
                table_entries = self.table_entries_from_transaction(entry)

            ledger_table += table_entries

        ledger_table = self.filter_to_currency(ledger_table, currency)

        current_balance = starting_ledger_balance

        for table_entry in reversed(ledger_table):
            if 'credit' in table_entry:
                current_balance += table_entry['credit']
            if 'debit' in table_entry:
                current_balance -= table_entry['debit']

            table_entry['balance'] = current_balance

        return fiat_currency, currency, ledger_table
Esempio n. 12
0
def get_ledger_table_for_time(exchange_name,
                              start_time,
                              end_time,
                              currency=None):
    if currency:
        currency = currency.upper()

    exchange_name = exchange_name.capitalize()
    exchange = exchange_factory.make_exchange_from_key(exchange_name)

    exchange_data = exchange_factory.make_exchange_data_from_key(
        exchange_name,
        db,
    )

    fiat_currency = exchange.currency

    ledger = exchange_data.ledger(
        start_time=start_time,
        end_time=end_time,
        currency=currency,
    )

    # ledger is empty for this time period.
    if len(ledger) == 0:
        return fiat_currency, currency, []

    # get the exchange balance from before these ledger entries started
    oldest_entry = ledger[-1]
    oldest_time = oldest_entry.time_created

    # There can be multiple entries at the same time
    entries_at_oldest_time = []

    for entry in ledger:
        if isinstance(entry, Trade) and entry.time_created == oldest_time:
            entries_at_oldest_time.append(entry)
        elif isinstance(entry,
                        Transaction) and entry.time_completed == oldest_time:
            entries_at_oldest_time.append(entry)

    oldest_time = pytz.utc.localize(oldest_time)
    balance_at_oldest_time = exchange_data.ledger_balance(end_time=oldest_time)

    # balance_at_oldest_time includes all the entries_at_oldest_time
    # so we need to remove them to get the pre-ledger balance
    pre_ledger_balance = balance_at_oldest_time

    for entry in entries_at_oldest_time:
        pre_ledger_balance -= entry.position

    starting_ledger_balance = exchange_data.ledger_balance(end_time=start_time)
    ledger_diff = exchange_data.ledger_balance(
        start_time=start_time,
        end_time=end_time,
    )
    ending_ledger_balance = starting_ledger_balance + ledger_diff

    ledger_table = []

    for entry in ledger:
        if isinstance(entry, Trade):
            table_entries = table_entries_from_trade(entry)
        elif isinstance(entry, Transaction):
            table_entries = table_entries_from_transaction(entry)

        ledger_table += table_entries

    #ledger_table = self.filter_to_currency(ledger_table, currency)

    current_balance = starting_ledger_balance

    for table_entry in reversed(ledger_table):
        if 'credit' in table_entry:
            current_balance += table_entry['credit']
        if 'debit' in table_entry:
            current_balance -= table_entry['debit']

        table_entry['balance'] = current_balance

    return fiat_currency, currency, ledger_table