Create strategy_wrapper to call user-defined code with

This commit is contained in:
Matthias
2020-02-06 20:26:04 +01:00
parent b5ee4f17cb
commit 2816b96650
4 changed files with 47 additions and 18 deletions

View File

@@ -35,3 +35,10 @@ class TemporaryError(FreqtradeException):
This could happen when an exchange is congested, unavailable, or the user
has networking problems. Usually resolves itself after a time.
"""
class StrategyError(FreqtradeException):
"""
Errors with custom user-code deteced.
Usually caused by errors in the strategy.
"""

View File

@@ -3,21 +3,22 @@ IStrategy interface
This module defines the interface to apply for strategies
"""
import logging
import warnings
from abc import ABC, abstractmethod
from datetime import datetime, timezone
from enum import Enum
from typing import Dict, List, NamedTuple, Optional, Tuple
import warnings
import arrow
from pandas import DataFrame
from freqtrade.data.dataprovider import DataProvider
from freqtrade.exceptions import StrategyError
from freqtrade.exchange import timeframe_to_minutes
from freqtrade.persistence import Trade
from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper
from freqtrade.wallets import Wallets
logger = logging.getLogger(__name__)
@@ -255,20 +256,12 @@ class IStrategy(ABC):
return False, False
try:
dataframe = self._analyze_ticker_internal(dataframe, {'pair': pair})
except ValueError as error:
logger.warning(
'Unable to analyze ticker for pair %s: %s',
pair,
str(error)
)
return False, False
except Exception as error:
logger.exception(
'Unexpected error when analyzing ticker for pair %s: %s',
pair,
str(error)
)
dataframe = strategy_safe_wrapper(
self._analyze_ticker_internal, message=""
)(dataframe, {'pair': pair})
except StrategyError as error:
logger.warning(f"Unable to analyze ticker for pair {pair}: {error}")
return False, False
if dataframe.empty:

View File

@@ -0,0 +1,29 @@
import logging
from freqtrade.exceptions import StrategyError
logger = logging.getLogger(__name__)
def strategy_safe_wrapper(f, message: str, default_retval=None):
def wrapper(*args, **kwargs):
try:
return f(*args, **kwargs)
except ValueError as error:
logger.warning(
f"{message}"
f"Strategy caused the following exception: {error}"
f"{f}"
)
if not default_retval:
raise StrategyError(str(error)) from error
return default_retval
except Exception as error:
logger.exception(
f"Unexpected error {error} calling {f}"
)
if not default_retval:
raise StrategyError(str(error)) from error
return default_retval
return wrapper