From: Ismaƫl Bouya Date: Tue, 1 May 2018 15:35:55 +0000 (+0200) Subject: Merge branch 'dev' X-Git-Tag: v1.5 X-Git-Url: https://git.immae.eu/?p=perso%2FImmae%2FProjets%2FCryptomonnaies%2FCryptoportfolio%2FTrader.git;a=commitdiff_plain;h=9eb0de20f243bb78de0bf9118289f01f1ea1f77c;hp=6cffa4af8b5a04b17ffd95738b8e843c4605d4e7 Merge branch 'dev' --- diff --git a/ccxt_wrapper.py b/ccxt_wrapper.py index d2c9b4c..c4aa94d 100644 --- a/ccxt_wrapper.py +++ b/ccxt_wrapper.py @@ -66,6 +66,13 @@ class poloniexE(poloniex): def nanoseconds(): return int(time.time() * 1000000000) + def is_dust_trade(self, amount, rate): + if abs(amount) < decimal.Decimal("0.000001"): + return True + if abs(amount * rate) < decimal.Decimal("0.0001"): + return True + return False + def fetch_margin_balance(self): """ portfolio.market.privatePostGetMarginPosition({"currencyPair": "BTC_DASH"}) @@ -232,39 +239,9 @@ class poloniexE(poloniex): return all_balances - def create_exchange_order(self, symbol, type, side, amount, price=None, params={}): - return super().create_order(symbol, type, side, amount, price=price, params=params) - - def create_margin_order(self, symbol, type, side, amount, price=None, lending_rate=None, params={}): - if type == 'market': - raise ExchangeError(self.id + ' allows limit orders only') - self.load_markets() - method = 'privatePostMargin' + self.capitalize(side) - market = self.market(symbol) - price = float(price) - amount = float(amount) - if lending_rate is not None: - params = self.extend({"lendingRate": lending_rate}, params) - response = getattr(self, method)(self.extend({ - 'currencyPair': market['id'], - 'rate': self.price_to_precision(symbol, price), - 'amount': self.amount_to_precision(symbol, amount), - }, params)) - timestamp = self.milliseconds() - order = self.parse_order(self.extend({ - 'timestamp': timestamp, - 'status': 'open', - 'type': type, - 'side': side, - 'price': price, - 'amount': amount, - }, response), market) - id = order['id'] - self.orders[id] = order - return self.extend({'info': response}, order) - def order_precision(self, symbol): - return 8 + self.load_markets() + return self.markets[symbol]['precision']['price'] def transfer_balance(self, currency, amount, from_account, to_account): result = self.privatePostTransferBalance({ @@ -382,14 +359,49 @@ class poloniexE(poloniex): def create_order(self, symbol, type, side, amount, price=None, account="exchange", lending_rate=None, params={}): """ - Wrapped to handle margin and exchange accounts + Wrapped to handle margin and exchange accounts, and get decimals """ + if type == 'market': + raise ExchangeError(self.id + ' allows limit orders only') + self.load_markets() if account == "exchange": - return self.create_exchange_order(symbol, type, side, amount, price=price, params=params) + method = 'privatePost' + self.capitalize(side) elif account == "margin": - return self.create_margin_order(symbol, type, side, amount, price=price, lending_rate=lending_rate, params=params) + method = 'privatePostMargin' + self.capitalize(side) + if lending_rate is not None: + params = self.extend({"lendingRate": lending_rate}, params) else: raise NotImplementedError + market = self.market(symbol) + response = getattr(self, method)(self.extend({ + 'currencyPair': market['id'], + 'rate': self.price_to_precision(symbol, price), + 'amount': self.amount_to_precision(symbol, amount), + }, params)) + timestamp = self.milliseconds() + order = self.parse_order(self.extend({ + 'timestamp': timestamp, + 'status': 'open', + 'type': type, + 'side': side, + 'price': price, + 'amount': amount, + }, response), market) + id = order['id'] + self.orders[id] = order + return self.extend({'info': response}, order) + + def price_to_precision(self, symbol, price): + """ + Wrapped to avoid float + """ + return ('{:.' + str(self.markets[symbol]['precision']['price']) + 'f}').format(price).rstrip("0").rstrip(".") + + def amount_to_precision(self, symbol, amount): + """ + Wrapped to avoid float + """ + return ('{:.' + str(self.markets[symbol]['precision']['amount']) + 'f}').format(amount).rstrip("0").rstrip(".") def common_currency_code(self, currency): """ diff --git a/main.py b/main.py index 13c2240..a461207 100644 --- a/main.py +++ b/main.py @@ -63,7 +63,7 @@ def get_user_market(config_path, user_id, debug=False): if debug: args.append("--debug") args = parse_args(args) - pg_config = parse_config(args) + pg_config, redis_config = parse_config(args) market_id, market_config, user_id = list(fetch_markets(pg_config, str(user_id)))[0] return market.Market.from_config(market_config, args, pg_config=pg_config, market_id=market_id, diff --git a/market.py b/market.py index eff670c..fc6f9f6 100644 --- a/market.py +++ b/market.py @@ -391,14 +391,14 @@ class Processor: process_name = "process_{}__{}_{}".format(scenario_name, step["number"], step["name"]) self.market.report.log_stage("{}_begin".format(process_name)) 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) 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) self.market.report.log_stage("{}_end".format(process_name)) def method_arguments(self, action): diff --git a/portfolio.py b/portfolio.py index 1067b0b..d8a5465 100644 --- a/portfolio.py +++ b/portfolio.py @@ -320,8 +320,6 @@ class Trade: ticker = ticker["original"] rate = Computation.compute_value(ticker, self.order_action(), compute_value=compute_value) - # FIXME: Dust amount should be removed from there if they werent - # honored in other sales delta_in_base = abs(self.delta) # 9 BTC's worth of move (10 - 1 or 1 - 10 depending on case) @@ -580,12 +578,12 @@ class Order: self.fetch_mouvements() self.mark_disappeared_order() - + self.mark_dust_amount_remaining_order() self.mark_finished_order() - # FIXME: consider open order with dust remaining as closed - def dust_amount_remaining(self): - return self.remaining_amount() < Amount(self.amount.currency, D("0.001")) + def mark_dust_amount_remaining_order(self): + if self.market.ccxt.is_dust_trade(self.remaining_amount().value, self.rate): + self.status = "closed_dust_remaining" def remaining_amount(self): return self.amount - self.filled_amount() @@ -618,7 +616,7 @@ class Order: self.market.report.log_debug_action("Mark {} as cancelled".format(self)) self.status = "canceled" return - if self.open and self.id is not None: + if (self.status == "closed_dust_remaining" or self.open) and self.id is not None: try: self.market.ccxt.cancel_order(self.id) except OrderNotFound as e: # Closed inbetween @@ -650,7 +648,6 @@ class Order: return True similar_trades = self.market.ccxt.fetch_my_trades(symbol=symbol, since=start_timestamp) - # FIXME: use set instead of sorted(list(...)) for order_id in sorted(list(map(lambda x: x["order"], similar_trades))): trades = list(filter(lambda x: x["order"] == order_id, similar_trades)) if any(x["timestamp"] < start_timestamp for x in trades): diff --git a/store.py b/store.py index 072d3a2..cd0bf7b 100644 --- a/store.py +++ b/store.py @@ -98,7 +98,8 @@ class ReportStore: "args": args, }) - def log_balances(self, tag=None): + def log_balances(self, tag=None, tickers=None, + ticker_currency=None, compute_value=None, type=None): self.print_log("[Balance]") for currency, balance in self.market.balances.all.items(): self.print_log("\t{}".format(balance)) @@ -109,11 +110,22 @@ class ReportStore: "balances": self.market.balances.as_json() } + if tickers is not None: + log["tickers"] = self._ticker_hash(tickers, ticker_currency, + compute_value, type) + self.add_log(log.copy()) self.add_redis_status(log) def log_tickers(self, amounts, other_currency, compute_value, type): + log = self._ticker_hash(amounts, other_currency, compute_value, + type) + log["type"] = "tickers" + + self.add_log(log) + + def _ticker_hash(self, amounts, other_currency, compute_value, type): values = {} rates = {} if callable(compute_value): @@ -122,8 +134,7 @@ class ReportStore: for currency, amount in amounts.items(): values[currency] = amount.as_json()["value"] rates[currency] = amount.rate - log = { - "type": "tickers", + return { "compute_value": compute_value, "balance_type": type, "currency": other_currency, @@ -132,9 +143,6 @@ class ReportStore: "total": sum(amounts.values()).as_json()["value"] } - self.add_log(log.copy()) - self.add_redis_status(log) - def log_dispatch(self, amount, amounts, liquidity, repartition): self.add_log({ "type": "dispatch", @@ -294,13 +302,20 @@ class BalanceStore: compute_value, type) return amounts - def fetch_balances(self, tag=None): + def fetch_balances(self, tag=None, log_tickers=False, + ticker_currency="BTC", ticker_compute_value="average", ticker_type="total"): all_balances = self.market.ccxt.fetch_all_balances() for currency, balance in all_balances.items(): if balance["exchange_total"] != 0 or balance["margin_total"] != 0 or \ currency in self.all: self.all[currency] = portfolio.Balance(currency, balance) - self.market.report.log_balances(tag=tag) + if log_tickers: + tickers = self.in_currency(ticker_currency, compute_value=ticker_compute_value, type=ticker_type) + self.market.report.log_balances(tag=tag, + tickers=tickers, ticker_currency=ticker_currency, + compute_value=ticker_compute_value, type=ticker_type) + else: + self.market.report.log_balances(tag=tag) def dispatch_assets(self, amount, liquidity="medium", repartition=None): if repartition is None: diff --git a/tests/test_ccxt_wrapper.py b/tests/test_ccxt_wrapper.py index 10e334d..c326f0a 100644 --- a/tests/test_ccxt_wrapper.py +++ b/tests/test_ccxt_wrapper.py @@ -110,7 +110,23 @@ class poloniexETest(unittest.TestCase): retry_call.assert_not_called() def test_order_precision(self): - self.assertEqual(8, self.s.order_precision("FOO")) + self.s.markets = { + "FOO": { + "precision": { + "price": 5, + "amount": 6, + } + }, + "BAR": { + "precision": { + "price": 7, + "amount": 8, + } + } + } + with mock.patch.object(self.s, "load_markets") as load_markets: + self.assertEqual(5, self.s.order_precision("FOO")) + load_markets.assert_called_once() def test_transfer_balance(self): with self.subTest(success=True),\ @@ -167,33 +183,6 @@ class poloniexETest(unittest.TestCase): } self.assertEqual(expected, self.s.margin_summary()) - def test_create_order(self): - with mock.patch.object(self.s, "create_exchange_order") as exchange,\ - mock.patch.object(self.s, "create_margin_order") as margin: - with self.subTest(account="unspecified"): - self.s.create_order("symbol", "type", "side", "amount", price="price", lending_rate="lending_rate", params="params") - exchange.assert_called_once_with("symbol", "type", "side", "amount", price="price", params="params") - margin.assert_not_called() - exchange.reset_mock() - margin.reset_mock() - - with self.subTest(account="exchange"): - self.s.create_order("symbol", "type", "side", "amount", account="exchange", price="price", lending_rate="lending_rate", params="params") - exchange.assert_called_once_with("symbol", "type", "side", "amount", price="price", params="params") - margin.assert_not_called() - exchange.reset_mock() - margin.reset_mock() - - with self.subTest(account="margin"): - self.s.create_order("symbol", "type", "side", "amount", account="margin", price="price", lending_rate="lending_rate", params="params") - margin.assert_called_once_with("symbol", "type", "side", "amount", lending_rate="lending_rate", price="price", params="params") - exchange.assert_not_called() - exchange.reset_mock() - margin.reset_mock() - - with self.subTest(account="unknown"), self.assertRaises(NotImplementedError): - self.s.create_order("symbol", "type", "side", "amount", account="unknown") - def test_parse_ticker(self): ticker = { "high24hr": "12", @@ -439,11 +428,13 @@ class poloniexETest(unittest.TestCase): self.assertEqual(expected_doge, result["DOGE"]) self.assertEqual(expected_btc, result["BTC"]) - def test_create_margin_order(self): - with self.assertRaises(market.ExchangeError): - self.s.create_margin_order("FOO", "market", "buy", "10") + def test_create_order(self): + with self.subTest(type="market"),\ + self.assertRaises(market.ExchangeError): + self.s.create_order("FOO", "market", "buy", "10") - with mock.patch.object(self.s, "load_markets") as load_markets,\ + with self.subTest(type="limit", account="margin"),\ + mock.patch.object(self.s, "load_markets") as load_markets,\ mock.patch.object(self.s, "privatePostMarginBuy") as margin_buy,\ mock.patch.object(self.s, "privatePostMarginSell") as margin_sell,\ mock.patch.object(self.s, "market") as market_mock,\ @@ -460,26 +451,101 @@ class poloniexETest(unittest.TestCase): ptp.return_value = D("0.1") atp.return_value = D("12") - order = self.s.create_margin_order("BTC_ETC", "margin", "buy", "12", price="0.1") + order = self.s.create_order("BTC_ETC", "limit", "buy", "12", + account="margin", price="0.1") self.assertEqual(123, order["id"]) margin_buy.assert_called_once_with({"currencyPair": "BTC_ETC", "rate": D("0.1"), "amount": D("12")}) margin_sell.assert_not_called() margin_buy.reset_mock() margin_sell.reset_mock() - order = self.s.create_margin_order("BTC_ETC", "margin", "sell", "12", lending_rate="0.01", price="0.1") + order = self.s.create_order("BTC_ETC", "limit", "sell", + "12", account="margin", lending_rate="0.01", price="0.1") self.assertEqual(456, order["id"]) margin_sell.assert_called_once_with({"currencyPair": "BTC_ETC", "rate": D("0.1"), "amount": D("12"), "lendingRate": "0.01"}) margin_buy.assert_not_called() - def test_create_exchange_order(self): - with mock.patch.object(market.ccxt.poloniex, "create_order") as create_order: - self.s.create_order("symbol", "type", "side", "amount", price="price", params="params") + with self.subTest(type="limit", account="exchange"),\ + mock.patch.object(self.s, "load_markets") as load_markets,\ + mock.patch.object(self.s, "privatePostBuy") as exchange_buy,\ + mock.patch.object(self.s, "privatePostSell") as exchange_sell,\ + mock.patch.object(self.s, "market") as market_mock,\ + mock.patch.object(self.s, "price_to_precision") as ptp,\ + mock.patch.object(self.s, "amount_to_precision") as atp: + + exchange_buy.return_value = { + "orderNumber": 123 + } + exchange_sell.return_value = { + "orderNumber": 456 + } + market_mock.return_value = { "id": "BTC_ETC", "symbol": "BTC_ETC" } + ptp.return_value = D("0.1") + atp.return_value = D("12") + + order = self.s.create_order("BTC_ETC", "limit", "buy", "12", + account="exchange", price="0.1") + self.assertEqual(123, order["id"]) + exchange_buy.assert_called_once_with({"currencyPair": "BTC_ETC", "rate": D("0.1"), "amount": D("12")}) + exchange_sell.assert_not_called() + exchange_buy.reset_mock() + exchange_sell.reset_mock() - create_order.assert_called_once_with("symbol", "type", "side", "amount", price="price", params="params") + order = self.s.create_order("BTC_ETC", "limit", "sell", + "12", account="exchange", lending_rate="0.01", price="0.1") + self.assertEqual(456, order["id"]) + exchange_sell.assert_called_once_with({"currencyPair": "BTC_ETC", "rate": D("0.1"), "amount": D("12")}) + exchange_buy.assert_not_called() + + with self.subTest(account="unknown"), self.assertRaises(NotImplementedError),\ + mock.patch.object(self.s, "load_markets") as load_markets: + self.s.create_order("symbol", "type", "side", "amount", account="unknown") def test_common_currency_code(self): self.assertEqual("FOO", self.s.common_currency_code("FOO")) def test_currency_id(self): self.assertEqual("FOO", self.s.currency_id("FOO")) + + def test_amount_to_precision(self): + self.s.markets = { + "FOO": { + "precision": { + "price": 5, + "amount": 6, + } + }, + "BAR": { + "precision": { + "price": 7, + "amount": 8, + } + } + } + self.assertEqual("0.0001", self.s.amount_to_precision("FOO", D("0.0001"))) + self.assertEqual("0.0000001", self.s.amount_to_precision("BAR", D("0.0000001"))) + self.assertEqual("0.000001", self.s.amount_to_precision("FOO", D("0.000001"))) + + def test_price_to_precision(self): + self.s.markets = { + "FOO": { + "precision": { + "price": 5, + "amount": 6, + } + }, + "BAR": { + "precision": { + "price": 7, + "amount": 8, + } + } + } + self.assertEqual("0.0001", self.s.price_to_precision("FOO", D("0.0001"))) + self.assertEqual("0.0000001", self.s.price_to_precision("BAR", D("0.0000001"))) + self.assertEqual("0", self.s.price_to_precision("FOO", D("0.000001"))) + + def test_is_dust_trade(self): + self.assertTrue(self.s.is_dust_trade(D("0.0000009"), D("1000"))) + self.assertTrue(self.s.is_dust_trade(D("0.000001"), D("10"))) + self.assertFalse(self.s.is_dust_trade(D("0.000001"), D("100"))) diff --git a/tests/test_main.py b/tests/test_main.py index b650870..55b1382 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -103,7 +103,7 @@ class MainTest(WebMockTestCase): mock.patch("main.parse_config") as main_parse_config: with self.subTest(debug=False): main_parse_args.return_value = self.market_args() - main_parse_config.return_value = "pg_config" + main_parse_config.return_value = ["pg_config", "redis_config"] main_fetch_markets.return_value = [(1, {"key": "market_config"}, 3)] m = main.get_user_market("config_path.ini", 1) @@ -114,7 +114,7 @@ class MainTest(WebMockTestCase): main_parse_args.reset_mock() with self.subTest(debug=True): main_parse_args.return_value = self.market_args(debug=True) - main_parse_config.return_value = "pg_config" + main_parse_config.return_value = ["pg_config", "redis_config"] main_fetch_markets.return_value = [(1, {"key": "market_config"}, 3)] m = main.get_user_market("config_path.ini", 1, debug=True) diff --git a/tests/test_market.py b/tests/test_market.py index 53630b7..6a3322c 100644 --- a/tests/test_market.py +++ b/tests/test_market.py @@ -993,8 +993,8 @@ class ProcessorTest(WebMockTestCase): mock.call("process_foo__1_sell_end"), ]) self.m.balances.fetch_balances.assert_has_calls([ - mock.call(tag="process_foo__1_sell_begin"), - mock.call(tag="process_foo__1_sell_end"), + mock.call(tag="process_foo__1_sell_begin", log_tickers=True), + mock.call(tag="process_foo__1_sell_end", log_tickers=True), ]) self.assertEqual(5, run_action.call_count) diff --git a/tests/test_portfolio.py b/tests/test_portfolio.py index 4d78996..969f5d4 100644 --- a/tests/test_portfolio.py +++ b/tests/test_portfolio.py @@ -823,14 +823,16 @@ class OrderTest(WebMockTestCase): order.cancel() self.m.ccxt.cancel_order.assert_not_called() - def test_dust_amount_remaining(self): + def test_mark_dust_amount_remaining(self): order = portfolio.Order("buy", portfolio.Amount("ETH", 10), D("0.1"), "BTC", "long", self.m, "trade") - order.remaining_amount = mock.Mock(return_value=portfolio.Amount("ETH", 1)) - self.assertFalse(order.dust_amount_remaining()) + self.m.ccxt.is_dust_trade.return_value = False + order.mark_dust_amount_remaining_order() + self.assertEqual("pending", order.status) - order.remaining_amount = mock.Mock(return_value=portfolio.Amount("ETH", D("0.0001"))) - self.assertTrue(order.dust_amount_remaining()) + self.m.ccxt.is_dust_trade.return_value = True + order.mark_dust_amount_remaining_order() + self.assertEqual("closed_dust_remaining", order.status) @mock.patch.object(portfolio.Order, "fetch") @mock.patch.object(portfolio.Order, "filled_amount", return_value=portfolio.Amount("ETH", 1)) @@ -965,6 +967,7 @@ class OrderTest(WebMockTestCase): "status": "foo", "datetime": "timestamp" } + self.m.ccxt.is_dust_trade.return_value = False order.fetch() self.m.ccxt.fetch_order.assert_called_once_with(45) diff --git a/tests/test_store.py b/tests/test_store.py index df113b7..12999d3 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -369,17 +369,27 @@ class BalanceStoreTest(WebMockTestCase): balance_store = market.BalanceStore(self.m) - balance_store.fetch_balances() - self.assertNotIn("ETC", balance_store.currencies()) - self.assertListEqual(["USDT", "XVG", "XMR"], list(balance_store.currencies())) - - balance_store.all["ETC"] = portfolio.Balance("ETC", { - "exchange_total": "1", "exchange_free": "0", - "exchange_used": "1" }) - balance_store.fetch_balances(tag="foo") - self.assertEqual(0, balance_store.all["ETC"].total) - self.assertListEqual(["USDT", "XVG", "XMR", "ETC"], list(balance_store.currencies())) - self.m.report.log_balances.assert_called_with(tag="foo") + with self.subTest(log_tickers=False): + balance_store.fetch_balances() + self.assertNotIn("ETC", balance_store.currencies()) + self.assertListEqual(["USDT", "XVG", "XMR"], list(balance_store.currencies())) + + balance_store.all["ETC"] = portfolio.Balance("ETC", { + "exchange_total": "1", "exchange_free": "0", + "exchange_used": "1" }) + balance_store.fetch_balances(tag="foo") + self.assertEqual(0, balance_store.all["ETC"].total) + self.assertListEqual(["USDT", "XVG", "XMR", "ETC"], list(balance_store.currencies())) + self.m.report.log_balances.assert_called_with(tag="foo") + + with self.subTest(log_tickers=True),\ + mock.patch.object(balance_store, "in_currency") as in_currency: + in_currency.return_value = "tickers" + balance_store.fetch_balances(log_tickers=True, ticker_currency="FOO", + ticker_compute_value="compute", ticker_type="type") + self.m.report.log_balances.assert_called_with(compute_value='compute', + tag=None, ticker_currency='FOO', tickers='tickers', + type='type') @mock.patch.object(market.Portfolio, "repartition") def test_dispatch_assets(self, repartition): @@ -586,27 +596,77 @@ class ReportStoreTest(WebMockTestCase): self.m.balances.as_json.return_value = "json" self.m.balances.all = { "FOO": "bar", "BAR": "baz" } - report_store.log_balances(tag="tag") - print_log.assert_has_calls([ - mock.call("[Balance]"), - mock.call("\tbar"), - mock.call("\tbaz"), - ]) - add_log.assert_called_once_with({ - 'type': 'balance', - 'balances': 'json', - 'tag': 'tag' - }) - add_redis_status.assert_called_once_with({ - 'type': 'balance', - 'balances': 'json', - 'tag': 'tag' - }) + with self.subTest(tickers=None): + report_store.log_balances(tag="tag") + print_log.assert_has_calls([ + mock.call("[Balance]"), + mock.call("\tbar"), + mock.call("\tbaz"), + ]) + add_log.assert_called_once_with({ + 'type': 'balance', + 'balances': 'json', + 'tag': 'tag' + }) + add_redis_status.assert_called_once_with({ + 'type': 'balance', + 'balances': 'json', + 'tag': 'tag' + }) + add_log.reset_mock() + add_redis_status.reset_mock() + with self.subTest(tickers="present"): + amounts = { + "BTC": portfolio.Amount("BTC", 10), + "ETH": portfolio.Amount("BTC", D("0.3")) + } + amounts["ETH"].rate = D("0.1") + + report_store.log_balances(tag="tag", tickers=amounts, + ticker_currency="BTC", compute_value="default", + type="total") + add_log.assert_called_once_with({ + 'type': 'balance', + 'balances': 'json', + 'tag': 'tag', + 'tickers': { + 'compute_value': 'default', + 'balance_type': 'total', + 'currency': 'BTC', + 'balances': { + 'BTC': D('10'), + 'ETH': D('0.3') + }, + 'rates': { + 'BTC': None, + 'ETH': D('0.1') + }, + 'total': D('10.3') + }, + }) + add_redis_status.assert_called_once_with({ + 'type': 'balance', + 'balances': 'json', + 'tag': 'tag', + 'tickers': { + 'compute_value': 'default', + 'balance_type': 'total', + 'currency': 'BTC', + 'balances': { + 'BTC': D('10'), + 'ETH': D('0.3') + }, + 'rates': { + 'BTC': None, + 'ETH': D('0.1') + }, + 'total': D('10.3') + }, + }) @mock.patch.object(market.ReportStore, "print_log") @mock.patch.object(market.ReportStore, "add_log") - @mock.patch.object(market.ReportStore, "add_redis_status") - def test_log_tickers(self, add_redis_status, add_log, print_log): + def test_log_tickers(self, add_log, print_log): report_store = market.ReportStore(self.m) amounts = { "BTC": portfolio.Amount("BTC", 10), @@ -631,21 +691,6 @@ class ReportStoreTest(WebMockTestCase): }, 'total': D('10.3') }) - add_redis_status.assert_called_once_with({ - 'type': 'tickers', - 'compute_value': 'default', - 'balance_type': 'total', - 'currency': 'BTC', - 'balances': { - 'BTC': D('10'), - 'ETH': D('0.3') - }, - 'rates': { - 'BTC': None, - 'ETH': D('0.1') - }, - 'total': D('10.3') - }) add_log.reset_mock() compute_value = lambda x: x["bid"]