Introduce safe_value_fallback_2

This commit is contained in:
Matthias 2020-07-15 19:49:51 +02:00
parent 0f4fc67b83
commit d13cb4c055
4 changed files with 49 additions and 19 deletions

View File

@ -24,7 +24,7 @@ from freqtrade.exceptions import (DDosProtection, ExchangeError,
InvalidOrderException, OperationalException, InvalidOrderException, OperationalException,
RetryableOrderError, TemporaryError) RetryableOrderError, TemporaryError)
from freqtrade.exchange.common import BAD_EXCHANGES, retrier, retrier_async 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 CcxtModuleType = Any
@ -1139,7 +1139,7 @@ class Exchange:
if fee_curr in self.get_pair_base_currency(order['symbol']): if fee_curr in self.get_pair_base_currency(order['symbol']):
# Base currency - divide by amount # Base currency - divide by amount
return round( 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']): elif fee_curr in self.get_pair_quote_currency(order['symbol']):
# Quote currency - divide by cost # Quote currency - divide by cost
return round(order['fee']['cost'] / order['cost'], 8) if order['cost'] else None 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']) comb = self.get_valid_pair_combination(fee_curr, self._config['stake_currency'])
tick = self.fetch_ticker(comb) 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) return round((order['fee']['cost'] * fee_to_quote_rate) / order['cost'], 8)
except ExchangeError: except ExchangeError:
return None return None

View File

@ -20,7 +20,7 @@ from freqtrade.edge import Edge
from freqtrade.exceptions import (DependencyException, ExchangeError, from freqtrade.exceptions import (DependencyException, ExchangeError,
InvalidOrderException, PricingError) 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_fallback2
from freqtrade.pairlist.pairlistmanager import PairListManager from freqtrade.pairlist.pairlistmanager import PairListManager
from freqtrade.persistence import Trade from freqtrade.persistence import Trade
from freqtrade.resolvers import ExchangeResolver, StrategyResolver from freqtrade.resolvers import ExchangeResolver, StrategyResolver
@ -984,7 +984,7 @@ class FreqtradeBot:
logger.info('Buy order %s for %s.', reason, trade) logger.info('Buy order %s for %s.', reason, trade)
# Using filled to determine the filled amount # 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): if isclose(filled_amount, 0.0, abs_tol=constants.MATH_CLOSE_PREC):
logger.info('Buy order fully cancelled. Removing %s from database.', trade) logger.info('Buy order fully cancelled. Removing %s from database.', trade)

View File

@ -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()} 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. 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. Fall back to dict2 - return key2 from dict2 if it's not None.

View File

@ -11,7 +11,7 @@ from freqtrade.misc import (datesarray_to_datetimearray, file_dump_json,
file_load_json, format_ms_time, pair_to_filename, file_load_json, format_ms_time, pair_to_filename,
plural, render_template, plural, render_template,
render_template_with_fallback, safe_value_fallback, render_template_with_fallback, safe_value_fallback,
shorten_date) safe_value_fallback2, shorten_date)
def test_shorten_date() -> None: def test_shorten_date() -> None:
@ -96,24 +96,40 @@ def test_format_ms_time() -> None:
def test_safe_value_fallback(): 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} dict1 = {'keya': None, 'keyb': 2, 'keyc': 5, 'keyd': None}
dict2 = {'keya': 20, 'keyb': None, 'keyc': 6, 'keyd': None} dict2 = {'keya': 20, 'keyb': None, 'keyc': 6, 'keyd': None}
assert safe_value_fallback(dict1, dict2, 'keya', 'keya') == 20 assert safe_value_fallback2(dict1, dict2, 'keya', 'keya') == 20
assert safe_value_fallback(dict2, dict1, 'keya', 'keya') == 20 assert safe_value_fallback2(dict2, dict1, 'keya', 'keya') == 20
assert safe_value_fallback(dict1, dict2, 'keyb', 'keyb') == 2 assert safe_value_fallback2(dict1, dict2, 'keyb', 'keyb') == 2
assert safe_value_fallback(dict2, dict1, 'keyb', 'keyb') == 2 assert safe_value_fallback2(dict2, dict1, 'keyb', 'keyb') == 2
assert safe_value_fallback(dict1, dict2, 'keyc', 'keyc') == 5 assert safe_value_fallback2(dict1, dict2, 'keyc', 'keyc') == 5
assert safe_value_fallback(dict2, dict1, 'keyc', 'keyc') == 6 assert safe_value_fallback2(dict2, dict1, 'keyc', 'keyc') == 6
assert safe_value_fallback(dict1, dict2, 'keyd', 'keyd') is None assert safe_value_fallback2(dict1, dict2, 'keyd', 'keyd') is None
assert safe_value_fallback(dict2, dict1, 'keyd', 'keyd') is None assert safe_value_fallback2(dict2, dict1, 'keyd', 'keyd') is None
assert safe_value_fallback(dict2, dict1, 'keyd', 'keyd', 1234) == 1234 assert safe_value_fallback2(dict2, dict1, 'keyd', 'keyd', 1234) == 1234
assert safe_value_fallback(dict1, dict2, 'keyNo', 'keyNo') is None assert safe_value_fallback2(dict1, dict2, 'keyNo', 'keyNo') is None
assert safe_value_fallback(dict2, dict1, 'keyNo', 'keyNo') is None assert safe_value_fallback2(dict2, dict1, 'keyNo', 'keyNo') is None
assert safe_value_fallback(dict2, dict1, 'keyNo', 'keyNo', 1234) == 1234 assert safe_value_fallback2(dict2, dict1, 'keyNo', 'keyNo', 1234) == 1234
def test_plural() -> None: def test_plural() -> None: