diff options
Diffstat (limited to 'test.py')
-rw-r--r-- | test.py | 112 |
1 files changed, 64 insertions, 48 deletions
@@ -1403,6 +1403,38 @@ class MarketTest(WebMockTestCase): | |||
1403 | else: | 1403 | else: |
1404 | time_mock.assert_called_with(sleep) | 1404 | time_mock.assert_called_with(sleep) |
1405 | 1405 | ||
1406 | with self.subTest("disappearing order"), \ | ||
1407 | mock.patch("market.ReportStore"): | ||
1408 | all_orders.reset_mock() | ||
1409 | m = market.Market(self.ccxt, self.market_args()) | ||
1410 | |||
1411 | order_mock1 = mock.Mock() | ||
1412 | order_mock2 = mock.Mock() | ||
1413 | all_orders.side_effect = [ | ||
1414 | [order_mock1, order_mock2], | ||
1415 | [order_mock1, order_mock2], | ||
1416 | |||
1417 | [order_mock1, order_mock2], | ||
1418 | [order_mock1, order_mock2], | ||
1419 | |||
1420 | [] | ||
1421 | ] | ||
1422 | |||
1423 | order_mock1.get_status.side_effect = ["open", "closed"] | ||
1424 | order_mock2.get_status.side_effect = ["open", "error_disappeared"] | ||
1425 | |||
1426 | order_mock1.trade = mock.Mock() | ||
1427 | trade_mock = mock.Mock() | ||
1428 | order_mock2.trade = trade_mock | ||
1429 | |||
1430 | trade_mock.tick_actions_recreate.return_value = "tick1" | ||
1431 | |||
1432 | m.follow_orders() | ||
1433 | |||
1434 | trade_mock.tick_actions_recreate.assert_called_once_with(2) | ||
1435 | trade_mock.prepare_order.assert_called_once_with(compute_value="tick1") | ||
1436 | m.report.log_error.assert_called_once_with("follow_orders", message=mock.ANY) | ||
1437 | |||
1406 | @mock.patch.object(market.BalanceStore, "fetch_balances") | 1438 | @mock.patch.object(market.BalanceStore, "fetch_balances") |
1407 | def test_move_balance(self, fetch_balances): | 1439 | def test_move_balance(self, fetch_balances): |
1408 | for debug in [True, False]: | 1440 | for debug in [True, False]: |
@@ -2406,27 +2438,6 @@ class TradeTest(WebMockTestCase): | |||
2406 | order1.filled_amount.assert_called_with(in_base_currency=True) | 2438 | order1.filled_amount.assert_called_with(in_base_currency=True) |
2407 | order2.filled_amount.assert_called_with(in_base_currency=True) | 2439 | order2.filled_amount.assert_called_with(in_base_currency=True) |
2408 | 2440 | ||
2409 | def test_reopen_same_order(self): | ||
2410 | value_from = portfolio.Amount("BTC", "0.5") | ||
2411 | value_from.linked_to = portfolio.Amount("ETH", "10.0") | ||
2412 | value_to = portfolio.Amount("BTC", "1.0") | ||
2413 | trade = portfolio.Trade(value_from, value_to, "ETH", self.m) | ||
2414 | order = portfolio.Order("buy", portfolio.Amount("ETH", 10), | ||
2415 | D("0.1"), "BTC", "long", self.m, "trade") | ||
2416 | with mock.patch("portfolio.Order.run") as run: | ||
2417 | new_order = trade.reopen_same_order(order) | ||
2418 | self.assertEqual("buy", new_order.action) | ||
2419 | self.assertEqual(portfolio.Amount("ETH", 10), new_order.amount) | ||
2420 | self.assertEqual(D("0.1"), new_order.rate) | ||
2421 | self.assertEqual("BTC", new_order.base_currency) | ||
2422 | self.assertEqual("long", new_order.trade_type) | ||
2423 | self.assertEqual(self.m, new_order.market) | ||
2424 | self.assertEqual(False, new_order.close_if_possible) | ||
2425 | self.assertEqual(trade, new_order.trade) | ||
2426 | run.assert_called_once() | ||
2427 | self.assertEqual(1, len(trade.orders)) | ||
2428 | self.assertEqual(new_order, trade.orders[0]) | ||
2429 | |||
2430 | @mock.patch.object(portfolio.Computation, "compute_value") | 2441 | @mock.patch.object(portfolio.Computation, "compute_value") |
2431 | @mock.patch.object(portfolio.Trade, "filled_amount") | 2442 | @mock.patch.object(portfolio.Trade, "filled_amount") |
2432 | @mock.patch.object(portfolio, "Order") | 2443 | @mock.patch.object(portfolio, "Order") |
@@ -2582,6 +2593,21 @@ class TradeTest(WebMockTestCase): | |||
2582 | D("125"), "FOO", "long", self.m, | 2593 | D("125"), "FOO", "long", self.m, |
2583 | trade, close_if_possible=False) | 2594 | trade, close_if_possible=False) |
2584 | 2595 | ||
2596 | def test_tick_actions_recreate(self): | ||
2597 | value_from = portfolio.Amount("BTC", "0.5") | ||
2598 | value_from.linked_to = portfolio.Amount("ETH", "10.0") | ||
2599 | value_to = portfolio.Amount("BTC", "1.0") | ||
2600 | trade = portfolio.Trade(value_from, value_to, "ETH", self.m) | ||
2601 | |||
2602 | self.assertEqual("average", trade.tick_actions_recreate(0)) | ||
2603 | self.assertEqual("foo", trade.tick_actions_recreate(0, default="foo")) | ||
2604 | self.assertEqual("average", trade.tick_actions_recreate(1)) | ||
2605 | self.assertEqual(trade.tick_actions[2][1], trade.tick_actions_recreate(2)) | ||
2606 | self.assertEqual(trade.tick_actions[2][1], trade.tick_actions_recreate(3)) | ||
2607 | self.assertEqual(trade.tick_actions[5][1], trade.tick_actions_recreate(5)) | ||
2608 | self.assertEqual(trade.tick_actions[5][1], trade.tick_actions_recreate(6)) | ||
2609 | self.assertEqual("default", trade.tick_actions_recreate(7)) | ||
2610 | self.assertEqual("default", trade.tick_actions_recreate(8)) | ||
2585 | 2611 | ||
2586 | @mock.patch.object(portfolio.Trade, "prepare_order") | 2612 | @mock.patch.object(portfolio.Trade, "prepare_order") |
2587 | def test_update_order(self, prepare_order): | 2613 | def test_update_order(self, prepare_order): |
@@ -2984,12 +3010,12 @@ class OrderTest(WebMockTestCase): | |||
2984 | self.m.ccxt.privatePostReturnOrderTrades.return_value = [ | 3010 | self.m.ccxt.privatePostReturnOrderTrades.return_value = [ |
2985 | { | 3011 | { |
2986 | "tradeID": 42, "type": "buy", "fee": "0.0015", | 3012 | "tradeID": 42, "type": "buy", "fee": "0.0015", |
2987 | "date": "2017-12-30 12:00:12", "rate": "0.1", | 3013 | "date": "2017-12-30 13:00:12", "rate": "0.1", |
2988 | "amount": "3", "total": "0.3" | 3014 | "amount": "3", "total": "0.3" |
2989 | }, | 3015 | }, |
2990 | { | 3016 | { |
2991 | "tradeID": 43, "type": "buy", "fee": "0.0015", | 3017 | "tradeID": 43, "type": "buy", "fee": "0.0015", |
2992 | "date": "2017-12-30 13:00:12", "rate": "0.2", | 3018 | "date": "2017-12-30 12:00:12", "rate": "0.2", |
2993 | "amount": "2", "total": "0.4" | 3019 | "amount": "2", "total": "0.4" |
2994 | } | 3020 | } |
2995 | ] | 3021 | ] |
@@ -3002,8 +3028,8 @@ class OrderTest(WebMockTestCase): | |||
3002 | 3028 | ||
3003 | self.m.ccxt.privatePostReturnOrderTrades.assert_called_with({"orderNumber": 12}) | 3029 | self.m.ccxt.privatePostReturnOrderTrades.assert_called_with({"orderNumber": 12}) |
3004 | self.assertEqual(2, len(order.mouvements)) | 3030 | self.assertEqual(2, len(order.mouvements)) |
3005 | self.assertEqual(42, order.mouvements[0].id) | 3031 | self.assertEqual(43, order.mouvements[0].id) |
3006 | self.assertEqual(43, order.mouvements[1].id) | 3032 | self.assertEqual(42, order.mouvements[1].id) |
3007 | 3033 | ||
3008 | self.m.ccxt.privatePostReturnOrderTrades.side_effect = portfolio.ExchangeError | 3034 | self.m.ccxt.privatePostReturnOrderTrades.side_effect = portfolio.ExchangeError |
3009 | order = portfolio.Order("buy", portfolio.Amount("ETH", 10), | 3035 | order = portfolio.Order("buy", portfolio.Amount("ETH", 10), |
@@ -3059,9 +3085,9 @@ class OrderTest(WebMockTestCase): | |||
3059 | self.m.report.log_debug_action.assert_called_once() | 3085 | self.m.report.log_debug_action.assert_called_once() |
3060 | 3086 | ||
3061 | @mock.patch.object(portfolio.Order, "fetch_mouvements") | 3087 | @mock.patch.object(portfolio.Order, "fetch_mouvements") |
3062 | @mock.patch.object(portfolio.Order, "fix_disappeared_order") | 3088 | @mock.patch.object(portfolio.Order, "mark_disappeared_order") |
3063 | @mock.patch.object(portfolio.Order, "mark_finished_order") | 3089 | @mock.patch.object(portfolio.Order, "mark_finished_order") |
3064 | def test_fetch(self, mark_finished_order, fix_disappeared_order, fetch_mouvements): | 3090 | def test_fetch(self, mark_finished_order, mark_disappeared_order, fetch_mouvements): |
3065 | order = portfolio.Order("buy", portfolio.Amount("ETH", 10), | 3091 | order = portfolio.Order("buy", portfolio.Amount("ETH", 10), |
3066 | D("0.1"), "BTC", "long", self.m, "trade") | 3092 | D("0.1"), "BTC", "long", self.m, "trade") |
3067 | order.id = 45 | 3093 | order.id = 45 |
@@ -3072,7 +3098,7 @@ class OrderTest(WebMockTestCase): | |||
3072 | self.m.report.log_debug_action.reset_mock() | 3098 | self.m.report.log_debug_action.reset_mock() |
3073 | self.m.ccxt.fetch_order.assert_not_called() | 3099 | self.m.ccxt.fetch_order.assert_not_called() |
3074 | mark_finished_order.assert_not_called() | 3100 | mark_finished_order.assert_not_called() |
3075 | fix_disappeared_order.assert_not_called() | 3101 | mark_disappeared_order.assert_not_called() |
3076 | fetch_mouvements.assert_not_called() | 3102 | fetch_mouvements.assert_not_called() |
3077 | 3103 | ||
3078 | with self.subTest(debug=False): | 3104 | with self.subTest(debug=False): |
@@ -3090,7 +3116,7 @@ class OrderTest(WebMockTestCase): | |||
3090 | self.assertEqual(1, len(order.results)) | 3116 | self.assertEqual(1, len(order.results)) |
3091 | self.m.report.log_debug_action.assert_not_called() | 3117 | self.m.report.log_debug_action.assert_not_called() |
3092 | mark_finished_order.assert_called_once() | 3118 | mark_finished_order.assert_called_once() |
3093 | fix_disappeared_order.assert_called_once() | 3119 | mark_disappeared_order.assert_called_once() |
3094 | 3120 | ||
3095 | mark_finished_order.reset_mock() | 3121 | mark_finished_order.reset_mock() |
3096 | with self.subTest(missing_order=True): | 3122 | with self.subTest(missing_order=True): |
@@ -3101,7 +3127,7 @@ class OrderTest(WebMockTestCase): | |||
3101 | self.assertEqual("closed_unknown", order.status) | 3127 | self.assertEqual("closed_unknown", order.status) |
3102 | mark_finished_order.assert_called_once() | 3128 | mark_finished_order.assert_called_once() |
3103 | 3129 | ||
3104 | def test_fix_disappeared_order(self): | 3130 | def test_mark_disappeared_order(self): |
3105 | with self.subTest("Open order"): | 3131 | with self.subTest("Open order"): |
3106 | order = portfolio.Order("buy", portfolio.Amount("ETH", 10), | 3132 | order = portfolio.Order("buy", portfolio.Amount("ETH", 10), |
3107 | D("0.1"), "BTC", "long", self.m, "trade") | 3133 | D("0.1"), "BTC", "long", self.m, "trade") |
@@ -3116,9 +3142,8 @@ class OrderTest(WebMockTestCase): | |||
3116 | "fee":"0.00150000", | 3142 | "fee":"0.00150000", |
3117 | "date":"2018-04-02 00:09:13" | 3143 | "date":"2018-04-02 00:09:13" |
3118 | })) | 3144 | })) |
3119 | with mock.patch.object(order, "trade") as trade: | 3145 | order.mark_disappeared_order() |
3120 | order.fix_disappeared_order() | 3146 | self.assertEqual("pending", order.status) |
3121 | trade.reopen_same_order.assert_not_called() | ||
3122 | 3147 | ||
3123 | with self.subTest("Non-zero amount"): | 3148 | with self.subTest("Non-zero amount"): |
3124 | order = portfolio.Order("buy", portfolio.Amount("ETH", 10), | 3149 | order = portfolio.Order("buy", portfolio.Amount("ETH", 10), |
@@ -3135,10 +3160,8 @@ class OrderTest(WebMockTestCase): | |||
3135 | "fee":"0.00150000", | 3160 | "fee":"0.00150000", |
3136 | "date":"2018-04-02 00:09:13" | 3161 | "date":"2018-04-02 00:09:13" |
3137 | })) | 3162 | })) |
3138 | with mock.patch.object(order, "trade") as trade: | 3163 | order.mark_disappeared_order() |
3139 | order.fix_disappeared_order() | 3164 | self.assertEqual("closed", order.status) |
3140 | self.assertEqual("closed", order.status) | ||
3141 | trade.reopen_same_order.assert_not_called() | ||
3142 | 3165 | ||
3143 | with self.subTest("Other mouvements"): | 3166 | with self.subTest("Other mouvements"): |
3144 | order = portfolio.Order("buy", portfolio.Amount("ETH", 10), | 3167 | order = portfolio.Order("buy", portfolio.Amount("ETH", 10), |
@@ -3165,10 +3188,8 @@ class OrderTest(WebMockTestCase): | |||
3165 | "fee":"0.00150000", | 3188 | "fee":"0.00150000", |
3166 | "date":"2018-04-02 00:09:13" | 3189 | "date":"2018-04-02 00:09:13" |
3167 | })) | 3190 | })) |
3168 | with mock.patch.object(order, "trade") as trade: | 3191 | order.mark_disappeared_order() |
3169 | order.fix_disappeared_order() | 3192 | self.assertEqual("error_disappeared", order.status) |
3170 | self.assertEqual("closed", order.status) | ||
3171 | trade.reopen_same_order.assert_not_called() | ||
3172 | 3193 | ||
3173 | with self.subTest("Order disappeared"): | 3194 | with self.subTest("Order disappeared"): |
3174 | order = portfolio.Order("buy", portfolio.Amount("ETH", 10), | 3195 | order = portfolio.Order("buy", portfolio.Amount("ETH", 10), |
@@ -3185,13 +3206,8 @@ class OrderTest(WebMockTestCase): | |||
3185 | "fee":"0.00150000", | 3206 | "fee":"0.00150000", |
3186 | "date":"2018-04-02 00:09:13" | 3207 | "date":"2018-04-02 00:09:13" |
3187 | })) | 3208 | })) |
3188 | with mock.patch.object(order, "trade") as trade: | 3209 | order.mark_disappeared_order() |
3189 | trade.reopen_same_order.return_value = "New order" | 3210 | self.assertEqual("error_disappeared", order.status) |
3190 | order.fix_disappeared_order() | ||
3191 | self.assertEqual("error_disappeared", order.status) | ||
3192 | trade.reopen_same_order.assert_called_once_with(order) | ||
3193 | self.m.report.log_error.assert_called_once_with('fetch', | ||
3194 | message='Order Order(buy long 10.00000000 ETH at 0.1 BTC [error_disappeared]) disappeared, recreating it as New order') | ||
3195 | 3211 | ||
3196 | @mock.patch.object(portfolio.Order, "fetch") | 3212 | @mock.patch.object(portfolio.Order, "fetch") |
3197 | def test_get_status(self, fetch): | 3213 | def test_get_status(self, fetch): |