Ejemplo n.º 1
0
def pre_rebalance(exchange: Exchange,
                  weights: Dict[str, Decimal],
                  base: str = 'USDT'):
    resources = exchange.get_resources()
    currencies = (exchange.through_trade_currencies()
                  | set(list(resources.keys())) | set(list(weights.keys())))
    all_possible_products = [
        '_'.join([i, j]) for i in currencies for j in currencies
    ]

    orderbooks = exchange.get_orderbooks(all_possible_products)
    # getting all ordebrooks and filtering out orderbooks,
    # that use other currencies
    products = set(orderbook.product for orderbook in orderbooks)

    price_estimates = get_price_estimates_from_orderbooks(orderbooks, base)
    initial_weights = get_weights_from_resources(resources, price_estimates)
    portfolio_value = get_portfolio_value_from_resources(
        resources, price_estimates)
    orderbooks = {orderbook.product: orderbook for orderbook in orderbooks}

    spread_fees = {
        product: spread_to_fee(orderbook)
        for product, orderbook in orderbooks.items()
    }

    return (products, resources, orderbooks, price_estimates, portfolio_value,
            initial_weights, spread_fees)
Ejemplo n.º 2
0
    def test(self):

        ex = Exchange()

        order = {
            "amount": 15,
            "price": 20
        }

        ex.add_order(order, "sell", None)

        self.assertEqual(ex.sells[0]["amount"], 15)
        self.assertEqual(len(ex.sells), 1)
Ejemplo n.º 3
0
def market_order_rebalance(exchange: Exchange,
                           weights: Dict[str, Decimal],
                           update_function,
                           base: str = 'USDT'):
    pre_rebalance_results = pre_rebalance(exchange, weights, base)

    if isinstance(pre_rebalance_results, list):
        return pre_rebalance_results

    (products, resources, orderbooks, price_estimates, portfolio_value,
     initial_weights, spread_fees) = pre_rebalance_results

    fees = {product: exchange.get_taker_fee(product) for product in products}

    total_fees = {
        product: 1 - get_total_fee(fees[product], spread_fees[product])
        for product in products
    }

    orders = rebalance_orders(initial_weights, weights, total_fees)

    if isinstance(orders, Exception):
        return orders

    orders = [(*order[:2], order[2] * portfolio_value) for order in orders]
    orders = topological_sort(orders)
    orders = [
        parse_order(order, products, price_estimates, base) for order in orders
    ]
    length = len(orders)
    update_function(length * 10000)
    ret_orders = []
    for order in orders:
        for i in range(10):
            ret_order = exchange.place_market_order(order, price_estimates)
            if not isinstance(ret_order, Exception):
                ret_orders.append(ret_order)
                break
        length -= 1
        update_function(length * 10000)
        if ret_order is None or isinstance(ret_order, Exception):
            continue
        ret_order['mid_market_price'] = orderbooks[
            order.product].get_mid_market_price()

    return ret_orders
Ejemplo n.º 4
0
    def test(self):
        #BigchainDB and Exchange instantiated
        bc_db = BigchainInterface("http://kyber.ipdb.foundation", 80)
        exchange = Exchange()


        # Two users exist
        prosumer = TokenWallet(bc_db)
        consumer = TokenWallet(bc_db)


        # Prosumer is producing 5 kWh
        for i in range(0,5):

            data ={
                'manufacturer': "Vattenfall",
                'timestamp': str(datetime.now()),
                'source': "GREEN"
            }

            token = EnergyToken.fetch(data)
            txid = prosumer.issue(token)
            print(bc_db.get_transaction(txid))

        time.sleep(1)

        print("\n\nList of issued token id's:\n" + str(prosumer.get_utxos()))


        # Prosumer is selling some token (1 kWh)
        order = {
            "amount": 3,
            "price": 25.00
        }
        print("\n\nProsumer is selling:\n" + str(order))
        if order["amount"] <= prosumer.get_balance():
            exchange.add_order(order, "sell", prosumer)


        # Consumer is buying 1 token (1 kWh)
        order = {
            "amount": 1,
            "price": 25.10
        }
        print("\n\nConsumer is buying:\n" + str(order))
        exchange.add_order(order, "buy", consumer)
        order = {
            "amount": 1,
            "price": 25.10
        }
        print("\n\nConsumer is buying:\n" + str(order))
        exchange.add_order(order, "buy", consumer)

        print("Leftover sellside:\n" + str(exchange.sells))

        self.assertEqual(exchange.sells[0]["rem_amount"], 1)
def main():
    if not options.debug:
        sys.tracebacklimit = 0

    log.basicConfig(
        level=log.DEBUG if options.debug else log.INFO,
        format=
        "[%(asctime)s.%(msecs)03d] %(levelname)s [%(name)s.%(funcName)s:%(lineno)d] %(message)s",
        datefmt='%H:%M:%S',
        filename=options.logfile)

    loop = asyncio.get_event_loop()
    server = ProtocolMessageServer(OuchClientMessages)
    book_logger = BookLogger(
        options.book_log) if options.book_log is not None else None

    if options.mechanism == 'cda':
        book = CDABook()
        exchange = Exchange(order_book=book,
                            order_reply=server.send_server_response,
                            message_broadcast=server.broadcast_server_message,
                            loop=loop,
                            order_book_logger=book_logger)
    elif options.mechanism == 'fba':
        book = FBABook()
        exchange = FBAExchange(
            order_book=book,
            order_reply=server.send_server_response,
            message_broadcast=server.broadcast_server_message,
            loop=loop,
            order_book_logger=book_logger,
            interval=options.interval)
        exchange.start()

    server.register_listener(exchange.process_message)
    server.start(loop)

    try:
        loop.run_forever()
    except KeyboardInterrupt:
        loop.close()
    finally:
        loop.close()
Ejemplo n.º 6
0
    def test(self):

        ex = Exchange(onchain=False)

        start = datetime.datetime.now()
        end = datetime.datetime.now()
        count = 0

        while end - start < datetime.timedelta(seconds=10):

            ex.add_order({
                "amount": 10,
                "price": 25.00
            }, "sell", None)

            ex.add_order({
                "amount": 5,
                "price": 25.01
            }, "buy", None)

            count += 1
            end = datetime.datetime.now()

            res = ex.sells[0]["rem_amount"]

        print(count/10)
Ejemplo n.º 7
0
def limit_order_rebalance(exchange: Exchange,
                          weights: Dict[str, Decimal],
                          user,
                          update_function,
                          *,
                          max_retries: int = 10,
                          time_delta: int = 30,
                          base: str = 'USDT'):
    pre_rebalance_results = pre_rebalance(exchange, weights, base)
    if isinstance(pre_rebalance_results, list):
        return pre_rebalance_results
    (products, resources, orderbooks, price_estimates, portfolio_value,
     initial_weights, spread_fees) = pre_rebalance_results
    fees = {product: exchange.get_maker_fee(product) for product in products}

    reverse_spread_fees = {
        product: 1 - 1 / (1 - spread_fee)
        for product, spread_fee in spread_fees.items()
    }

    limit_pseudo_fee = Decimal('1e2')
    # adding 2 to each cost
    # because total cost is less than 2, algorithm will minimize number of
    # orders first, than total fee
    total_fees = {
        product:
        (1 - get_total_fee(fees[product], reverse_spread_fees[product])) /
        limit_pseudo_fee
        for product in products
    }
    orders = rebalance_orders(initial_weights, weights, total_fees)
    if isinstance(orders, Exception):
        return orders
    orders = [(*order[:2], order[2] * portfolio_value) for order in orders]
    orders = [
        parse_order(order, products, price_estimates, base, OrderType.LIMIT,
                    Decimal()) for order in orders
    ]
    return limit_order_rebalance_with_orders(update_function, exchange,
                                             resources, products, orders,
                                             max_retries, time_delta, base)
Ejemplo n.º 8
0
def main():
    loop = asyncio.get_event_loop()

    # Evaluate cmdline args
    parser = argparse.ArgumentParser("Stock exchange simulation server")
    parser.add_argument("--order-port", type=int, default=7001, help="Port of order/private channel")
    parser.add_argument("--datastream-port", type=int, default=7002, help="Port of datastream/public channel")
    parser.add_argument("--print-stats", action='store_true', help="Print statistics of open orders")
    args = parser.parse_args()

    # create Exchange
    exchange = Exchange()

    # create TCP servers and start listening
    order_server = OrderServer("localhost", args.order_port, exchange)
    datastream_server = DatastreamServer("localhost", args.datastream_port, exchange)
    exchange.set_callbacks(order_server.fill_order_report, datastream_server.send_datastream_report)
    try:
        order_server.start(loop)
        datastream_server.start(loop)
    except OSError as ex:
        exit("Cannot bind address. Is another server already started?\nFull message: %s" % ex.strerror)

    # abort on Ctrl+C or TERM signal
    for signame in ('SIGINT', 'SIGTERM'):
        loop.add_signal_handler(getattr(signal, signame), _stop_server, signame, loop)

    # Print stats every second if requested
    if args.print_stats:
        loop.call_soon(_stats_wakeup, loop, exchange)

    print("Stock exchange simulation server started.")
    try:
        loop.run_forever()
    finally:
        if args.print_stats:
            exchange.print_stats()
        order_server.stop(loop)
        loop.close()
Ejemplo n.º 9
0
def limit_order_rebalance_with_orders(update_function, exchange: Exchange,
                                      resources: Dict[str, Decimal],
                                      products: List[str], orders: List[Order],
                                      max_retries: int, time_delta: int,
                                      base: str):
    number_of_trials = {order.product: 0 for order in orders}
    rets = []
    while len(orders) and (all(number_of_trials[order.product] <= max_retries
                               for order in orders)):
        orderbooks = exchange.get_orderbooks(products)
        orderbooks = {ob.product: ob for ob in orderbooks}
        currencies_from = set()
        currencies_to = set()
        for order in orders:
            currency_commodity, currency_base = order.product.split('_')
            if order._action == OrderAction.SELL:
                currencies_from.add(currency_commodity)
                currencies_to.add(currency_base)
            else:
                currencies_to.add(currency_commodity)
                currencies_from.add(currency_base)

        currencies_free = currencies_from - currencies_to

        order_responses = []
        orders_to_remove = []
        for order in orders:
            currency_commodity, currency_base = order.product.split('_')
            orderbook = orderbooks[order.product]
            order._price = orderbook.get_mid_market_price()
            if order._action == OrderAction.SELL:
                if (currency_commodity not in currencies_free
                        and resources[currency_commodity] < order._quantity):
                    # if selling commodity, which we don't have yet
                    continue
            else:
                if (currency_base not in currencies_free
                        and resources[currency_base] <
                        order._quantity * order._price):
                    # if buying commodity, for which we don't have base yet
                    continue
            order_response = exchange.place_limit_order(order)
            if order_response is None:
                number_of_trials[order.product] = max_retries
                orders_to_remove.append(order)
            elif not isinstance(order_response, Exception):
                order_response.update({'order': order})
                order_responses.append(order_response)
            else:
                number_of_trials[order.product] += 1
        for order in orders_to_remove:
            number_of_trials[order.product] = max_retries
            orders.remove(order)

        update_function(
            limit_order_rebalance_retry_after_time_estimate(
                number_of_trials, max_retries, time_delta))
        time.sleep(time_delta)
        for order_response in order_responses:
            exchange.cancel_limit_order(order_response)
            resp = exchange.get_order(order_response)
            rets.append(resp)
            order = order_response['order']
            if (Decimal(resp['orig_quantity']) -
                    Decimal(resp['executed_quantity'])) > Decimal('1e-3'):
                order._quantity = Decimal(resp['orig_quantity']) - Decimal(
                    resp['executed_quantity'])

                number_of_trials[order.product] += 1
            else:
                number_of_trials[order.product] = max_retries
                orders.remove(order)

    return rets
Ejemplo n.º 10
0


# App Setup & Utilities ===============================================================================================>

app = Flask(__name__)
app.config['JSONIFY_PRETTYPRINT_REGULAR'] = False

limiter = Limiter(
    app,
    key_func=get_remote_address
)

cache = SimpleCache()

exchange = Exchange()

settings = {}

settings["public_rate_limit"] = ""
settings["private_rate_limit"] = ""
settings["default_initial_balance"] = 10000.00
settings["default_initial_status"] = "ACTIVE"


def auth_request():
    api_key = request.headers.get('X-APIKEY')

    if api_key is None or api_key not in exchange.accounts:
        raise Error('Cannot find account with public key: {}'.format(api_key))
    account = exchange.accounts[api_key]