def liquidity_trader_order(simulation_id, stock_id): simulation = Simulation.objects.get(pk=simulation_id) stock = Stock.objects.get(pk=stock_id) team = Team.objects.get(current_simulation_id=simulation_id, team_type=Team.LIQUIDITY_MANAGER) shares = current_shares(team.id, stock.id) day_duration = simulation.ticker.day_duration first_order_type = [Order.BID, Order.ASK] second_order_type = first_order_type.pop(randint(0, 1)) first_order_type = first_order_type[0] first_order_time = randint(0, int(day_duration/4*3/2)) second_order_time = int(day_duration/4*3/2) - first_order_time + randint(0, int(day_duration/4*3/2)) #open_quantity = Order.objects.all().filter(stock_id=stock.id, order_type=second_order_type, price__isnull=False, quantity__lt=200).aggregate(Sum('quantity'))['quantity__sum'] #if open_quantity: quantity = randint(0, int(shares*0.05)) if quantity > 0: create_order.apply_async(args=[stock.id, team.id, first_order_type, quantity], countdown=first_order_time) #open_quantity = Order.objects.all().filter(stock_id=stock.id, order_type=first_order_type, price__isnull=False, quantity__lt=200).aggregate(Sum('quantity'))['quantity__sum'] #if open_quantity: quantity = randint(0, int(shares*0.05)) if quantity > 0: create_order.apply_async(args=[stock.id, team.id, second_order_type, quantity], countdown=second_order_time)
def process_order(simulation, sell_order, buy_order, quantity, force=False): """ Fulfill two matching orders. .. note:: This is called by :func:`check_matching_orders` :param simulation: A simulation object. :param sell_order: An order object (sell). :param buy_order: An order object (buy). :param quantity: The quantity to exchange (could be a partial fulfillment). :return: Nothing. """ stock = Stock.objects.get(pk=sell_order.stock_id) ready_to_process = True new_transaction = Transaction(simulation=simulation, transaction_type=Transaction.ORDER) new_transaction.save() price = 0 new_sell_order = None new_buy_order = None if sell_order.price and not buy_order.price: price = sell_order.price elif buy_order.price and not sell_order.price: price = buy_order.price elif buy_order.price == sell_order.price: price = sell_order.price else: # Due to rounding differences price = (buy_order.price + sell_order.price)/2 print("PRICE: %s" % price) if stock.price == 0 and stock.opening_price == 0: # TODO: Check if we need to do something here # We open the market pass elif force: ready_to_process = True if current_shares(sell_order.team_id, sell_order.stock_id) < quantity: ready_to_process = False sell_order.state = Order.FAILED sell_order.save() if current_cash(buy_order.team_id, simulation.id) < quantity * price: ready_to_process = False buy_order.state = Order.FAILED buy_order.save() if buy_order.team.team_type == Team.LIQUIDITY_MANAGER or sell_order.team.team_type == Team.LIQUIDITY_MANAGER: # TODO tester qu'il y a au moins x teams avant de passer la transaction bids = Order.objects.filter(state=Order.SUBMITTED, stock=stock, order_type=Order.BID).count() asks = Order.objects.filter(state=Order.SUBMITTED, stock=stock, order_type=Order.ASK).count() if bids > 3 and asks > 3: try: max_bid = Order.objects.filter(state=Order.SUBMITTED, stock=stock, order_type=Order.BID).order_by('-price')[0] max_bid_price = max_bid.price except IndexError: max_bid_price = False try: min_ask = Order.objects.filter(state=Order.SUBMITTED, stock=stock, order_type=Order.ASK).order_by('price')[0] min_ask_price = min_ask.price except IndexError: min_ask_price = False # TODO Implement better test! if price > Decimal(655.50): ready_to_process = False elif price > Decimal(1.5) * stock.price or price < Decimal(0.5) * stock.price: ready_to_process = False elif max_bid_price and min_ask_price: try: spread = min_ask_price - max_bid_price mean = (min_ask_price + max_bid_price)/2 except: spread = None mean = 0 # It's too dangerous for the liquidity manager if spread: if spread > mean*Decimal(0.33): # It's too dangerous for the liquidity manager if buy_order.team.team_type == Team.LIQUIDITY_MANAGER: buy_order.price = max_bid_price * Decimal(1.1) buy_order.save() ready_to_process = False if sell_order.team.team_type == Team.LIQUIDITY_MANAGER: sell_order.price = min_ask_price * Decimal(0.9) sell_order.save() ready_to_process = False else: ready_to_process = False else: ready_to_process = False if price > 0 and ready_to_process: sell = TransactionLine(transaction=new_transaction, stock=stock, team=sell_order.team, quantity=-1*quantity, price=price, amount=-1*quantity*price, asset_type=TransactionLine.STOCKS) sell_revenue = TransactionLine(transaction=new_transaction, team=sell_order.team, quantity=1, price=quantity*price, amount=quantity*price, asset_type=TransactionLine.CASH) buy = TransactionLine(transaction=new_transaction, stock=stock, team=buy_order.team, quantity=quantity, price=price, amount=quantity*price, asset_type=TransactionLine.STOCKS) buy_cost = TransactionLine(transaction=new_transaction, team=buy_order.team, quantity=quantity, price=-1*quantity*price, amount=-1*quantity*price, asset_type=TransactionLine.CASH) if sell_order.quantity != quantity: new_sell_order = Order(stock=stock, team=sell_order.team, order_type=sell_order.order_type, quantity=sell_order.quantity-quantity, price=sell_order.price, created_at=sell_order.created_at) sell_order.quantity = quantity if buy_order.quantity != quantity: new_buy_order = Order(stock=stock, team=buy_order.team, order_type=buy_order.order_type, quantity=buy_order.quantity-quantity, price=buy_order.price, created_at=buy_order.created_at) buy_order.quantity = quantity sell.save() sell_revenue.save() buy.save() buy_cost.save() sell_order.transaction = new_transaction sell_order.state = Order.PROCESSED sell_order.save() buy_order.transaction = new_transaction buy_order.state = Order.PROCESSED buy_order.save() set_stock_quote.apply_async([stock.id, price]) if new_sell_order: new_sell_order.save() if new_buy_order: new_buy_order.save() if simulation.transaction_cost > 0: tc_sell = TransactionLine(transaction=new_transaction, team=sell_order.team, quantity=-1, price=simulation.transaction_cost, amount=-1*simulation.transaction_cost, asset_type=TransactionLine.TRANSACTIONS) tc_buy = TransactionLine(transaction=new_transaction, team=buy_order.team, quantity=-1, price=simulation.transaction_cost, amount=-1*simulation.transaction_cost, asset_type=TransactionLine.TRANSACTIONS) tc_sell.save() tc_buy.save() if simulation.variable_transaction_cost > 0: transaction_price = float(price) * simulation.variable_transaction_cost / 100 tc_sell = TransactionLine(transaction=new_transaction, team=sell_order.team, quantity=-1*quantity, price=Decimal(transaction_price), amount=Decimal(-1*quantity*transaction_price), asset_type=TransactionLine.TRANSACTIONS) tc_buy = TransactionLine(transaction=new_transaction, team=buy_order.team, quantity=-1*quantity, price=Decimal(transaction_price), amount=Decimal(-1*quantity*transaction_price), asset_type=TransactionLine.TRANSACTIONS) tc_sell.save() tc_buy.save()
def process_order(simulation, sell_order, buy_order, quantity, force=False): """ Fulfill two matching orders. .. note:: This is called by :func:`check_matching_orders` :param simulation: A simulation object. :param sell_order: An order object (sell). :param buy_order: An order object (buy). :param quantity: The quantity to exchange (could be a partial fulfillment). :return: Nothing. """ stock = Stock.objects.get(pk=sell_order.stock_id) ready_to_process = True new_transaction = Transaction(simulation=simulation, transaction_type=Transaction.ORDER) new_transaction.save() price = 0 new_sell_order = None new_buy_order = None if sell_order.price and not buy_order.price: price = sell_order.price elif buy_order.price and not sell_order.price: price = buy_order.price elif buy_order.price == sell_order.price: price = sell_order.price else: # Due to rounding differences price = (buy_order.price + sell_order.price) / 2 print("PRICE: %s" % price) if stock.price == 0 and stock.opening_price == 0: # TODO: Check if we need to do something here # We open the market pass elif force: ready_to_process = True if current_shares(sell_order.team_id, sell_order.stock_id) < quantity: ready_to_process = False sell_order.state = Order.FAILED sell_order.save() if current_cash(buy_order.team_id, simulation.id) < quantity * price: ready_to_process = False buy_order.state = Order.FAILED buy_order.save() if buy_order.team.team_type == Team.LIQUIDITY_MANAGER or sell_order.team.team_type == Team.LIQUIDITY_MANAGER: # TODO tester qu'il y a au moins x teams avant de passer la transaction bids = Order.objects.filter(state=Order.SUBMITTED, stock=stock, order_type=Order.BID).count() asks = Order.objects.filter(state=Order.SUBMITTED, stock=stock, order_type=Order.ASK).count() if bids > 3 and asks > 3: try: max_bid = Order.objects.filter( state=Order.SUBMITTED, stock=stock, order_type=Order.BID).order_by('-price')[0] max_bid_price = max_bid.price except IndexError: max_bid_price = False try: min_ask = Order.objects.filter( state=Order.SUBMITTED, stock=stock, order_type=Order.ASK).order_by('price')[0] min_ask_price = min_ask.price except IndexError: min_ask_price = False # TODO Implement better test! if price > Decimal(655.50): ready_to_process = False elif price > Decimal(1.5) * stock.price or price < Decimal( 0.5) * stock.price: ready_to_process = False elif max_bid_price and min_ask_price: try: spread = min_ask_price - max_bid_price mean = (min_ask_price + max_bid_price) / 2 except: spread = None mean = 0 # It's too dangerous for the liquidity manager if spread: if spread > mean * Decimal(0.33): # It's too dangerous for the liquidity manager if buy_order.team.team_type == Team.LIQUIDITY_MANAGER: buy_order.price = max_bid_price * Decimal(1.1) buy_order.save() ready_to_process = False if sell_order.team.team_type == Team.LIQUIDITY_MANAGER: sell_order.price = min_ask_price * Decimal(0.9) sell_order.save() ready_to_process = False else: ready_to_process = False else: ready_to_process = False if price > 0 and ready_to_process: sell = TransactionLine(transaction=new_transaction, stock=stock, team=sell_order.team, quantity=-1 * quantity, price=price, amount=-1 * quantity * price, asset_type=TransactionLine.STOCKS) sell_revenue = TransactionLine(transaction=new_transaction, team=sell_order.team, quantity=1, price=quantity * price, amount=quantity * price, asset_type=TransactionLine.CASH) buy = TransactionLine(transaction=new_transaction, stock=stock, team=buy_order.team, quantity=quantity, price=price, amount=quantity * price, asset_type=TransactionLine.STOCKS) buy_cost = TransactionLine(transaction=new_transaction, team=buy_order.team, quantity=quantity, price=-1 * quantity * price, amount=-1 * quantity * price, asset_type=TransactionLine.CASH) if sell_order.quantity != quantity: new_sell_order = Order(stock=stock, team=sell_order.team, order_type=sell_order.order_type, quantity=sell_order.quantity - quantity, price=sell_order.price, created_at=sell_order.created_at) sell_order.quantity = quantity if buy_order.quantity != quantity: new_buy_order = Order(stock=stock, team=buy_order.team, order_type=buy_order.order_type, quantity=buy_order.quantity - quantity, price=buy_order.price, created_at=buy_order.created_at) buy_order.quantity = quantity sell.save() sell_revenue.save() buy.save() buy_cost.save() sell_order.transaction = new_transaction sell_order.state = Order.PROCESSED sell_order.save() buy_order.transaction = new_transaction buy_order.state = Order.PROCESSED buy_order.save() set_stock_quote.apply_async([stock.id, price]) if new_sell_order: new_sell_order.save() if new_buy_order: new_buy_order.save() if simulation.transaction_cost > 0: tc_sell = TransactionLine(transaction=new_transaction, team=sell_order.team, quantity=-1, price=simulation.transaction_cost, amount=-1 * simulation.transaction_cost, asset_type=TransactionLine.TRANSACTIONS) tc_buy = TransactionLine(transaction=new_transaction, team=buy_order.team, quantity=-1, price=simulation.transaction_cost, amount=-1 * simulation.transaction_cost, asset_type=TransactionLine.TRANSACTIONS) tc_sell.save() tc_buy.save() if simulation.variable_transaction_cost > 0: transaction_price = float( price) * simulation.variable_transaction_cost / 100 tc_sell = TransactionLine(transaction=new_transaction, team=sell_order.team, quantity=-1 * quantity, price=Decimal(transaction_price), amount=Decimal(-1 * quantity * transaction_price), asset_type=TransactionLine.TRANSACTIONS) tc_buy = TransactionLine(transaction=new_transaction, team=buy_order.team, quantity=-1 * quantity, price=Decimal(transaction_price), amount=Decimal(-1 * quantity * transaction_price), asset_type=TransactionLine.TRANSACTIONS) tc_sell.save() tc_buy.save()