From d13cb4c05569e1116f07f5fef0fb896f42c13b7d Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 15 Jul 2020 19:49:51 +0200 Subject: [PATCH] Introduce safe_value_fallback_2 --- freqtrade/exchange/exchange.py | 6 ++--- freqtrade/freqtradebot.py | 4 ++-- freqtrade/misc.py | 16 ++++++++++++- tests/test_misc.py | 42 +++++++++++++++++++++++----------- 4 files changed, 49 insertions(+), 19 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index a3a548176..5c4e4c530 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -24,7 +24,7 @@ from freqtrade.exceptions import (DDosProtection, ExchangeError, InvalidOrderException, OperationalException, RetryableOrderError, TemporaryError) from freqtrade.exchange.common import BAD_EXCHANGES, retrier, retrier_async -from freqtrade.misc import deep_merge_dicts, safe_value_fallback +from freqtrade.misc import deep_merge_dicts, safe_value_fallback2 CcxtModuleType = Any @@ -1139,7 +1139,7 @@ class Exchange: if fee_curr in self.get_pair_base_currency(order['symbol']): # Base currency - divide by amount return round( - order['fee']['cost'] / safe_value_fallback(order, order, 'filled', 'amount'), 8) + order['fee']['cost'] / safe_value_fallback2(order, order, 'filled', 'amount'), 8) elif fee_curr in self.get_pair_quote_currency(order['symbol']): # Quote currency - divide by cost return round(order['fee']['cost'] / order['cost'], 8) if order['cost'] else None @@ -1152,7 +1152,7 @@ class Exchange: comb = self.get_valid_pair_combination(fee_curr, self._config['stake_currency']) tick = self.fetch_ticker(comb) - fee_to_quote_rate = safe_value_fallback(tick, tick, 'last', 'ask') + fee_to_quote_rate = safe_value_fallback2(tick, tick, 'last', 'ask') return round((order['fee']['cost'] * fee_to_quote_rate) / order['cost'], 8) except ExchangeError: return None diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index ab7c2b527..9a0b3c40f 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -20,7 +20,7 @@ from freqtrade.edge import Edge from freqtrade.exceptions import (DependencyException, ExchangeError, InvalidOrderException, PricingError) from freqtrade.exchange import timeframe_to_minutes, timeframe_to_next_date -from freqtrade.misc import safe_value_fallback +from freqtrade.misc import safe_value_fallback2 from freqtrade.pairlist.pairlistmanager import PairListManager from freqtrade.persistence import Trade from freqtrade.resolvers import ExchangeResolver, StrategyResolver @@ -984,7 +984,7 @@ class FreqtradeBot: logger.info('Buy order %s for %s.', reason, trade) # Using filled to determine the filled amount - filled_amount = safe_value_fallback(corder, order, 'filled', 'filled') + filled_amount = safe_value_fallback2(corder, order, 'filled', 'filled') if isclose(filled_amount, 0.0, abs_tol=constants.MATH_CLOSE_PREC): logger.info('Buy order fully cancelled. Removing %s from database.', trade) diff --git a/freqtrade/misc.py b/freqtrade/misc.py index ac6084eb7..623f6cb8f 100644 --- a/freqtrade/misc.py +++ b/freqtrade/misc.py @@ -134,7 +134,21 @@ def round_dict(d, n): return {k: (round(v, n) if isinstance(v, float) else v) for k, v in d.items()} -def safe_value_fallback(dict1: dict, dict2: dict, key1: str, key2: str, default_value=None): +def safe_value_fallback(obj: dict, key1: str, key2: str, default_value=None): + """ + Search a value in obj, return this if it's not None. + Then search key2 in obj - return that if it's not none - then use default_value. + Else falls back to None. + """ + if key1 in obj and obj[key1] is not None: + return obj[key1] + else: + if key2 in obj and obj[key2] is not None: + return obj[key2] + return default_value + + +def safe_value_fallback2(dict1: dict, dict2: dict, key1: str, key2: str, default_value=None): """ Search a value in dict1, return this if it's not None. Fall back to dict2 - return key2 from dict2 if it's not None. diff --git a/tests/test_misc.py b/tests/test_misc.py index 9fd6164d5..a185cbba4 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -11,7 +11,7 @@ from freqtrade.misc import (datesarray_to_datetimearray, file_dump_json, file_load_json, format_ms_time, pair_to_filename, plural, render_template, render_template_with_fallback, safe_value_fallback, - shorten_date) + safe_value_fallback2, shorten_date) def test_shorten_date() -> None: @@ -96,24 +96,40 @@ def test_format_ms_time() -> None: def test_safe_value_fallback(): + dict1 = {'keya': None, 'keyb': 2, 'keyc': 5, 'keyd': None} + assert safe_value_fallback(dict1, 'keya', 'keyb') == 2 + assert safe_value_fallback(dict1, 'keyb', 'keya') == 2 + + assert safe_value_fallback(dict1, 'keyb', 'keyc') == 2 + assert safe_value_fallback(dict1, 'keya', 'keyc') == 5 + + assert safe_value_fallback(dict1, 'keyc', 'keyb') == 5 + + assert safe_value_fallback(dict1, 'keya', 'keyd') is None + + assert safe_value_fallback(dict1, 'keyNo', 'keyNo') is None + assert safe_value_fallback(dict1, 'keyNo', 'keyNo', 55) == 55 + + +def test_safe_value_fallback2(): dict1 = {'keya': None, 'keyb': 2, 'keyc': 5, 'keyd': None} dict2 = {'keya': 20, 'keyb': None, 'keyc': 6, 'keyd': None} - assert safe_value_fallback(dict1, dict2, 'keya', 'keya') == 20 - assert safe_value_fallback(dict2, dict1, 'keya', 'keya') == 20 + assert safe_value_fallback2(dict1, dict2, 'keya', 'keya') == 20 + assert safe_value_fallback2(dict2, dict1, 'keya', 'keya') == 20 - assert safe_value_fallback(dict1, dict2, 'keyb', 'keyb') == 2 - assert safe_value_fallback(dict2, dict1, 'keyb', 'keyb') == 2 + assert safe_value_fallback2(dict1, dict2, 'keyb', 'keyb') == 2 + assert safe_value_fallback2(dict2, dict1, 'keyb', 'keyb') == 2 - assert safe_value_fallback(dict1, dict2, 'keyc', 'keyc') == 5 - assert safe_value_fallback(dict2, dict1, 'keyc', 'keyc') == 6 + assert safe_value_fallback2(dict1, dict2, 'keyc', 'keyc') == 5 + assert safe_value_fallback2(dict2, dict1, 'keyc', 'keyc') == 6 - assert safe_value_fallback(dict1, dict2, 'keyd', 'keyd') is None - assert safe_value_fallback(dict2, dict1, 'keyd', 'keyd') is None - assert safe_value_fallback(dict2, dict1, 'keyd', 'keyd', 1234) == 1234 + assert safe_value_fallback2(dict1, dict2, 'keyd', 'keyd') is None + assert safe_value_fallback2(dict2, dict1, 'keyd', 'keyd') is None + assert safe_value_fallback2(dict2, dict1, 'keyd', 'keyd', 1234) == 1234 - assert safe_value_fallback(dict1, dict2, 'keyNo', 'keyNo') is None - assert safe_value_fallback(dict2, dict1, 'keyNo', 'keyNo') is None - assert safe_value_fallback(dict2, dict1, 'keyNo', 'keyNo', 1234) == 1234 + assert safe_value_fallback2(dict1, dict2, 'keyNo', 'keyNo') is None + assert safe_value_fallback2(dict2, dict1, 'keyNo', 'keyNo') is None + assert safe_value_fallback2(dict2, dict1, 'keyNo', 'keyNo', 1234) == 1234 def test_plural() -> None: