|
@@ -298,6 +298,7 @@ def get_user_ownership(user_id):
|
|
|
WHERE user_id = ?
|
|
|
AND (ownership.amount > 0 OR ownership.ownable_id = ?)
|
|
|
AND ownership.ownable_id = ownables.rowid
|
|
|
+ ORDER BY ownables.rowid ASC
|
|
|
''', (currency_id(), user_id, currency_id(),))
|
|
|
|
|
|
return cursor.fetchall()
|
|
@@ -589,26 +590,73 @@ def execute_orders(ownable_id):
|
|
|
while True:
|
|
|
# find order to execute
|
|
|
cursor.execute('''
|
|
|
- SELECT buy_order.*, sell_order.*, buyer.user_id, seller.user_id, buy_order.rowid, sell_order.rowid
|
|
|
- FROM orders buy_order, orders sell_order, ownership buyer, ownership seller
|
|
|
- WHERE buy_order.buy AND NOT sell_order.buy
|
|
|
- AND buyer.rowid = buy_order.ownership_id
|
|
|
- AND seller.rowid = sell_order.ownership_id
|
|
|
- AND buyer.ownable_id = ?
|
|
|
- AND seller.ownable_id = ?
|
|
|
- AND (buy_order."limit" IS NULL
|
|
|
- OR sell_order."limit" IS NULL
|
|
|
- OR (sell_order."limit" <= buy_order."limit"
|
|
|
- AND NOT sell_order.stop_loss
|
|
|
- AND NOT buy_order.stop_loss))
|
|
|
- ORDER BY CASE WHEN sell_order."limit" IS NULL THEN 0 ELSE 1 END ASC,
|
|
|
- CASE WHEN buy_order."limit" IS NULL THEN 0 ELSE 1 END ASC,
|
|
|
- buy_order."limit" DESC,
|
|
|
- sell_order."limit" ASC,
|
|
|
- buy_order.ordered_amount - buy_order.executed_amount DESC,
|
|
|
- sell_order.ordered_amount - sell_order.executed_amount DESC
|
|
|
+ -- two best orders
|
|
|
+ SELECT * FROM (
|
|
|
+ SELECT buy_order.*, sell_order.*, buyer.user_id, seller.user_id, buy_order.rowid, sell_order.rowid
|
|
|
+ FROM orders buy_order, orders sell_order, ownership buyer, ownership seller
|
|
|
+ WHERE buy_order.buy AND NOT sell_order.buy
|
|
|
+ AND buyer.rowid = buy_order.ownership_id
|
|
|
+ AND seller.rowid = sell_order.ownership_id
|
|
|
+ AND buyer.ownable_id = ?
|
|
|
+ AND seller.ownable_id = ?
|
|
|
+ AND buy_order."limit" IS NULL
|
|
|
+ AND sell_order."limit" IS NULL
|
|
|
+ ORDER BY buy_order.rowid ASC,
|
|
|
+ sell_order.rowid ASC
|
|
|
+ LIMIT 1)
|
|
|
+ UNION ALL -- best buy orders
|
|
|
+ SELECT * FROM (
|
|
|
+ SELECT buy_order.*, sell_order.*, buyer.user_id, seller.user_id, buy_order.rowid, sell_order.rowid
|
|
|
+ FROM orders buy_order, orders sell_order, ownership buyer, ownership seller
|
|
|
+ WHERE buy_order.buy AND NOT sell_order.buy
|
|
|
+ AND buyer.rowid = buy_order.ownership_id
|
|
|
+ AND seller.rowid = sell_order.ownership_id
|
|
|
+ AND buyer.ownable_id = ?
|
|
|
+ AND seller.ownable_id = ?
|
|
|
+ AND buy_order."limit" IS NULL
|
|
|
+ AND sell_order."limit" IS NOT NULL
|
|
|
+ AND NOT sell_order.stop_loss
|
|
|
+ ORDER BY sell_order."limit" ASC,
|
|
|
+ buy_order.rowid ASC,
|
|
|
+ sell_order.rowid ASC
|
|
|
+ LIMIT 1)
|
|
|
+ UNION ALL -- best sell orders
|
|
|
+ SELECT * FROM (
|
|
|
+ SELECT buy_order.*, sell_order.*, buyer.user_id, seller.user_id, buy_order.rowid, sell_order.rowid
|
|
|
+ FROM orders buy_order, orders sell_order, ownership buyer, ownership seller
|
|
|
+ WHERE buy_order.buy AND NOT sell_order.buy
|
|
|
+ AND buyer.rowid = buy_order.ownership_id
|
|
|
+ AND seller.rowid = sell_order.ownership_id
|
|
|
+ AND buyer.ownable_id = ?
|
|
|
+ AND seller.ownable_id = ?
|
|
|
+ AND buy_order."limit" IS NOT NULL
|
|
|
+ AND NOT buy_order.stop_loss
|
|
|
+ AND sell_order."limit" IS NULL
|
|
|
+ ORDER BY buy_order."limit" DESC,
|
|
|
+ buy_order.rowid ASC,
|
|
|
+ sell_order.rowid ASC
|
|
|
+ LIMIT 1)
|
|
|
+ UNION ALL -- both limit orders
|
|
|
+ SELECT * FROM (
|
|
|
+ SELECT buy_order.*, sell_order.*, buyer.user_id, seller.user_id, buy_order.rowid, sell_order.rowid
|
|
|
+ FROM orders buy_order, orders sell_order, ownership buyer, ownership seller
|
|
|
+ WHERE buy_order.buy AND NOT sell_order.buy
|
|
|
+ AND buyer.rowid = buy_order.ownership_id
|
|
|
+ AND seller.rowid = sell_order.ownership_id
|
|
|
+ AND buyer.ownable_id = ?
|
|
|
+ AND seller.ownable_id = ?
|
|
|
+ AND buy_order."limit" IS NOT NULL
|
|
|
+ AND sell_order."limit" IS NOT NULL
|
|
|
+ AND sell_order."limit" <= buy_order."limit"
|
|
|
+ AND NOT sell_order.stop_loss
|
|
|
+ AND NOT buy_order.stop_loss
|
|
|
+ ORDER BY buy_order."limit" DESC,
|
|
|
+ sell_order."limit" ASC,
|
|
|
+ buy_order.rowid ASC,
|
|
|
+ sell_order.rowid ASC
|
|
|
+ LIMIT 1)
|
|
|
LIMIT 1
|
|
|
- ''', (ownable_id, ownable_id,))
|
|
|
+ ''', tuple(ownable_id for _ in range(8)))
|
|
|
|
|
|
matching_orders = cursor.fetchone()
|
|
|
# return type: (ownership_id,buy,limit,stop_loss,ordered_amount,executed_amount,expiry_dt,
|
|
@@ -619,8 +667,8 @@ def execute_orders(ownable_id):
|
|
|
break
|
|
|
|
|
|
buy_ownership_id, _, buy_limit, _, buy_order_amount, buy_executed_amount, buy_expiry_dt, \
|
|
|
- sell_ownership_id, _, sell_limit, _, sell_order_amount, sell_executed_amount, sell_expiry_dt, \
|
|
|
- buyer_id, seller_id, buy_order_id, sell_order_id \
|
|
|
+ sell_ownership_id, _, sell_limit, _, sell_order_amount, sell_executed_amount, sell_expiry_dt, \
|
|
|
+ buyer_id, seller_id, buy_order_id, sell_order_id \
|
|
|
= matching_orders
|
|
|
|
|
|
if buy_limit is None and sell_limit is None:
|
|
@@ -630,14 +678,23 @@ def execute_orders(ownable_id):
|
|
|
elif sell_limit is None:
|
|
|
price = buy_limit
|
|
|
else: # both not NULL
|
|
|
- # that is not how it works at the real exchange, the price of the older order is used
|
|
|
- price = (float(sell_limit) + float(buy_limit)) / 2
|
|
|
+ # the price of the older order is used, just like in the real exchange
|
|
|
+ if buy_order_id < sell_order_id:
|
|
|
+ price = buy_limit
|
|
|
+ else:
|
|
|
+ price = sell_limit
|
|
|
|
|
|
buyer_money = user_money(buyer_id)
|
|
|
|
|
|
+ def _my_division(x,y):
|
|
|
+ try:
|
|
|
+ return floor(x/y)
|
|
|
+ except ZeroDivisionError:
|
|
|
+ return float('Inf')
|
|
|
+
|
|
|
amount = min(buy_order_amount - buy_executed_amount,
|
|
|
sell_order_amount - sell_executed_amount,
|
|
|
- floor(buyer_money / price))
|
|
|
+ _my_division(buyer_money,price))
|
|
|
|
|
|
if amount == 0: # probable because buyer has not enough money
|
|
|
delete_order(buy_order_id)
|