]> git.immae.eu Git - perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Trader.git/blobdiff - main.py
Merge branch 'dev'
[perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Trader.git] / main.py
diff --git a/main.py b/main.py
index 856d449fc16cf94263c81ad45b11bcb406a12ce0..a7ad8f73db8e3983171b9727a9e0e898915c7b5b 100644 (file)
--- a/main.py
+++ b/main.py
@@ -1,7 +1,5 @@
-from datetime import datetime
-import argparse
-import configparser
-import psycopg2
+import configargparse
+import dbs
 import os
 import sys
 
@@ -61,47 +59,56 @@ def make_order(market, value, currency, action="acquire",
     market.report.log_stage("make_order_end")
 
 def get_user_market(config_path, user_id, debug=False):
-    pg_config, report_path = parse_config(config_path)
-    market_config = list(fetch_markets(pg_config, str(user_id)))[0][0]
-    return market.Market.from_config(market_config, debug=debug)
+    args = ["--config", config_path]
+    if debug:
+        args.append("--debug")
+    args = parse_args(args)
+    parse_config(args)
+    market_id, market_config, user_id, options = list(fetch_markets(str(user_id)))[0]
+    return market.Market.from_config(market_config, args, user_id=user_id, options=options)
 
-def fetch_markets(pg_config, user):
-    connection = psycopg2.connect(**pg_config)
-    cursor = connection.cursor()
+def fetch_markets(user):
+    cursor = dbs.psql.cursor()
 
     if user is None:
-        cursor.execute("SELECT config,user_id FROM market_configs")
+        cursor.execute("SELECT id,config,user_id,portfolio_profile FROM market_configs_augmented WHERE status='enabled'")
     else:
-        cursor.execute("SELECT config,user_id FROM market_configs WHERE user_id = %s", user)
+        cursor.execute("SELECT id,config,user_id,portfolio_profile FROM market_configs_augmented WHERE status='enabled' AND user_id = %s", [user])
 
     for row in cursor:
-        yield row
-
-def parse_config(config_file):
-    config = configparser.ConfigParser()
-    config.read(config_file)
+        options = {
+                "liquidity": parse_liquidity(row[3])
+                }
+        yield row[0:3] + (options,)
+
+def parse_liquidity(value):
+    if value == "high-liquidity":
+        return "high"
+    elif value == "medium-liquidity":
+        return "medium"
+    else:
+        return None
 
-    if "postgresql" not in config:
-        print("no configuration for postgresql in config file")
-        sys.exit(1)
+def parse_config(args):
+    if args.db_host is not None:
+        dbs.connect_psql(args)
 
-    if "app" in config and "report_path" in config["app"]:
-        report_path = config["app"]["report_path"]
+    if args.redis_host is not None:
+        dbs.connect_redis(args)
 
-        if not os.path.exists(report_path):
-            os.makedirs(report_path)
-    else:
-        report_path = None
+    report_path = args.report_path
 
-    return [config["postgresql"], report_path]
+    if report_path is not None and not \
+            os.path.exists(report_path):
+        os.makedirs(report_path)
 
 def parse_args(argv):
-    parser = argparse.ArgumentParser(
-            description="Run the trade bot")
+    parser = configargparse.ArgumentParser(
+            description="Run the trade bot.")
 
     parser.add_argument("-c", "--config",
             default="config.ini",
-            required=False,
+            required=False, is_config_file=True,
             help="Config file to load (default: config.ini)")
     parser.add_argument("--before",
             default=False, action='store_const', const=True,
@@ -109,6 +116,9 @@ def parse_args(argv):
     parser.add_argument("--after",
             default=False, action='store_const', const=True,
             help="Run the steps after the cryptoportfolio update")
+    parser.add_argument("--quiet",
+            default=False, action='store_const', const=True,
+            help="Don't print messages")
     parser.add_argument("--debug",
             default=False, action='store_const', const=True,
             help="Run in debug mode")
@@ -119,19 +129,45 @@ def parse_args(argv):
             help="Do a different action than trading (add several times to chain)")
     parser.add_argument("--parallel", action='store_true', default=True, dest="parallel")
     parser.add_argument("--no-parallel", action='store_false', dest="parallel")
-
-    args = parser.parse_args(argv)
-
-    if not os.path.exists(args.config):
-        print("no config file found, exiting")
-        sys.exit(1)
-
-    return args
-
-def process(market_config, user_id, report_path, args):
+    parser.add_argument("--report-db", action='store_true', default=True, dest="report_db",
+            help="Store report to database (default)")
+    parser.add_argument("--no-report-db", action='store_false', dest="report_db",
+            help="Don't store report to database")
+    parser.add_argument("--report-redis", action='store_true', default=False, dest="report_redis",
+            help="Store report to redis")
+    parser.add_argument("--no-report-redis", action='store_false', dest="report_redis",
+            help="Don't store report to redis (default)")
+    parser.add_argument("--report-path", required=False,
+            help="Where to store the reports (default: absent, don't store)")
+    parser.add_argument("--no-report-path", action='store_const', dest='report_path', const=None,
+            help="Don't store the report to file (default)")
+    parser.add_argument("--db-host", default="localhost",
+            help="Host access to database (default: localhost)")
+    parser.add_argument("--db-port", default=5432,
+            help="Port access to database (default: 5432)")
+    parser.add_argument("--db-user", default="cryptoportfolio",
+            help="User access to database (default: cryptoportfolio)")
+    parser.add_argument("--db-password", default="cryptoportfolio",
+            help="Password access to database (default: cryptoportfolio)")
+    parser.add_argument("--db-database", default="cryptoportfolio",
+            help="Database access to database (default: cryptoportfolio)")
+    parser.add_argument("--redis-host", default="localhost",
+            help="Host access to database (default: localhost). Use path for socket")
+    parser.add_argument("--redis-port", default=6379,
+            help="Port access to redis (default: 6379)")
+    parser.add_argument("--redis-database", default=0,
+            help="Redis database to use (default: 0)")
+
+    parsed = parser.parse_args(argv)
+    if parsed.action is None:
+        parsed.action = ["sell_all"]
+    return parsed
+
+def process(market_config, market_id, user_id, args, options):
     try:
         market.Market\
-                .from_config(market_config, debug=args.debug, user_id=user_id, report_path=report_path)\
+                .from_config(market_config, args, market_id=market_id,
+                        user_id=user_id, options=options)\
                 .process(args.action, before=args.before, after=args.after)
     except Exception as e:
         print("{}: {}".format(e.__class__.__name__, e))
@@ -139,17 +175,29 @@ def process(market_config, user_id, report_path, args):
 def main(argv):
     args = parse_args(argv)
 
-    pg_config, report_path = parse_config(args.config)
+    parse_config(args)
+
+    market.Portfolio.report.set_verbose(not args.quiet)
 
     if args.parallel:
         import threading
         market.Portfolio.start_worker()
 
-        for market_config, user_id in fetch_markets(pg_config, args.user):
-            threading.Thread(target=process, args=[market_config, user_id, report_path, args]).start()
+        threads = []
+        def process_(*args):
+            thread = threading.Thread(target=process, args=args)
+            thread.start()
+            threads.append(thread)
     else:
-        for market_config, user_id in fetch_markets(pg_config, args.user):
-            process(market_config, user_id, report_path, args)
+        process_ = process
+
+    for market_id, market_config, user_id, options in fetch_markets(args.user):
+        process_(market_config, market_id, user_id, args, options)
+
+    if args.parallel:
+        for thread in threads:
+            thread.join()
+        market.Portfolio.stop_worker()
 
 if __name__ == '__main__': # pragma: no cover
     main(sys.argv[1:])