mirror of
https://github.com/freqtrade/freqtrade.git
synced 2024-11-10 10:21:59 +00:00
Merge pull request #3676 from freqtrade/stoploss_remove_unused_argument
[minor] Cleanup and exception hierarchy documentation
This commit is contained in:
commit
22f6e884ed
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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')
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user