We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
allow extra-parameters (ex : unfilledtimeout.buy) to be defined either in configuration file or strategy
**As** a trader,
**I want** to be able to customize strategy depends parameters (like `unfilledtimeout.buy`) straight in my strategy file
**So that** my configuration file in more generic,  not embedded strategy design choices and allow me to reduce the number of config file in dryrun/live.

`unfilledtimeout.buy` is just an example but others parameters can be strategy dependents.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `freqtrade/resolvers/strategy_resolver.py`
Content:
```
1 # pragma pylint: disable=attribute-defined-outside-init
2 
3 """
4 This module load custom strategies
5 """
6 import logging
7 import tempfile
8 from base64 import urlsafe_b64decode
9 from collections import OrderedDict
10 from inspect import getfullargspec
11 from pathlib import Path
12 from typing import Dict, Optional
13 
14 from freqtrade import constants, OperationalException
15 from freqtrade.resolvers import IResolver
16 from freqtrade.strategy.interface import IStrategy
17 
18 logger = logging.getLogger(__name__)
19 
20 
21 class StrategyResolver(IResolver):
22     """
23     This class contains all the logic to load custom strategy class
24     """
25 
26     __slots__ = ['strategy']
27 
28     def __init__(self, config: Optional[Dict] = None) -> None:
29         """
30         Load the custom class from config parameter
31         :param config: configuration dictionary or None
32         """
33         config = config or {}
34 
35         if not config.get('strategy'):
36             raise OperationalException("No strategy set. Please use `--strategy` to specify "
37                                        "the strategy class to use.")
38 
39         strategy_name = config['strategy']
40         self.strategy: IStrategy = self._load_strategy(strategy_name,
41                                                        config=config,
42                                                        extra_dir=config.get('strategy_path'))
43 
44         # make sure ask_strategy dict is available
45         if 'ask_strategy' not in config:
46             config['ask_strategy'] = {}
47 
48         # Set attributes
49         # Check if we need to override configuration
50         #             (Attribute name,                    default,     ask_strategy)
51         attributes = [("minimal_roi",                     {"0": 10.0}, False),
52                       ("ticker_interval",                 None,        False),
53                       ("stoploss",                        None,        False),
54                       ("trailing_stop",                   None,        False),
55                       ("trailing_stop_positive",          None,        False),
56                       ("trailing_stop_positive_offset",   0.0,         False),
57                       ("trailing_only_offset_is_reached", None,        False),
58                       ("process_only_new_candles",        None,        False),
59                       ("order_types",                     None,        False),
60                       ("order_time_in_force",             None,        False),
61                       ("stake_currency",                  None,        False),
62                       ("stake_amount",                    None,        False),
63                       ("startup_candle_count",            None,        False),
64                       ("use_sell_signal",                 True,        True),
65                       ("sell_profit_only",                False,       True),
66                       ("ignore_roi_if_buy_signal",        False,       True),
67                       ]
68         for attribute, default, ask_strategy in attributes:
69             if ask_strategy:
70                 self._override_attribute_helper(config['ask_strategy'], attribute, default)
71             else:
72                 self._override_attribute_helper(config, attribute, default)
73 
74         # Loop this list again to have output combined
75         for attribute, _, exp in attributes:
76             if exp and attribute in config['ask_strategy']:
77                 logger.info("Strategy using %s: %s", attribute, config['ask_strategy'][attribute])
78             elif attribute in config:
79                 logger.info("Strategy using %s: %s", attribute, config[attribute])
80 
81         # Sort and apply type conversions
82         self.strategy.minimal_roi = OrderedDict(sorted(
83             {int(key): value for (key, value) in self.strategy.minimal_roi.items()}.items(),
84             key=lambda t: t[0]))
85         self.strategy.stoploss = float(self.strategy.stoploss)
86 
87         self._strategy_sanity_validations()
88 
89     def _override_attribute_helper(self, config, attribute: str, default):
90         """
91         Override attributes in the strategy.
92         Prevalence:
93         - Configuration
94         - Strategy
95         - default (if not None)
96         """
97         if attribute in config:
98             setattr(self.strategy, attribute, config[attribute])
99             logger.info("Override strategy '%s' with value in config file: %s.",
100                         attribute, config[attribute])
101         elif hasattr(self.strategy, attribute):
102             val = getattr(self.strategy, attribute)
103             # None's cannot exist in the config, so do not copy them
104             if val is not None:
105                 config[attribute] = val
106         # Explicitly check for None here as other "falsy" values are possible
107         elif default is not None:
108             setattr(self.strategy, attribute, default)
109             config[attribute] = default
110 
111     def _strategy_sanity_validations(self):
112         if not all(k in self.strategy.order_types for k in constants.REQUIRED_ORDERTYPES):
113             raise ImportError(f"Impossible to load Strategy '{self.strategy.__class__.__name__}'. "
114                               f"Order-types mapping is incomplete.")
115 
116         if not all(k in self.strategy.order_time_in_force for k in constants.REQUIRED_ORDERTIF):
117             raise ImportError(f"Impossible to load Strategy '{self.strategy.__class__.__name__}'. "
118                               f"Order-time-in-force mapping is incomplete.")
119 
120     def _load_strategy(
121             self, strategy_name: str, config: dict, extra_dir: Optional[str] = None) -> IStrategy:
122         """
123         Search and loads the specified strategy.
124         :param strategy_name: name of the module to import
125         :param config: configuration for the strategy
126         :param extra_dir: additional directory to search for the given strategy
127         :return: Strategy instance or None
128         """
129         current_path = Path(__file__).parent.parent.joinpath('strategy').resolve()
130 
131         abs_paths = self.build_search_paths(config, current_path=current_path,
132                                             user_subdir=constants.USERPATH_STRATEGY,
133                                             extra_dir=extra_dir)
134 
135         if ":" in strategy_name:
136             logger.info("loading base64 encoded strategy")
137             strat = strategy_name.split(":")
138 
139             if len(strat) == 2:
140                 temp = Path(tempfile.mkdtemp("freq", "strategy"))
141                 name = strat[0] + ".py"
142 
143                 temp.joinpath(name).write_text(urlsafe_b64decode(strat[1]).decode('utf-8'))
144                 temp.joinpath("__init__.py").touch()
145 
146                 strategy_name = strat[0]
147 
148                 # register temp path with the bot
149                 abs_paths.insert(0, temp.resolve())
150 
151         strategy = self._load_object(paths=abs_paths, object_type=IStrategy,
152                                      object_name=strategy_name, kwargs={'config': config})
153         if strategy:
154             strategy._populate_fun_len = len(getfullargspec(strategy.populate_indicators).args)
155             strategy._buy_fun_len = len(getfullargspec(strategy.populate_buy_trend).args)
156             strategy._sell_fun_len = len(getfullargspec(strategy.populate_sell_trend).args)
157             if any([x == 2 for x in [strategy._populate_fun_len,
158                                      strategy._buy_fun_len,
159                                      strategy._sell_fun_len]]):
160                 strategy.INTERFACE_VERSION = 1
161 
162             return strategy
163 
164         raise OperationalException(
165             f"Impossible to load Strategy '{strategy_name}'. This class does not exist "
166             "or contains Python code errors."
167         )
168
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/freqtrade/resolvers/strategy_resolver.py b/freqtrade/resolvers/strategy_resolver.py
--- a/freqtrade/resolvers/strategy_resolver.py
+++ b/freqtrade/resolvers/strategy_resolver.py
@@ -61,6 +61,7 @@
                       ("stake_currency",                  None,        False),
                       ("stake_amount",                    None,        False),
                       ("startup_candle_count",            None,        False),
+                      ("unfilledtimeout",                 None,        False),
                       ("use_sell_signal",                 True,        True),
                       ("sell_profit_only",                False,       True),
                       ("ignore_roi_if_buy_signal",        False,       True),

{"golden_diff": "diff --git a/freqtrade/resolvers/strategy_resolver.py b/freqtrade/resolvers/strategy_resolver.py\n--- a/freqtrade/resolvers/strategy_resolver.py\n+++ b/freqtrade/resolvers/strategy_resolver.py\n@@ -61,6 +61,7 @@\n                       (\"stake_currency\",                  None,        False),\n                       (\"stake_amount\",                    None,        False),\n                       (\"startup_candle_count\",            None,        False),\n+                      (\"unfilledtimeout\",                 None,        False),\n                       (\"use_sell_signal\",                 True,        True),\n                       (\"sell_profit_only\",                False,       True),\n                       (\"ignore_roi_if_buy_signal\",        False,       True),\n", "issue": "allow extra-parameters (ex : unfilledtimeout.buy) to be defined either in configuration file or strategy\n**As** a trader,\r\n**I want** to be able to customize strategy depends parameters (like `unfilledtimeout.buy`) straight in my strategy file\r\n**So that** my configuration file in more generic,  not embedded strategy design choices and allow me to reduce the number of config file in dryrun/live.\r\n\r\n`unfilledtimeout.buy` is just an example but others parameters can be strategy dependents.\n", "before_files": [{"content": "# pragma pylint: disable=attribute-defined-outside-init\n\n\"\"\"\nThis module load custom strategies\n\"\"\"\nimport logging\nimport tempfile\nfrom base64 import urlsafe_b64decode\nfrom collections import OrderedDict\nfrom inspect import getfullargspec\nfrom pathlib import Path\nfrom typing import Dict, Optional\n\nfrom freqtrade import constants, OperationalException\nfrom freqtrade.resolvers import IResolver\nfrom freqtrade.strategy.interface import IStrategy\n\nlogger = logging.getLogger(__name__)\n\n\nclass StrategyResolver(IResolver):\n    \"\"\"\n    This class contains all the logic to load custom strategy class\n    \"\"\"\n\n    __slots__ = ['strategy']\n\n    def __init__(self, config: Optional[Dict] = None) -> None:\n        \"\"\"\n        Load the custom class from config parameter\n        :param config: configuration dictionary or None\n        \"\"\"\n        config = config or {}\n\n        if not config.get('strategy'):\n            raise OperationalException(\"No strategy set. Please use `--strategy` to specify \"\n                                       \"the strategy class to use.\")\n\n        strategy_name = config['strategy']\n        self.strategy: IStrategy = self._load_strategy(strategy_name,\n                                                       config=config,\n                                                       extra_dir=config.get('strategy_path'))\n\n        # make sure ask_strategy dict is available\n        if 'ask_strategy' not in config:\n            config['ask_strategy'] = {}\n\n        # Set attributes\n        # Check if we need to override configuration\n        #             (Attribute name,                    default,     ask_strategy)\n        attributes = [(\"minimal_roi\",                     {\"0\": 10.0}, False),\n                      (\"ticker_interval\",                 None,        False),\n                      (\"stoploss\",                        None,        False),\n                      (\"trailing_stop\",                   None,        False),\n                      (\"trailing_stop_positive\",          None,        False),\n                      (\"trailing_stop_positive_offset\",   0.0,         False),\n                      (\"trailing_only_offset_is_reached\", None,        False),\n                      (\"process_only_new_candles\",        None,        False),\n                      (\"order_types\",                     None,        False),\n                      (\"order_time_in_force\",             None,        False),\n                      (\"stake_currency\",                  None,        False),\n                      (\"stake_amount\",                    None,        False),\n                      (\"startup_candle_count\",            None,        False),\n                      (\"use_sell_signal\",                 True,        True),\n                      (\"sell_profit_only\",                False,       True),\n                      (\"ignore_roi_if_buy_signal\",        False,       True),\n                      ]\n        for attribute, default, ask_strategy in attributes:\n            if ask_strategy:\n                self._override_attribute_helper(config['ask_strategy'], attribute, default)\n            else:\n                self._override_attribute_helper(config, attribute, default)\n\n        # Loop this list again to have output combined\n        for attribute, _, exp in attributes:\n            if exp and attribute in config['ask_strategy']:\n                logger.info(\"Strategy using %s: %s\", attribute, config['ask_strategy'][attribute])\n            elif attribute in config:\n                logger.info(\"Strategy using %s: %s\", attribute, config[attribute])\n\n        # Sort and apply type conversions\n        self.strategy.minimal_roi = OrderedDict(sorted(\n            {int(key): value for (key, value) in self.strategy.minimal_roi.items()}.items(),\n            key=lambda t: t[0]))\n        self.strategy.stoploss = float(self.strategy.stoploss)\n\n        self._strategy_sanity_validations()\n\n    def _override_attribute_helper(self, config, attribute: str, default):\n        \"\"\"\n        Override attributes in the strategy.\n        Prevalence:\n        - Configuration\n        - Strategy\n        - default (if not None)\n        \"\"\"\n        if attribute in config:\n            setattr(self.strategy, attribute, config[attribute])\n            logger.info(\"Override strategy '%s' with value in config file: %s.\",\n                        attribute, config[attribute])\n        elif hasattr(self.strategy, attribute):\n            val = getattr(self.strategy, attribute)\n            # None's cannot exist in the config, so do not copy them\n            if val is not None:\n                config[attribute] = val\n        # Explicitly check for None here as other \"falsy\" values are possible\n        elif default is not None:\n            setattr(self.strategy, attribute, default)\n            config[attribute] = default\n\n    def _strategy_sanity_validations(self):\n        if not all(k in self.strategy.order_types for k in constants.REQUIRED_ORDERTYPES):\n            raise ImportError(f\"Impossible to load Strategy '{self.strategy.__class__.__name__}'. \"\n                              f\"Order-types mapping is incomplete.\")\n\n        if not all(k in self.strategy.order_time_in_force for k in constants.REQUIRED_ORDERTIF):\n            raise ImportError(f\"Impossible to load Strategy '{self.strategy.__class__.__name__}'. \"\n                              f\"Order-time-in-force mapping is incomplete.\")\n\n    def _load_strategy(\n            self, strategy_name: str, config: dict, extra_dir: Optional[str] = None) -> IStrategy:\n        \"\"\"\n        Search and loads the specified strategy.\n        :param strategy_name: name of the module to import\n        :param config: configuration for the strategy\n        :param extra_dir: additional directory to search for the given strategy\n        :return: Strategy instance or None\n        \"\"\"\n        current_path = Path(__file__).parent.parent.joinpath('strategy').resolve()\n\n        abs_paths = self.build_search_paths(config, current_path=current_path,\n                                            user_subdir=constants.USERPATH_STRATEGY,\n                                            extra_dir=extra_dir)\n\n        if \":\" in strategy_name:\n            logger.info(\"loading base64 encoded strategy\")\n            strat = strategy_name.split(\":\")\n\n            if len(strat) == 2:\n                temp = Path(tempfile.mkdtemp(\"freq\", \"strategy\"))\n                name = strat[0] + \".py\"\n\n                temp.joinpath(name).write_text(urlsafe_b64decode(strat[1]).decode('utf-8'))\n                temp.joinpath(\"__init__.py\").touch()\n\n                strategy_name = strat[0]\n\n                # register temp path with the bot\n                abs_paths.insert(0, temp.resolve())\n\n        strategy = self._load_object(paths=abs_paths, object_type=IStrategy,\n                                     object_name=strategy_name, kwargs={'config': config})\n        if strategy:\n            strategy._populate_fun_len = len(getfullargspec(strategy.populate_indicators).args)\n            strategy._buy_fun_len = len(getfullargspec(strategy.populate_buy_trend).args)\n            strategy._sell_fun_len = len(getfullargspec(strategy.populate_sell_trend).args)\n            if any([x == 2 for x in [strategy._populate_fun_len,\n                                     strategy._buy_fun_len,\n                                     strategy._sell_fun_len]]):\n                strategy.INTERFACE_VERSION = 1\n\n            return strategy\n\n        raise OperationalException(\n            f\"Impossible to load Strategy '{strategy_name}'. This class does not exist \"\n            \"or contains Python code errors.\"\n        )\n", "path": "freqtrade/resolvers/strategy_resolver.py"}], "after_files": [{"content": "# pragma pylint: disable=attribute-defined-outside-init\n\n\"\"\"\nThis module load custom strategies\n\"\"\"\nimport logging\nimport tempfile\nfrom base64 import urlsafe_b64decode\nfrom collections import OrderedDict\nfrom inspect import getfullargspec\nfrom pathlib import Path\nfrom typing import Dict, Optional\n\nfrom freqtrade import constants, OperationalException\nfrom freqtrade.resolvers import IResolver\nfrom freqtrade.strategy.interface import IStrategy\n\nlogger = logging.getLogger(__name__)\n\n\nclass StrategyResolver(IResolver):\n    \"\"\"\n    This class contains all the logic to load custom strategy class\n    \"\"\"\n\n    __slots__ = ['strategy']\n\n    def __init__(self, config: Optional[Dict] = None) -> None:\n        \"\"\"\n        Load the custom class from config parameter\n        :param config: configuration dictionary or None\n        \"\"\"\n        config = config or {}\n\n        if not config.get('strategy'):\n            raise OperationalException(\"No strategy set. Please use `--strategy` to specify \"\n                                       \"the strategy class to use.\")\n\n        strategy_name = config['strategy']\n        self.strategy: IStrategy = self._load_strategy(strategy_name,\n                                                       config=config,\n                                                       extra_dir=config.get('strategy_path'))\n\n        # make sure ask_strategy dict is available\n        if 'ask_strategy' not in config:\n            config['ask_strategy'] = {}\n\n        # Set attributes\n        # Check if we need to override configuration\n        #             (Attribute name,                    default,     ask_strategy)\n        attributes = [(\"minimal_roi\",                     {\"0\": 10.0}, False),\n                      (\"ticker_interval\",                 None,        False),\n                      (\"stoploss\",                        None,        False),\n                      (\"trailing_stop\",                   None,        False),\n                      (\"trailing_stop_positive\",          None,        False),\n                      (\"trailing_stop_positive_offset\",   0.0,         False),\n                      (\"trailing_only_offset_is_reached\", None,        False),\n                      (\"process_only_new_candles\",        None,        False),\n                      (\"order_types\",                     None,        False),\n                      (\"order_time_in_force\",             None,        False),\n                      (\"stake_currency\",                  None,        False),\n                      (\"stake_amount\",                    None,        False),\n                      (\"startup_candle_count\",            None,        False),\n                      (\"unfilledtimeout\",                 None,        False),\n                      (\"use_sell_signal\",                 True,        True),\n                      (\"sell_profit_only\",                False,       True),\n                      (\"ignore_roi_if_buy_signal\",        False,       True),\n                      ]\n        for attribute, default, ask_strategy in attributes:\n            if ask_strategy:\n                self._override_attribute_helper(config['ask_strategy'], attribute, default)\n            else:\n                self._override_attribute_helper(config, attribute, default)\n\n        # Loop this list again to have output combined\n        for attribute, _, exp in attributes:\n            if exp and attribute in config['ask_strategy']:\n                logger.info(\"Strategy using %s: %s\", attribute, config['ask_strategy'][attribute])\n            elif attribute in config:\n                logger.info(\"Strategy using %s: %s\", attribute, config[attribute])\n\n        # Sort and apply type conversions\n        self.strategy.minimal_roi = OrderedDict(sorted(\n            {int(key): value for (key, value) in self.strategy.minimal_roi.items()}.items(),\n            key=lambda t: t[0]))\n        self.strategy.stoploss = float(self.strategy.stoploss)\n\n        self._strategy_sanity_validations()\n\n    def _override_attribute_helper(self, config, attribute: str, default):\n        \"\"\"\n        Override attributes in the strategy.\n        Prevalence:\n        - Configuration\n        - Strategy\n        - default (if not None)\n        \"\"\"\n        if attribute in config:\n            setattr(self.strategy, attribute, config[attribute])\n            logger.info(\"Override strategy '%s' with value in config file: %s.\",\n                        attribute, config[attribute])\n        elif hasattr(self.strategy, attribute):\n            val = getattr(self.strategy, attribute)\n            # None's cannot exist in the config, so do not copy them\n            if val is not None:\n                config[attribute] = val\n        # Explicitly check for None here as other \"falsy\" values are possible\n        elif default is not None:\n            setattr(self.strategy, attribute, default)\n            config[attribute] = default\n\n    def _strategy_sanity_validations(self):\n        if not all(k in self.strategy.order_types for k in constants.REQUIRED_ORDERTYPES):\n            raise ImportError(f\"Impossible to load Strategy '{self.strategy.__class__.__name__}'. \"\n                              f\"Order-types mapping is incomplete.\")\n\n        if not all(k in self.strategy.order_time_in_force for k in constants.REQUIRED_ORDERTIF):\n            raise ImportError(f\"Impossible to load Strategy '{self.strategy.__class__.__name__}'. \"\n                              f\"Order-time-in-force mapping is incomplete.\")\n\n    def _load_strategy(\n            self, strategy_name: str, config: dict, extra_dir: Optional[str] = None) -> IStrategy:\n        \"\"\"\n        Search and loads the specified strategy.\n        :param strategy_name: name of the module to import\n        :param config: configuration for the strategy\n        :param extra_dir: additional directory to search for the given strategy\n        :return: Strategy instance or None\n        \"\"\"\n        current_path = Path(__file__).parent.parent.joinpath('strategy').resolve()\n\n        abs_paths = self.build_search_paths(config, current_path=current_path,\n                                            user_subdir=constants.USERPATH_STRATEGY,\n                                            extra_dir=extra_dir)\n\n        if \":\" in strategy_name:\n            logger.info(\"loading base64 encoded strategy\")\n            strat = strategy_name.split(\":\")\n\n            if len(strat) == 2:\n                temp = Path(tempfile.mkdtemp(\"freq\", \"strategy\"))\n                name = strat[0] + \".py\"\n\n                temp.joinpath(name).write_text(urlsafe_b64decode(strat[1]).decode('utf-8'))\n                temp.joinpath(\"__init__.py\").touch()\n\n                strategy_name = strat[0]\n\n                # register temp path with the bot\n                abs_paths.insert(0, temp.resolve())\n\n        strategy = self._load_object(paths=abs_paths, object_type=IStrategy,\n                                     object_name=strategy_name, kwargs={'config': config})\n        if strategy:\n            strategy._populate_fun_len = len(getfullargspec(strategy.populate_indicators).args)\n            strategy._buy_fun_len = len(getfullargspec(strategy.populate_buy_trend).args)\n            strategy._sell_fun_len = len(getfullargspec(strategy.populate_sell_trend).args)\n            if any([x == 2 for x in [strategy._populate_fun_len,\n                                     strategy._buy_fun_len,\n                                     strategy._sell_fun_len]]):\n                strategy.INTERFACE_VERSION = 1\n\n            return strategy\n\n        raise OperationalException(\n            f\"Impossible to load Strategy '{strategy_name}'. This class does not exist \"\n            \"or contains Python code errors.\"\n        )\n", "path": "freqtrade/resolvers/strategy_resolver.py"}]}