]> git.immae.eu Git - perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Trader.git/blobdiff - market.py
Include current portfolio currencies when printing balances
[perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Trader.git] / market.py
index ce0c48cddb67597845e3e979eb8b373300037866..5876071875750df01a1d658698216b2c30670bb0 100644 (file)
--- a/market.py
+++ b/market.py
@@ -1,8 +1,7 @@
 from ccxt import ExchangeError, NotSupported, RequestTimeout, InvalidNonce
 import ccxt_wrapper as ccxt
 import time
-import psycopg2
-import redis
+import dbs
 from store import *
 from cachetools.func import ttl_cache
 from datetime import datetime
@@ -27,7 +26,7 @@ class Market:
         self.balances = BalanceStore(self)
         self.processor = Processor(self)
 
-        for key in ["user_id", "market_id", "pg_config", "redis_config"]:
+        for key in ["user_id", "market_id"]:
             setattr(self, key, kwargs.get(key, None))
 
         self.report.log_market(self.args)
@@ -45,9 +44,9 @@ class Market:
         date = datetime.datetime.now()
         if self.args.report_path is not None:
             self.store_file_report(date)
-        if self.pg_config is not None and self.args.report_db:
+        if dbs.psql_connected() and self.args.report_db:
             self.store_database_report(date)
-        if self.redis_config is not None and self.args.report_redis:
+        if dbs.redis_connected() and self.args.report_redis:
             self.store_redis_report(date)
 
     def store_file_report(self, date):
@@ -64,27 +63,26 @@ class Market:
         try:
             report_query = 'INSERT INTO reports("date", "market_config_id", "debug") VALUES (%s, %s, %s) RETURNING id;'
             line_query = 'INSERT INTO report_lines("date", "report_id", "type", "payload") VALUES (%s, %s, %s, %s);'
-            connection = psycopg2.connect(**self.pg_config)
-            cursor = connection.cursor()
+            cursor = dbs.psql.cursor()
             cursor.execute(report_query, (date, self.market_id, self.debug))
             report_id = cursor.fetchone()[0]
             for date, type_, payload in self.report.to_json_array():
                 cursor.execute(line_query, (date, report_id, type_, payload))
 
-            connection.commit()
+            dbs.psql.commit()
             cursor.close()
-            connection.close()
         except Exception as e:
             print("impossible to store report to database: {}; {}".format(e.__class__.__name__, e))
 
     def store_redis_report(self, date):
         try:
-            conn = redis.Redis(**self.redis_config)
             for type_, log in self.report.to_json_redis():
                 key = "/cryptoportfolio/{}/{}/{}".format(self.market_id, date.isoformat(), type_)
-                conn.set(key, log, ex=31*24*60*60)
+                dbs.redis.set(key, log, ex=31*24*60*60)
                 key = "/cryptoportfolio/{}/latest/{}".format(self.market_id, type_)
-                conn.set(key, log)
+                dbs.redis.set(key, log)
+            key = "/cryptoportfolio/{}/latest/date".format(self.market_id)
+            dbs.redis.set(key, date.isoformat())
         except Exception as e:
             print("impossible to store report to redis: {}; {}".format(e.__class__.__name__, e))
 
@@ -208,18 +206,32 @@ class Market:
         self.report.log_stage("follow_orders_end")
 
     def prepare_trades(self, base_currency="BTC", liquidity="medium",
-            compute_value="average", repartition=None, only=None):
+            compute_value="average", repartition=None, only=None,
+            available_balance_only=False):
 
         self.report.log_stage("prepare_trades",
                 base_currency=base_currency, liquidity=liquidity,
                 compute_value=compute_value, only=only,
-                repartition=repartition)
+                repartition=repartition, available_balance_only=available_balance_only)
 
         values_in_base = self.balances.in_currency(base_currency,
                 compute_value=compute_value)
-        total_base_value = sum(values_in_base.values())
+        if available_balance_only:
+            balance = self.balances.all.get(base_currency)
+            if balance is None:
+                total_base_value = portfolio.Amount(base_currency, 0)
+            else:
+                total_base_value = balance.exchange_free + balance.margin_available
+        else:
+            total_base_value = sum(values_in_base.values())
         new_repartition = self.balances.dispatch_assets(total_base_value,
                 liquidity=liquidity, repartition=repartition)
+        if available_balance_only:
+            for currency, amount in values_in_base.items():
+                if currency != base_currency:
+                    new_repartition.setdefault(currency, portfolio.Amount(base_currency, 0))
+                    new_repartition[currency] += amount
+
         self.trades.compute_trades(values_in_base, new_repartition, only=only)
 
     def print_tickers(self, base_currency="BTC"):
@@ -243,6 +255,7 @@ class Processor:
                     "name": "print_balances",
                     "number": 1,
                     "fetch_balances": ["begin"],
+                    "fetch_balances_args": { "add_portfolio": True },
                     "print_tickers": { "base_currency": "BTC" },
                     }
                 ],
@@ -290,7 +303,7 @@ class Processor:
                     "before": False,
                     "after": True,
                     "fetch_balances": ["begin", "end"],
-                    "prepare_trades": { "only": "acquire" },
+                    "prepare_trades": { "only": "acquire", "available_balance_only": True },
                     "prepare_orders": { "only": "acquire", "compute_value": "average" },
                     "move_balances": {},
                     "run_orders": {},
@@ -324,7 +337,7 @@ class Processor:
                     "before": False,
                     "after": True,
                     "fetch_balances": ["begin", "end"],
-                    "prepare_trades": {},
+                    "prepare_trades": { "available_balance_only": True },
                     "prepare_orders": { "compute_value": "average" },
                     "move_balances": {},
                     "run_orders": {},
@@ -374,15 +387,19 @@ class Processor:
     def process_step(self, scenario_name, step, kwargs):
         process_name = "process_{}__{}_{}".format(scenario_name, step["number"], step["name"])
         self.market.report.log_stage("{}_begin".format(process_name))
+
+        fetch_args = step.get("fetch_balances_args", {})
         if "begin" in step.get("fetch_balances", []):
-            self.market.balances.fetch_balances(tag="{}_begin".format(process_name))
+            self.market.balances.fetch_balances(tag="{}_begin".format(process_name),
+                    log_tickers=True, **fetch_args)
 
         for action in self.ordered_actions:
             if action in step:
                 self.run_action(action, step[action], kwargs)
 
         if "end" in step.get("fetch_balances", []):
-            self.market.balances.fetch_balances(tag="{}_end".format(process_name))
+            self.market.balances.fetch_balances(tag="{}_end".format(process_name),
+                    log_tickers=True, **fetch_args)
         self.market.report.log_stage("{}_end".format(process_name))
 
     def method_arguments(self, action):