Beispiel #1
0
def main():
    print("Merkato Alpha v0.1.1\n")


    if no_merkatos_table_exists():
        create_merkatos_table()

    if no_exchanges_table_exists():
        create_exchanges_table()

    merkatos = get_all_merkatos()
    for merkato in merkatos:
        exchange_name = merkato['exchange']
        exchange_class = get_relevant_exchange(exchange_name)
        round_trip_fee = round_trip_exchange_fees[exchange_name]
        config = load_config(exchange_name)
        exchange = exchange_class(config, merkato['alt'], merkato['base'])
        last_trade_price = exchange.get_last_trade_price()
        spread = merkato['spread']
        initial_base = float(merkato['bid_reserved_balance']) * 4 + float(merkato['base_profit'])
        initial_quote = float(merkato['ask_reserved_balance']) * 4 + float(merkato['quote_profit'])
        quote_volume = merkato['quote_volume']
        base_volume = merkato['base_volume']
        UUID = merkato['exchange_pair']

        base_profit = (base_volume) * (spread - round_trip_fee)
        quote_profit = (quote_volume) * (spread - round_trip_fee)

        print('STATS FOR {}'.format(UUID))
        print('Quote Volume: {} Base Volume: {}'.format(quote_volume, base_volume))
        print('Quote Profit: {} Base Profit: {}'.format(quote_profit, base_profit))
        relative_base_prof = str((base_profit/initial_base) * 100) + '%'
        relative_quote_prof = str((quote_profit/initial_quote ) * 100) + '%'
        print('Relative Quote Profit: {} Relative Base Profit: {}'.format(relative_quote_prof, relative_base_prof))

        print('*WARNING THIS RESET SHOULD ONLY BE DONE ON AT THE END OF EVERY MONTH, AND WILL REMOVE ALL CURRENT VOLUME*')
        print('*ANY FEE SHOULD BE REMOVED FROM THE ACCOUNT IMMIEDIATELY AFTER*')
        choice_to_continue = input('Would you like to continue? (y/n)')
        should_continue = choice_to_continue == 'y' or choice_to_continue == 'Y'
        if should_continue:
            print('The base profit that will be added to the account is {}'.format(base_profit * .7))
            print('The quote profit that will be added to the account is {}'.format(quote_profit * .7))
            print('The starting_price that will be updated for the merkato is {}'.format(last_trade_price))
            finalize_choice = input('Do these numbers look correct?(y/n)')
            should_execute = finalize_choice == 'y' or choice_to_continue == 'Y'
            if should_execute:
                new_base_profit = merkato['base_profit'] + (base_profit * .7)
                new_quote_profit = merkato['quote_profit'] + (quote_profit * .7)
                update_merkato(UUID, 'base_profit', new_base_profit)
                update_merkato(UUID, 'quote_profit', new_quote_profit)
                update_merkato(UUID, 'base_volume', 0)
                update_merkato(UUID, 'quote_volume', 0)
                update_merkato(UUID, 'starting_price', last_trade_price)
                print('Profits updated new base:{} new quote: {} new starting_price: {}'.format(new_base_profit, new_quote_profit, last_trade_price))
Beispiel #2
0
 def remove_reserve(self, amount, type_of_reserve):
     current_reserve_amount = self.ask_reserved_balance if type_of_reserve == ASK_RESERVE else self.bid_reserved_balance
     invalid_reserve_reduction = amount > current_reserve_amount
     if invalid_reserve_reduction:
         return False
     
     if type_of_reserve == ASK_RESERVE:
         new_amount = self.ask_reserved_balance - amount
         self.ask_reserved_balance = new_amount            
     else:
         new_amount = self.bid_reserved_balance - amount
         self.bid_reserved_balance = new_amount
     update_merkato(self.mutex_UUID, type_of_reserve, new_amount)
     return True
Beispiel #3
0
    def distribute_initial_orders(self, total_base, total_alt):
        ''' TODO: Function comment
        '''
        current_price = (Decimal(self.exchange.get_highest_bid()) +
                         Decimal(self.exchange.get_lowest_ask())) / 2
        if self.user_interface:
            current_price = Decimal(
                self.user_interface.confirm_price(current_price))
            update_merkato(self.mutex_UUID, STARTING_PRICE, current_price)
        ask_start = current_price + current_price * self.spread / 2
        bid_start = current_price - current_price * self.spread / 2

        self.distribute_bids(bid_start, total_base)
        self.distribute_asks(ask_start, total_alt)
Beispiel #4
0
    def remove_reserve(self, amount, type_of_reserve):
        ''' TODO: Function comment
        '''
        current_reserve_amount = self.ask_reserved_balance if type_of_reserve == ASK_RESERVE else self.bid_reserved_balance
        invalid_reserve_reduction = amount > current_reserve_amount

        if invalid_reserve_reduction:
            return False
        if type_of_reserve == ASK_RESERVE:
            new_amount = self.ask_reserved_balance - amount
            self.ask_reserved_balance = new_amount
        elif type_of_reserve == BID_RESERVE:
            new_amount = self.bid_reserved_balance - amount
            self.bid_reserved_balance = new_amount

        update_merkato(self.mutex_UUID, type_of_reserve, float(new_amount))
        return True
Beispiel #5
0
    def __init__(self, configuration, coin, base, spread,
                 bid_reserved_balance, ask_reserved_balance,
                 user_interface=None, profit_margin=0, first_order=''):

        validate_merkato_initialization(configuration, coin, base, spread)
        self.initialized = False
        UUID = configuration[EXCHANGE] + "coin={}_base={}".format(coin,base)
        self.mutex_UUID = UUID
        self.distribution_strategy = 1
        self.spread = float(spread)
        self.profit_margin = profit_margin
        # Create ladders from the bid and ask bidget here
        self.bid_reserved_balance = bid_reserved_balance
        self.ask_reserved_balance = ask_reserved_balance
        self.user_interface = user_interface
        exchange_class = get_relevant_exchange(configuration[EXCHANGE])
        self.exchange = exchange_class(configuration, coin=coin, base=base)
        merkato_does_exist = merkato_exists(UUID)

        if not merkato_does_exist:
            log.info("Creating New Merkato")
            self.cancelrange(ONE_SATOSHI, ONE_BITCOIN)
            total_pair_balances = self.exchange.get_balances()
            log.info("total pair balances", total_pair_balances)
            allocated_pair_balances = get_allocated_pair_balances(configuration['exchange'], base, coin)
            check_reserve_balances(total_pair_balances, allocated_pair_balances, coin_reserve=ask_reserved_balance, base_reserve=bid_reserved_balance)
            insert_merkato(configuration[EXCHANGE], UUID, base, coin, spread, bid_reserved_balance, ask_reserved_balance, first_order)
            history = self.exchange.get_my_trade_history()
            print('initial history', history)
            if len(history) > 0:
                print('updating history', history[0]['orderId'])
                new_last_order = history[0]['orderId']
                update_merkato(self.mutex_UUID, LAST_ORDER, new_last_order)
            self.distribute_initial_orders(total_base=bid_reserved_balance, total_alt=ask_reserved_balance)

        else:
            #self.history = get_old_history(self.exchange.get_my_trade_history(), self.mutex_UUID)
            first_order = get_first_order(self.mutex_UUID)
            current_history = self.exchange.get_my_trade_history(first_order)
            last_order = get_last_order(self.mutex_UUID)
            new_history = get_new_history(current_history, last_order)
            self.rebalance_orders(new_history)
        self.initialized = True  # to avoid being updated before orders placed
Beispiel #6
0
 def update_orders(self, coin, amount_to_add):
     print('amount_to_add', amount_to_add, 'coin', coin)
     amount_to_add = Decimal(float(amount_to_add))
     self.check_balances_available(coin, amount_to_add)
     add_percentage = self.calculate_add_percentage(coin, amount_to_add)
     print('add percentage', add_percentage)
     if coin == self.exchange.coin:
         old_reserves = self.ask_reserved_balance + self.quote_partials_balance
     else:
         old_reserves = self.bid_reserved_balance + self.base_partials_balance
     current_orders = self.exchange.get_my_open_orders()
     for order_id, order in current_orders.items():
         current_amount = order['amount']
         order_type = order['type']
         order_price = Decimal(float(order['price']))
         amount_to_add = Decimal(
             float(current_amount * (1 + add_percentage)))
         print('cancel order')
         print('coin', coin, 'self.exchange.coin', self.exchange.coin,
               'order_type', order_type)
         if coin == self.exchange.coin and order_type == SELL:
             self.exchange.cancel_order(order['id'])
             self.exchange.sell(amount_to_add, order_price)
             print('replace sell')
         if coin == self.exchange.base and order_type == BUY:
             self.exchange.cancel_order(order['id'])
             self.exchange.buy(amount_to_add, order_price)
             print('replace buy')
     if coin == self.exchange.coin:
         print('old reserve balance', self.ask_reserved_balance)
         update_merkato(self.mutex_UUID, 'ask_reserved_balance',
                        float(old_reserves * (1 + add_percentage)))
         self.ask_reserved_balance = Decimal(
             float(old_reserves * (1 + add_percentage)))
         print('new reserve balances', self.ask_reserved_balance)
     elif coin == self.exchange.base:
         print('old reserve balance', self.bid_reserved_balance)
         update_merkato(self.mutex_UUID, 'bid_reserved_balance',
                        float(old_reserves * (1 + add_percentage)))
         self.bid_reserved_balance = Decimal(
             float(old_reserves * (1 + add_percentage)))
         print('new reserve balances', self.bid_reserved_balance)
Beispiel #7
0
 def apply_filled_difference(self, tx, total_amount):
     filled_difference = total_amount - Decimal(tx['amount'])
     log.info('apply_filled_difference tx: {} total_amount: {}'.format(
         tx, total_amount))
     tx_type = tx['type']
     if filled_difference > 0:
         if tx_type == SELL:
             self.base_partials_balance -= filled_difference * Decimal(
                 tx[PRICE])
             update_merkato(self.mutex_UUID, 'base_partials_balance',
                            float(self.base_partials_balance))
             log.info(
                 'apply_filled_difference base_partials_balance: {}'.format(
                     self.base_partials_balance))
         if tx_type == BUY:
             self.quote_partials_balance -= filled_difference
             update_merkato(self.mutex_UUID, 'quote_partials_balance',
                            float(self.quote_partials_balance))
             log.info('apply_filled_difference quote_partials_balance: {}'.
                      format(self.quote_partials_balance))
Beispiel #8
0
    def handle_market_order(self, amount, price, type_to_place, tx_id):
        log.info(
            'handle market order price: {}, amount: {}, type_to_place: {}'.
            format(price, amount, type_to_place))

        last_id_before_market = get_last_order(self.mutex_UUID)

        if type_to_place == BUY:
            self.exchange.market_buy(amount, price)

        elif type_to_place == SELL:
            self.exchange.market_sell(amount, price)

        current_history = self.exchange.get_my_trade_history()
        if self.exchange.name != 'tux':
            self.exchange.process_new_transactions(current_history)
        market_history = get_new_history(current_history,
                                         last_id_before_market)
        market_data = get_market_results(market_history)

        # The sell gave us some BTC. The buy is executed with that BTC.
        # The market buy will get us X xmr in return. All of that xmr
        # should be placed at the original order's matching price.
        #
        # We need to do something here about the partials if it doesnt fully fill
        amount_executed = Decimal(market_data['amount_executed'])
        price_numerator = Decimal(market_data['price_numerator'])
        last_txid = market_data['last_txid']
        log.info('market data: {}'.format(market_data))
        update_merkato(self.mutex_UUID, LAST_ORDER, last_txid)

        market_order_filled = amount <= amount_executed
        if market_order_filled:
            if type_to_place == BUY:
                price = price * Decimal(1 + self.spread)
                self.exchange.sell(amount_executed,
                                   price)  # Should never market order
            elif type_to_place == SELL:
                price = price * Decimal(1 - self.spread)
                self.exchange.buy(amount_executed, price)
        else:
            log.info(
                'handle_market_order: partials affected, amount: {} amount_executed: {}'
                .format(amount, amount_executed))
            if type_to_place == BUY:
                self.quote_partials_balance += amount_executed
                update_merkato(self.mutex_UUID, 'quote_partials_balance',
                               float(self.quote_partials_balance))
                log.info('market buy partials after: {}'.format(
                    self.quote_partials_balance))
            else:
                self.base_partials_balance += amount_executed * price_numerator
                update_merkato(self.mutex_UUID, 'base_partials_balance',
                               float(self.base_partials_balance))
                log.info('market sell partials after {}'.format(
                    self.base_partials_balance))
Beispiel #9
0
 def handle_is_in_filled_orders(self, tx):
     tx_type = tx[TYPE]
     filled_amount = Decimal(tx['amount'])
     price = Decimal(tx[PRICE])
     tx_id = tx[ID]
     if tx_type == BUY:
         self.quote_partials_balance += filled_amount
         update_merkato(self.mutex_UUID, 'quote_partials_balance',
                        float(self.quote_partials_balance))
     if tx_type == SELL:
         self.base_partials_balance += filled_amount * price
         update_merkato(self.mutex_UUID, 'base_partials_balance',
                        float(self.base_partials_balance))
     log.info(
         '{}, orderid in filled_orders filled_amount: {} tx_id: {} '.format(
             tx_type, filled_amount, tx_id))
     update_merkato(self.mutex_UUID, LAST_ORDER, tx_id)
Beispiel #10
0
    def handle_partial_fill(self, type, filled_qty, tx_id):
        # This was a buy, so we gained more of the quote asset.
        # This was a partial fill, so the user's balance is increased by that amount.
        # However, that amount is 'reserved' (will be placed on the books once the
        # rest of the order is filled), and therefore is unavailable when creating new
        # Merkatos. Add this amount to a field 'quote_partials_balance'.
        log.info('handle_partial_fill type {} filledqty {} tx_id {}'.format(
            type, filled_qty, tx_id))
        update_merkato(self.mutex_UUID, LAST_ORDER, tx_id)
        if type == BUY:
            self.quote_partials_balance += filled_qty  # may need a multiply by price
            update_merkato(self.mutex_UUID, 'quote_partials_balance',
                           float(self.quote_partials_balance))

        elif type == SELL:
            self.base_partials_balance += filled_qty
            update_merkato(self.mutex_UUID, 'base_partials_balance',
                           float(self.base_partials_balance))
Beispiel #11
0
    def __init__(self,
                 configuration,
                 coin,
                 base,
                 spread,
                 bid_reserved_balance,
                 ask_reserved_balance,
                 user_interface=None,
                 profit_margin=0,
                 first_order='',
                 starting_price=.018,
                 increased_orders=0,
                 step=1.0033,
                 distribution_strategy=1,
                 init_base_balance=0,
                 init_quote_balance=0,
                 base_profit=0,
                 quote_profit=0,
                 buy_volume=0,
                 sell_volume=0):

        validate_merkato_initialization(configuration, coin, base, spread)
        self.initialized = False
        UUID = configuration[EXCHANGE] + "coin={}_base={}".format(coin, base)
        self.mutex_UUID = UUID
        self.distribution_strategy = distribution_strategy
        self.spread = Decimal(spread)
        self.profit_margin = Decimal(profit_margin)
        self.starting_price = starting_price
        self.step = step
        self.increased_orders = increased_orders
        self.quote_profit = Decimal(quote_profit)
        self.base_profit = Decimal(base_profit)
        self.bid_reserved_balance = Decimal(float(bid_reserved_balance))
        self.ask_reserved_balance = Decimal(float(ask_reserved_balance))
        self.init_base_balance = init_base_balance
        self.init_quote_balance = init_quote_balance
        # The current sum of all partially filled orders
        self.base_partials_balance = 0
        self.quote_partials_balance = 0
        self.buy_volume = buy_volume
        self.sell_volume = sell_volume
        self.last_placed_UUID = ''  #this assures that no faulty doubled up orders will be placed sequentially

        self.user_interface = user_interface

        exchange_class = get_relevant_exchange(configuration[EXCHANGE])
        self.exchange = exchange_class(configuration, coin=coin, base=base)

        merkato_does_exist = merkato_exists(self.mutex_UUID)

        if not merkato_does_exist:
            log.info("Creating New Merkato")

            self.cancelrange(ONE_SATOSHI, ONE_BITCOIN)

            total_pair_balances = self.exchange.get_balances()

            log.info("total pair balances: {}".format(total_pair_balances))

            allocated_pair_balances = get_allocated_pair_balances(
                configuration['exchange'], base, coin)
            check_reserve_balances(total_pair_balances,
                                   allocated_pair_balances,
                                   coin_reserve=ask_reserved_balance,
                                   base_reserve=bid_reserved_balance)

            insert_merkato(configuration[EXCHANGE],
                           self.mutex_UUID,
                           base,
                           coin,
                           spread,
                           bid_reserved_balance,
                           ask_reserved_balance,
                           first_order,
                           starting_price,
                           init_base_balance=bid_reserved_balance,
                           init_quote_balance=ask_reserved_balance,
                           step=step)
            history = self.exchange.get_my_trade_history()

            log.debug('initial history: {}'.format(history))

            if len(history) > 0:
                log.debug('updating history first ID: {}'.format(
                    history[0][ID]))
                new_last_order = history[0][ID]
                update_merkato(self.mutex_UUID, LAST_ORDER, new_last_order)
            self.distribute_initial_orders(total_base=bid_reserved_balance,
                                           total_alt=ask_reserved_balance)

        else:
            first_order = get_first_order(self.mutex_UUID)
            current_history = self.exchange.get_my_trade_history()
            last_order = get_last_order(self.mutex_UUID)
            new_history = get_new_history(current_history, last_order)
            self.rebalance_orders(new_history)

        self.initialized = True  # to avoid being updated before orders placed
Beispiel #12
0
 def update_sell_volume(self, new_volume):
     self.sell_volume += float(new_volume)
     update_merkato(self.mutex_UUID, SELL_VOLUME, self.sell_volume)
Beispiel #13
0
 def update_buy_volume(self, raw_volume, price):
     finalized_volume = float(raw_volume) * float(price)
     self.buy_volume += finalized_volume
     update_merkato(self.mutex_UUID, BUY_VOLUME, self.buy_volume)
Beispiel #14
0
def reset_merkato_metrics(merkato, base_balance, quote_balance):
    UUID = merkato['exchange_pair']
    update_merkato(UUID, 'buy_volume', 0)
    update_merkato(UUID, 'sell_volume', 0)
    update_merkato(UUID, 'init_base_balance', base_balance)
    update_merkato(UUID, 'init_quote_balance', quote_balance)
    update_merkato(UUID, 'quote_profit', 0)
    update_merkato(UUID, 'base_profit', 0)
Beispiel #15
0
    def merge_orders(self):
        # Takes all bids/asks that are at the same price, and combines them.
        #
        # Consider changing semantics from existing_order and order to order and new_order.
        # That is, existing_order currently becomes order, and order becomes new_order.
        # Coin is a string
        # TODO: Make orders/orderbook variables less semantically similar

        orders = self.exchange.get_my_open_orders()

        # Create a dictionary to store our desired orderbook
        orderbook = dict()

        for order in orders:
            log.info('order {}'.format(order))

            price    = orders[order][PRICE]
            coin     = orders[order]["coin"]
            amount   = float(orders[order]["amount"]) # Amount in asset
            total    = float(orders[order]["total"])  # Total in BTC
            order_id = orders[order]['id']

            log.debug(orders[order])

            if coin != self.exchange.ticker:
                continue

            if price not in orderbook:

                price_data = create_price_data(orders, order)

                orderbook[price] = price_data
                log.debug("Found new bid at {}".format(price))

            else:

                log.info("Collision at {}".format(price))

                existing_order        = orderbook[price]
                existing_order_id     = existing_order['id']
                existing_order_type   = existing_order['type']
                existing_order_total  = float(existing_order['total'])
                existing_order_amount = float(existing_order['amount'])

                # Cancel the colliding orders
                self.exchange.cancel_order(order_id)
                self.exchange.cancel_order(existing_order_id)

                # Update the totals to represent the new totals
                existing_order['total']  = str(existing_order_total + total)
                existing_order['amount'] = str(existing_order_amount + amount)

                # Place a new order on the books with the sum
                if existing_order_type == "buy":
                    log.info("Placing buy for {} - {} of {} at a price of {}".format(
                        existing_order['total'], self.exchange.base, self.exchange.ticker, price
                    ))
                    new_id = self.exchange.buy(float(existing_order['total'])/float(price), float(price), self.exchange.ticker)

                else: # existing_order_type is sell
                    log.info("Placing sell for {} - {} of {} at a price of {}".format(
                        existing_order['total'], self.exchange.base, self.exchange.ticker, price
                    ))
                    new_id = self.exchange.sell(float(existing_order['amount']), float(price), self.exchange.ticker)

                if new_id == 0:
                    log.warning("Something went wrong.")
                    return 1
                else: update_merkato(self.mutex_UUID, LAST_ORDER, new_id)

                log.debug("consolidation successful")
                existing_order['id'] = new_id

                log.debug(existing_order)

        log.info("Consolidation Successful")
        return 0
Beispiel #16
0
    def rebalance_orders(self, new_txes):
        # This function places a matching order for every new transaction since last run
        #
        # profit_margin is a number from 0 to 1 representing the percent of the spread to return
        # to the user's balance before placing the matching order.
        #
        # TODO: Modify so that the parent function only passes in the new transactions, don't
        # do the index check internally.

        # new_history is an array of transactions
        # new_txes is the number of new transactions contained in new_history
        factor = self.spread*self.profit_margin/2
        ordered_transactions = new_txes
        log.info('ordered transactions rebalanced: {}'.format(ordered_transactions))
        for tx in ordered_transactions:
            log.info('length of ordered_transactions length length: {}'.format(len(ordered_transactions)))
            if tx['type'] == SELL:
                log.info("Found sell {} corresponding buy {}".format(tx, sell_price))
                
                amount = float(tx['amount']) * float(tx[PRICE])*(1-factor)
                price = float(tx[PRICE])
                buy_price = price * ( 1  - self.spread)
                log.info("found sell {}; corresponding buy {}".format(tx, buy_price))
                market = self.exchange.buy(amount, buy_price)
                if market == MARKET:
                    log.info('market sell', market)
                    last_order_time = str(int(time.time()))
                    self.exchange.market_buy(amount, buy_price)
                    market_history = self.exchange.get_my_trade_history(start=last_order_time)
                    market_data = get_market_results(market_history)

                    # We have a sell executed. We want to place a matching buy order.
                    # If the whole order is executed, no edge case.
                    # If the order has a remainder, the remainder will be on the books at
                    # the appropriate price. So no problem. 
                    # If the remainder is too small to have a matching order, it could 
                    # disappear, but this is such a minor edge case we can ignore it.
                    # 
                    # The sell gave us some BTC. The buy is executed with that BTC.
                    # The market buy will get us X xmr in return. All of that xmr
                    # should be placed at the original order's matching price.
                    amount_executed = float(market_data['amount_executed'])
                    last_orderid    = market_data['last_orderid']
                    log.info('market data: {}'.format(market_data))

                    self.exchange.sell(amount_executed, price) # Should never market order

                    # A market buy occurred, so we need to update the db with the latest tx
                    update_merkato(self.mutex_UUID, LAST_ORDER, last_orderid)

            if tx['type'] == BUY:
                amount = float(tx['amount'])*float((1-factor))
                price = tx[PRICE]
                sell_price = float(price) * ( 1  + self.spread)
                log.info("Found buy {} corresponding sell {}".format(tx, sell_price))
                market = self.exchange.sell(amount, sell_price)
                if market == MARKET:
                    log.info('market buy {}'.format(market))
                    last_order_time = str(int(time.time()))
                    self.exchange.market_sell(amount, sell_price)
                    market_history = self.exchange.get_my_trade_history(start=last_order_time)
                    market_data = get_market_results(market_history)

                    # We have a buy executed. We want to place a matching sell order.
                    # If the whole order is executed, no edge case.
                    # If the order has a remainder, the remainder will be on the books at
                    # the appropriate price. So no problem. 
                    # If the remainder is too small to have a matching order, it could 
                    # disappear, but this is such a minor edge case we can ignore it.
                    # 
                    # The buy gave us some alt. The sell is executed with that alt.
                    # The market sell will get us X btc in return. All of that btc
                    # should be placed at the original order's matching price.
                    amount_executed = float(market_data['total_gotten'])
                    last_orderid    = market_data['last_orderid']
                    log.info('market data {}'.format(market_data))
                    self.exchange.buy(amount_executed, float(price)) # Should never market order

                    # A market buy occurred, so we need to update the db with the latest tx
                    update_merkato(self.mutex_UUID, LAST_ORDER, last_orderid)

            if market != MARKET: 
                log.info('market != MARKET market != MARKET')
                update_merkato(self.mutex_UUID, LAST_ORDER, tx['orderId'])
            
            first_order = get_first_order(self.mutex_UUID)
            no_first_order = first_order == ''
            if no_first_order:
                update_merkato(self.mutex_UUID, FIRST_ORDER, tx['orderId'])

        self.log_new_transactions(ordered_transactions)
        
        return ordered_transactions
Beispiel #17
0
    def rebalance_orders(self, new_txes):
        # This function places matching orders for all orders that filled fully since last

        factor = self.spread * self.profit_margin / 2
        ordered_transactions = new_txes

        log.info(
            'ordered transactions rebalanced: {}'.format(ordered_transactions))

        filled_orders = []
        market_orders = []

        if self.exchange.name != 'tux':
            self.exchange.process_new_transactions(ordered_transactions)

        for tx in ordered_transactions:
            log.info('Checking Transaction: {}\n'.format(tx))
            orderid = tx['orderId']
            tx_id = tx[ID]
            price = tx[PRICE]

            filled_amount = Decimal(tx['amount'])
            init_amount = Decimal(tx['initamount'])

            if self.exchange.name == 'tux':
                partial_fill_info = self.exchange.get_my_order_info(orderid)
                init_amount = partial_fill_info['initamount']
                partial_fill = (partial_fill_info['state'] == 'closed')
            else:
                partial_fill = self.exchange.is_partial_fill(
                    orderid)  # todo implement for tux (binance done)

            total_amount = self.get_total_amount(init_amount, orderid)
            amount = Decimal(total_amount) * Decimal((1 - factor))

            if partial_fill:
                self.handle_partial_fill(tx[TYPE], filled_amount, tx_id)
                continue

            if orderid in filled_orders:
                self.handle_is_in_filled_orders(tx)
                continue

            if tx[TYPE] == SELL:
                buy_price = Decimal(price) * (1 - self.spread)
                log.info(
                    "Found sell {} corresponding buy price: {} amount: {}".
                    format(tx, buy_price, amount))

                market = self.exchange.buy(amount, buy_price)
                # A lock is probably needed somewhere near here in case of unexpected shutdowns

                if market == MARKET:
                    log.info('MARKET ORDER buy {}'.format(market))
                    market_orders.append((
                        amount,
                        buy_price,
                        BUY,
                        tx_id,
                    ))

                self.apply_filled_difference(tx, total_amount)

                is_round_trip = float(price) <= (float(self.starting_price) *
                                                 float(1 + (self.spread / 2)))
                if is_round_trip:
                    log.info('Is round trip sell price: {}'.format(price))
                    self.base_volume += total_amount * Decimal(float(price))
                    update_merkato(self.mutex_UUID, BASE_VOLUME,
                                   float(self.base_volume))

            if tx[TYPE] == BUY:
                sell_price = Decimal(price) * (1 + self.spread)

                log.info(
                    "Found buy {} corresponding sell price: {} amount: {}".
                    format(tx, sell_price, amount))

                market = self.exchange.sell(amount, sell_price)

                if market == MARKET:
                    log.info('MARKET ORDER sell {}'.format(market))
                    market_orders.append((amount, sell_price, SELL, tx_id))

                self.apply_filled_difference(tx, total_amount)

                is_round_trip = float(price) >= (float(self.starting_price) *
                                                 float(
                                                     (1 - (self.spread / 2))))

                if is_round_trip:
                    log.info('Is round trip buy price: {}'.format(price))
                    self.quote_volume += total_amount
                    update_merkato(self.mutex_UUID, QUOTE_VOLUME,
                                   float(self.quote_volume))

            insert_transaction(self.mutex_UUID,
                               self.exchange.base, self.exchange.coin,
                               float(self.spread), tx_id, orderid,
                               float(price), float(filled_amount), tx['time'])

            if market != MARKET:
                log.info('NOT MARKET ORDER')
                update_merkato(self.mutex_UUID, LAST_ORDER, tx[ID])

            filled_orders.append(orderid)

            first_order = get_first_order(self.mutex_UUID)
            no_first_order = first_order == ''

            if no_first_order:
                update_merkato(self.mutex_UUID, FIRST_ORDER, tx_id)

        for order in market_orders:
            self.handle_market_order(*order)

        self.log_new_cointrackr_transactions(ordered_transactions)
        log.info('ending partials base: {} quote: {}'.format(
            self.base_partials_balance, self.quote_partials_balance))
        return ordered_transactions
Beispiel #18
0
    def rebalance_orders(self, new_txes):
        # This function places matching orders for all orders that filled fully since last

        factor = self.spread * self.profit_margin / 2
        ordered_transactions = new_txes

        log.info(
            'ordered transactions rebalanced: {}'.format(ordered_transactions))

        filled_orders = []
        market_orders = []

        if self.exchange.name != 'tux':
            self.exchange.process_new_transactions(ordered_transactions)

        for tx in ordered_transactions:
            log.info('Checking Transaction: {}'.format(tx))
            orderid = tx['orderId']
            tx_id = tx[ID]
            price = tx[PRICE]

            filled_amount = Decimal(tx['amount'])
            init_amount = Decimal(tx['initamount'])

            if self.exchange.name == 'tux':
                partial_fill_info = self.exchange.get_my_order_info(orderid)
                init_amount = partial_fill_info['initamount']
                partial_fill = (partial_fill_info['state'] == 'closed')
            else:
                partial_fill = self.exchange.is_partial_fill(
                    orderid)  # todo implement for tux (binance done)

            total_amount = self.get_total_amount(init_amount, orderid)
            amount = Decimal(total_amount) * Decimal((1 - factor))

            if partial_fill:
                self.handle_partial_fill(tx[TYPE], filled_amount, tx_id)
                continue

            if orderid in filled_orders:
                self.handle_is_in_filled_orders(tx)
                continue

            if tx[TYPE] == SELL:
                buy_price = Decimal(price) * (1 - self.spread)

                # Convert from the coin amount into base at the executed price
                base_amt = Decimal(price) * amount
                # Convert the base amount into coin at the final price
                coin_amt = base_amt / buy_price
                # This is the actual number we want to apply, not the original executed amount.
                amount = coin_amt

                if self.last_placed_UUID != buy_price + amount:
                    log.info(
                        "Found sell {} corresponding buy price: {} amount: {}".
                        format(tx, buy_price, amount))
                    order_response = self.exchange.buy(amount, buy_price)
                else:
                    order_response = None

                self.update_sell_volume(filled_amount)

                if order_response == MARKET:
                    log.info('MARKET ORDER buy {}'.format(order_response))
                    market_orders.append((
                        amount,
                        buy_price,
                        BUY,
                        tx_id,
                    ))

                self.apply_filled_difference(tx, total_amount)

                is_round_trip = float(price) <= (float(self.starting_price) *
                                                 float(1 + (self.spread / 2)))
                if is_round_trip:
                    log.info('Is round trip sell price: {}'.format(price))
                    self.base_profit += total_amount * Decimal(
                        float(price)) * (self.spread -
                                         Decimal(self.exchange.fee * 2))
                    update_merkato(self.mutex_UUID, BASE_PROFIT,
                                   float(self.base_profit))
                order_price = buy_price

            if tx[TYPE] == BUY:
                sell_price = Decimal(price) * (1 + self.spread)

                if self.last_placed_UUID != sell_price + amount:
                    log.info(
                        "Found buy {} corresponding sell price: {} amount: {}".
                        format(tx, sell_price, amount))
                    order_response = self.exchange.sell(amount, sell_price)
                else:
                    order_response = None

                self.update_buy_volume(filled_amount, price)

                if order_response == MARKET:
                    log.info('MARKET ORDER sell {}'.format(order_response))
                    market_orders.append((amount, sell_price, SELL, tx_id))

                self.apply_filled_difference(tx, total_amount)

                is_round_trip = float(price) >= (float(self.starting_price) *
                                                 float(1 - (self.spread / 2)))
                if is_round_trip:
                    log.info('Is round trip buy price: {}'.format(price))
                    self.quote_profit += total_amount * Decimal(
                        self.spread - Decimal(self.exchange.fee * 2))
                    update_merkato(self.mutex_UUID, QUOTE_PROFIT,
                                   float(self.quote_profit))
                order_price = sell_price

            if order_response != MARKET:
                log.info('NOT MARKET ORDER')
                update_merkato(self.mutex_UUID, LAST_ORDER, tx[ID])

            filled_orders.append(orderid)

            first_order = get_first_order(self.mutex_UUID)
            no_first_order = first_order == ''

            if no_first_order:
                update_merkato(self.mutex_UUID, FIRST_ORDER, tx_id)
            self.last_placed_UUID = order_price + amount

        for order in market_orders:
            self.handle_market_order(*order)
        log.info('ending partials base: {} quote: {}'.format(
            self.base_partials_balance, self.quote_partials_balance))
        return ordered_transactions
Beispiel #19
0
def calculate_add_percentage(ticker_pair, coin, amount_to_add):
	orderbook_sum = sum_orderbook(ticker_pair, coin)
	reserve_sum = get_reserves(ticker_pair, coin)
	total_amount = orderbook_sum + reserve_sum
	return amount_to_add/total_amount

def update_orders(ticker_pair, coin, amount_to_add)
	add_percentage = calculate_add_percentage(ticker_pair, coin, amount_to_add)
	old_reserves = get_reserves(ticker_pair, coin)
	for order in current_orders:
		current_amount = order['amount']
		order_type = order['type']
		order_price = order['price']
		amount_to_add = current_amount * (1 + add_percentage)
		cancel_order(order['id'])
		place_order(amount_to_add, order_price)
		if coin != 'BTC':
			update_merkato(UUID, 'ask_reserved_balance', old_reserves * (1 + add_percentage))
			#update coin reserves with old_reserves * (1 + add_percentage)
		else:
			update_merkato(UUID, 'bid_reserved_balance', old_reserves * (1 + add_percentage))
			#update base reserves



def cancel_order(order_id):
	pass

def place_order(amount, price)
	pass
Beispiel #20
0
    def __init__(self,
                 configuration,
                 coin,
                 base,
                 spread,
                 bid_reserved_balance,
                 ask_reserved_balance,
                 user_interface=None,
                 profit_margin=0,
                 first_order='',
                 starting_price=.018,
                 quote_volume=0,
                 base_volume=0,
                 step=1.0033):

        validate_merkato_initialization(configuration, coin, base, spread)
        self.initialized = False
        UUID = configuration[EXCHANGE] + "coin={}_base={}".format(coin, base)
        self.mutex_UUID = UUID
        self.distribution_strategy = 1
        self.spread = Decimal(spread)
        self.profit_margin = Decimal(profit_margin)
        self.starting_price = starting_price
        self.quote_volume = Decimal(quote_volume)
        self.base_volume = Decimal(base_volume)
        self.step = step
        # Exchanges have a maximum number of orders every user can place. Due
        # to this, every Merkato has a reserve of coins that are not currently
        # allocated. As the price approaches unallocated regions, the reserves
        # are deployed.
        self.bid_reserved_balance = Decimal(float(bid_reserved_balance))
        self.ask_reserved_balance = Decimal(float(ask_reserved_balance))

        # The current sum of all partially filled orders
        self.base_partials_balance = 0
        self.quote_partials_balance = 0

        self.user_interface = user_interface

        exchange_class = get_relevant_exchange(configuration[EXCHANGE])
        self.exchange = exchange_class(configuration, coin=coin, base=base)

        merkato_does_exist = merkato_exists(self.mutex_UUID)

        log.info("Creating New Merkato")

        self.cancelrange(ONE_SATOSHI, ONE_BITCOIN)

        total_pair_balances = self.exchange.get_balances()

        log.info("total pair balances: {}".format(total_pair_balances))

        allocated_pair_balances = get_allocated_pair_balances(
            configuration['exchange'], base, coin)
        check_reserve_balances(total_pair_balances,
                               allocated_pair_balances,
                               coin_reserve=ask_reserved_balance,
                               base_reserve=bid_reserved_balance)

        insert_merkato(configuration[EXCHANGE], self.mutex_UUID, base, coin,
                       spread, bid_reserved_balance, ask_reserved_balance,
                       first_order, starting_price)
        history = self.exchange.get_my_trade_history()

        log.debug('initial history: {}'.format(history))

        if len(history) > 0:
            log.debug('updating history first ID: {}'.format(history[0][ID]))
            new_last_order = history[0][ID]
            update_merkato(self.mutex_UUID, LAST_ORDER, new_last_order)
        self.distribute_initial_orders(total_base=bid_reserved_balance,
                                       total_alt=ask_reserved_balance)

        self.initialized = True  # to avoid being updated before orders placed