self.assertTrue(ticker["inverted"])
self.assertIn("original", ticker)
self.assertEqual(10, ticker["original"]["bid"])
+ self.assertEqual(25, ticker["original"]["average"])
ticker = m.get_ticker("XVG", "XMR")
self.assertIsNone(ticker)
self.assertTrue(ticker["inverted"])
self.assertIn("original", ticker)
self.assertEqual(10, ticker["original"]["bid"])
+ self.assertEqual(25, ticker["original"]["average"])
ticker = m.get_ticker("XVG", "XMR")
self.assertIsNone(ticker)
self.assertEqual(D("0.01"), call[0][0]["XVG"].value)
self.assertEqual(D("0.2525"), call[0][1]["BTC"].value)
self.assertEqual(D("0.7575"), call[0][1]["XEM"].value)
- m.report.log_stage.assert_called_once_with("prepare_trades")
+ m.report.log_stage.assert_called_once_with("prepare_trades",
+ base_currency='BTC', compute_value='average',
+ liquidity='medium', only=None, repartition=None)
m.report.log_balances.assert_called_once_with(tag="tag")
- @mock.patch.object(portfolio.Portfolio, "repartition")
- @mock.patch.object(market.Market, "get_ticker")
- @mock.patch.object(market.TradeStore, "compute_trades")
- def test_update_trades(self, compute_trades, get_ticker, repartition):
- repartition.return_value = {
- "XEM": (D("0.75"), "long"),
- "BTC": (D("0.25"), "long"),
- }
- def _get_ticker(c1, c2):
- if c1 == "USDT" and c2 == "BTC":
- return { "average": D("0.0001") }
- if c1 == "XVG" and c2 == "BTC":
- return { "average": D("0.000001") }
- if c1 == "XEM" and c2 == "BTC":
- return { "average": D("0.001") }
- self.fail("Should be called with {}, {}".format(c1, c2))
- get_ticker.side_effect = _get_ticker
-
- with mock.patch("market.ReportStore"):
- m = market.Market(self.ccxt)
- self.ccxt.fetch_all_balances.return_value = {
- "USDT": {
- "exchange_free": D("10000.0"),
- "exchange_used": D("0.0"),
- "exchange_total": D("10000.0"),
- "total": D("10000.0")
- },
- "XVG": {
- "exchange_free": D("10000.0"),
- "exchange_used": D("0.0"),
- "exchange_total": D("10000.0"),
- "total": D("10000.0")
- },
- }
-
- m.balances.fetch_balances(tag="tag")
-
- m.update_trades()
- compute_trades.assert_called()
-
- call = compute_trades.call_args
- self.assertEqual(1, call[0][0]["USDT"].value)
- self.assertEqual(D("0.01"), call[0][0]["XVG"].value)
- self.assertEqual(D("0.2525"), call[0][1]["BTC"].value)
- self.assertEqual(D("0.7575"), call[0][1]["XEM"].value)
- m.report.log_stage.assert_called_once_with("update_trades")
- m.report.log_balances.assert_called_once_with(tag="tag")
-
- @mock.patch.object(portfolio.Portfolio, "repartition")
- @mock.patch.object(market.Market, "get_ticker")
- @mock.patch.object(market.TradeStore, "compute_trades")
- def test_prepare_trades_to_sell_all(self, compute_trades, get_ticker, repartition):
- def _get_ticker(c1, c2):
- if c1 == "USDT" and c2 == "BTC":
- return { "average": D("0.0001") }
- if c1 == "XVG" and c2 == "BTC":
- return { "average": D("0.000001") }
- self.fail("Should be called with {}, {}".format(c1, c2))
- get_ticker.side_effect = _get_ticker
-
- with mock.patch("market.ReportStore"):
- m = market.Market(self.ccxt)
- self.ccxt.fetch_all_balances.return_value = {
- "USDT": {
- "exchange_free": D("10000.0"),
- "exchange_used": D("0.0"),
- "exchange_total": D("10000.0"),
- "total": D("10000.0")
- },
- "XVG": {
- "exchange_free": D("10000.0"),
- "exchange_used": D("0.0"),
- "exchange_total": D("10000.0"),
- "total": D("10000.0")
- },
- }
-
- m.balances.fetch_balances(tag="tag")
-
- m.prepare_trades_to_sell_all()
-
- repartition.assert_not_called()
- compute_trades.assert_called()
-
- call = compute_trades.call_args
- self.assertEqual(1, call[0][0]["USDT"].value)
- self.assertEqual(D("0.01"), call[0][0]["XVG"].value)
- self.assertEqual(D("1.01"), call[0][1]["BTC"].value)
- m.report.log_stage.assert_called_once_with("prepare_trades_to_sell_all")
- m.report.log_balances.assert_called_once_with(tag="tag")
@mock.patch.object(portfolio.time, "sleep")
@mock.patch.object(market.TradeStore, "all_orders")
@mock.patch.object(market.ReportStore, "add_log")
def test_log_stage(self, add_log, print_log):
report_store = market.ReportStore(self.m)
- report_store.log_stage("foo")
+ c = lambda x: x
+ report_store.log_stage("foo", bar="baz", c=c, d=portfolio.Amount("BTC", 1))
print_log.assert_has_calls([
mock.call("-----------"),
- mock.call("[Stage] foo"),
+ mock.call("[Stage] foo bar=baz, c=c = lambda x: x, d={'currency': 'BTC', 'value': Decimal('1')}"),
])
- add_log.assert_called_once_with({'type': 'stage', 'stage': 'foo'})
+ add_log.assert_called_once_with({
+ 'type': 'stage',
+ 'stage': 'foo',
+ 'args': {
+ 'bar': 'baz',
+ 'c': 'c = lambda x: x',
+ 'd': {
+ 'currency': 'BTC',
+ 'value': D('1')
+ }
+ }
+ })
@mock.patch.object(market.ReportStore, "print_log")
@mock.patch.object(market.ReportStore, "add_log")
self.assertRegex(stdout_mock.getvalue(), "impossible to store report file: FileNotFoundError;")
- @mock.patch("helper.process_sell_all__1_all_sell")
- @mock.patch("helper.process_sell_all__2_all_buy")
- @mock.patch("portfolio.Portfolio.wait_for_recent")
- def test_main_process_market(self, wait, buy, sell):
+ @mock.patch("helper.Processor.process")
+ def test_main_process_market(self, process):
with self.subTest(before=False, after=False):
- helper.main_process_market("user", None)
-
- wait.assert_not_called()
- buy.assert_not_called()
- sell.assert_not_called()
+ m = mock.Mock()
+ helper.main_process_market(m, None)
- buy.reset_mock()
- wait.reset_mock()
- sell.reset_mock()
+ process.assert_not_called()
+
+ process.reset_mock()
with self.subTest(before=True, after=False):
- helper.main_process_market("user", None, before=True)
-
- wait.assert_not_called()
- buy.assert_not_called()
- sell.assert_called_once_with("user")
+ helper.main_process_market(m, None, before=True)
+
+ process.assert_called_once_with("sell_all", steps="before")
- buy.reset_mock()
- wait.reset_mock()
- sell.reset_mock()
+ process.reset_mock()
with self.subTest(before=False, after=True):
- helper.main_process_market("user", None, after=True)
+ helper.main_process_market(m, None, after=True)
- wait.assert_called_once_with("user")
- buy.assert_called_once_with("user")
- sell.assert_not_called()
+ process.assert_called_once_with("sell_all", steps="after")
- buy.reset_mock()
- wait.reset_mock()
- sell.reset_mock()
+ process.reset_mock()
with self.subTest(before=True, after=True):
- helper.main_process_market("user", None, before=True, after=True)
-
- wait.assert_called_once_with("user")
- buy.assert_called_once_with("user")
- sell.assert_called_once_with("user")
+ helper.main_process_market(m, None, before=True, after=True)
+
+ process.assert_has_calls([
+ mock.call("sell_all", steps="before"),
+ mock.call("sell_all", steps="after"),
+ ])
- buy.reset_mock()
- wait.reset_mock()
- sell.reset_mock()
+ process.reset_mock()
with self.subTest(action="print_balances"),\
mock.patch("helper.print_balances") as print_balances:
- helper.main_process_market("user", "print_balances")
+ helper.main_process_market("user", ["print_balances"])
- buy.assert_not_called()
- wait.assert_not_called()
- sell.assert_not_called()
+ process.assert_not_called()
print_balances.assert_called_once_with("user")
with self.subTest(action="print_orders"),\
- mock.patch("helper.print_orders") as print_orders:
- helper.main_process_market("user", "print_orders")
+ mock.patch("helper.print_orders") as print_orders,\
+ mock.patch("helper.print_balances") as print_balances:
+ helper.main_process_market("user", ["print_orders", "print_balances"])
- buy.assert_not_called()
- wait.assert_not_called()
- sell.assert_not_called()
+ process.assert_not_called()
print_orders.assert_called_once_with("user")
+ print_balances.assert_called_once_with("user")
with self.subTest(action="unknown"),\
self.assertRaises(NotImplementedError):
- helper.main_process_market("user", "unknown")
+ helper.main_process_market("user", ["unknown"])
@mock.patch.object(helper, "psycopg2")
def test_fetch_markets(self, psycopg2):
mock.call(tag="process_sell_needed__2_buy_begin"),
mock.call(tag="process_sell_needed__2_buy_end"),
])
- self.m.update_trades.assert_called_with(base_currency="BTC",
+ self.m.prepare_trades.assert_called_with(base_currency="BTC",
liquidity="medium", only="acquire")
self.m.trades.prepare_orders.assert_called_with(compute_value="average",
only="acquire")
mock.call(tag="process_sell_all__1_all_sell_begin"),
mock.call(tag="process_sell_all__1_all_sell_end"),
])
- self.m.prepare_trades_to_sell_all.assert_called_with(base_currency="BTC")
+ self.m.prepare_trades.assert_called_with(base_currency="BTC",
+ liquidity="medium", repartition={'BTC': (1, 'long')})
self.m.trades.prepare_orders.assert_called_with(compute_value="average")
self.m.trades.run_orders.assert_called()
self.m.follow_orders.assert_called()
mock.call("process_sell_all__1_all_sell_end")
])
- def test_process_sell_all__2_all_buy(self):
- helper.process_sell_all__2_all_buy(self.m)
+ @mock.patch("portfolio.Portfolio.wait_for_recent")
+ def test_process_sell_all__2_wait(self, wait):
+ helper.process_sell_all__2_wait(self.m)
+
+ wait.assert_called_once_with(self.m)
+ self.m.report.log_stage.assert_has_calls([
+ mock.call("process_sell_all__2_wait_begin"),
+ mock.call("process_sell_all__2_wait_end")
+ ])
+
+ def test_process_sell_all__3_all_buy(self):
+ helper.process_sell_all__3_all_buy(self.m)
self.m.balances.fetch_balances.assert_has_calls([
- mock.call(tag="process_sell_all__2_all_buy_begin"),
- mock.call(tag="process_sell_all__2_all_buy_end"),
+ mock.call(tag="process_sell_all__3_all_buy_begin"),
+ mock.call(tag="process_sell_all__3_all_buy_end"),
])
self.m.prepare_trades.assert_called_with(base_currency="BTC",
liquidity="medium")
self.m.trades.run_orders.assert_called()
self.m.follow_orders.assert_called()
self.m.report.log_stage.assert_has_calls([
- mock.call("process_sell_all__2_all_buy_begin"),
- mock.call("process_sell_all__2_all_buy_end")
+ mock.call("process_sell_all__3_all_buy_begin"),
+ mock.call("process_sell_all__3_all_buy_end")
])
@unittest.skipUnless("acceptance" in limits, "Acceptance skipped")
with mock.patch.object(portfolio.Portfolio, "repartition", return_value=repartition):
# Action 5
- helper.update_trades(market, only="acquire", compute_value="average")
+ helper.prepare_trades(market, only="acquire", compute_value="average")
balances = portfolio.BalanceStore.all
self.assertEqual(portfolio.Amount("ETH", 1 / D("3")), balances["ETH"].total)