Exemplo n.º 1
0
class Bot:
    def __init__(self,tradeType):
        self.trader = BTCChina(API_ACCESS, API_SECRET,tradeType)
        self.portfolio = []
        self.profit = 0

    def get_lowest_market_ask(self, market_depth):
        return float(market_depth['market_depth']['ask'][0]['price'])

    def get_highest_market_bid(self, market_depth):
        return float(market_depth['market_depth']['bid'][0]['price'])

    def should_buy(self, lowest_ask, highest_bid):
        return lowest_ask - highest_bid > DIFFERENCE_STEP

    def get_orders(self):
        orders = None

        if DEBUG_MODE:
            print '---'
            print 'Attempting to get orders'

        for trial in xrange(MAX_TRIAL):
            response = self.trader.get_orders()

            if not response is None:
                orders = response['order']
                if DEBUG_MODE:
                    print 'Received order information'

                break

        return orders

    def cancel_order(self, order_id):
        if DEBUG_MODE:
            print '---'
            print 'Attempting to cancel order', order_id

        ret = None

        for trial in xrange(MAX_TRIAL):
            ret = self.trader.cancel(order_id)
            if not ret is None:
                if DEBUG_MODE:
                    print'Canceled order', order_id

                break

        return ret

    def reset(self):
        if CANCEL_ALL_ON_STARTUP:
            if DEBUG_MODE:
                print '---'
                print 'Attempting to cancel over night orders'

            orders = self.get_orders()
            while len(orders) > 0:
                if orders is None:
                    exit(1)

                for order in orders:
                    if self.cancel_order(order['id']) is None:
                        exit(1)
                orders = self.get_orders()

    def get_market_depth(self):
        market_depth = None

        for trial in xrange(MAX_TRIAL):
            market_depth = self.trader.get_market_depth({'limit': 1})
            if market_depth:
                break

        return market_depth

    def get_num_open_bids(self, orders):
        bid_count = 0
        if orders is None:
            return None

        for order in orders:
            if order['type'] == 'bid':
                bid_count += 1
        return bid_count

    def get_num_open_asks(self, orders):
        ask_count = 0
        if orders is None:
            return None

        for order in orders:
            if order['type'] == 'ask':
                ask_count += 1
        return ask_count

    def get_num_portfolio_bids(self):
        bid_count = 0
        for order in self.portfolio:
            if order['status'] == 'buy':
                bid_count += 1
        return bid_count

    def get_num_portfolio_asks(self):
        ask_count = 0
        for order in self.portfolio:
            if order['status'] == 'sell':
                ask_count += 1
        return ask_count

    def get_highest_bid(self):
        highest_bid = None
        highest_bid_price = -1
        for order in self.portfolio:
            if order['status'] == 'buy' and order['bid'] > highest_bid_price:
                highest_bid_price = order['bid']
                highest_bid = order
        return highest_bid

    def get_lowest_bid(self):
        lowest_bid = None
        lowest_bid_price = float('inf')
        for order in self.portfolio:
            if order['status'] == 'buy' and float(order['bid']) < lowest_bid_price:
                lowest_bid_price = float(order['bid'])
                lowest_bid = order
        return lowest_bid

    def get_lowest_ask(self):
        lowest_ask = None
        lowest_ask_price = float('inf')
        for order in self.portfolio:
            if order['status'] == 'sell' and float(order['ask']) < lowest_ask_price:
                lowest_ask_price = float(order['ask'])
                lowest_ask = order
        return lowest_ask

    def get_highest_bid_id(self, orders):
        highest_bid_id = None
        highest_bid_price = -1
        for order in orders:
            if order['type'] == 'bid' and float(order['price']) > highest_bid_price:
                highest_bid_price = float(order['price'])
                highest_bid_id = order['id']
        return highest_bid_id

    def get_lowest_bid_id(self, orders):
        lowest_bid_id = None
        lowest_bid_price = float('inf')
        for order in orders:
            if order['type'] == 'bid' and float(order['price']) < lowest_bid_price:
                lowest_bid_price = float(order['price'])
                lowest_bid_id = order['id']
        return lowest_bid_id

    def bid_filled(self, bid):
        for trial in xrange(MAX_TRIAL):
            response = self.trader.sell('{0:.2f}'.format(bid['ask']), BTC_AMOUNT)
            if response is True:
                bid['status'] = 'sell'

                if DEBUG_MODE:
                    print 'will sell at', bid['ask']

                break
            else:
                if DEBUG_MODE:
                    print 'Sell failed:', response

    def highest_bid_filled(self):
        highest_bid = self.get_highest_bid()

        if highest_bid is None:
            return

        if DEBUG_MODE:
            print '---'
            print 'Bid at', highest_bid['bid'], 'filled'
            print 'Attempting to put sell order at', highest_bid['ask']

        self.bid_filled(highest_bid)

    def lowest_ask_filled(self):
        lowest_ask = self.get_lowest_ask()

        if lowest_ask is None:
            return

        self.profit += (lowest_ask['ask'] - lowest_ask['bid']) * BTC_AMOUNT
        self.portfolio.remove(lowest_ask)

        if DEBUG_MODE:
            print '---'
            print 'Ask at', lowest_ask['ask'], 'filled, bought at', lowest_ask['bid']
            print 'current profit:', '\033[93m', self.profit, '\033[0m'

    def update_portfolio(self, check_old_orders=False):
        orders = self.get_orders()
        if orders is None:
            return None

        num_open_bids = self.get_num_open_bids(orders)
        num_open_asks = self.get_num_open_asks(orders)
        num_port_bids = self.get_num_portfolio_bids()
        num_port_asks = self.get_num_portfolio_asks()

        if DEBUG_MODE:
            print '---'
            print 'I have', num_port_asks - num_open_asks, 'asks filled'
            print 'I have', num_port_bids - num_open_bids, 'bids filled'

        for num_asks_filled in xrange(num_port_asks - num_open_asks):
            self.lowest_ask_filled()

        for num_bids_filled in xrange(num_port_bids - num_open_bids):
            self.highest_bid_filled()

        if check_old_orders:
            if len(self.portfolio) < MAX_OPEN_ORDERS:
                return orders

            lowest_bid_id = self.get_lowest_bid_id(orders)
            if lowest_bid_id is None:
                return orders

            my_lowest_bid = self.get_lowest_bid()
            my_lowest_bid_price = my_lowest_bid['bid']
            market_highest_bid = self.get_highest_market_bid(self.get_market_depth())

            if market_highest_bid - my_lowest_bid_price >= REMOVE_THRESHOLD:
                response = self.cancel_order(lowest_bid_id)
                if response is True:
                    self.portfolio.remove(my_lowest_bid)

        return orders

    def loop_body(self):
        orders = self.update_portfolio()
        if orders is None:
            return

        if DEBUG_MODE:
            print '---'
            print 'I recorded', self.get_num_portfolio_bids(), 'open bids,', self.get_num_portfolio_asks(), 'asks.'
            print 'API shows', self.get_num_open_bids(orders), 'open bids,', self.get_num_open_asks(orders), 'asks.'

        if len(self.portfolio) >= MAX_OPEN_ORDERS and REMOVE_UNREALISTIC:
            self.update_portfolio(True)

        if len(self.portfolio) >= MAX_OPEN_ORDERS:
            if DEBUG_MODE:
                print '---'
                print 'Too many open orders, sleep for', TOO_MANY_OPEN_SLEEP, 'seconds.'

            if GET_INFO_BEFORE_SLEEP:
                print '---'
                print 'I have', self.get_num_portfolio_bids(), 'open bids,', self.get_num_portfolio_asks(), 'asks.'
                print 'Total profit', '\033[93m', self.profit, '\033[0m'

            sleep(TOO_MANY_OPEN_SLEEP)
            return

        market_depth = self.get_market_depth()
        if not market_depth:
            return

        highest_bid = self.get_highest_market_bid(market_depth)
        lowest_ask = self.get_lowest_market_ask(market_depth)

        if not self.should_buy(lowest_ask, highest_bid):
            if DEBUG_MODE:
                print '---'
                print 'Market spread:', str(lowest_ask - highest_bid)
                print 'Nothing interesting, sleep for', NO_GOOD_SLEEP, 'seconds.'

            if GET_INFO_BEFORE_SLEEP:
                print '---'
                print 'I have', self.get_num_portfolio_bids(), 'open bids,', self.get_num_portfolio_asks(), 'asks.'
                print 'Total profit', '\033[93m', self.profit, '\033[0m'

            sleep(NO_GOOD_SLEEP)
            return

        my_bid_price = highest_bid + CNY_STEP
        my_ask_price = my_bid_price + MIN_SURPLUS

        if DEBUG_MODE:
            print '---'
            print 'Attempting to bid at', my_bid_price

        for trial in xrange(MAX_TRIAL):
            if self.trader.buy('{0:.2f}'.format(my_bid_price), BTC_AMOUNT):
                if DEBUG_MODE:
                    print 'I ordered', BTC_AMOUNT, 'bitcoins at', my_bid_price
                    print 'will sell at', my_ask_price

                self.portfolio.append(
                    {'bid': my_bid_price, 'ask': my_ask_price, 'status': 'buy'})
                break

    def start(self):
        self.reset()
        while True:
            self.loop_body()
Exemplo n.º 2
0
 def __init__(self,tradeType):
     self.trader = BTCChina(API_ACCESS, API_SECRET,tradeType)
     self.portfolio = []
     self.profit = 0