Support limit orders
This commit is contained in:
		| @@ -28,9 +28,13 @@ class Ftx(Exchange): | |||||||
|  |  | ||||||
|     def stoploss(self, pair: str, amount: float, stop_price: float, order_types: Dict) -> Dict: |     def stoploss(self, pair: str, amount: float, stop_price: float, order_types: Dict) -> Dict: | ||||||
|         """ |         """ | ||||||
|         Creates a stoploss market order. |         Creates a stoploss order. | ||||||
|         Stoploss market orders is the only stoploss type supported by ftx. |         depending on order_types.stoploss configuration, uses 'market' or limit order. | ||||||
|  |  | ||||||
|  |         Limit orders are defined by having orderPrice set, otherwise a market order is used. | ||||||
|         """ |         """ | ||||||
|  |         limit_price_pct = order_types.get('stoploss_on_exchange_limit_ratio', 0.99) | ||||||
|  |         limit_rate = stop_price * limit_price_pct | ||||||
|  |  | ||||||
|         ordertype = "stop" |         ordertype = "stop" | ||||||
|  |  | ||||||
| @@ -43,9 +47,11 @@ class Ftx(Exchange): | |||||||
|  |  | ||||||
|         try: |         try: | ||||||
|             params = self._params.copy() |             params = self._params.copy() | ||||||
|  |             if order_types.get('stoploss', 'market') == 'limit': | ||||||
|  |                 # set orderPrice to place limit order, otherwise it's a market order | ||||||
|  |                 params['orderPrice'] = limit_rate | ||||||
|  |  | ||||||
|             amount = self.amount_to_precision(pair, amount) |             amount = self.amount_to_precision(pair, amount) | ||||||
|             # set orderPrice to place limit order (?) |  | ||||||
|  |  | ||||||
|             order = self._api.create_order(symbol=pair, type=ordertype, side='sell', |             order = self._api.create_order(symbol=pair, type=ordertype, side='sell', | ||||||
|                                            amount=amount, price=stop_price, params=params) |                                            amount=amount, price=stop_price, params=params) | ||||||
|   | |||||||
| @@ -34,6 +34,14 @@ def test_stoploss_order_ftx(default_conf, mocker): | |||||||
|     # stoploss_on_exchange_limit_ratio is irrelevant for ftx market orders |     # stoploss_on_exchange_limit_ratio is irrelevant for ftx market orders | ||||||
|     order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=190, |     order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=190, | ||||||
|                               order_types={'stoploss_on_exchange_limit_ratio': 1.05}) |                               order_types={'stoploss_on_exchange_limit_ratio': 1.05}) | ||||||
|  |  | ||||||
|  |     assert api_mock.create_order.call_args_list[0][1]['symbol'] == 'ETH/BTC' | ||||||
|  |     assert api_mock.create_order.call_args_list[0][1]['type'] == STOPLOSS_ORDERTYPE | ||||||
|  |     assert api_mock.create_order.call_args_list[0][1]['side'] == 'sell' | ||||||
|  |     assert api_mock.create_order.call_args_list[0][1]['amount'] == 1 | ||||||
|  |     assert api_mock.create_order.call_args_list[0][1]['price'] == 190 | ||||||
|  |     assert 'orderPrice' not in api_mock.create_order.call_args_list[0][1]['params'] | ||||||
|  |  | ||||||
|     assert api_mock.create_order.call_count == 1 |     assert api_mock.create_order.call_count == 1 | ||||||
|  |  | ||||||
|     api_mock.create_order.reset_mock() |     api_mock.create_order.reset_mock() | ||||||
| @@ -48,6 +56,22 @@ def test_stoploss_order_ftx(default_conf, mocker): | |||||||
|     assert api_mock.create_order.call_args_list[0][1]['side'] == 'sell' |     assert api_mock.create_order.call_args_list[0][1]['side'] == 'sell' | ||||||
|     assert api_mock.create_order.call_args_list[0][1]['amount'] == 1 |     assert api_mock.create_order.call_args_list[0][1]['amount'] == 1 | ||||||
|     assert api_mock.create_order.call_args_list[0][1]['price'] == 220 |     assert api_mock.create_order.call_args_list[0][1]['price'] == 220 | ||||||
|  |     assert 'orderPrice' not in api_mock.create_order.call_args_list[0][1]['params'] | ||||||
|  |  | ||||||
|  |     api_mock.create_order.reset_mock() | ||||||
|  |     order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, | ||||||
|  |                               order_types={'stoploss': 'limit'}) | ||||||
|  |  | ||||||
|  |     assert 'id' in order | ||||||
|  |     assert 'info' in order | ||||||
|  |     assert order['id'] == order_id | ||||||
|  |     assert api_mock.create_order.call_args_list[0][1]['symbol'] == 'ETH/BTC' | ||||||
|  |     assert api_mock.create_order.call_args_list[0][1]['type'] == STOPLOSS_ORDERTYPE | ||||||
|  |     assert api_mock.create_order.call_args_list[0][1]['side'] == 'sell' | ||||||
|  |     assert api_mock.create_order.call_args_list[0][1]['amount'] == 1 | ||||||
|  |     assert api_mock.create_order.call_args_list[0][1]['price'] == 220 | ||||||
|  |     assert 'orderPrice' in api_mock.create_order.call_args_list[0][1]['params'] | ||||||
|  |     assert api_mock.create_order.call_args_list[0][1]['params']['orderPrice'] == 217.8 | ||||||
|  |  | ||||||
|     # test exception handling |     # test exception handling | ||||||
|     with pytest.raises(DependencyException): |     with pytest.raises(DependencyException): | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user