Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def execute_order(order, open_orders):
"""
Attempts to execute an order against open_orders. Note this whole
function is protected by a transaction and a lock.
Logic for buying:
- Search for lowest prices. If several orders have the same prices
then fill them out oldest first.
Logic for selling:
- Search for highest prices. If several orders have the highest price
then fill them out oldest first.
"""
if order.order_type == Order.ORDER_TYPE_BUY:
open_orders = open_orders.order_by('unit_price', 'last_modified')
elif order.order_type == Order.ORDER_TYPE_SELL:
open_orders = open_orders.order_by('-unit_price', 'last_modified')
remaining_items = order.quantity
transfers = []
logger.debug(open_orders)
for open_order in open_orders:
if remaining_items == 0:
break
transfer, remaining_items = (
try_next_order(open_order, order, remaining_items))
if not transfer:
break
transfers.append(transfer)
logger.debug(transfers)
return transfers
# We acquire the lock prior to order validation as nothing can change
# between the order being validated and it possibly being matched.
lonelock(Order, future.pk)
error = validate_order_params(num_shares, price, wallet, order_type,
future)
if error:
return response(error, status=400)
open_orders = Order.objects.filter(filled=False, future=future).exclude(
creator=wallet.user)
# Create an order.
order = Order(future=future, quantity=int(num_shares),
unit_price=int(price), creator=wallet.user)
if order_type == 'buy':
order.order_type = Order.ORDER_TYPE_BUY
open_orders = open_orders.filter(order_type=Order.ORDER_TYPE_SELL)
elif order_type == 'sell':
order.order_type = Order.ORDER_TYPE_SELL
open_orders = open_orders.filter(order_type=Order.ORDER_TYPE_BUY)
# Save the order, then we will see if we have a match.
order.save()
freeze_assets(order, wallet)
logger.debug('*' * 20)
logger.debug(order)
# Try to execute order now, if possible.
transfers = execute_order(order, open_orders)
# Try to execute all transfers.
execute_transfers(transfers)
logger.debug('*' * 20)
# sale price.
if open_order.unit_price > order.unit_price:
# We are not offering enough; break out.
return None, None
elif order.order_type == Order.ORDER_TYPE_SELL:
# If we're selling make sure that we don't sell at less than the
# highest buy price.
if open_order.unit_price < order.unit_price:
return None, None
# We can fill the order (either fully or partially!). Set up the
# points & stock transfer.
transaction = SuccessfulTransaction(future=order.future,
quantity=open_order.quantity,
unit_price=open_order.unit_price)
if order.order_type == Order.ORDER_TYPE_BUY:
# Transfer points from order.creator to open_order.creator
transfer = {'buyer': order.creator.pk,
'buyer_order': order.pk,
'seller': open_order.creator.pk,
'seller_order': open_order.pk,
'price': open_order.unit_price,
'points': quantity * open_order.unit_price,
'share_quantity': quantity,
'share_type': order.future.pk}
transaction.buyer = order.creator
transaction.seller = open_order.creator
elif order.order_type == Order.ORDER_TYPE_SELL:
# Transfer points from open_order.creator to order.creator
transfer = {'buyer': open_order.creator.pk,
'buyer_order': open_order.pk,
'seller': order.creator.pk,
future)
if error:
return response(error, status=400)
open_orders = Order.objects.filter(filled=False, future=future).exclude(
creator=wallet.user)
# Create an order.
order = Order(future=future, quantity=int(num_shares),
unit_price=int(price), creator=wallet.user)
if order_type == 'buy':
order.order_type = Order.ORDER_TYPE_BUY
open_orders = open_orders.filter(order_type=Order.ORDER_TYPE_SELL)
elif order_type == 'sell':
order.order_type = Order.ORDER_TYPE_SELL
open_orders = open_orders.filter(order_type=Order.ORDER_TYPE_BUY)
# Save the order, then we will see if we have a match.
order.save()
freeze_assets(order, wallet)
logger.debug('*' * 20)
logger.debug(order)
# Try to execute order now, if possible.
transfers = execute_order(order, open_orders)
# Try to execute all transfers.
execute_transfers(transfers)
logger.debug('*' * 20)
# Update bid/ask
update_bid_ask(future.pk)
return response('Success') # Front-end should just refresh the page for
# ease.