ソースを参照

Trading bot should now work as described

Eren Yilmaz 6 年 前
コミット
9fea8c8b97
2 ファイル変更52 行追加36 行削除
  1. 15 12
      assets/follower.py
  2. 37 24
      trading_bot.py

+ 15 - 12
assets/follower.py

@@ -2,9 +2,9 @@
 from math import ceil
 from random import uniform
 
-from secret_trading_tools import tradables_except_kollar, flip_a_coin, cheapest_buy_order, best_sell_order, \
-    some_orders_on, buy, sell, old_order_is_expired, delete_order_on, \
-    transactions_size_since_last_order_on, order_on
+from secret_trading_tools import tradables_except_kollar, best_buy_order, cheapest_sell_order, \
+    some_orders_on, buy, sell, old_order_is_just_expired, delete_order_on, \
+    transactions_size_since_last_order_on, order_on, own_money, owned_amount, some_order_has_just_been_executed
 
 
 def follower():
@@ -16,32 +16,35 @@ def follower():
 
     while True:
         for tradable in tradables_except_kollar:
-            if old_order_is_expired(tradable):
+            if old_order_is_just_expired(tradable):
                 create_order_on(tradable)
 
-            if transactions_size_since_last_order_on(tradable) > 2 * order_on(tradable).amount:
-                delete_order_on(tradable)
-                create_order_on(tradable)
+            if some_order_has_just_been_executed(tradable):
+                if transactions_size_since_last_order_on(tradable) > 2 * order_on(tradable).amount:
+                    delete_order_on(tradable)
+                    create_order_on(tradable)
 
 
 def create_order_on(tradable):
     """
     This function places a new order on the given tradable
     """
-    limit = uniform(cheapest_buy_order, best_sell_order)
+    limit = uniform(best_buy_order, cheapest_sell_order)
 
     duration = 43200
 
-    some_orders = some_orders_on(tradable)  # returns us roughly math.log2(x) orders where x is the total # of orders
+    some_orders = some_orders_on(tradable)  # returns us roughly log2(x) orders where x is the total # of orders
     some_amounts = [order.amount for order in some_orders]
     amount = ceil(sum(some_amounts) / len(some_amounts))
 
     stop_loss = False
 
-    if flip_a_coin() == 'heads':
-        buy(tradable, amount, limit, stop_loss, duration)
+    if limit - best_buy_order < cheapest_sell_order - limit:
+        if limit * amount < own_money:
+            buy(tradable, amount, limit, stop_loss, duration)
     else:
-        sell(tradable, amount, limit, stop_loss, duration)
+        if amount < owned_amount(tradable):
+            sell(tradable, amount, limit, stop_loss, duration)
 
 
 if __name__ == '__main__':

+ 37 - 24
trading_bot.py

@@ -4,8 +4,7 @@ from math import log2, ceil
 
 import model
 from debug import debug
-
-order_expiry = 43200
+from game import DEFAULT_ORDER_EXPIRY
 
 
 def place_order(ownable_id):
@@ -14,24 +13,33 @@ def place_order(ownable_id):
     :param ownable_id: on which ownable to place the order
     :return: True iff a new order was placed
     """
-    cheapest_buy_order, best_sell_order = model.abs_spread(ownable_id)
-    if cheapest_buy_order is None or best_sell_order is None:
+    best_buy_order, cheapest_sell_order = model.abs_spread(ownable_id)
+    if best_buy_order is None or cheapest_sell_order is None:
         return False
     investors_id = model.bank_id()
 
     orders = model.get_ownable_orders(investors_id, ownable_id)
     orders = [random.choice(orders) for _ in range(int(ceil(log2(len(orders)))))]
     amounts = [order[3] for order in orders]
-    amount = sum(amounts) / len(amounts)
-
-    expiry = datetime.strptime(model.current_db_time(), '%Y-%m-%d %H:%M:%S') + timedelta(minutes=order_expiry)
-
-    model.place_order(buy=bool(random.getrandbits(1)),
-                      ownership_id=model.get_ownership_id(ownable_id, investors_id),
-                      limit=random.uniform(cheapest_buy_order, best_sell_order),
-                      stop_loss=False,
-                      amount=amount,
-                      expiry=expiry)
+    amount = ceil(sum(amounts) / len(amounts))
+
+    expiry = datetime.strptime(model.current_db_time(), '%Y-%m-%d %H:%M:%S') + timedelta(minutes=DEFAULT_ORDER_EXPIRY)
+
+    limit = random.uniform(best_buy_order, cheapest_sell_order)
+    if limit - best_buy_order < cheapest_sell_order - limit:
+        model.place_order(buy=True,
+                          ownership_id=model.get_ownership_id(ownable_id, investors_id),
+                          limit=limit,
+                          stop_loss=False,
+                          amount=amount,
+                          expiry=expiry)
+    else:
+        model.place_order(buy=False,
+                          ownership_id=model.get_ownership_id(ownable_id, investors_id),
+                          limit=limit,
+                          stop_loss=False,
+                          amount=amount,
+                          expiry=expiry)
     return True
 
 
@@ -88,24 +96,28 @@ def notify_order_traded(ownable_id):
             raise AssertionError('The bot should have at most one order.')
 
     model.cursor.execute('''
-        SELECT rowid, amount, expiry
+        SELECT rowid, ordered_amount, expiry_dt
         FROM orders 
         WHERE ownership_id = ? 
-         -- no need for ORDER since the bot should have only one order
-         -- ORDER BY rowid DESC -- equivalent to ordering by time created
-         -- LIMIT might still improve performance
+        -- no need for ORDER since the bot should have only one order
+        UNION ALL
+        SELECT * FROM (
+            SELECT NULL, ordered_amount, expiry_dt
+            FROM order_history
+            ORDER BY rowid DESC -- equivalent to ordering by time created
+        )
         LIMIT 1
     ''', (ownership_id,))
-    data = model.cursor.fechtall()
-    # TODO Neu überdenken, das geht so nicht, wenn die order schon ausgeführt ist, ist sie nicht mehr in der DB
+    data = model.cursor.fetchall()
     if not data:
         return place_order(ownable_id)
 
-    my_last_order = model.cursor.fechtone()
+    my_last_order = data[0]
+    last_order_open = my_last_order[0] is None
     last_order_id = my_last_order[0]
     last_amount = my_last_order[1]
     expiry = my_last_order[2]
-    dt_order_placed = datetime.strptime(expiry, '%Y-%m-%d %H:%M:%S') - timedelta(minutes=order_expiry)
+    dt_order_placed = datetime.strptime(expiry, '%Y-%m-%d %H:%M:%S') - timedelta(minutes=DEFAULT_ORDER_EXPIRY)
 
     model.cursor.execute('''
         SELECT 2 * SUM(amount) >= ?
@@ -114,8 +126,9 @@ def notify_order_traded(ownable_id):
           AND dt >= ?
     ''', (last_amount, ownable_id, dt_order_placed))
 
-    if model.cursor.fechtone()[0]:
-        model.delete_order(last_order_id, 'Canceled')
+    if model.cursor.fetchone()[0]:
+        if last_order_open:
+            model.delete_order(last_order_id, 'Canceled')
         return place_order(ownable_id)
 
     return False