diff --git a/freqtrade/exchange/__init__.py b/freqtrade/exchange/__init__.py index b3338670f..4e2fd0841 100644 --- a/freqtrade/exchange/__init__.py +++ b/freqtrade/exchange/__init__.py @@ -209,22 +209,43 @@ def get_ticker_history(pair: str, tick_interval: str) -> List[Dict]: return [] -def cancel_order(order_id: str) -> None: +def cancel_order(order_id: str, pair: str) -> None: if _CONF['dry_run']: return - return _API.cancel_order(order_id) + try: + return _API.cancel_order(order_id, pair) + except ccxt.NetworkError as e: + raise NetworkException( + 'Could not get order due to networking error. Message: {}'.format(e) + ) + except ccxt.InvalidOrder as e: + raise DependencyException( + 'Could not cancel order. Message: {}'.format(e) + ) + except ccxt.BaseError as e: + raise OperationalException(e) -def get_order(order_id: str) -> Dict: +def get_order(order_id: str, pair: str) -> Dict: if _CONF['dry_run']: order = _DRY_RUN_OPEN_ORDERS[order_id] order.update({ 'id': order_id }) return order - - return _API.get_order(order_id) + try: + return _API.fetch_order(order_id, pair) + except ccxt.NetworkError as e: + raise NetworkException( + 'Could not get order due to networking error. Message: {}'.format(e) + ) + except ccxt.InvalidOrder as e: + raise DependencyException( + 'Could not get order. Message: {}'.format(e) + ) + except ccxt.BaseError as e: + raise OperationalException(e) # TODO: reimplement, not part of ccxt diff --git a/freqtrade/main.py b/freqtrade/main.py index f8a2b9b38..bfb09e5d6 100755 --- a/freqtrade/main.py +++ b/freqtrade/main.py @@ -8,7 +8,6 @@ from datetime import datetime from typing import Dict, List, Optional, Any import arrow -import requests from cachetools import cached, TTLCache from freqtrade import (DependencyException, OperationalException, NetworkException, __version__, @@ -86,7 +85,7 @@ def process_maybe_execute_sell(trade, interval): if trade.open_order_id: # Update trade with order values logger.info('Got open order for %s', trade) - trade.update(exchange.get_order(trade.open_order_id)) + trade.update(exchange.get_order(trade.open_order_id, trade.pair)) if trade.is_open and trade.open_order_id is None: # Check if we can sell our current pair @@ -150,7 +149,7 @@ def handle_timedout_limit_buy(trade: Trade, order: Dict) -> bool: """Buy timeout - cancel order :return: True if order was fully cancelled """ - exchange.cancel_order(trade.open_order_id) + exchange.cancel_order(trade.open_order_id, trade.pair) if order['remaining'] == order['amount']: # if trade is not partially completed, just delete the trade Trade.session.delete(trade) @@ -181,7 +180,7 @@ def handle_timedout_limit_sell(trade: Trade, order: Dict) -> bool: """ if order['remaining'] == order['amount']: # if trade is not partially completed, just cancel the trade - exchange.cancel_order(trade.open_order_id) + exchange.cancel_order(trade.open_order_id, trade.pair) trade.close_rate = None trade.close_profit = None trade.close_date = None @@ -206,8 +205,8 @@ def check_handle_timedout(timeoutvalue: int) -> None: for trade in Trade.query.filter(Trade.open_order_id.isnot(None)).all(): try: - order = exchange.get_order(trade.open_order_id) - except requests.exceptions.RequestException: + order = exchange.get_order(trade.open_order_id, trade.pair) + except (NetworkException, DependencyException): logger.info('Cannot query order for %s due to %s', trade, traceback.format_exc()) continue ordertime = arrow.get(order['opened']) diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 366dd9037..a680db3c7 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -140,7 +140,7 @@ def _status(bot: Bot, update: Update) -> None: for trade in trades: order = None if trade.open_order_id: - order = exchange.get_order(trade.open_order_id) + order = exchange.get_order(trade.open_order_id, trade.pair) # calculate profit and send message to user current_rate = exchange.get_ticker(trade.pair, False)['bid'] current_profit = trade.calc_profit_percent(current_rate) @@ -599,11 +599,11 @@ def shorten_date(_date): def _exec_forcesell(trade: Trade) -> None: # Check if there is there is an open order if trade.open_order_id: - order = exchange.get_order(trade.open_order_id) + order = exchange.get_order(trade.open_order_id, trade.pair) # Cancel open LIMIT_BUY orders and close trade if order and not order['closed'] and order['type'] == 'LIMIT_BUY': - exchange.cancel_order(trade.open_order_id) + exchange.cancel_order(trade.open_order_id, trade.pair) trade.close(order.get('rate') or trade.open_rate) # TODO: sell amount which has been bought already return diff --git a/freqtrade/tests/exchange/test_exchange.py b/freqtrade/tests/exchange/test_exchange.py index 86c73c680..52095a274 100644 --- a/freqtrade/tests/exchange/test_exchange.py +++ b/freqtrade/tests/exchange/test_exchange.py @@ -271,7 +271,7 @@ def test_cancel_order_dry_run(default_conf, mocker): default_conf['dry_run'] = True mocker.patch.dict('freqtrade.exchange._CONF', default_conf) - assert cancel_order(order_id='123') is None + assert cancel_order(order_id='123', pair='TKN/BTC') is None # Ensure that if not dry_run, we should call API @@ -281,7 +281,7 @@ def test_cancel_order(default_conf, mocker): api_mock = MagicMock() api_mock.cancel_order = MagicMock(return_value=123) mocker.patch('freqtrade.exchange._API', api_mock) - assert cancel_order(order_id='_') == 123 + assert cancel_order(order_id='_', pair='TKN/BTC') == 123 def test_get_order(default_conf, mocker): @@ -290,15 +290,15 @@ def test_get_order(default_conf, mocker): order = MagicMock() order.myid = 123 exchange._DRY_RUN_OPEN_ORDERS['X'] = order - print(exchange.get_order('X')) - assert exchange.get_order('X').myid == 123 + print(exchange.get_order('X', 'TKN/BTC')) + assert exchange.get_order('X', 'TKN/BTC').myid == 123 default_conf['dry_run'] = False mocker.patch.dict('freqtrade.exchange._CONF', default_conf) api_mock = MagicMock() - api_mock.get_order = MagicMock(return_value=456) + api_mock.fetch_order = MagicMock(return_value=456) mocker.patch('freqtrade.exchange._API', api_mock) - assert exchange.get_order('X') == 456 + assert exchange.get_order('X', 'TKN/BTC') == 456 def test_get_name(default_conf, mocker):