Merge pull request #3676 from freqtrade/stoploss_remove_unused_argument

[minor] Cleanup and exception hierarchy documentation
This commit is contained in:
Matthias 2020-08-14 07:11:56 +02:00 committed by GitHub
commit 22f6e884ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 53 additions and 26 deletions

View File

@ -85,6 +85,35 @@ docker-compose exec freqtrade_develop /bin/bash
![image](https://user-images.githubusercontent.com/419355/65456522-ba671a80-de06-11e9-9598-df9ca0d8dcac.png)
## ErrorHandling
Freqtrade Exceptions all inherit from `FreqtradeException`.
This general class of error should however not be used directly. Instead, multiple specialized sub-Exceptions exist.
Below is an outline of exception inheritance hierarchy:
```
+ FreqtradeException
|
+---+ OperationalException
|
+---+ DependencyException
| |
| +---+ PricingError
| |
| +---+ ExchangeError
| |
| +---+ TemporaryError
| |
| +---+ DDosProtection
| |
| +---+ InvalidOrderException
| |
| +---+ RetryableOrderError
|
+---+ StrategyError
```
## Modules
### Dynamic Pairlist

View File

@ -29,7 +29,14 @@ class PricingError(DependencyException):
"""
class InvalidOrderException(FreqtradeException):
class ExchangeError(DependencyException):
"""
Error raised out of the exchange.
Has multiple Errors to determine the appropriate error.
"""
class InvalidOrderException(ExchangeError):
"""
This is returned when the order is not valid. Example:
If stoploss on exchange order is hit, then trying to cancel the order
@ -44,13 +51,6 @@ class RetryableOrderError(InvalidOrderException):
"""
class ExchangeError(DependencyException):
"""
Error raised out of the exchange.
Has multiple Errors to determine the appropriate error.
"""
class TemporaryError(ExchangeError):
"""
Temporary network or exchange related error.

View File

@ -975,7 +975,7 @@ class Exchange:
except ccxt.BaseError as e:
raise OperationalException(e) from e
# Assign method to fetch_stoploss_order to allow easy overriding in other classes
# Assign method to cancel_stoploss_order to allow easy overriding in other classes
cancel_stoploss_order = cancel_order
def is_cancel_order_result_suitable(self, corder) -> bool:
@ -1041,10 +1041,10 @@ class Exchange:
@retrier
def fetch_l2_order_book(self, pair: str, limit: int = 100) -> dict:
"""
get order book level 2 from exchange
Notes:
20180619: bittrex doesnt support limits -.-
Get L2 order book from exchange.
Can be limited to a certain amount (if supported).
Returns a dict in the format
{'asks': [price, volume], 'bids': [price, volume]}
"""
try:

View File

@ -770,7 +770,7 @@ class FreqtradeBot:
logger.debug('Found no sell signal for %s.', trade)
return False
def create_stoploss_order(self, trade: Trade, stop_price: float, rate: float) -> bool:
def create_stoploss_order(self, trade: Trade, stop_price: float) -> bool:
"""
Abstracts creating stoploss orders from the logic.
Handles errors and updates the trade database object.
@ -833,14 +833,13 @@ class FreqtradeBot:
stoploss = self.edge.stoploss(pair=trade.pair) if self.edge else self.strategy.stoploss
stop_price = trade.open_rate * (1 + stoploss)
if self.create_stoploss_order(trade=trade, stop_price=stop_price, rate=stop_price):
if self.create_stoploss_order(trade=trade, stop_price=stop_price):
trade.stoploss_last_update = datetime.now()
return False
# If stoploss order is canceled for some reason we add it
if stoploss_order and stoploss_order['status'] in ('canceled', 'cancelled'):
if self.create_stoploss_order(trade=trade, stop_price=trade.stop_loss,
rate=trade.stop_loss):
if self.create_stoploss_order(trade=trade, stop_price=trade.stop_loss):
return False
else:
trade.stoploss_order_id = None
@ -877,8 +876,7 @@ class FreqtradeBot:
f"for pair {trade.pair}")
# Create new stoploss order
if not self.create_stoploss_order(trade=trade, stop_price=trade.stop_loss,
rate=trade.stop_loss):
if not self.create_stoploss_order(trade=trade, stop_price=trade.stop_loss):
logger.warning(f"Could not create trailing stoploss order "
f"for pair {trade.pair}.")
@ -923,7 +921,7 @@ class FreqtradeBot:
if not trade.open_order_id:
continue
order = self.exchange.fetch_order(trade.open_order_id, trade.pair)
except (ExchangeError, InvalidOrderException):
except (ExchangeError):
logger.info('Cannot query order for %s due to %s', trade, traceback.format_exc())
continue
@ -956,7 +954,7 @@ class FreqtradeBot:
for trade in Trade.get_open_order_trades():
try:
order = self.exchange.fetch_order(trade.open_order_id, trade.pair)
except (DependencyException, InvalidOrderException):
except (ExchangeError):
logger.info('Cannot query order for %s due to %s', trade, traceback.format_exc())
continue

View File

@ -11,7 +11,7 @@ from typing import Any, Dict, List, Optional, Tuple, Union
import arrow
from numpy import NAN, mean
from freqtrade.exceptions import (ExchangeError, InvalidOrderException,
from freqtrade.exceptions import (ExchangeError,
PricingError)
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_msecs
from freqtrade.misc import shorten_date
@ -555,7 +555,7 @@ class RPC:
try:
self._freqtrade.exchange.cancel_order(trade.open_order_id, trade.pair)
c_count += 1
except (ExchangeError, InvalidOrderException):
except (ExchangeError):
pass
# cancel stoploss on exchange ...
@ -565,7 +565,7 @@ class RPC:
self._freqtrade.exchange.cancel_stoploss_order(trade.stoploss_order_id,
trade.pair)
c_count += 1
except (ExchangeError, InvalidOrderException):
except (ExchangeError):
pass
Trade.session.delete(trade)

View File

@ -1301,7 +1301,7 @@ def test_create_stoploss_order_invalid_order(mocker, default_conf, caplog, fee,
freqtrade.enter_positions()
trade = Trade.query.first()
caplog.clear()
freqtrade.create_stoploss_order(trade, 200, 199)
freqtrade.create_stoploss_order(trade, 200)
assert trade.stoploss_order_id is None
assert trade.sell_reason == SellType.EMERGENCY_SELL.value
assert log_has("Unable to place a stoploss order on exchange. ", caplog)
@ -4107,7 +4107,7 @@ def test_sync_wallet_dry_run(mocker, default_conf, ticker, fee, limit_buy_order,
def test_cancel_all_open_orders(mocker, default_conf, fee, limit_buy_order, limit_sell_order):
default_conf['cancel_open_orders_on_exit'] = True
mocker.patch('freqtrade.exchange.Exchange.fetch_order',
side_effect=[DependencyException(), limit_sell_order, limit_buy_order])
side_effect=[ExchangeError(), limit_sell_order, limit_buy_order])
buy_mock = mocker.patch('freqtrade.freqtradebot.FreqtradeBot.handle_cancel_buy')
sell_mock = mocker.patch('freqtrade.freqtradebot.FreqtradeBot.handle_cancel_sell')