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)
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)
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
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()
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)
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)
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()
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
# 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]