diff options
Diffstat (limited to 'test.py')
-rw-r--r-- | test.py | 135 |
1 files changed, 99 insertions, 36 deletions
@@ -174,7 +174,7 @@ class PortfolioTest(unittest.TestCase): | |||
174 | 174 | ||
175 | with open("test_portfolio.json") as example: | 175 | with open("test_portfolio.json") as example: |
176 | import json | 176 | import json |
177 | self.json_response = json.load(example) | 177 | self.json_response = json.load(example, parse_int=portfolio.D, parse_float=portfolio.D) |
178 | 178 | ||
179 | self.patcher = mock.patch.multiple(portfolio.Portfolio, data=None, liquidities={}) | 179 | self.patcher = mock.patch.multiple(portfolio.Portfolio, data=None, liquidities={}) |
180 | self.patcher.start() | 180 | self.patcher.start() |
@@ -220,29 +220,63 @@ class PortfolioTest(unittest.TestCase): | |||
220 | self.assertEqual(10, len(liquidities["medium"].keys())) | 220 | self.assertEqual(10, len(liquidities["medium"].keys())) |
221 | self.assertEqual(10, len(liquidities["high"].keys())) | 221 | self.assertEqual(10, len(liquidities["high"].keys())) |
222 | 222 | ||
223 | expected = {'BTC': 2857, 'DGB': 1015, 'DOGE': 1805, 'SC': 623, 'ZEC': 3701} | 223 | expected = { |
224 | 'BTC': (D("0.2857"), "long"), | ||
225 | 'DGB': (D("0.1015"), "long"), | ||
226 | 'DOGE': (D("0.1805"), "long"), | ||
227 | 'SC': (D("0.0623"), "long"), | ||
228 | 'ZEC': (D("0.3701"), "long"), | ||
229 | } | ||
224 | self.assertDictEqual(expected, liquidities["high"]['2018-01-08']) | 230 | self.assertDictEqual(expected, liquidities["high"]['2018-01-08']) |
225 | 231 | ||
226 | expected = {'ETC': 1000, 'FCT': 1000, 'GAS': 1000, 'NAV': 1000, 'OMG': 1000, 'OMNI': 1000, 'PPC': 1000, 'RIC': 1000, 'VIA': 1000, 'XCP': 1000} | 232 | expected = { |
233 | 'BTC': (D("1.1102e-16"), "long"), | ||
234 | 'ETC': (D("0.1"), "long"), | ||
235 | 'FCT': (D("0.1"), "long"), | ||
236 | 'GAS': (D("0.1"), "long"), | ||
237 | 'NAV': (D("0.1"), "long"), | ||
238 | 'OMG': (D("0.1"), "long"), | ||
239 | 'OMNI': (D("0.1"), "long"), | ||
240 | 'PPC': (D("0.1"), "long"), | ||
241 | 'RIC': (D("0.1"), "long"), | ||
242 | 'VIA': (D("0.1"), "long"), | ||
243 | 'XCP': (D("0.1"), "long"), | ||
244 | } | ||
227 | self.assertDictEqual(expected, liquidities["medium"]['2018-01-08']) | 245 | self.assertDictEqual(expected, liquidities["medium"]['2018-01-08']) |
228 | 246 | ||
229 | # It doesn't refetch the data when available | 247 | # It doesn't refetch the data when available |
230 | portfolio.Portfolio.parse_cryptoportfolio() | 248 | portfolio.Portfolio.parse_cryptoportfolio() |
231 | mock_get.assert_called_once_with() | 249 | mock_get.assert_called_once_with() |
232 | 250 | ||
233 | portfolio.Portfolio.data["portfolio_1"]["holding"]["direction"][3] = "short" | ||
234 | self.assertRaises(AssertionError, portfolio.Portfolio.parse_cryptoportfolio) | ||
235 | |||
236 | @mock.patch.object(portfolio.Portfolio, "get_cryptoportfolio") | 251 | @mock.patch.object(portfolio.Portfolio, "get_cryptoportfolio") |
237 | def test_repartition_pertenthousand(self, mock_get): | 252 | def test_repartition(self, mock_get): |
238 | mock_get.side_effect = self.fill_data | 253 | mock_get.side_effect = self.fill_data |
239 | 254 | ||
240 | expected_medium = {'USDT': 1000, 'ETC': 1000, 'FCT': 1000, 'OMG': 1000, 'STEEM': 1000, 'STRAT': 1000, 'XEM': 1000, 'XMR': 1000, 'XVC': 1000, 'ZRX': 1000} | 255 | expected_medium = { |
241 | expected_high = {'USDT': 1226, 'BTC': 1429, 'ETC': 1127, 'ETH': 1569, 'FCT': 3341, 'GAS': 1308} | 256 | 'BTC': (D("1.1102e-16"), "long"), |
257 | 'USDT': (D("0.1"), "long"), | ||
258 | 'ETC': (D("0.1"), "long"), | ||
259 | 'FCT': (D("0.1"), "long"), | ||
260 | 'OMG': (D("0.1"), "long"), | ||
261 | 'STEEM': (D("0.1"), "long"), | ||
262 | 'STRAT': (D("0.1"), "long"), | ||
263 | 'XEM': (D("0.1"), "long"), | ||
264 | 'XMR': (D("0.1"), "long"), | ||
265 | 'XVC': (D("0.1"), "long"), | ||
266 | 'ZRX': (D("0.1"), "long"), | ||
267 | } | ||
268 | expected_high = { | ||
269 | 'USDT': (D("0.1226"), "long"), | ||
270 | 'BTC': (D("0.1429"), "long"), | ||
271 | 'ETC': (D("0.1127"), "long"), | ||
272 | 'ETH': (D("0.1569"), "long"), | ||
273 | 'FCT': (D("0.3341"), "long"), | ||
274 | 'GAS': (D("0.1308"), "long"), | ||
275 | } | ||
242 | 276 | ||
243 | self.assertEqual(expected_medium, portfolio.Portfolio.repartition_pertenthousand()) | 277 | self.assertEqual(expected_medium, portfolio.Portfolio.repartition()) |
244 | self.assertEqual(expected_medium, portfolio.Portfolio.repartition_pertenthousand(liquidity="medium")) | 278 | self.assertEqual(expected_medium, portfolio.Portfolio.repartition(liquidity="medium")) |
245 | self.assertEqual(expected_high, portfolio.Portfolio.repartition_pertenthousand(liquidity="high")) | 279 | self.assertEqual(expected_high, portfolio.Portfolio.repartition(liquidity="high")) |
246 | 280 | ||
247 | def tearDown(self): | 281 | def tearDown(self): |
248 | self.patcher.stop() | 282 | self.patcher.stop() |
@@ -339,7 +373,7 @@ class BalanceTest(unittest.TestCase): | |||
339 | self.assertEqual(0, portfolio.Balance.known_balances["ETC"].total) | 373 | self.assertEqual(0, portfolio.Balance.known_balances["ETC"].total) |
340 | self.assertListEqual(["USDT", "XVG", "ETC"], list(portfolio.Balance.currencies())) | 374 | self.assertListEqual(["USDT", "XVG", "ETC"], list(portfolio.Balance.currencies())) |
341 | 375 | ||
342 | @mock.patch.object(portfolio.Portfolio, "repartition_pertenthousand") | 376 | @mock.patch.object(portfolio.Portfolio, "repartition") |
343 | @mock.patch.object(portfolio.market, "fetch_balance") | 377 | @mock.patch.object(portfolio.market, "fetch_balance") |
344 | def test_dispatch_assets(self, fetch_balance, repartition): | 378 | def test_dispatch_assets(self, fetch_balance, repartition): |
345 | fetch_balance.return_value = self.fetch_balance | 379 | fetch_balance.return_value = self.fetch_balance |
@@ -348,8 +382,8 @@ class BalanceTest(unittest.TestCase): | |||
348 | self.assertNotIn("XEM", portfolio.Balance.currencies()) | 382 | self.assertNotIn("XEM", portfolio.Balance.currencies()) |
349 | 383 | ||
350 | repartition.return_value = { | 384 | repartition.return_value = { |
351 | "XEM": 7500, | 385 | "XEM": (D("0.75"), "long"), |
352 | "BTC": 2600, | 386 | "BTC": (D("0.26"), "long"), |
353 | } | 387 | } |
354 | 388 | ||
355 | amounts = portfolio.Balance.dispatch_assets(portfolio.Amount("BTC", "10.1")) | 389 | amounts = portfolio.Balance.dispatch_assets(portfolio.Amount("BTC", "10.1")) |
@@ -357,13 +391,13 @@ class BalanceTest(unittest.TestCase): | |||
357 | self.assertEqual(D("2.6"), amounts["BTC"].value) | 391 | self.assertEqual(D("2.6"), amounts["BTC"].value) |
358 | self.assertEqual(D("7.5"), amounts["XEM"].value) | 392 | self.assertEqual(D("7.5"), amounts["XEM"].value) |
359 | 393 | ||
360 | @mock.patch.object(portfolio.Portfolio, "repartition_pertenthousand") | 394 | @mock.patch.object(portfolio.Portfolio, "repartition") |
361 | @mock.patch.object(portfolio.Trade, "get_ticker") | 395 | @mock.patch.object(portfolio.Trade, "get_ticker") |
362 | @mock.patch.object(portfolio.Trade, "compute_trades") | 396 | @mock.patch.object(portfolio.Trade, "compute_trades") |
363 | def test_prepare_trades(self, compute_trades, get_ticker, repartition): | 397 | def test_prepare_trades(self, compute_trades, get_ticker, repartition): |
364 | repartition.return_value = { | 398 | repartition.return_value = { |
365 | "XEM": 7500, | 399 | "XEM": (D("0.75"), "long"), |
366 | "BTC": 2500, | 400 | "BTC": (D("0.25"), "long"), |
367 | } | 401 | } |
368 | def _get_ticker(c1, c2, market): | 402 | def _get_ticker(c1, c2, market): |
369 | if c1 == "USDT" and c2 == "BTC": | 403 | if c1 == "USDT" and c2 == "BTC": |
@@ -587,11 +621,12 @@ class AcceptanceTest(unittest.TestCase): | |||
587 | }, | 621 | }, |
588 | } | 622 | } |
589 | repartition = { | 623 | repartition = { |
590 | "ETH": 2500, | 624 | "ETH": (D("0.25"), "long"), |
591 | "ETC": 2500, | 625 | "ETC": (D("0.25"), "long"), |
592 | "BTC": 4000, | 626 | "BTC": (D("0.4"), "long"), |
593 | "BTD": 500, | 627 | "BTD": (D("0.01"), "short"), |
594 | "USDT": 500, | 628 | "B2X": (D("0.04"), "long"), |
629 | "USDT": (D("0.05"), "long"), | ||
595 | } | 630 | } |
596 | 631 | ||
597 | def fetch_ticker(symbol): | 632 | def fetch_ticker(symbol): |
@@ -619,6 +654,12 @@ class AcceptanceTest(unittest.TestCase): | |||
619 | "bid": D("0.0008"), | 654 | "bid": D("0.0008"), |
620 | "ask": D("0.0012") | 655 | "ask": D("0.0012") |
621 | } | 656 | } |
657 | if symbol == "B2X/BTC": | ||
658 | return { | ||
659 | "symbol": "B2X/BTC", | ||
660 | "bid": D("0.0008"), | ||
661 | "ask": D("0.0012") | ||
662 | } | ||
622 | if symbol == "USDT/BTC": | 663 | if symbol == "USDT/BTC": |
623 | raise portfolio.ExchangeError | 664 | raise portfolio.ExchangeError |
624 | if symbol == "BTC/USDT": | 665 | if symbol == "BTC/USDT": |
@@ -632,7 +673,7 @@ class AcceptanceTest(unittest.TestCase): | |||
632 | market = mock.Mock() | 673 | market = mock.Mock() |
633 | market.fetch_balance.return_value = fetch_balance | 674 | market.fetch_balance.return_value = fetch_balance |
634 | market.fetch_ticker.side_effect = fetch_ticker | 675 | market.fetch_ticker.side_effect = fetch_ticker |
635 | with mock.patch.object(portfolio.Portfolio, "repartition_pertenthousand", return_value=repartition): | 676 | with mock.patch.object(portfolio.Portfolio, "repartition", return_value=repartition): |
636 | # Action 1 | 677 | # Action 1 |
637 | portfolio.Balance.prepare_trades(market) | 678 | portfolio.Balance.prepare_trades(market) |
638 | 679 | ||
@@ -654,9 +695,13 @@ class AcceptanceTest(unittest.TestCase): | |||
654 | self.assertNotIn("BTC", trades) | 695 | self.assertNotIn("BTC", trades) |
655 | 696 | ||
656 | self.assertEqual(portfolio.Amount("BTC", D("0.00")), trades["BTD"].value_from) | 697 | self.assertEqual(portfolio.Amount("BTC", D("0.00")), trades["BTD"].value_from) |
657 | self.assertEqual(portfolio.Amount("BTC", D("0.01")), trades["BTD"].value_to) | 698 | self.assertEqual(portfolio.Amount("BTC", D("0.002")), trades["BTD"].value_to) |
658 | self.assertEqual("buy", trades["BTD"].action) | 699 | self.assertEqual("buy", trades["BTD"].action) |
659 | 700 | ||
701 | self.assertEqual(portfolio.Amount("BTC", D("0.00")), trades["B2X"].value_from) | ||
702 | self.assertEqual(portfolio.Amount("BTC", D("0.008")), trades["B2X"].value_to) | ||
703 | self.assertEqual("buy", trades["B2X"].action) | ||
704 | |||
660 | self.assertEqual(portfolio.Amount("BTC", D("0.00")), trades["USDT"].value_from) | 705 | self.assertEqual(portfolio.Amount("BTC", D("0.00")), trades["USDT"].value_from) |
661 | self.assertEqual(portfolio.Amount("BTC", D("0.01")), trades["USDT"].value_to) | 706 | self.assertEqual(portfolio.Amount("BTC", D("0.01")), trades["USDT"].value_to) |
662 | self.assertEqual("buy", trades["USDT"].action) | 707 | self.assertEqual("buy", trades["USDT"].action) |
@@ -680,7 +725,7 @@ class AcceptanceTest(unittest.TestCase): | |||
680 | self.assertEqual("limit", type) | 725 | self.assertEqual("limit", type) |
681 | if symbol == "ETH/BTC": | 726 | if symbol == "ETH/BTC": |
682 | self.assertEqual("sell", action) | 727 | self.assertEqual("sell", action) |
683 | self.assertEqual(2, 3*amount) | 728 | self.assertEqual(D('0.66666666'), amount) |
684 | self.assertEqual(D("0.14014"), price) | 729 | self.assertEqual(D("0.14014"), price) |
685 | elif symbol == "XVG/BTC": | 730 | elif symbol == "XVG/BTC": |
686 | self.assertEqual("sell", action) | 731 | self.assertEqual("sell", action) |
@@ -693,6 +738,7 @@ class AcceptanceTest(unittest.TestCase): | |||
693 | "id": symbol, | 738 | "id": symbol, |
694 | } | 739 | } |
695 | market.create_order.side_effect = create_order | 740 | market.create_order.side_effect = create_order |
741 | market.order_precision.return_value = 8 | ||
696 | 742 | ||
697 | # Action 3 | 743 | # Action 3 |
698 | portfolio.Trade.run_orders() | 744 | portfolio.Trade.run_orders() |
@@ -734,7 +780,7 @@ class AcceptanceTest(unittest.TestCase): | |||
734 | } | 780 | } |
735 | market.fetch_balance.return_value = fetch_balance | 781 | market.fetch_balance.return_value = fetch_balance |
736 | 782 | ||
737 | with mock.patch.object(portfolio.Portfolio, "repartition_pertenthousand", return_value=repartition): | 783 | with mock.patch.object(portfolio.Portfolio, "repartition", return_value=repartition): |
738 | # Action 5 | 784 | # Action 5 |
739 | portfolio.Balance.update_trades(market, only="buy", compute_value="average") | 785 | portfolio.Balance.update_trades(market, only="buy", compute_value="average") |
740 | 786 | ||
@@ -757,9 +803,13 @@ class AcceptanceTest(unittest.TestCase): | |||
757 | self.assertNotIn("BTC", trades) | 803 | self.assertNotIn("BTC", trades) |
758 | 804 | ||
759 | self.assertEqual(portfolio.Amount("BTC", D("0.00")), trades["BTD"].value_from) | 805 | self.assertEqual(portfolio.Amount("BTC", D("0.00")), trades["BTD"].value_from) |
760 | self.assertEqual(portfolio.Amount("BTC", D("0.0097")), trades["BTD"].value_to) | 806 | self.assertEqual(portfolio.Amount("BTC", D("0.00194")), trades["BTD"].value_to) |
761 | self.assertEqual("buy", trades["BTD"].action) | 807 | self.assertEqual("buy", trades["BTD"].action) |
762 | 808 | ||
809 | self.assertEqual(portfolio.Amount("BTC", D("0.00")), trades["B2X"].value_from) | ||
810 | self.assertEqual(portfolio.Amount("BTC", D("0.00776")), trades["B2X"].value_to) | ||
811 | self.assertEqual("buy", trades["B2X"].action) | ||
812 | |||
763 | self.assertEqual(portfolio.Amount("BTC", D("0.00")), trades["USDT"].value_from) | 813 | self.assertEqual(portfolio.Amount("BTC", D("0.00")), trades["USDT"].value_from) |
764 | self.assertEqual(portfolio.Amount("BTC", D("0.0097")), trades["USDT"].value_to) | 814 | self.assertEqual(portfolio.Amount("BTC", D("0.0097")), trades["USDT"].value_to) |
765 | self.assertEqual("buy", trades["USDT"].action) | 815 | self.assertEqual("buy", trades["USDT"].action) |
@@ -772,21 +822,34 @@ class AcceptanceTest(unittest.TestCase): | |||
772 | portfolio.Trade.prepare_orders(only="buy", compute_value=lambda x, y: x["ask"]) | 822 | portfolio.Trade.prepare_orders(only="buy", compute_value=lambda x, y: x["ask"]) |
773 | 823 | ||
774 | all_orders = portfolio.Trade.all_orders(state="pending") | 824 | all_orders = portfolio.Trade.all_orders(state="pending") |
775 | self.assertEqual(3, len(all_orders)) | 825 | self.assertEqual(4, len(all_orders)) |
776 | self.assertEqual(portfolio.Amount("ETC", D("38.5")/3), all_orders[0].amount) | 826 | self.assertEqual(portfolio.Amount("ETC", D("12.83333333")), round(all_orders[0].amount)) |
777 | self.assertEqual(D("0.003"), all_orders[0].rate) | 827 | self.assertEqual(D("0.003"), all_orders[0].rate) |
778 | self.assertEqual("buy", all_orders[0].action) | 828 | self.assertEqual("buy", all_orders[0].action) |
829 | self.assertEqual("long", all_orders[0].trade_type) | ||
779 | 830 | ||
780 | self.assertEqual(portfolio.Amount("BTD", D("24.25")/3), all_orders[1].amount) | 831 | self.assertEqual(portfolio.Amount("BTD", D("1.61666666")), round(all_orders[1].amount)) |
781 | self.assertEqual(D("0.0012"), all_orders[1].rate) | 832 | self.assertEqual(D("0.0012"), all_orders[1].rate) |
782 | self.assertEqual("buy", all_orders[1].action) | 833 | self.assertEqual("sell", all_orders[1].action) |
834 | self.assertEqual("short", all_orders[1].trade_type) | ||
835 | |||
836 | diff = portfolio.Amount("B2X", D("19.4")/3) - all_orders[2].amount | ||
837 | self.assertAlmostEqual(0, diff.value) | ||
838 | self.assertEqual(D("0.0012"), all_orders[2].rate) | ||
839 | self.assertEqual("buy", all_orders[2].action) | ||
840 | self.assertEqual("long", all_orders[2].trade_type) | ||
841 | |||
842 | self.assertEqual(portfolio.Amount("BTC", D("0.0097")), all_orders[3].amount) | ||
843 | self.assertEqual(D("16000"), all_orders[3].rate) | ||
844 | self.assertEqual("sell", all_orders[3].action) | ||
845 | self.assertEqual("long", all_orders[3].trade_type) | ||
783 | 846 | ||
784 | self.assertEqual(portfolio.Amount("BTC", D("0.0097")), all_orders[2].amount) | 847 | # Action 7 |
785 | self.assertEqual(D("16000"), all_orders[2].rate) | 848 | # TODO |
786 | self.assertEqual("sell", all_orders[2].action) | 849 | # portfolio.Trade.run_orders() |
787 | 850 | ||
788 | with mock.patch.object(portfolio.time, "sleep") as sleep: | 851 | with mock.patch.object(portfolio.time, "sleep") as sleep: |
789 | # Action 7 | 852 | # Action 8 |
790 | portfolio.Trade.follow_orders(verbose=False) | 853 | portfolio.Trade.follow_orders(verbose=False) |
791 | 854 | ||
792 | sleep.assert_called_with(30) | 855 | sleep.assert_called_with(30) |