Exemple #1
0
class TestCompareArbitrage(unittest.TestCase):
    def setUp(self):
        self.arbitrer = Arbitrer()
        self.arbitrerNG = ArbitrerNG()

        bs = BitstampUSD()
        bs_file = open('bitstamp_data.json', 'r')
        bs_depth = json.loads(bs_file.read())
        bs_file.close()
        self.bs_data = bs.format_depth(bs_depth)

        cbx = CampBXUSD()
        cbx_file = open('cbx_data.json', 'r')
        cbx_depth = json.loads(cbx_file.read())
        cbx_file.close()
        self.cbx_data = cbx.format_depth(cbx_depth)

        mt = MtGoxUSD()
        mt_file = open('mtgox_data.json', 'r')
        mt_depth = json.loads(mt_file.read())["data"]
        mt_file.close()
        self.mt_data = mt.format_depth(mt_depth)

    def test_compare_arbitrage_depth_opportunity_1(self):
        self.arbitrer.depths = {'AAA': self.bs_data, 'BBB': self.cbx_data}
        self.arbitrerNG.depths = {'AAA': self.bs_data, 'BBB': self.cbx_data}
        self._do_compare()

    def test_compare_arbitrage_depth_opportunity_2(self):
        self.arbitrer.depths = {'AAA': self.bs_data, 'BBB': self.mt_data}
        self.arbitrerNG.depths = {'AAA': self.bs_data, 'BBB': self.mt_data}
        self._do_compare()

    def test_compare_arbitrage_depth_opportunity_3(self):
        self.arbitrer.depths = {'AAA': self.cbx_data, 'BBB': self.mt_data}
        self.arbitrerNG.depths = {'AAA': self.cbx_data, 'BBB': self.mt_data}
        self._do_compare()

    def _do_compare(self):
        print(
            "profit, volume, buyprice, sellprice, weighted_buyprice, weighted_sellprice"
        )

        T1 = self.arbitrer.arbitrage_depth_opportunity('AAA', 'BBB')
        val1 = [v for v in T1]
        print(','.join(str(v) for v in T1))
        T2 = self.arbitrerNG.arbitrage_depth_opportunity('AAA', 'BBB', 10)
        val2 = [v for v in T2]
        print(','.join(str(v) for v in T2))

        # les tuples marchent pas bien avec les assert quand ils sont KO... à creuser
        # pb lié au plugin 'nose manager'
        # assert T1 == T2
        for (a, b) in zip(val1, val2):
            assert a == b

        T = self.arbitrer.arbitrage_depth_opportunity('BBB', 'AAA')
        print(','.join(str(v) for v in T))
        T = self.arbitrerNG.arbitrage_depth_opportunity('BBB', 'AAA', 10)
        print(','.join(str(v) for v in T))
class TestCompareArbitrage(unittest.TestCase):
    def setUp(self):
        self.arbitrer = Arbitrer()
        self.arbitrerNG = ArbitrerNG()

        bs = BitstampUSD()
        bs_file = open('bitstamp_data.json', 'r')
        bs_depth = json.loads(bs_file.read())
        bs_file.close()
        self.bs_data = bs.format_depth(bs_depth)

        cbx = CampBXUSD()
        cbx_file = open('cbx_data.json', 'r')
        cbx_depth = json.loads(cbx_file.read())
        cbx_file.close()
        self.cbx_data = cbx.format_depth(cbx_depth)

        mt = MtGoxUSD()
        mt_file = open('mtgox_data.json', 'r')
        mt_depth = json.loads(mt_file.read())["data"]
        mt_file.close()
        self.mt_data = mt.format_depth(mt_depth)


    def test_compare_arbitrage_depth_opportunity_1(self):
        self.arbitrer.depths = {'AAA': self.bs_data, 'BBB': self.cbx_data}
        self.arbitrerNG.depths = {'AAA': self.bs_data, 'BBB': self.cbx_data}
        self._do_compare()

    def test_compare_arbitrage_depth_opportunity_2(self):
        self.arbitrer.depths = {'AAA': self.bs_data, 'BBB': self.mt_data}
        self.arbitrerNG.depths = {'AAA': self.bs_data, 'BBB': self.mt_data}
        self._do_compare()

    def test_compare_arbitrage_depth_opportunity_3(self):
        self.arbitrer.depths = {'AAA': self.cbx_data, 'BBB': self.mt_data}
        self.arbitrerNG.depths = {'AAA': self.cbx_data, 'BBB': self.mt_data}
        self._do_compare()


    def _do_compare(self):
        print("profit, volume, buyprice, sellprice, weighted_buyprice, weighted_sellprice")

        T1 = self.arbitrer.arbitrage_depth_opportunity('AAA', 'BBB')
        val1 = [v for v in T1]
        print(','.join(str(v) for v in T1))
        T2 = self.arbitrerNG.arbitrage_depth_opportunity('AAA', 'BBB', 10)
        val2 = [v for v in T2]
        print(','.join(str(v) for v in T2))

        # les tuples marchent pas bien avec les assert quand ils sont KO... à creuser
        # pb lié au plugin 'nose manager'
        # assert T1 == T2
        for (a, b) in zip(val1, val2):
            assert a == b

        T = self.arbitrer.arbitrage_depth_opportunity('BBB', 'AAA')
        print(','.join(str(v) for v in T))
        T = self.arbitrerNG.arbitrage_depth_opportunity('BBB', 'AAA', 10)
        print(','.join(str(v) for v in T))
 def create_arbitrer(self, args):
     self.arbitrer = Arbitrer()
     if args.observers:
         self.arbitrer.init_observers(args.observers.split(","))
     if args.markets:
         self.arbitrer.init_markets(args.markets.split(","))
     return self.arbitrer
Exemple #4
0
 def create_arbitrer(self, args):
     logging.info("creating")
     self.arbitrer = Arbitrer()
     if args.observers:
         self.arbitrer.init_observers(args.observers.split(","))
     if args.markets:
         self.arbitrer.init_markets(args.markets.split(","))
def main():
    arbitrer = Arbitrer()
    depths = arbitrer.depths = json.load(open("speed-test.json"))
    print('start test')
    start_time = time.time()
    testobs = TestObserver()
    arbitrer.observers = [testobs]
    arbitrer.arbitrage_opportunity("BitstampUSD",
                                   depths["BitstampUSD"]["asks"][0],
                                   "KrakenEUR", depths["KrakenEUR"]["asks"][0])
    print('end test')
    # FIXME: add asserts
    elapsed = time.time() - start_time
    print("Time: %.3f" % elapsed)
Exemple #6
0
    def setUp(self):
        self.arbitrer = Arbitrer()
        self.arbitrerNG = ArbitrerNG()

        bs = BitstampUSD()
        bs_file = open('bitstamp_data.json', 'r')
        bs_depth = json.loads(bs_file.read())
        bs_file.close()
        self.bs_data = bs.format_depth(bs_depth)

        cbx = CampBXUSD()
        cbx_file = open('cbx_data.json', 'r')
        cbx_depth = json.loads(cbx_file.read())
        cbx_file.close()
        self.cbx_data = cbx.format_depth(cbx_depth)

        mt = MtGoxUSD()
        mt_file = open('mtgox_data.json', 'r')
        mt_depth = json.loads(mt_file.read())["data"]
        mt_file.close()
        self.mt_data = mt.format_depth(mt_depth)
class TestArbitrage(unittest.TestCase):
    def setUp(self):
        self.arbitrer = Arbitrer()

    def test_getprofit1(self):
        self.arbitrer.depths = depths2
        profit, vol, wb, ws = self.arbitrer.get_profit_for(
            0, 0, 'BitcoinCentralEUR', 'MtGoxEUR')
        assert (80 == int(profit * 100))
        assert (vol == 2)

    def test_getprofit2(self):
        self.arbitrer.depths = depths2
        profit, vol, wb, ws = self.arbitrer.get_profit_for(
            2, 1, 'BitcoinCentralEUR', 'MtGoxEUR')
        assert (159 == int(profit * 100))
        assert (vol == 5)

    def test_getprofit3(self):
        self.arbitrer.depths = depths3
        profit, vol, wb, ws = self.arbitrer.get_profit_for(
            2, 1, 'BitcoinCentralEUR', 'MtGoxEUR')
        assert (profit == 0)
        assert (vol == 0)
class TestArbitrage(unittest.TestCase):
    def setUp(self):
        self.arbitrer = Arbitrer()

    def test_getprofit1(self):
        self.arbitrer.depths = depths2
        profit, vol, wb, ws = self.arbitrer.get_profit_for(
            0, 0, 'BitcoinCentralEUR', 'MtGoxEUR')
        assert (80 == int(profit * 100))
        assert (vol == 2)

    def test_getprofit2(self):
        self.arbitrer.depths = depths2
        profit, vol, wb, ws = self.arbitrer.get_profit_for(
            2, 1, 'BitcoinCentralEUR', 'MtGoxEUR')
        assert (159 == int(profit * 100))
        assert (vol == 5)

    def test_getprofit3(self):
        self.arbitrer.depths = depths3
        profit, vol, wb, ws = self.arbitrer.get_profit_for(
            2, 1, 'BitcoinCentralEUR', 'MtGoxEUR')
        assert (profit == 0)
        assert (vol == 0)
    def setUp(self):
        self.arbitrer = Arbitrer()
        self.arbitrerNG = ArbitrerNG()

        bs = BitstampUSD()
        bs_file = open('bitstamp_data.json', 'r')
        bs_depth = json.loads(bs_file.read())
        bs_file.close()
        self.bs_data = bs.format_depth(bs_depth)

        cbx = CampBXUSD()
        cbx_file = open('cbx_data.json', 'r')
        cbx_depth = json.loads(cbx_file.read())
        cbx_file.close()
        self.cbx_data = cbx.format_depth(cbx_depth)

        mt = MtGoxUSD()
        mt_file = open('mtgox_data.json', 'r')
        mt_depth = json.loads(mt_file.read())["data"]
        mt_file.close()
        self.mt_data = mt.format_depth(mt_depth)
Exemple #10
0
 def create_arbitrer(self, args):
     self.arbitrer = Arbitrer()
     if args.observers:
         self.arbitrer.init_observers(args.observers.split(","))
     if args.markets:
         self.arbitrer.init_markets(args.markets.split(","))
Exemple #11
0
class ArbitrerCLI:
    def __init__(self):
        self.inject_verbose_info()

    def inject_verbose_info(self):
        logging.VERBOSE = 15
        logging.verbose = lambda x: logging.log(logging.VERBOSE, x)
        logging.addLevelName(logging.VERBOSE, "VERBOSE")

    def exec_command(self, args):
        if "watch" in args.command:
            self.create_arbitrer(args)
            self.arbitrer.loop()
        if "replay-history" in args.command:
            self.create_arbitrer(args)
            self.arbitrer.replay_history(args.replay_history)
        if "get-balance" in args.command:
            self.get_balance(args)
        if "list-public-markets" in args.command:
            self.list_markets()

    def list_markets(self):
        markets = []
        for filename in glob.glob(os.path.join(public_markets.__path__[0], "*.py")):
            module_name = os.path.basename(filename).replace(".py", "")
            if not module_name.startswith("_"):
                module = __import__("arbitrage.public_markets." + module_name)
                test = eval("module.public_markets." + module_name)
                for name, obj in inspect.getmembers(test):
                    if inspect.isclass(obj) and "Market" in (j.__name__ for j in obj.mro()[1:]):
                        if not obj.__module__.split(".")[-1].startswith("_"):
                            markets.append(obj.__name__)
        markets.sort()
        print("\n".join(markets))
        sys.exit(0)

    def get_balance(self, args):
        if not args.markets:
            logging.error("You must use --markets argument to specify markets")
            sys.exit(2)
        pmarkets = args.markets.split(",")
        pmarketsi = []
        for pmarket in pmarkets:
            exec("import arbitrage.private_markets." + pmarket.lower())
            market = eval(
                "arbitrage.private_markets." + pmarket.lower() + ".Private" + pmarket + "()"
            )
            pmarketsi.append(market)
        for market in pmarketsi:
            print(market)

    def create_arbitrer(self, args):
        self.arbitrer = Arbitrer()
        if args.observers:
            self.arbitrer.init_observers(args.observers.split(","))
        if args.markets:
            self.arbitrer.init_markets(args.markets.split(","))

    def init_logger(self, args):
        level = logging.INFO
        if args.verbose:
            level = logging.VERBOSE
        if args.debug:
            level = logging.DEBUG
        logging.basicConfig(format="%(asctime)s [%(levelname)s] %(message)s", level=level)

    def main(self):
        parser = argparse.ArgumentParser()
        parser.add_argument("-d", "--debug", help="debug verbose mode", action="store_true")
        parser.add_argument("-v", "--verbose", help="info verbose mode", action="store_true")
        parser.add_argument(
            "-o", "--observers", type=str, help="observers, example: -oLogger,Emailer"
        )
        parser.add_argument(
            "-m", "--markets", type=str, help="markets, example: -m BitstampEUR,KrakenEUR"
        )
        parser.add_argument(
            "command",
            nargs="*",
            default="watch",
            help='verb: "watch|replay-history|get-balance|list-public-markets"',
        )
        args = parser.parse_args()
        self.init_logger(args)
        self.exec_command(args)
 def setUp(self):
     self.arbitrer = Arbitrer()
 def setUp(self):
     self.arbitrer = Arbitrer()
Exemple #14
0
class ArbitrerCLI:
    def __init__(self):
        self.inject_verbose_info()

    def inject_verbose_info(self):
        logging.VERBOSE = 15
        logging.verbose = lambda x: logging.log(logging.VERBOSE, x)
        logging.addLevelName(logging.VERBOSE, "VERBOSE")

    def exec_command(self, args):
        if "watch" in args.command:
            self.create_arbitrer(args)
            self.arbitrer.loop()
        if "replay-history" in args.command:
            self.create_arbitrer(args)
            self.arbitrer.replay_history(args.replay_history)
        if "get-balance" in args.command:
            self.get_balance(args)
        if "list-public-markets" in args.command:
            self.list_markets()

    def list_markets(self):
        markets = []
        for filename in glob.glob(
                os.path.join(public_markets.__path__[0], "*.py")):
            module_name = os.path.basename(filename).replace('.py', '')
            if not module_name.startswith('_'):
                module = __import__("arbitrage.public_markets." + module_name)
                test = eval('module.public_markets.' + module_name)
                for name, obj in inspect.getmembers(test):
                    if inspect.isclass(obj) and 'Market' in (
                            j.__name__ for j in obj.mro()[1:]):
                        if not obj.__module__.split('.')[-1].startswith('_'):
                            markets.append(obj.__name__)
        markets.sort()
        print("\n".join(markets))
        sys.exit(0)

    def get_balance(self, args):
        if not args.markets:
            logging.error("You must use --markets argument to specify markets")
            sys.exit(2)
        pmarkets = args.markets.split(",")
        pmarketsi = []
        for pmarket in pmarkets:
            exec('import arbitrage.private_markets.' + pmarket.lower())
            market = eval('arbitrage.private_markets.' + pmarket.lower() +
                          '.Private' + pmarket + '()')
            pmarketsi.append(market)
        for market in pmarketsi:
            print(market)

    def create_arbitrer(self, args):
        self.arbitrer = Arbitrer()
        if args.observers:
            self.arbitrer.init_observers(args.observers.split(","))
        if args.markets:
            self.arbitrer.init_markets(args.markets.split(","))

    def init_logger(self, args):
        level = logging.INFO
        if args.verbose:
            level = logging.VERBOSE
        if args.debug:
            level = logging.DEBUG
        logging.basicConfig(format='%(asctime)s [%(levelname)s] %(message)s',
                            level=level)

        if not os.path.exists('tmp'):
            os.makedirs('tmp')
        fh = logging.FileHandler('./tmp/log.txt')
        formatter = logging.Formatter(
            '%(asctime)s [%(levelname)s] %(message)s')
        fh.setFormatter(formatter)
        logging.getLogger('').addHandler(fh)

    def main(self):
        parser = argparse.ArgumentParser()
        parser.add_argument("-d",
                            "--debug",
                            help="debug verbose mode",
                            action="store_true")
        parser.add_argument("-v",
                            "--verbose",
                            help="info verbose mode",
                            action="store_true")
        parser.add_argument("-o",
                            "--observers",
                            type=str,
                            help="observers, example: -oLogger,Emailer")
        parser.add_argument("-m",
                            "--markets",
                            type=str,
                            help="markets, example: -m BitstampEUR,KrakenEUR")
        parser.add_argument(
            "command",
            nargs='*',
            default="watch",
            help='verb: "watch|replay-history|get-balance|list-public-markets"'
        )
        args = parser.parse_args()
        self.init_logger(args)
        try:
            send_message("Arbitrage Started!")
            self.exec_command(args)
        except Exception as e:
            s = traceback.format_exc()
            logging.info(e)
            logging.error(s)
            send_message("Exception: " + str(e))
class ArbitrerCLI:
    def __init__(self):
        self.inject_verbose_info()

    def inject_verbose_info(self):
        logging.VERBOSE = 15
        logging.verbose = lambda x: logging.log(logging.VERBOSE, x)
        logging.addLevelName(logging.VERBOSE, "VERBOSE")

    def exec_command(self, args):
        if "watch" in args.command:
            self.create_arbitrer(args).loop()
        if "replay-history" in args.command:
            self.create_arbitrer(args)
            self.arbitrer.replay_history(args.replay_history)
        if "get-balance" in args.command:
            self.get_balance(args)
        if "list-public-markets" in args.command:
            self.list_markets()
        if "compare-depths" in args.command:
            self.compare_depths(args)
        if "generate-config" in args.command:
            self.generate_sample_config()

    def compare_depths(self, args):
        if not args.exchanges:
            logging.error(
                "You must use --exchanges argument to specify exchanges")
            sys.exit(2)
        pexchanges = args.exchanges.split(",")
        pexchangei = []
        for pexchange in pexchanges:
            exec("import arbitrage.public_markets._" + pexchange.lower())

            # FIXME: Fix the following hard-coded USDT and btc_usdt
            market = eval("arbitrage.public_markets._" + pexchange.lower() +
                          "." + pexchange +
                          "('USDT','btc_usdt').update_depth().depth_1pct()")
            pexchangei.append(('1%', pexchange, market))
            market = eval("arbitrage.public_markets._" + pexchange.lower() +
                          "." + pexchange +
                          "('USDT','btc_usdt').update_depth().depth_01pct()")
            pexchangei.append(('0.1%', pexchange, market))

        for market in pexchangei:
            print(market)

        sys.exit(0)

    def get_market_list(self):
        markets = []
        for filename in glob.glob(
                os.path.join(public_markets.__path__[0], "*.py")):
            module_name = os.path.basename(filename).replace(".py", "")
            if not module_name.startswith("_"):
                module = __import__("arbitrage.public_markets." + module_name)
                test = eval("module.public_markets." + module_name)
                for name, obj in inspect.getmembers(test):
                    if inspect.isclass(obj) and "Market" in (
                            j.__name__ for j in obj.mro()[1:]):
                        if not obj.__module__.split(".")[-1].startswith("_"):
                            markets.append(obj.__name__)
        return markets

    def list_markets(self):
        markets = self.get_market_list()
        markets.sort()
        print("\n".join(markets))
        sys.exit(0)

    def generate_sample_config(self):
        markets = self.get_market_list()
        markets.sort()
        print("markets = [")
        print('",\n'.join(['  "' + i for i in markets]) + '"')
        print("]")
        print('observers = ["Logger"]')
        print("""
refresh_rate = 60
market_expiration_time = 120  # in seconds: 2 minutes

# SafeGuards
max_tx_volume = 1  # in BTC
min_tx_volume = 0.01  # in BTC
balance_margin = 0.05  # 5%
profit_thresh = 0  # in USD
perc_thresh = 0  # in %""")
        sys.exit(0)

    def get_balance(self, args):
        if not args.markets:
            logging.error("You must use --markets argument to specify markets")
            sys.exit(2)
        pmarkets = args.markets.split(",")
        pmarketsi = []
        for pmarket in pmarkets:
            exec("import arbitrage.private_markets." + pmarket.lower())
            market = eval("arbitrage.private_markets." + pmarket.lower() +
                          ".Private" + pmarket + "()")
            pmarketsi.append(market)
        for market in pmarketsi:
            print(market)

    def create_arbitrer(self, args):
        self.arbitrer = Arbitrer()
        if args.observers:
            self.arbitrer.init_observers(args.observers.split(","))
        if args.markets:
            self.arbitrer.init_markets(args.markets.split(","))
        return self.arbitrer

    def init_logger(self, args):
        level = logging.INFO
        if args.verbose:
            level = logging.VERBOSE
        if args.debug:
            level = logging.DEBUG
        logging.basicConfig(format="%(asctime)s [%(levelname)s] %(message)s",
                            level=level)

    def main(self):
        parser = argparse.ArgumentParser()
        parser.add_argument("-d",
                            "--debug",
                            help="debug verbose mode",
                            action="store_true")
        parser.add_argument("-v",
                            "--verbose",
                            help="info verbose mode",
                            action="store_true")
        parser.add_argument("-o",
                            "--observers",
                            type=str,
                            help="observers, example: -oLogger,Emailer")
        parser.add_argument("-m",
                            "--markets",
                            type=str,
                            help="markets, example: -m BitstampEUR,KrakenEUR")
        parser.add_argument("-e",
                            "--exchanges",
                            type=str,
                            help="exchanges, example: -e OKCoin")
        parser.add_argument(
            "command",
            nargs="*",
            default="watch",
            help=
            'verb: "watch|replay-history|get-balance|list-public-markets|compare-depths"',
        )
        args = parser.parse_args()
        self.init_logger(args)
        self.exec_command(args)
Exemple #16
0
class ArbitrerCLI:
    def __init__(self):
        self.inject_verbose_info()

    def inject_verbose_info(self):
        logging.VERBOSE = 15
        logging.verbose = lambda x: logging.log(logging.VERBOSE, x)
        logging.addLevelName(logging.VERBOSE, "VERBOSE")

    def exec_command(self, args):
        if "watch" in args.command:
            self.create_arbitrer(args)
            self.arbitrer.loop()
        if "replay-history" in args.command:
            self.create_arbitrer(args)
            self.arbitrer.replay_history(args.replay_history)
        if "get-balance" in args.command:
            self.get_balance(args)
        if "list-public-markets" in args.command:
            self.list_markets()

    def list_markets(self):
        markets = []
        for filename in glob.glob(
                os.path.join(public_markets.__path__[0], "*.py")):
            module_name = os.path.basename(filename).replace('.py', '')
            if not module_name.startswith('_'):
                module = __import__("arbitrage.public_markets." + module_name)
                test = eval('module.public_markets.' + module_name)
                for name, obj in inspect.getmembers(test):
                    if inspect.isclass(obj) and 'Market' in (
                            j.__name__ for j in obj.mro()[1:]):
                        if not obj.__module__.split('.')[-1].startswith('_'):
                            markets.append(obj.__name__)
        markets.sort()
        print("\n".join(markets))
        sys.exit(0)

    def get_balance(self, args):
        if not args.markets:
            logging.error("You must use --markets argument to specify markets")
            sys.exit(2)
        pmarkets = args.markets.split(",")
        pmarketsi = []
        for pmarket in pmarkets:
            exec('import arbitrage.private_markets.' + pmarket.lower())
            market = eval('arbitrage.private_markets.' + pmarket.lower() +
                          '.Private' + pmarket + '()')
            pmarketsi.append(market)
        for market in pmarketsi:
            print(market)

    def create_arbitrer(self, args):
        logging.info("creating")
        self.arbitrer = Arbitrer()
        if args.observers:
            self.arbitrer.init_observers(args.observers.split(","))
        if args.markets:
            self.arbitrer.init_markets(args.markets.split(","))

    def init_logger(self, args):
        level = logging.INFO
        if args.verbose:
            level = logging.VERBOSE
        if args.debug:
            level = logging.DEBUG

        file = "log/%s.log" % config.profit_thresh
        os.makedirs(os.path.dirname(file), exist_ok=True)
        logging.basicConfig(format='%(asctime)s [%(levelname)s] %(message)s',
                            filename=file,
                            filemode='a',
                            level=level)

    def init_config(self, args):
        if args.profit:
            config.profit_thresh = args.profit

    def main(self):
        parser = argparse.ArgumentParser()
        parser.add_argument("-d",
                            "--debug",
                            help="debug verbose mode",
                            action="store_true")
        parser.add_argument("-v",
                            "--verbose",
                            help="info verbose mode",
                            action="store_true")
        parser.add_argument("-o",
                            "--observers",
                            type=str,
                            help="observers, example: -oLogger,Emailer")
        parser.add_argument("-p",
                            "--profit",
                            type=int,
                            help="profit, example for 20USD: -p20")
        parser.add_argument("-m",
                            "--markets",
                            type=str,
                            help="markets, example: -mMtGox,Bitstamp")
        parser.add_argument(
            "command",
            nargs='*',
            default="watch",
            help='verb: "watch|replay-history|get-balance|list-public-markets"'
        )
        args = parser.parse_args()
        self.init_config(args)
        self.init_logger(args)
        self.exec_command(args)