Merge pull request #4047 from freqtrade/strategy_manatory
Ensure non-defined attributes fail correctly
This commit is contained in:
commit
7126aa9514
@ -519,8 +519,7 @@ class FreqtradeBot:
|
||||
# reserve some percent defined in config (5% default) + stoploss
|
||||
amount_reserve_percent = 1.0 - self.config.get('amount_reserve_percent',
|
||||
constants.DEFAULT_AMOUNT_RESERVE_PERCENT)
|
||||
if self.strategy.stoploss is not None:
|
||||
amount_reserve_percent += self.strategy.stoploss
|
||||
amount_reserve_percent += self.strategy.stoploss
|
||||
# it should not be more than 50%
|
||||
amount_reserve_percent = max(amount_reserve_percent, 0.5)
|
||||
|
||||
|
@ -88,9 +88,6 @@ class StrategyResolver(IResolver):
|
||||
StrategyResolver._override_attribute_helper(strategy, config,
|
||||
attribute, default)
|
||||
|
||||
# Assign deprecated variable - to not break users code relying on this.
|
||||
strategy.ticker_interval = strategy.timeframe
|
||||
|
||||
# Loop this list again to have output combined
|
||||
for attribute, _, subkey in attributes:
|
||||
if subkey and attribute in config[subkey]:
|
||||
@ -98,11 +95,7 @@ class StrategyResolver(IResolver):
|
||||
elif attribute in config:
|
||||
logger.info("Strategy using %s: %s", attribute, config[attribute])
|
||||
|
||||
# Sort and apply type conversions
|
||||
strategy.minimal_roi = OrderedDict(sorted(
|
||||
{int(key): value for (key, value) in strategy.minimal_roi.items()}.items(),
|
||||
key=lambda t: t[0]))
|
||||
strategy.stoploss = float(strategy.stoploss)
|
||||
StrategyResolver._normalize_attributes(strategy)
|
||||
|
||||
StrategyResolver._strategy_sanity_validations(strategy)
|
||||
return strategy
|
||||
@ -131,6 +124,24 @@ class StrategyResolver(IResolver):
|
||||
setattr(strategy, attribute, default)
|
||||
config[attribute] = default
|
||||
|
||||
@staticmethod
|
||||
def _normalize_attributes(strategy: IStrategy) -> IStrategy:
|
||||
"""
|
||||
Normalize attributes to have the correct type.
|
||||
"""
|
||||
# Assign deprecated variable - to not break users code relying on this.
|
||||
if hasattr(strategy, 'timeframe'):
|
||||
strategy.ticker_interval = strategy.timeframe
|
||||
|
||||
# Sort and apply type conversions
|
||||
if hasattr(strategy, 'minimal_roi'):
|
||||
strategy.minimal_roi = OrderedDict(sorted(
|
||||
{int(key): value for (key, value) in strategy.minimal_roi.items()}.items(),
|
||||
key=lambda t: t[0]))
|
||||
if hasattr(strategy, 'stoploss'):
|
||||
strategy.stoploss = float(strategy.stoploss)
|
||||
return strategy
|
||||
|
||||
@staticmethod
|
||||
def _strategy_sanity_validations(strategy):
|
||||
if not all(k in strategy.order_types for k in REQUIRED_ORDERTYPES):
|
||||
|
@ -551,8 +551,7 @@ class IStrategy(ABC):
|
||||
# evaluate if the stoploss was hit if stoploss is not on exchange
|
||||
# in Dry-Run, this handles stoploss logic as well, as the logic will not be different to
|
||||
# regular stoploss handling.
|
||||
if ((self.stoploss is not None) and
|
||||
(trade.stop_loss >= current_rate) and
|
||||
if ((trade.stop_loss >= current_rate) and
|
||||
(not self.order_types.get('stoploss_on_exchange') or self.config['dry_run'])):
|
||||
|
||||
sell_type = SellType.STOP_LOSS
|
||||
|
Loading…
Reference in New Issue
Block a user