From 2b1ee8f4d54fa1672510141a71a5817120ac031c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isma=C3=ABl=20Bouya?= Date: Tue, 1 May 2018 17:24:40 +0200 Subject: Store tickers in balance log --- market.py | 4 +- store.py | 31 ++++++++---- tests/test_market.py | 4 +- tests/test_store.py | 133 ++++++++++++++++++++++++++++++++++----------------- 4 files changed, 116 insertions(+), 56 deletions(-) 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/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_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_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"] -- cgit v1.2.3