Introduce ExchangeError
This commit is contained in:
parent
e74d2af857
commit
bf61bc9d83
@ -10,7 +10,7 @@ from typing import Any, Dict, List, Optional
|
|||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
|
|
||||||
from freqtrade.data.history import load_pair_history
|
from freqtrade.data.history import load_pair_history
|
||||||
from freqtrade.exceptions import DependencyException, OperationalException
|
from freqtrade.exceptions import ExchangeError, OperationalException
|
||||||
from freqtrade.exchange import Exchange
|
from freqtrade.exchange import Exchange
|
||||||
from freqtrade.state import RunMode
|
from freqtrade.state import RunMode
|
||||||
from freqtrade.constants import ListPairsWithTimeframes
|
from freqtrade.constants import ListPairsWithTimeframes
|
||||||
@ -105,7 +105,7 @@ class DataProvider:
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return self._exchange.fetch_ticker(pair)
|
return self._exchange.fetch_ticker(pair)
|
||||||
except DependencyException:
|
except ExchangeError:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
def orderbook(self, pair: str, maximum: int) -> Dict[str, List]:
|
def orderbook(self, pair: str, maximum: int) -> Dict[str, List]:
|
||||||
|
@ -37,7 +37,14 @@ class InvalidOrderException(FreqtradeException):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class TemporaryError(DependencyException):
|
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.
|
Temporary network or exchange related error.
|
||||||
This could happen when an exchange is congested, unavailable, or the user
|
This could happen when an exchange is congested, unavailable, or the user
|
||||||
|
@ -4,7 +4,7 @@ from typing import Dict
|
|||||||
|
|
||||||
import ccxt
|
import ccxt
|
||||||
|
|
||||||
from freqtrade.exceptions import (DDosProtection, DependencyException,
|
from freqtrade.exceptions import (DDosProtection, ExchangeError,
|
||||||
InvalidOrderException, OperationalException,
|
InvalidOrderException, OperationalException,
|
||||||
TemporaryError)
|
TemporaryError)
|
||||||
from freqtrade.exchange import Exchange
|
from freqtrade.exchange import Exchange
|
||||||
@ -80,7 +80,7 @@ class Binance(Exchange):
|
|||||||
'stop price: %s. limit: %s', pair, stop_price, rate)
|
'stop price: %s. limit: %s', pair, stop_price, rate)
|
||||||
return order
|
return order
|
||||||
except ccxt.InsufficientFunds as e:
|
except ccxt.InsufficientFunds as e:
|
||||||
raise DependencyException(
|
raise ExchangeError(
|
||||||
f'Insufficient funds to create {ordertype} sell order on market {pair}.'
|
f'Insufficient funds to create {ordertype} sell order on market {pair}.'
|
||||||
f'Tried to sell amount {amount} at rate {rate}. '
|
f'Tried to sell amount {amount} at rate {rate}. '
|
||||||
f'Message: {e}') from e
|
f'Message: {e}') from e
|
||||||
|
@ -20,7 +20,7 @@ from pandas import DataFrame
|
|||||||
|
|
||||||
from freqtrade.constants import ListPairsWithTimeframes
|
from freqtrade.constants import ListPairsWithTimeframes
|
||||||
from freqtrade.data.converter import ohlcv_to_dataframe, trades_dict_to_list
|
from freqtrade.data.converter import ohlcv_to_dataframe, trades_dict_to_list
|
||||||
from freqtrade.exceptions import (DDosProtection, DependencyException,
|
from freqtrade.exceptions import (DDosProtection, ExchangeError,
|
||||||
InvalidOrderException, OperationalException,
|
InvalidOrderException, OperationalException,
|
||||||
TemporaryError)
|
TemporaryError)
|
||||||
from freqtrade.exchange.common import BAD_EXCHANGES, retrier, retrier_async
|
from freqtrade.exchange.common import BAD_EXCHANGES, retrier, retrier_async
|
||||||
@ -352,7 +352,7 @@ class Exchange:
|
|||||||
for pair in [f"{curr_1}/{curr_2}", f"{curr_2}/{curr_1}"]:
|
for pair in [f"{curr_1}/{curr_2}", f"{curr_2}/{curr_1}"]:
|
||||||
if pair in self.markets and self.markets[pair].get('active'):
|
if pair in self.markets and self.markets[pair].get('active'):
|
||||||
return pair
|
return pair
|
||||||
raise DependencyException(f"Could not combine {curr_1} and {curr_2} to get a valid pair.")
|
raise ExchangeError(f"Could not combine {curr_1} and {curr_2} to get a valid pair.")
|
||||||
|
|
||||||
def validate_timeframes(self, timeframe: Optional[str]) -> None:
|
def validate_timeframes(self, timeframe: Optional[str]) -> None:
|
||||||
"""
|
"""
|
||||||
@ -519,12 +519,12 @@ class Exchange:
|
|||||||
amount, rate_for_order, params)
|
amount, rate_for_order, params)
|
||||||
|
|
||||||
except ccxt.InsufficientFunds as e:
|
except ccxt.InsufficientFunds as e:
|
||||||
raise DependencyException(
|
raise ExchangeError(
|
||||||
f'Insufficient funds to create {ordertype} {side} order on market {pair}.'
|
f'Insufficient funds to create {ordertype} {side} order on market {pair}.'
|
||||||
f'Tried to {side} amount {amount} at rate {rate}.'
|
f'Tried to {side} amount {amount} at rate {rate}.'
|
||||||
f'Message: {e}') from e
|
f'Message: {e}') from e
|
||||||
except ccxt.InvalidOrder as e:
|
except ccxt.InvalidOrder as e:
|
||||||
raise DependencyException(
|
raise ExchangeError(
|
||||||
f'Could not create {ordertype} {side} order on market {pair}.'
|
f'Could not create {ordertype} {side} order on market {pair}.'
|
||||||
f'Tried to {side} amount {amount} at rate {rate}.'
|
f'Tried to {side} amount {amount} at rate {rate}.'
|
||||||
f'Message: {e}') from e
|
f'Message: {e}') from e
|
||||||
@ -637,7 +637,7 @@ class Exchange:
|
|||||||
def fetch_ticker(self, pair: str) -> dict:
|
def fetch_ticker(self, pair: str) -> dict:
|
||||||
try:
|
try:
|
||||||
if pair not in self._api.markets or not self._api.markets[pair].get('active'):
|
if pair not in self._api.markets or not self._api.markets[pair].get('active'):
|
||||||
raise DependencyException(f"Pair {pair} not available")
|
raise ExchangeError(f"Pair {pair} not available")
|
||||||
data = self._api.fetch_ticker(pair)
|
data = self._api.fetch_ticker(pair)
|
||||||
return data
|
return data
|
||||||
except ccxt.DDoSProtection as e:
|
except ccxt.DDoSProtection as e:
|
||||||
@ -1151,7 +1151,7 @@ class Exchange:
|
|||||||
|
|
||||||
fee_to_quote_rate = safe_value_fallback(tick, tick, 'last', 'ask')
|
fee_to_quote_rate = safe_value_fallback(tick, tick, 'last', 'ask')
|
||||||
return round((order['fee']['cost'] * fee_to_quote_rate) / order['cost'], 8)
|
return round((order['fee']['cost'] * fee_to_quote_rate) / order['cost'], 8)
|
||||||
except DependencyException:
|
except ExchangeError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def extract_cost_curr_rate(self, order: Dict) -> Tuple[float, str, Optional[float]]:
|
def extract_cost_curr_rate(self, order: Dict) -> Tuple[float, str, Optional[float]]:
|
||||||
|
@ -4,7 +4,7 @@ from typing import Dict
|
|||||||
|
|
||||||
import ccxt
|
import ccxt
|
||||||
|
|
||||||
from freqtrade.exceptions import (DDosProtection, DependencyException,
|
from freqtrade.exceptions import (DDosProtection, ExchangeError,
|
||||||
InvalidOrderException, OperationalException,
|
InvalidOrderException, OperationalException,
|
||||||
TemporaryError)
|
TemporaryError)
|
||||||
from freqtrade.exchange import Exchange
|
from freqtrade.exchange import Exchange
|
||||||
@ -61,7 +61,7 @@ class Ftx(Exchange):
|
|||||||
'stop price: %s.', pair, stop_price)
|
'stop price: %s.', pair, stop_price)
|
||||||
return order
|
return order
|
||||||
except ccxt.InsufficientFunds as e:
|
except ccxt.InsufficientFunds as e:
|
||||||
raise DependencyException(
|
raise ExchangeError(
|
||||||
f'Insufficient funds to create {ordertype} sell order on market {pair}. '
|
f'Insufficient funds to create {ordertype} sell order on market {pair}. '
|
||||||
f'Tried to create stoploss with amount {amount} at stoploss {stop_price}. '
|
f'Tried to create stoploss with amount {amount} at stoploss {stop_price}. '
|
||||||
f'Message: {e}') from e
|
f'Message: {e}') from e
|
||||||
|
@ -4,8 +4,9 @@ from typing import Dict
|
|||||||
|
|
||||||
import ccxt
|
import ccxt
|
||||||
|
|
||||||
from freqtrade.exceptions import (DependencyException, InvalidOrderException, DDosProtection,
|
from freqtrade.exceptions import (DDosProtection, ExchangeError,
|
||||||
OperationalException, TemporaryError)
|
InvalidOrderException, OperationalException,
|
||||||
|
TemporaryError)
|
||||||
from freqtrade.exchange import Exchange
|
from freqtrade.exchange import Exchange
|
||||||
from freqtrade.exchange.common import retrier
|
from freqtrade.exchange.common import retrier
|
||||||
|
|
||||||
@ -87,7 +88,7 @@ class Kraken(Exchange):
|
|||||||
'stop price: %s.', pair, stop_price)
|
'stop price: %s.', pair, stop_price)
|
||||||
return order
|
return order
|
||||||
except ccxt.InsufficientFunds as e:
|
except ccxt.InsufficientFunds as e:
|
||||||
raise DependencyException(
|
raise ExchangeError(
|
||||||
f'Insufficient funds to create {ordertype} sell order on market {pair}.'
|
f'Insufficient funds to create {ordertype} sell order on market {pair}.'
|
||||||
f'Tried to create stoploss with amount {amount} at stoploss {stop_price}. '
|
f'Tried to create stoploss with amount {amount} at stoploss {stop_price}. '
|
||||||
f'Message: {e}') from e
|
f'Message: {e}') from e
|
||||||
|
@ -11,14 +11,14 @@ from typing import Any, Dict, List, Optional
|
|||||||
|
|
||||||
import arrow
|
import arrow
|
||||||
from cachetools import TTLCache
|
from cachetools import TTLCache
|
||||||
from requests.exceptions import RequestException
|
|
||||||
|
|
||||||
from freqtrade import __version__, constants, persistence
|
from freqtrade import __version__, constants, persistence
|
||||||
from freqtrade.configuration import validate_config_consistency
|
from freqtrade.configuration import validate_config_consistency
|
||||||
from freqtrade.data.converter import order_book_to_dataframe
|
from freqtrade.data.converter import order_book_to_dataframe
|
||||||
from freqtrade.data.dataprovider import DataProvider
|
from freqtrade.data.dataprovider import DataProvider
|
||||||
from freqtrade.edge import Edge
|
from freqtrade.edge import Edge
|
||||||
from freqtrade.exceptions import DependencyException, InvalidOrderException, PricingError
|
from freqtrade.exceptions import (DependencyException, ExchangeError,
|
||||||
|
InvalidOrderException, PricingError)
|
||||||
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_next_date
|
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_next_date
|
||||||
from freqtrade.misc import safe_value_fallback
|
from freqtrade.misc import safe_value_fallback
|
||||||
from freqtrade.pairlist.pairlistmanager import PairListManager
|
from freqtrade.pairlist.pairlistmanager import PairListManager
|
||||||
@ -755,7 +755,7 @@ class FreqtradeBot:
|
|||||||
logger.warning('Selling the trade forcefully')
|
logger.warning('Selling the trade forcefully')
|
||||||
self.execute_sell(trade, trade.stop_loss, sell_reason=SellType.EMERGENCY_SELL)
|
self.execute_sell(trade, trade.stop_loss, sell_reason=SellType.EMERGENCY_SELL)
|
||||||
|
|
||||||
except DependencyException:
|
except ExchangeError:
|
||||||
trade.stoploss_order_id = None
|
trade.stoploss_order_id = None
|
||||||
logger.exception('Unable to place a stoploss order on exchange.')
|
logger.exception('Unable to place a stoploss order on exchange.')
|
||||||
return False
|
return False
|
||||||
@ -891,7 +891,7 @@ class FreqtradeBot:
|
|||||||
if not trade.open_order_id:
|
if not trade.open_order_id:
|
||||||
continue
|
continue
|
||||||
order = self.exchange.get_order(trade.open_order_id, trade.pair)
|
order = self.exchange.get_order(trade.open_order_id, trade.pair)
|
||||||
except (RequestException, DependencyException, InvalidOrderException):
|
except (ExchangeError, InvalidOrderException):
|
||||||
logger.info('Cannot query order for %s due to %s', trade, traceback.format_exc())
|
logger.info('Cannot query order for %s due to %s', trade, traceback.format_exc())
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ from typing import Any, Dict, List, Optional, Tuple
|
|||||||
import arrow
|
import arrow
|
||||||
from numpy import NAN, mean
|
from numpy import NAN, mean
|
||||||
|
|
||||||
from freqtrade.exceptions import DependencyException, TemporaryError
|
from freqtrade.exceptions import ExchangeError, PricingError
|
||||||
from freqtrade.misc import shorten_date
|
from freqtrade.misc import shorten_date
|
||||||
from freqtrade.persistence import Trade
|
from freqtrade.persistence import Trade
|
||||||
from freqtrade.rpc.fiat_convert import CryptoToFiatConverter
|
from freqtrade.rpc.fiat_convert import CryptoToFiatConverter
|
||||||
@ -130,7 +130,7 @@ class RPC:
|
|||||||
# calculate profit and send message to user
|
# calculate profit and send message to user
|
||||||
try:
|
try:
|
||||||
current_rate = self._freqtrade.get_sell_rate(trade.pair, False)
|
current_rate = self._freqtrade.get_sell_rate(trade.pair, False)
|
||||||
except DependencyException:
|
except (ExchangeError, PricingError):
|
||||||
current_rate = NAN
|
current_rate = NAN
|
||||||
current_profit = trade.calc_profit_ratio(current_rate)
|
current_profit = trade.calc_profit_ratio(current_rate)
|
||||||
current_profit_abs = trade.calc_profit(current_rate)
|
current_profit_abs = trade.calc_profit(current_rate)
|
||||||
@ -174,7 +174,7 @@ class RPC:
|
|||||||
# calculate profit and send message to user
|
# calculate profit and send message to user
|
||||||
try:
|
try:
|
||||||
current_rate = self._freqtrade.get_sell_rate(trade.pair, False)
|
current_rate = self._freqtrade.get_sell_rate(trade.pair, False)
|
||||||
except DependencyException:
|
except (PricingError, ExchangeError):
|
||||||
current_rate = NAN
|
current_rate = NAN
|
||||||
trade_percent = (100 * trade.calc_profit_ratio(current_rate))
|
trade_percent = (100 * trade.calc_profit_ratio(current_rate))
|
||||||
trade_profit = trade.calc_profit(current_rate)
|
trade_profit = trade.calc_profit(current_rate)
|
||||||
@ -286,7 +286,7 @@ class RPC:
|
|||||||
# Get current rate
|
# Get current rate
|
||||||
try:
|
try:
|
||||||
current_rate = self._freqtrade.get_sell_rate(trade.pair, False)
|
current_rate = self._freqtrade.get_sell_rate(trade.pair, False)
|
||||||
except DependencyException:
|
except (PricingError, ExchangeError):
|
||||||
current_rate = NAN
|
current_rate = NAN
|
||||||
profit_ratio = trade.calc_profit_ratio(rate=current_rate)
|
profit_ratio = trade.calc_profit_ratio(rate=current_rate)
|
||||||
|
|
||||||
@ -352,7 +352,7 @@ class RPC:
|
|||||||
total = 0.0
|
total = 0.0
|
||||||
try:
|
try:
|
||||||
tickers = self._freqtrade.exchange.get_tickers()
|
tickers = self._freqtrade.exchange.get_tickers()
|
||||||
except (TemporaryError, DependencyException):
|
except (ExchangeError):
|
||||||
raise RPCException('Error getting current tickers.')
|
raise RPCException('Error getting current tickers.')
|
||||||
|
|
||||||
self._freqtrade.wallets.update(require_update=False)
|
self._freqtrade.wallets.update(require_update=False)
|
||||||
@ -373,7 +373,7 @@ class RPC:
|
|||||||
if pair.startswith(stake_currency):
|
if pair.startswith(stake_currency):
|
||||||
rate = 1.0 / rate
|
rate = 1.0 / rate
|
||||||
est_stake = rate * balance.total
|
est_stake = rate * balance.total
|
||||||
except (TemporaryError, DependencyException):
|
except (ExchangeError):
|
||||||
logger.warning(f" Could not get rate for pair {coin}.")
|
logger.warning(f" Could not get rate for pair {coin}.")
|
||||||
continue
|
continue
|
||||||
total = total + (est_stake or 0)
|
total = total + (est_stake or 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user