Repository: hummingbot/hummingbot
Pull request: Refactor/ Add init_params fn to strategies
**Before submitting this PR, please make sure**:

- [x] Your code builds clean without any errors or warnings
- [x] You are using approved title ("feat/", "fix/", "docs/", "refactor/")

**A description of the changes proposed in the pull request**:
- Add init_params to assign strategy parameters to be called after object is created.
- This is st. the function can be introspected and the parameters discovered dynamically 

**For testers**
Since this PR contains some important changes to core libraries, e.g. cython, can you please test all the strategies on our major connectors - liquidity mining and Gateway connectors.


Problem statement:
Expose argument details and values for all strategies
**Feature Suggestion**
Expose two things for each strategy class:
- `classmethod` `argument_details` that contains details of all arguments (as we cannot introspect cython class `__init__`)
- `property` `argument_values` that contains a dictionary mapping all the argument names to their current values


**Impact**
This lets me use grid search and other optimisation techniques in Hummingbot Pro.

**Additional context**

Hints from issue discussion:
Related clubhouse stories
https://app.clubhouse.io/coinalpha/story/14279/add-required-methods-to-single-market-hummingbot-strategies-for-grid-search
https://app.clubhouse.io/coinalpha/story/15065/add-required-methods-to-remaining-hummingbot-strategies-for-grid-search
I had a discussion with @kmcgowan2000 on this, here is summary.
- The PR #3175 is not needed for the alpha release of Hummingbot Pro next week
- We agreed the approach on the PR is not ideal, the better approach is to standardise the strategy construction using configuration map. This will automate many repetitive tasks on initialising a strategy object. I'll create another story for this soon.
- The solution is not urgent but should be prioritise for coming release. Hummingsim will need update to incorporate this change as well. I'll keep @kmcgowan2000 in the loop. 
A simple solution to this is to add a function init_params which is called directly after the strategy initialisation. The parameters in init_params are then discoverable through introspect.

Commit message: (refactor) add start unit tests

Patch to review:
diff --git a/hummingbot/client/command/config_command.py b/hummingbot/client/command/config_command.py
index d852b96b1e8..02188b1ad54 100644
--- a/hummingbot/client/command/config_command.py
+++ b/hummingbot/client/command/config_command.py
@@ -20,6 +20,7 @@
 from hummingbot.client.config.security import Security
 from hummingbot.client.config.config_var import ConfigVar
 from hummingbot.core.utils.async_utils import safe_ensure_future
+from hummingbot.core.utils import map_df_to_str
 from hummingbot.model.inventory_cost import InventoryCost
 from hummingbot.strategy.pure_market_making import (
     PureMarketMakingStrategy
@@ -74,14 +75,14 @@ def list_configs(self,  # type: HummingbotApplication
         columns = ["Key", "  Value"]
         data = [[cv.key, cv.value] for cv in global_config_map.values()
                 if cv.key in global_configs_to_display and not cv.is_secure]
-        df = pd.DataFrame(data=data, columns=columns)
+        df = map_df_to_str(pd.DataFrame(data=data, columns=columns))
         self._notify("\nGlobal Configurations:")
         lines = ["    " + line for line in df.to_string(index=False, max_colwidth=50).split("\n")]
         self._notify("\n".join(lines))
 
         if self.strategy_name is not None:
             data = [[cv.printable_key or cv.key, cv.value] for cv in self.strategy_config_map.values() if not cv.is_secure]
-            df = pd.DataFrame(data=data, columns=columns)
+            df = map_df_to_str(pd.DataFrame(data=data, columns=columns))
             self._notify("\nStrategy Configurations:")
             lines = ["    " + line for line in df.to_string(index=False, max_colwidth=50).split("\n")]
             self._notify("\n".join(lines))
diff --git a/hummingbot/core/utils/__init__.py b/hummingbot/core/utils/__init__.py
index 7f9b7e6c999..f4f02d1da00 100644
--- a/hummingbot/core/utils/__init__.py
+++ b/hummingbot/core/utils/__init__.py
@@ -1,5 +1,7 @@
 import cachetools
 import functools
+import pandas as pd
+import numpy as np
 
 
 def async_ttl_cache(ttl: int = 3600, maxsize: int = 1):
@@ -17,3 +19,7 @@ async def memoize(*args, **kwargs):
         return memoize
 
     return decorator
+
+
+def map_df_to_str(df: pd.DataFrame) -> pd.DataFrame:
+    return df.applymap(lambda x: np.format_float_positional(x, trim="-") if isinstance(x, float) else x).astype(str)
diff --git a/hummingbot/strategy/amm_arb/amm_arb.py b/hummingbot/strategy/amm_arb/amm_arb.py
index 34c57339fa9..e1434bdee5b 100644
--- a/hummingbot/strategy/amm_arb/amm_arb.py
+++ b/hummingbot/strategy/amm_arb/amm_arb.py
@@ -36,17 +36,20 @@ def logger(cls) -> HummingbotLogger:
             amm_logger = logging.getLogger(__name__)
         return amm_logger
 
-    def __init__(self,
-                 market_info_1: MarketTradingPairTuple,
-                 market_info_2: MarketTradingPairTuple,
-                 min_profitability: Decimal,
-                 order_amount: Decimal,
-                 market_1_slippage_buffer: Decimal = Decimal("0"),
-                 market_2_slippage_buffer: Decimal = Decimal("0"),
-                 concurrent_orders_submission: bool = True,
-                 status_report_interval: float = 900,
-                 rate_source: Any = FixedRateSource()):
+    def init_params(self,
+                    market_info_1: MarketTradingPairTuple,
+                    market_info_2: MarketTradingPairTuple,
+                    min_profitability: Decimal,
+                    order_amount: Decimal,
+                    market_1_slippage_buffer: Decimal = Decimal("0"),
+                    market_2_slippage_buffer: Decimal = Decimal("0"),
+                    concurrent_orders_submission: bool = True,
+                    status_report_interval: float = 900,
+                    rate_source: Any = FixedRateSource()):
         """
+        Assigns strategy parameters, this function must be called directly after init.
+        The reason for this is to make the parameters discoverable on introspect (it is not possible on init of
+        a Cython class).
         :param market_info_1: The first market
         :param market_info_2: The second market
         :param min_profitability: The minimum profitability for execute trades (e.g. 0.0003 for 0.3%)
@@ -61,7 +64,6 @@ def __init__(self,
         :param status_report_interval: Amount of seconds to wait to refresh the status report
         :param rate_source: Provider of conversion rates between tokens
         """
-        super().__init__()
         self._market_info_1 = market_info_1
         self._market_info_2 = market_info_2
         self._min_profitability = min_profitability
diff --git a/hummingbot/strategy/amm_arb/start.py b/hummingbot/strategy/amm_arb/start.py
index caa8f06f08b..3068ce64f68 100644
--- a/hummingbot/strategy/amm_arb/start.py
+++ b/hummingbot/strategy/amm_arb/start.py
@@ -35,11 +35,12 @@ def start(self):
         rate_source = FixedRateSource()
         rate_source.add_rate(f"{quote_2}-{quote_1}", secondary_to_primary_quote_conversion_rate)
 
-    self.strategy = AmmArbStrategy(market_info_1=market_info_1,
-                                   market_info_2=market_info_2,
-                                   min_profitability=min_profitability,
-                                   order_amount=order_amount,
-                                   market_1_slippage_buffer=market_1_slippage_buffer,
-                                   market_2_slippage_buffer=market_2_slippage_buffer,
-                                   concurrent_orders_submission=concurrent_orders_submission,
-                                   rate_source=rate_source)
+    self.strategy = AmmArbStrategy()
+    self.strategy.init_params(market_info_1=market_info_1,
+                              market_info_2=market_info_2,
+                              min_profitability=min_profitability,
+                              order_amount=order_amount,
+                              market_1_slippage_buffer=market_1_slippage_buffer,
+                              market_2_slippage_buffer=market_2_slippage_buffer,
+                              concurrent_orders_submission=concurrent_orders_submission,
+                              rate_source=rate_source)
diff --git a/hummingbot/strategy/arbitrage/arbitrage.pyx b/hummingbot/strategy/arbitrage/arbitrage.pyx
index fea504d9b5a..efb4849bc8a 100755
--- a/hummingbot/strategy/arbitrage/arbitrage.pyx
+++ b/hummingbot/strategy/arbitrage/arbitrage.pyx
@@ -44,17 +44,17 @@ cdef class ArbitrageStrategy(StrategyBase):
             as_logger = logging.getLogger(__name__)
         return as_logger
 
-    def __init__(self,
-                 market_pairs: List[ArbitrageMarketPair],
-                 min_profitability: Decimal,
-                 logging_options: int = OPTION_LOG_ORDER_COMPLETED,
-                 status_report_interval: float = 60.0,
-                 next_trade_delay_interval: float = 15.0,
-                 failed_order_tolerance: int = 1,
-                 use_oracle_conversion_rate: bool = False,
-                 secondary_to_primary_base_conversion_rate: Decimal = Decimal("1"),
-                 secondary_to_primary_quote_conversion_rate: Decimal = Decimal("1"),
-                 hb_app_notification: bool = False):
+    def init_params(self,
+                    market_pairs: List[ArbitrageMarketPair],
+                    min_profitability: Decimal,
+                    logging_options: int = OPTION_LOG_ORDER_COMPLETED,
+                    status_report_interval: float = 60.0,
+                    next_trade_delay_interval: float = 15.0,
+                    failed_order_tolerance: int = 1,
+                    use_oracle_conversion_rate: bool = False,
+                    secondary_to_primary_base_conversion_rate: Decimal = Decimal("1"),
+                    secondary_to_primary_quote_conversion_rate: Decimal = Decimal("1"),
+                    hb_app_notification: bool = False):
         """
         :param market_pairs: list of arbitrage market pairs
         :param min_profitability: minimum profitability limit, for calculating arbitrage order sizes
@@ -69,10 +69,8 @@ cdef class ArbitrageStrategy(StrategyBase):
         :param secondary_to_primary_quote_conversion_rate: Conversion rate of quote token between markets. The default is 1
         :param hb_app_notification: Enables sending notifications to the client application. The default is false.
         """
-
         if len(market_pairs) < 0:
             raise ValueError(f"market_pairs must not be empty.")
-        super().__init__()
         self._logging_options = logging_options
         self._market_pairs = market_pairs
         self._min_profitability = min_profitability
@@ -100,6 +98,14 @@ cdef class ArbitrageStrategy(StrategyBase):
 
         self.c_add_markets(list(all_markets))
 
+    @property
+    def min_profitability(self) -> Decimal:
+        return self._min_profitability
+
+    @property
+    def use_oracle_conversion_rate(self) -> Decimal:
+        return self._use_oracle_conversion_rate
+
     @property
     def tracked_limit_orders(self) -> List[Tuple[ExchangeBase, LimitOrder]]:
         return self._sb_order_tracker.tracked_limit_orders
diff --git a/hummingbot/strategy/arbitrage/start.py b/hummingbot/strategy/arbitrage/start.py
index b429e8cb893..b140630c12e 100644
--- a/hummingbot/strategy/arbitrage/start.py
+++ b/hummingbot/strategy/arbitrage/start.py
@@ -39,10 +39,11 @@ def start(self):
     secondary_data = [self.markets[secondary_market], secondary_trading_pair] + list(secondary_assets)
     self.market_trading_pair_tuples = [MarketTradingPairTuple(*primary_data), MarketTradingPairTuple(*secondary_data)]
     self.market_pair = ArbitrageMarketPair(*self.market_trading_pair_tuples)
-    self.strategy = ArbitrageStrategy(market_pairs=[self.market_pair],
-                                      min_profitability=min_profitability,
-                                      logging_options=ArbitrageStrategy.OPTION_LOG_ALL,
-                                      use_oracle_conversion_rate=use_oracle_conversion_rate,
-                                      secondary_to_primary_base_conversion_rate=secondary_to_primary_base_conversion_rate,
-                                      secondary_to_primary_quote_conversion_rate=secondary_to_primary_quote_conversion_rate,
-                                      hb_app_notification=True)
+    self.strategy = ArbitrageStrategy()
+    self.strategy.init_params(market_pairs=[self.market_pair],
+                              min_profitability=min_profitability,
+                              logging_options=ArbitrageStrategy.OPTION_LOG_ALL,
+                              use_oracle_conversion_rate=use_oracle_conversion_rate,
+                              secondary_to_primary_base_conversion_rate=secondary_to_primary_base_conversion_rate,
+                              secondary_to_primary_quote_conversion_rate=secondary_to_primary_quote_conversion_rate,
+                              hb_app_notification=True)
diff --git a/hummingbot/strategy/avellaneda_market_making/avellaneda_market_making.pyx b/hummingbot/strategy/avellaneda_market_making/avellaneda_market_making.pyx
index 160cc8b1d18..52a7ff66ae2 100644
--- a/hummingbot/strategy/avellaneda_market_making/avellaneda_market_making.pyx
+++ b/hummingbot/strategy/avellaneda_market_making/avellaneda_market_making.pyx
@@ -60,39 +60,38 @@ cdef class AvellanedaMarketMakingStrategy(StrategyBase):
             pmm_logger = logging.getLogger(__name__)
         return pmm_logger
 
-    def __init__(self,
-                 market_info: MarketTradingPairTuple,
-                 order_amount: Decimal,
-                 order_refresh_time: float = 30.0,
-                 max_order_age: float = 1800,
-                 order_refresh_tolerance_pct: Decimal = s_decimal_neg_one,
-                 order_optimization_enabled = True,
-                 filled_order_delay: float = 60.0,
-                 order_levels: int = 0,
-                 order_override: Dict[str, List[str]] = {},
-                 hanging_orders_enabled: bool = False,
-                 hanging_orders_aggregation_type: HangingOrdersAggregationType = HangingOrdersAggregationType.NO_AGGREGATION,
-                 hanging_orders_cancel_pct: Decimal = Decimal("0.1"),
-                 inventory_target_base_pct: Decimal = s_decimal_zero,
-                 add_transaction_costs_to_orders: bool = True,
-                 logging_options: int = OPTION_LOG_ALL,
-                 status_report_interval: float = 900,
-                 hb_app_notification: bool = False,
-                 parameters_based_on_spread: bool = True,
-                 min_spread: Decimal = Decimal("0.15"),
-                 max_spread: Decimal = Decimal("2"),
-                 vol_to_spread_multiplier: Decimal = Decimal("1.3"),
-                 volatility_sensibility: Decimal = Decimal("0.2"),
-                 inventory_risk_aversion: Decimal = Decimal("0.5"),
-                 order_book_depth_factor: Decimal = Decimal("0.1"),
-                 risk_factor: Decimal = Decimal("0.5"),
-                 order_amount_shape_factor: Decimal = Decimal("0.005"),
-                 closing_time: Decimal = Decimal("1"),
-                 debug_csv_path: str = '',
-                 volatility_buffer_size: int = 30,
-                 is_debug: bool = False,
-                 ):
-        super().__init__()
+    def init_params(self,
+                    market_info: MarketTradingPairTuple,
+                    order_amount: Decimal,
+                    order_refresh_time: float = 30.0,
+                    max_order_age: float = 1800,
+                    order_refresh_tolerance_pct: Decimal = s_decimal_neg_one,
+                    order_optimization_enabled = True,
+                    filled_order_delay: float = 60.0,
+                    order_levels: int = 0,
+                    order_override: Dict[str, List[str]] = {},
+                    hanging_orders_enabled: bool = False,
+                    hanging_orders_aggregation_type: HangingOrdersAggregationType = HangingOrdersAggregationType.NO_AGGREGATION,
+                    hanging_orders_cancel_pct: Decimal = Decimal("0.1"),
+                    inventory_target_base_pct: Decimal = s_decimal_zero,
+                    add_transaction_costs_to_orders: bool = True,
+                    logging_options: int = OPTION_LOG_ALL,
+                    status_report_interval: float = 900,
+                    hb_app_notification: bool = False,
+                    parameters_based_on_spread: bool = True,
+                    min_spread: Decimal = Decimal("0.15"),
+                    max_spread: Decimal = Decimal("2"),
+                    vol_to_spread_multiplier: Decimal = Decimal("1.3"),
+                    volatility_sensibility: Decimal = Decimal("0.2"),
+                    inventory_risk_aversion: Decimal = Decimal("0.5"),
+                    order_book_depth_factor: Decimal = Decimal("0.1"),
+                    risk_factor: Decimal = Decimal("0.5"),
+                    order_amount_shape_factor: Decimal = Decimal("0.005"),
+                    closing_time: Decimal = Decimal("1"),
+                    debug_csv_path: str = '',
+                    volatility_buffer_size: int = 30,
+                    is_debug: bool = False,
+                    ):
         self._sb_order_tracker = OrderTracker()
         self._market_info = market_info
         self._order_amount = order_amount
@@ -153,6 +152,14 @@ cdef class AvellanedaMarketMakingStrategy(StrategyBase):
     def all_markets_ready(self):
         return all([market.ready for market in self._sb_markets])
 
+    @property
+    def volatility_sensibility(self) -> Decimal:
+        return self._volatility_sensibility
+
+    @property
+    def inventory_risk_aversion(self) -> Decimal:
+        return self._inventory_risk_aversion
+
     @property
     def latest_parameter_calculation_vol(self):
         return self._latest_parameter_calculation_vol
diff --git a/hummingbot/strategy/avellaneda_market_making/start.py b/hummingbot/strategy/avellaneda_market_making/start.py
index f969f7f034b..01abf9f3290 100644
--- a/hummingbot/strategy/avellaneda_market_making/start.py
+++ b/hummingbot/strategy/avellaneda_market_making/start.py
@@ -68,7 +68,8 @@ def start(self):
                                       HummingbotApplication.main_application().strategy_file_name.rsplit('.', 1)[0] +
                                       f"_{pd.Timestamp.now().strftime('%Y-%m-%d_%H-%M-%S')}.csv")
 
-        self.strategy = AvellanedaMarketMakingStrategy(
+        self.strategy = AvellanedaMarketMakingStrategy()
+        self.strategy.init_params(
             market_info=MarketTradingPairTuple(*maker_data),
             order_amount=order_amount,
             order_optimization_enabled=order_optimization_enabled,
diff --git a/hummingbot/strategy/celo_arb/celo_arb.pyx b/hummingbot/strategy/celo_arb/celo_arb.pyx
index e12e6a099eb..571a0811095 100644
--- a/hummingbot/strategy/celo_arb/celo_arb.pyx
+++ b/hummingbot/strategy/celo_arb/celo_arb.pyx
@@ -91,16 +91,15 @@ cdef class CeloArbStrategy(StrategyBase):
             ds_logger = logging.getLogger(__name__)
         return ds_logger
 
-    def __init__(self,
-                 market_info: MarketTradingPairTuple,
-                 min_profitability: Decimal,
-                 order_amount: Decimal,
-                 celo_slippage_buffer: Decimal = Decimal("0.0001"),
-                 logging_options: int = OPTION_LOG_ALL,
-                 status_report_interval: float = 900,
-                 hb_app_notification: bool = True,
-                 mock_celo_cli_mode: bool = False):
-        super().__init__()
+    def init_params(self,
+                    market_info: MarketTradingPairTuple,
+                    min_profitability: Decimal,
+                    order_amount: Decimal,
+                    celo_slippage_buffer: Decimal = Decimal("0.0001"),
+                    logging_options: int = OPTION_LOG_ALL,
+                    status_report_interval: float = 900,
+                    hb_app_notification: bool = True,
+                    mock_celo_cli_mode: bool = False):
         self._market_info = market_info
         self._exchange = market_info.market.name
         self._min_profitability = min_profitability
@@ -124,6 +123,10 @@ cdef class CeloArbStrategy(StrategyBase):
         self._hb_app_notification = hb_app_notification
         self.c_add_markets([market_info.market])
 
+    @property
+    def celo_slippage_buffer(self):
+        return self._celo_slippage_buffer
+
     @property
     def min_profitability(self) -> Decimal:
         return self._min_profitability
diff --git a/hummingbot/strategy/celo_arb/start.py b/hummingbot/strategy/celo_arb/start.py
index 37571d6ad54..0c447d56c4a 100644
--- a/hummingbot/strategy/celo_arb/start.py
+++ b/hummingbot/strategy/celo_arb/start.py
@@ -30,4 +30,5 @@ def start(self):
     secondary_data = [self.markets[secondary_exchange], secondary_trading_pair] + list(secondary_assets)
     market_info = MarketTradingPairTuple(*secondary_data)
     self.market_trading_pair_tuples = [market_info]
-    self.strategy = CeloArbStrategy(market_info, min_profitability, order_amount, celo_slippage_buffer)
+    self.strategy = CeloArbStrategy()
+    self.strategy.init_params(market_info, min_profitability, order_amount, celo_slippage_buffer)
diff --git a/hummingbot/strategy/cross_exchange_market_making/cross_exchange_market_making.pyx b/hummingbot/strategy/cross_exchange_market_making/cross_exchange_market_making.pyx
index 82d18455aa6..11b73264ca1 100755
--- a/hummingbot/strategy/cross_exchange_market_making/cross_exchange_market_making.pyx
+++ b/hummingbot/strategy/cross_exchange_market_making/cross_exchange_market_making.pyx
@@ -61,26 +61,26 @@ cdef class CrossExchangeMarketMakingStrategy(StrategyBase):
             s_logger = logging.getLogger(__name__)
         return s_logger
 
-    def __init__(self,
-                 market_pairs: List[CrossExchangeMarketPair],
-                 min_profitability: Decimal,
-                 order_amount: Optional[Decimal] = Decimal("0.0"),
-                 order_size_taker_volume_factor: Decimal = Decimal("0.25"),
-                 order_size_taker_balance_factor: Decimal = Decimal("0.995"),
-                 order_size_portfolio_ratio_limit: Decimal = Decimal("0.1667"),
-                 limit_order_min_expiration: float = 130.0,
-                 adjust_order_enabled: bool = True,
-                 anti_hysteresis_duration: float = 60.0,
-                 active_order_canceling: bint = True,
-                 cancel_order_threshold: Decimal = Decimal("0.05"),
-                 top_depth_tolerance: Decimal = Decimal(0),
-                 logging_options: int = OPTION_LOG_ALL,
-                 status_report_interval: float = 900,
-                 use_oracle_conversion_rate: bool = False,
-                 taker_to_maker_base_conversion_rate: Decimal = Decimal("1"),
-                 taker_to_maker_quote_conversion_rate: Decimal = Decimal("1"),
-                 hb_app_notification: bool = False
-                 ):
+    def init_params(self,
+                    market_pairs: List[CrossExchangeMarketPair],
+                    min_profitability: Decimal,
+                    order_amount: Optional[Decimal] = Decimal("0.0"),
+                    order_size_taker_volume_factor: Decimal = Decimal("0.25"),
+                    order_size_taker_balance_factor: Decimal = Decimal("0.995"),
+                    order_size_portfolio_ratio_limit: Decimal = Decimal("0.1667"),
+                    limit_order_min_expiration: float = 130.0,
+                    adjust_order_enabled: bool = True,
+                    anti_hysteresis_duration: float = 60.0,
+                    active_order_canceling: bint = True,
+                    cancel_order_threshold: Decimal = Decimal("0.05"),
+                    top_depth_tolerance: Decimal = Decimal(0),
+                    logging_options: int = OPTION_LOG_ALL,
+                    status_report_interval: float = 900,
+                    use_oracle_conversion_rate: bool = False,
+                    taker_to_maker_base_conversion_rate: Decimal = Decimal("1"),
+                    taker_to_maker_quote_conversion_rate: Decimal = Decimal("1"),
+                    hb_app_notification: bool = False
+                    ):
         """
         Initializes a cross exchange market making strategy object.
 
@@ -109,7 +109,6 @@ cdef class CrossExchangeMarketMakingStrategy(StrategyBase):
         if not 0 <= order_size_taker_balance_factor <= 1:
             raise ValueError(f"order_size_taker_balance_factor must be between 0 and 1.")
 
-        super().__init__()
         self._market_pairs = {
             (market_pair.maker.market, market_pair.maker.trading_pair): market_pair
             for market_pair in market_pairs
@@ -148,6 +147,14 @@ cdef class CrossExchangeMarketMakingStrategy(StrategyBase):
 
         self.c_add_markets(all_markets)
 
+    @property
+    def order_amount(self):
+        return self._order_amount
+
+    @property
+    def min_profitability(self):
+        return self._min_profitability
+
     @property
     def active_limit_orders(self) -> List[Tuple[ExchangeBase, LimitOrder]]:
         return [(ex, order) for ex, order in self._sb_order_tracker.active_limit_orders
diff --git a/hummingbot/strategy/cross_exchange_market_making/start.py b/hummingbot/strategy/cross_exchange_market_making/start.py
index a735d69863a..d6a36b99f2b 100644
--- a/hummingbot/strategy/cross_exchange_market_making/start.py
+++ b/hummingbot/strategy/cross_exchange_market_making/start.py
@@ -69,7 +69,8 @@ def start(self):
         | CrossExchangeMarketMakingStrategy.OPTION_LOG_STATUS_REPORT
         | CrossExchangeMarketMakingStrategy.OPTION_LOG_MAKER_ORDER_HEDGED
     )
-    self.strategy = CrossExchangeMarketMakingStrategy(
+    self.strategy = CrossExchangeMarketMakingStrategy()
+    self.strategy.init_params(
         market_pairs=[self.market_pair],
         min_profitability=min_profitability,
         status_report_interval=strategy_report_interval,
diff --git a/hummingbot/strategy/liquidity_mining/liquidity_mining.py b/hummingbot/strategy/liquidity_mining/liquidity_mining.py
index 63944715e9e..4838f89e86c 100644
--- a/hummingbot/strategy/liquidity_mining/liquidity_mining.py
+++ b/hummingbot/strategy/liquidity_mining/liquidity_mining.py
@@ -36,25 +36,24 @@ def logger(cls) -> HummingbotLogger:
             lms_logger = logging.getLogger(__name__)
         return lms_logger
 
-    def __init__(self,
-                 exchange: ExchangeBase,
-                 market_infos: Dict[str, MarketTradingPairTuple],
-                 token: str,
-                 order_amount: Decimal,
-                 spread: Decimal,
-                 inventory_skew_enabled: bool,
-                 target_base_pct: Decimal,
-                 order_refresh_time: float,
-                 order_refresh_tolerance_pct: Decimal,
-                 inventory_range_multiplier: Decimal = Decimal("1"),
-                 volatility_interval: int = 60 * 5,
-                 avg_volatility_period: int = 10,
-                 volatility_to_spread_multiplier: Decimal = Decimal("1"),
-                 max_spread: Decimal = Decimal("-1"),
-                 max_order_age: float = 60. * 60.,
-                 status_report_interval: float = 900,
-                 hb_app_notification: bool = False):
-        super().__init__()
+    def init_params(self,
+                    exchange: ExchangeBase,
+                    market_infos: Dict[str, MarketTradingPairTuple],
+                    token: str,
+                    order_amount: Decimal,
+                    spread: Decimal,
+                    inventory_skew_enabled: bool,
+                    target_base_pct: Decimal,
+                    order_refresh_time: float,
+                    order_refresh_tolerance_pct: Decimal,
+                    inventory_range_multiplier: Decimal = Decimal("1"),
+                    volatility_interval: int = 60 * 5,
+                    avg_volatility_period: int = 10,
+                    volatility_to_spread_multiplier: Decimal = Decimal("1"),
+                    max_spread: Decimal = Decimal("-1"),
+                    max_order_age: float = 60. * 60.,
+                    status_report_interval: float = 900,
+                    hb_app_notification: bool = False):
         self._exchange = exchange
         self._market_infos = market_infos
         self._token = token
diff --git a/hummingbot/strategy/liquidity_mining/start.py b/hummingbot/strategy/liquidity_mining/start.py
index 933a838b36f..1c622c819dc 100644
--- a/hummingbot/strategy/liquidity_mining/start.py
+++ b/hummingbot/strategy/liquidity_mining/start.py
@@ -31,7 +31,8 @@ def start(self):
     for market in markets:
         base, quote = market.split("-")
         market_infos[market] = MarketTradingPairTuple(exchange, market, base, quote)
-    self.strategy = LiquidityMiningStrategy(
+    self.strategy = LiquidityMiningStrategy()
+    self.strategy.init_params(
         exchange=exchange,
         market_infos=market_infos,
         token=token,
diff --git a/hummingbot/strategy/perpetual_market_making/perpetual_market_making.pyx b/hummingbot/strategy/perpetual_market_making/perpetual_market_making.pyx
index e78feab1257..8e4ec195c80 100644
--- a/hummingbot/strategy/perpetual_market_making/perpetual_market_making.pyx
+++ b/hummingbot/strategy/perpetual_market_making/perpetual_market_making.pyx
@@ -64,49 +64,48 @@ cdef class PerpetualMarketMakingStrategy(StrategyBase):
             pmm_logger = logging.getLogger(__name__)
         return pmm_logger
 
-    def __init__(self,
-                 market_info: MarketTradingPairTuple,
-                 leverage: int,
-                 position_mode: str,
-                 bid_spread: Decimal,
-                 ask_spread: Decimal,
-                 order_amount: Decimal,
-                 position_management: str,
-                 long_profit_taking_spread: Decimal,
-                 short_profit_taking_spread: Decimal,
-                 ts_activation_spread: Decimal,
-                 ts_callback_rate: Decimal,
-                 stop_loss_spread: Decimal,
-                 close_position_order_type: str,
-                 order_levels: int = 1,
-                 order_level_spread: Decimal = s_decimal_zero,
-                 order_level_amount: Decimal = s_decimal_zero,
-                 order_refresh_time: float = 30.0,
-                 order_refresh_tolerance_pct: Decimal = s_decimal_neg_one,
-                 filled_order_delay: float = 60.0,
-                 hanging_orders_enabled: bool = False,
-                 hanging_orders_cancel_pct: Decimal = Decimal("0.1"),
-                 order_optimization_enabled: bool = False,
-                 ask_order_optimization_depth: Decimal = s_decimal_zero,
-                 bid_order_optimization_depth: Decimal = s_decimal_zero,
-                 add_transaction_costs_to_orders: bool = False,
-                 asset_price_delegate: AssetPriceDelegate = None,
-                 price_type: str = "mid_price",
-                 take_if_crossed: bool = False,
-                 price_ceiling: Decimal = s_decimal_neg_one,
-                 price_floor: Decimal = s_decimal_neg_one,
-                 ping_pong_enabled: bool = False,
-                 logging_options: int = OPTION_LOG_ALL,
-                 status_report_interval: float = 900,
-                 minimum_spread: Decimal = Decimal(0),
-                 hb_app_notification: bool = False,
-                 order_override: Dict[str, List[str]] = {},
-                 ):
+    def init_params(self,
+                    market_info: MarketTradingPairTuple,
+                    leverage: int,
+                    position_mode: str,
+                    bid_spread: Decimal,
+                    ask_spread: Decimal,
+                    order_amount: Decimal,
+                    position_management: str,
+                    long_profit_taking_spread: Decimal,
+                    short_profit_taking_spread: Decimal,
+                    ts_activation_spread: Decimal,
+                    ts_callback_rate: Decimal,
+                    stop_loss_spread: Decimal,
+                    close_position_order_type: str,
+                    order_levels: int = 1,
+                    order_level_spread: Decimal = s_decimal_zero,
+                    order_level_amount: Decimal = s_decimal_zero,
+                    order_refresh_time: float = 30.0,
+                    order_refresh_tolerance_pct: Decimal = s_decimal_neg_one,
+                    filled_order_delay: float = 60.0,
+                    hanging_orders_enabled: bool = False,
+                    hanging_orders_cancel_pct: Decimal = Decimal("0.1"),
+                    order_optimization_enabled: bool = False,
+                    ask_order_optimization_depth: Decimal = s_decimal_zero,
+                    bid_order_optimization_depth: Decimal = s_decimal_zero,
+                    add_transaction_costs_to_orders: bool = False,
+                    asset_price_delegate: AssetPriceDelegate = None,
+                    price_type: str = "mid_price",
+                    take_if_crossed: bool = False,
+                    price_ceiling: Decimal = s_decimal_neg_one,
+                    price_floor: Decimal = s_decimal_neg_one,
+                    ping_pong_enabled: bool = False,
+                    logging_options: int = OPTION_LOG_ALL,
+                    status_report_interval: float = 900,
+                    minimum_spread: Decimal = Decimal(0),
+                    hb_app_notification: bool = False,
+                    order_override: Dict[str, List[str]] = {},
+                    ):
 
         if price_ceiling != s_decimal_neg_one and price_ceiling < price_floor:
             raise ValueError("Parameter price_ceiling cannot be lower than price_floor.")
 
-        super().__init__()
         self._sb_order_tracker = PerpetualMarketMakingOrderTracker()
         self._market_info = market_info
         self._leverage = leverage
diff --git a/hummingbot/strategy/perpetual_market_making/start.py b/hummingbot/strategy/perpetual_market_making/start.py
index bfb7fadbbbb..b182bcc3fd9 100644
--- a/hummingbot/strategy/perpetual_market_making/start.py
+++ b/hummingbot/strategy/perpetual_market_making/start.py
@@ -74,7 +74,8 @@ def start(self):
 
         strategy_logging_options = PerpetualMarketMakingStrategy.OPTION_LOG_ALL
 
-        self.strategy = PerpetualMarketMakingStrategy(
+        self.strategy = PerpetualMarketMakingStrategy()
+        self.strategy.init_params(
             market_info=MarketTradingPairTuple(*maker_data),
             leverage=leverage,
             position_mode=position_mode,
diff --git a/hummingbot/strategy/pure_market_making/pure_market_making.pyx b/hummingbot/strategy/pure_market_making/pure_market_making.pyx
index 26e3ab126e9..b8811c5fc48 100644
--- a/hummingbot/strategy/pure_market_making/pure_market_making.pyx
+++ b/hummingbot/strategy/pure_market_making/pure_market_making.pyx
@@ -20,6 +20,7 @@ from hummingbot.core.network_iterator import NetworkStatus
 from hummingbot.connector.exchange_base import ExchangeBase
 from hummingbot.connector.exchange_base cimport ExchangeBase
 from hummingbot.core.event.events import OrderType
+from hummingbot.core.utils import map_df_to_str
 
 from hummingbot.strategy.market_trading_pair_tuple import MarketTradingPairTuple
 from hummingbot.strategy.strategy_base import StrategyBase
@@ -61,45 +62,42 @@ cdef class PureMarketMakingStrategy(StrategyBase):
             pmm_logger = logging.getLogger(__name__)
         return pmm_logger
 
-    def __init__(self,
-                 market_info: MarketTradingPairTuple,
-                 bid_spread: Decimal,
-                 ask_spread: Decimal,
-                 order_amount: Decimal,
-                 order_levels: int = 1,
-                 order_level_spread: Decimal = s_decimal_zero,
-                 order_level_amount: Decimal = s_decimal_zero,
-                 order_refresh_time: float = 30.0,
-                 max_order_age = 1800.0,
-                 order_refresh_tolerance_pct: Decimal = s_decimal_neg_one,
-                 filled_order_delay: float = 60.0,
-                 inventory_skew_enabled: bool = False,
-                 inventory_target_base_pct: Decimal = s_decimal_zero,
-                 inventory_range_multiplier: Decimal = s_decimal_zero,
-                 hanging_orders_enabled: bool = False,
-                 hanging_orders_cancel_pct: Decimal = Decimal("0.1"),
-                 order_optimization_enabled: bool = False,
-                 ask_order_optimization_depth: Decimal = s_decimal_zero,
-                 bid_order_optimization_depth: Decimal = s_decimal_zero,
-                 add_transaction_costs_to_orders: bool = False,
-                 asset_price_delegate: AssetPriceDelegate = None,
-                 inventory_cost_price_delegate: InventoryCostPriceDelegate = None,
-                 price_type: str = "mid_price",
-                 take_if_crossed: bool = False,
-                 price_ceiling: Decimal = s_decimal_neg_one,
-                 price_floor: Decimal = s_decimal_neg_one,
-                 ping_pong_enabled: bool = False,
-                 logging_options: int = OPTION_LOG_ALL,
-                 status_report_interval: float = 900,
-                 minimum_spread: Decimal = Decimal(0),
-                 hb_app_notification: bool = False,
-                 order_override: Dict[str, List[str]] = {},
-                 ):
-
+    def init_params(self,
+                    market_info: MarketTradingPairTuple,
+                    bid_spread: Decimal,
+                    ask_spread: Decimal,
+                    order_amount: Decimal,
+                    order_levels: int = 1,
+                    order_level_spread: Decimal = s_decimal_zero,
+                    order_level_amount: Decimal = s_decimal_zero,
+                    order_refresh_time: float = 30.0,
+                    max_order_age: float = 1800.0,
+                    order_refresh_tolerance_pct: Decimal = s_decimal_neg_one,
+                    filled_order_delay: float = 60.0,
+                    inventory_skew_enabled: bool = False,
+                    inventory_target_base_pct: Decimal = s_decimal_zero,
+                    inventory_range_multiplier: Decimal = s_decimal_zero,
+                    hanging_orders_enabled: bool = False,
+                    hanging_orders_cancel_pct: Decimal = Decimal("0.1"),
+                    order_optimization_enabled: bool = False,
+                    ask_order_optimization_depth: Decimal = s_decimal_zero,
+                    bid_order_optimization_depth: Decimal = s_decimal_zero,
+                    add_transaction_costs_to_orders: bool = False,
+                    asset_price_delegate: AssetPriceDelegate = None,
+                    inventory_cost_price_delegate: InventoryCostPriceDelegate = None,
+                    price_type: str = "mid_price",
+                    take_if_crossed: bool = False,
+                    price_ceiling: Decimal = s_decimal_neg_one,
+                    price_floor: Decimal = s_decimal_neg_one,
+                    ping_pong_enabled: bool = False,
+                    logging_options: int = OPTION_LOG_ALL,
+                    status_report_interval: float = 900,
+                    minimum_spread: Decimal = Decimal(0),
+                    hb_app_notification: bool = False,
+                    order_override: Dict[str, List[str]] = {},
+                    ):
         if price_ceiling != s_decimal_neg_one and price_ceiling < price_floor:
             raise ValueError("Parameter price_ceiling cannot be lower than price_floor.")
-
-        super().__init__()
         self._sb_order_tracker = PureMarketMakingOrderTracker()
         self._market_info = market_info
         self._bid_spread = bid_spread
@@ -159,6 +157,30 @@ cdef class PureMarketMakingStrategy(StrategyBase):
     def market_info(self) -> MarketTradingPairTuple:
         return self._market_info
 
+    @property
+    def max_order_age(self) -> float:
+        return self._max_order_age
+
+    @property
+    def minimum_spread(self) -> Decimal:
+        return self._minimum_spread
+
+    @property
+    def ping_pong_enabled(self) -> bool:
+        return self._ping_pong_enabled
+
+    @property
+    def ask_order_optimization_depth(self) -> Decimal:
+        return self._ask_order_optimization_depth
+
+    @property
+    def bid_order_optimization_depth(self) -> Decimal:
+        return self._bid_order_optimization_depth
+
+    @property
+    def price_type(self) -> PriceType:
+        return self._price_type
+
     @property
     def order_refresh_tolerance_pct(self) -> Decimal:
         return self._order_refresh_tolerance_pct
@@ -593,13 +615,13 @@ cdef class PureMarketMakingStrategy(StrategyBase):
         warning_lines.extend(self._ping_pong_warning_lines)
         warning_lines.extend(self.network_warning([self._market_info]))
 
-        markets_df = self.market_status_data_frame([self._market_info])
+        markets_df = map_df_to_str(self.market_status_data_frame([self._market_info]))
         lines.extend(["", "  Markets:"] + ["    " + line for line in markets_df.to_string(index=False).split("\n")])
 
-        assets_df = self.pure_mm_assets_df(not self._inventory_skew_enabled)
+        assets_df = map_df_to_str(self.pure_mm_assets_df(not self._inventory_skew_enabled))
         # append inventory skew stats.
         if self._inventory_skew_enabled:
-            inventory_skew_df = self.inventory_skew_stats_data_frame()
+            inventory_skew_df = map_df_to_str(self.inventory_skew_stats_data_frame())
             assets_df = assets_df.append(inventory_skew_df)
 
         first_col_length = max(*assets_df[0].apply(len))
@@ -609,7 +631,7 @@ cdef class PureMarketMakingStrategy(StrategyBase):
 
         # See if there're any open orders.
         if len(self.active_orders) > 0:
-            df = self.active_orders_df()
+            df = map_df_to_str(self.active_orders_df())
             lines.extend(["", "  Orders:"] + ["    " + line for line in df.to_string(index=False).split("\n")])
         else:
             lines.extend(["", "  No active maker orders."])
diff --git a/hummingbot/strategy/pure_market_making/start.py b/hummingbot/strategy/pure_market_making/start.py
index 6c900e0320a..425eaaca7a5 100644
--- a/hummingbot/strategy/pure_market_making/start.py
+++ b/hummingbot/strategy/pure_market_making/start.py
@@ -75,8 +75,8 @@ def start(self):
         take_if_crossed = c_map.get("take_if_crossed").value
 
         strategy_logging_options = PureMarketMakingStrategy.OPTION_LOG_ALL
-
-        self.strategy = PureMarketMakingStrategy(
+        self.strategy = PureMarketMakingStrategy()
+        self.strategy.init_params(
             market_info=MarketTradingPairTuple(*maker_data),
             bid_spread=bid_spread,
             ask_spread=ask_spread,
@@ -90,7 +90,7 @@ def start(self):
             filled_order_delay=filled_order_delay,
             hanging_orders_enabled=hanging_orders_enabled,
             order_refresh_time=order_refresh_time,
-            max_order_age = max_order_age,
+            max_order_age=max_order_age,
             order_optimization_enabled=order_optimization_enabled,
             ask_order_optimization_depth=ask_order_optimization_depth,
             bid_order_optimization_depth=bid_order_optimization_depth,
diff --git a/hummingbot/strategy/spot_perpetual_arbitrage/spot_perpetual_arbitrage.py b/hummingbot/strategy/spot_perpetual_arbitrage/spot_perpetual_arbitrage.py
index da233461c0b..47f89d0fa9b 100644
--- a/hummingbot/strategy/spot_perpetual_arbitrage/spot_perpetual_arbitrage.py
+++ b/hummingbot/strategy/spot_perpetual_arbitrage/spot_perpetual_arbitrage.py
@@ -45,18 +45,18 @@ def logger(cls) -> HummingbotLogger:
             spa_logger = logging.getLogger(__name__)
         return spa_logger
 
-    def __init__(self,
-                 spot_market_info: MarketTradingPairTuple,
-                 derivative_market_info: MarketTradingPairTuple,
-                 order_amount: Decimal,
-                 derivative_leverage: int,
-                 min_divergence: Decimal,
-                 min_convergence: Decimal,
-                 spot_market_slippage_buffer: Decimal = Decimal("0"),
-                 derivative_market_slippage_buffer: Decimal = Decimal("0"),
-                 maximize_funding_rate: bool = True,
-                 next_arbitrage_cycle_delay: float = 120,
-                 status_report_interval: float = 10):
+    def init_params(self,
+                    spot_market_info: MarketTradingPairTuple,
+                    derivative_market_info: MarketTradingPairTuple,
+                    order_amount: Decimal,
+                    derivative_leverage: int,
+                    min_divergence: Decimal,
+                    min_convergence: Decimal,
+                    spot_market_slippage_buffer: Decimal = Decimal("0"),
+                    derivative_market_slippage_buffer: Decimal = Decimal("0"),
+                    maximize_funding_rate: bool = True,
+                    next_arbitrage_cycle_delay: float = 120,
+                    status_report_interval: float = 10):
         """
         :param spot_market_info: The first market
         :param derivative_market_info: The second market
@@ -71,7 +71,6 @@ def __init__(self,
         :param maximize_funding_rate: whether to submit both arbitrage taker orders (buy and sell) simultaneously
         If false, the bot will wait for first exchange order filled before submitting the other order.
         """
-        super().__init__()
         self._spot_market_info = spot_market_info
         self._derivative_market_info = derivative_market_info
         self._min_divergence = min_divergence
diff --git a/hummingbot/strategy/spot_perpetual_arbitrage/start.py b/hummingbot/strategy/spot_perpetual_arbitrage/start.py
index 4ba45dfb60b..119df667d00 100644
--- a/hummingbot/strategy/spot_perpetual_arbitrage/start.py
+++ b/hummingbot/strategy/spot_perpetual_arbitrage/start.py
@@ -27,13 +27,14 @@ def start(self):
     derivative_market_info = MarketTradingPairTuple(self.markets[derivative_connector], derivative_market, base_2, quote_2)
 
     self.market_trading_pair_tuples = [spot_market_info, derivative_market_info]
-    self.strategy = SpotPerpetualArbitrageStrategy(spot_market_info,
-                                                   derivative_market_info,
-                                                   order_amount,
-                                                   derivative_leverage,
-                                                   min_divergence,
-                                                   min_convergence,
-                                                   spot_market_slippage_buffer,
-                                                   derivative_market_slippage_buffer,
-                                                   maximize_funding_rate,
-                                                   next_arbitrage_cycle_delay)
+    self.strategy = SpotPerpetualArbitrageStrategy()
+    self.strategy.init_params(spot_market_info,
+                              derivative_market_info,
+                              order_amount,
+                              derivative_leverage,
+                              min_divergence,
+                              min_convergence,
+                              spot_market_slippage_buffer,
+                              derivative_market_slippage_buffer,
+                              maximize_funding_rate,
+                              next_arbitrage_cycle_delay)
diff --git a/hummingbot/strategy/strategy_base.pyx b/hummingbot/strategy/strategy_base.pyx
index c064abb4084..e1edc074e37 100755
--- a/hummingbot/strategy/strategy_base.pyx
+++ b/hummingbot/strategy/strategy_base.pyx
@@ -130,6 +130,14 @@ cdef class StrategyBase(TimeIterator):
 
         self._sb_order_tracker = OrderTracker()
 
+    def init_params(self, *args, **kwargs):
+        """
+        Assigns strategy parameters, this function must be called directly after init.
+        The reason for this is to make the parameters discoverable through introspect (this is not possible on init of
+        a Cython class).
+        """
+        raise NotImplementedError
+
     @property
     def active_markets(self) -> List[ConnectorBase]:
         return list(self._sb_markets)
diff --git a/setup.py b/setup.py
index 7bc570908b4..ccab4a0fb4f 100755
--- a/setup.py
+++ b/setup.py
@@ -22,7 +22,7 @@
 
 
 # Avoid a gcc warning below:
-# cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid
+# cc1plus: warning: command line option ???-Wstrict-prototypes??? is valid
 # for C/ObjC but not for C++
 class BuildExt(build_ext):
     def build_extensions(self):
@@ -33,7 +33,7 @@ def build_extensions(self):
 
 def main():
     cpu_count = os.cpu_count() or 8
-    version = "20210518"
+    version = "20210618"
     packages = [
         "hummingbot",
         "hummingbot.client",
@@ -78,6 +78,7 @@ def main():
         "hummingbot.connector.exchange.k2",
         "hummingbot.connector.derivative",
         "hummingbot.connector.derivative.binance_perpetual",
+        "hummingbot.model",
         "hummingbot.script",
         "hummingbot.strategy",
         "hummingbot.strategy.amm_arb",
@@ -106,6 +107,10 @@ def main():
         ],
     }
     install_requires = [
+        "0x-contract-artifacts",
+        "0x-contract-wrappers",
+        "0x-json-schemas",
+        "0x-order-utils",
         "aioconsole",
         "aiokafka",
         "attrdict",
@@ -135,7 +140,7 @@ def main():
         "attrs",
         "certifi",
         "chardet",
-        "cython==0.29.23",
+        "cython==3.0a7",
         "idna",
         "idna_ssl",
         "multidict",
diff --git a/setup/environment-linux.yml b/setup/environment-linux.yml
index 7aee6485fb4..b96cca10a1f 100644
--- a/setup/environment-linux.yml
+++ b/setup/environment-linux.yml
@@ -6,44 +6,42 @@ channels:
 dependencies:
   - _libgcc_mutex=0.1=conda_forge
   - _openmp_mutex=4.5=0_gnu
-  - blas=1.0=openblas
-  - blosc=1.16.3=hd408876_0
-  - bzip2=1.0.8=h7b6447c_0
-  - ca-certificates=2020.1.1=0
-  - certifi=2019.11.28=py38_0
+  - blas=1.1
+  - blosc=1.21.0
+  - bzip2=1.0.8
+  - ca-certificates
+  - certifi
   - coverage=5.5
-  - cython=0.29.15=py38he6710b0_0
-  - hdf5=1.10.4=hb1b8bf9_0
-  - intel-openmp=2020.0=166
+  - hdf5=1.10.5
+  - intel-openmp
   - ld_impl_linux-64=2.33.1=h53a641e_8
-  - libffi=3.2.1=he1b5a44_1006
-  - libgcc-ng=9.2.0=h24d8f2e_2
-  - libgfortran-ng=7.3.0=hdf63c60_0
-  - libgomp=9.2.0=h24d8f2e_2
-  - libopenblas=0.3.7=h5ec1e0e_6
-  - libstdcxx-ng=9.2.0=hdf63c60_2
-  - lz4-c=1.8.1.2=h14c3975_0
-  - lzo=2.10=h49e0be7_2
+  - libffi=3.2.1
+  - libgcc-ng
+  - libgfortran-ng
+  - libgomp
+  - libopenblas=0.3.13
+  - libstdcxx-ng
+  - lz4-c=1.9.3
+  - lzo=2.10
   - mock=4.0.1=py_0
   - ncurses=6.1=hf484d3e_1002
-  - nomkl=3.0=0
+  - nomkl=1.0
   - nose=1.3.7=py38_2
   - numexpr=2.7.1=py38h7ea95a0_0
-  - numpy=1.18.5=py38h7130bb8_0
+  - numpy=1.20.0
   - numpy-base=1.18.5=py38h2f8d375_0
-  - openblas=0.3.7=he1df0ab_6
-  - openssl=1.1.1d=h7b6447c_4
-  - pandas=1.0.1=py38h0573a6f_0
-  - pip=20.0.2=py_2
+  - openblas=0.3.4
+  - openssl=1.1.1k
+  - pandas=1.2.1
+  - pip=21.1.2
   - prompt_toolkit=3.0.3=py_0
   - pygments=2.5.2=py_0
-  - pytables=3.6.1=py38h9fd0a39_0
+  - pytables=3.6.1
   - python=3.8.2=h9d8adfe_4_cpython
   - python-dateutil=2.8.1=py_0
   - python_abi=3.8=1_cp38
   - pytz=2019.3=py_0
   - readline=8.0=hf8c457e_0
-  - setuptools=45.2.0=py38_0
   - six=1.14.0=py38_0
   - snappy=1.1.7=hbae5bb6_3
   - sqlalchemy=1.3.13=py38h7b6447c_0
@@ -80,14 +78,15 @@ dependencies:
     - coincurve==13.0.0
     - constantly==15.1.0
     - cryptography==2.8
-    - cytoolz==0.10.1
-    - dateparser==0.7.4
+    - cython==3.0a7
+    - cytoolz==0.11.0
+    - dateparser==1.0.0
     - decorator==4.4.2
     - deprecated==1.2.7
     - diff-cover==5.1.2
     - distlib==0.3.0
-    - dydx-python==0.11.2
-    - dydx-v3-python==1.0.0
+    - dydx-python==0.11.3
+    - dydx-v3-python==1.0.8
     - entrypoints==0.3
     - eth-abi==2.1.1
     - eth-account==0.4.0
@@ -105,7 +104,7 @@ dependencies:
     - hexbytes==0.2.0
     - hyperlink==19.0.0
     - identify==1.4.11
-    - idna==2.9
+    - idna==2.8
     - incremental==17.5.0
     - ipfshttpclient==0.4.12
     - jsonschema==3.2.0
@@ -137,7 +136,7 @@ dependencies:
     - python-telegram-bot==12.4.2
     - pyyaml==5.3
     - regex==2020.2.20
-    - requests==2.23.0
+    - requests==2.22.0
     - rlp==1.2.0
     - rsa==4.7
     - ruamel-yaml==0.16.10
@@ -153,11 +152,11 @@ dependencies:
     - urllib3==1.25.8
     - varint==1.0.2
     - virtualenv==20.0.8
-    - web3==5.5.1
+    - web3==5.8.0
     - websockets==8.1
     - wrapt==1.12.0
     - yarl==1.4.2
     - zope-interface==4.7.1
     - git+https://github.com/CoinAlpha/python-signalr-client.git
-    - https://hummingbot-python.s3-us-west-2.amazonaws.com/hummingsim-20200902-cp38-cp38-linux_x86_64.whl
+    - https://hummingbot-python.s3-us-west-2.amazonaws.com/hummingsim-20210601-cp38-cp38-linux_x86_64.whl
 prefix: /home/martin_kou/anaconda3/envs/hummingbot
diff --git a/setup/environment-win64.yml b/setup/environment-win64.yml
index 21f5f73d3e1..fbe9b15591f 100644
--- a/setup/environment-win64.yml
+++ b/setup/environment-win64.yml
@@ -4,51 +4,54 @@ channels:
   - defaults
 dependencies:
   - blas=1.0=mkl
-  - blosc=1.16.3=h7bd577a_0
-  - bzip2=1.0.8=he774522_0
-  - ca-certificates=2020.1.1=0
-  - certifi=2019.11.28=py38_0
-  - coverage=5.5
-  - cython=0.29.15=py38ha925a31_0
-  - hdf5=1.10.4=h7ebc959_0
+  - blosc=1.21.0=h0e60522_0
+  - bzip2=1.0.8=h8ffe710_4
+  - ca-certificates=2021.5.30=h5b45459_0
+  - certifi=2021.5.30=py38haa244fe_0
+  - coverage=5.5=py38h294d835_0
+  - hdf5=1.10.5=nompi_h4d922ce_1114
   - icc_rt=2019.0.0=h0cc432a_1
-  - intel-openmp=2020.0=166
-  - lz4-c=1.8.1.2=h2fa13f4_0
-  - lzo=2.10=h6df0209_2
-  - mkl=2020.0=166
-  - mkl-service=2.3.0=py38hb782905_0
-  - mkl_fft=1.0.15=py38h14836fe_0
-  - mkl_random=1.1.0=py38hf9181ef_0
-  - mock=4.0.1=py_0
-  - nose=1.3.7=py38_2
-  - numexpr=2.7.1=py38h25d0782_0
-  - numpy=1.18.1=py38h93ca92e_0
-  - numpy-base=1.18.1=py38hc3f5095_1
-  - openssl=1.1.1d=he774522_4
-  - pandas=1.0.1=py38h47e9c7a_0
-  - pip=20.0.2=py_2
+  - intel-openmp=2021.2.0=h57928b3_616
+  - libblas=3.9.0=8_mkl
+  - libcblas=3.9.0=8_mkl
+  - liblapack=3.9.0=8_mkl
+  - lz4=3.1.3=py38h34afd45_0
+  - lz4-c=1.9.3=h8ffe710_0
+  - lzo=2.10=he774522_1000
+  - mkl=2020.4=hb70f87d_311
+  - mkl-service=2.3.0=py38h1e8a9f7_2
+  - mkl_fft=1.3.0=py38h347fdf6_1
+  - mkl_random=1.2.0=py38h251f6bf_1
+  - mock=4.0.1=py_1
+  - nose=1.3.7=py_1006
+  - numexpr=2.7.1=py38h251f6bf_3
+  - numpy=1.20.0=py38h0cc643e_0
+  - numpy-base=1.18.5=py38hc3f5095_0
+  - openssl=1.1.1k=h8ffe710_0
+  - pandas=1.2.1=py38h4c96930_0
+  - pip=21.1.2=pyhd8ed1ab_0
   - prompt_toolkit=3.0.3=py_0
   - pygments=2.5.2=py_0
-  - pytables=3.6.1=py38ha5be198_0
-  - python=3.8.2=h5fd99cc_4_cpython
+  - pytables=3.6.1=py38h26f9782_1
+  - python=3.8.2=h5fd99cc_7_cpython
   - python-dateutil=2.8.1=py_0
-  - python_abi=3.8=1_cp38
+  - python_abi=3.8=2_cp38
   - pytz=2019.3=py_0
-  - setuptools=45.3.0=py38_0
-  - six=1.14.0=py38_0
-  - snappy=1.1.7=h777316e_3
-  - sqlalchemy=1.3.13=py38he774522_0
-  - sqlite=3.30.1=hfa6e2cd_0
-  - tzlocal=2.0.0=py38_0
-  - ujson=1.35=py38he774522_0
-  - vc=14.1=h0510ff6_4
-  - vs2015_runtime=14.16.27012=hf0eaf9b_1
-  - wcwidth=0.1.8=py_0
+  - six=1.14.0=py_1
+  - snappy=1.1.7=h6538335_1003
+  - sqlalchemy=1.3.13=py38hfa6e2cd_0
+  - sqlite=3.31.1=h2a8f88b_1
+  - tzlocal=2.0.0=py_0
+  - ucrt=10.0.20348.0=h57928b3_0
+  - ujson=1.35=py38h885f38d_1003
+  - vc=14.2=hb210afc_5
+  - vs2015_runtime=14.29.30037=h902a5da_5
+  - wcwidth=0.1.8=pyh9f0ad1d_1
   - wheel=0.34.2=py_1
-  - wincertstore=0.2=py38_1003
-  - xz=5.2.4=h2fa13f4_4
-  - zlib=1.2.11=h62dcd97_3
-  - zstd=1.3.7=h508b16e_0
+  - wincertstore=0.2=py38haa244fe_1006
+  - xz=5.2.4=h2fa13f4_1002
+  - zlib=1.2.11=h62dcd97_1010
+  - zstd=1.3.7=haafe652_1001
   - pip:
     - 0x-contract-addresses==3.0.0
     - 0x-contract-artifacts==2.0.0
@@ -62,26 +65,31 @@ dependencies:
     - appdirs==1.4.3
     - asn1crypto==1.3.0
     - async-timeout==3.0.1
+    - atomicwrites==1.4.0
     - attrdict==2.0.1
     - attrs==19.3.0
     - autobahn==20.3.1
     - automat==20.2.0
     - base58==2.0.0
+    - bitstring==3.1.7
     - cachetools==4.0.0
     - cffi==1.14.0
     - cfgv==3.1.0
     - chardet==3.0.4
     - coincurve==13.0.0
+    - colorama==0.4.4
     - constantly==15.1.0
     - cryptography==2.8
-    - cytoolz==0.10.1
-    - dateparser==0.7.4
+    - cython==3.0a7
+    - cytoolz==0.11.0
+    - dateparser==1.0.0
     - decorator==4.4.2
     - deprecated==1.2.7
     - diff-cover==5.1.2
     - distlib==0.3.0
-    - dydx-python==0.11.2
-    - dydx-v3-python==1.0.0
+    - dydx-python==0.11.3
+    - dydx-v3-python==1.0.8
+    - ecdsa==0.16.0
     - entrypoints==0.3
     - eth-abi==2.1.1
     - eth-account==0.4.0
@@ -99,25 +107,37 @@ dependencies:
     - hexbytes==0.2.0
     - hyperlink==19.0.0
     - identify==1.4.11
-    - idna==2.9
+    - idna==2.8
+    - importlib-metadata==0.23
     - incremental==17.5.0
+    - inflect==5.3.0
     - ipfshttpclient==0.4.12
+    - jinja2==3.0.1
+    - jinja2-pluralize==0.3.0
     - jsonschema==3.2.0
     - kafka-python==1.4.6
     - lru-dict==1.1.6
+    - markupsafe==2.0.1
     - mccabe==0.6.1
+    - more-itertools==8.8.0
+    - mpmath==1.0.0
     - multiaddr==0.0.9
     - multidict==4.7.5
     - mypy-extensions==0.4.3
     - netaddr==0.7.19
     - nodeenv==1.3.5
+    - objgraph==3.5.0
+    - packaging==21.0
     - parsimonious==0.8.1
-    - pefile==2019.4.18
+    - pefile==2021.5.24
+    - pluggy==0.13.1
     - pre-commit==2.1.1
     - protobuf==3.11.3
     - psutil==5.7.2
+    - py==1.10.0
     - pyasn1==0.4.8
     - pyasn1-modules==0.2.8
+    - pyblake2==1.1.2
     - pycodestyle==2.5.0
     - pycparser==2.20
     - pycryptodome==3.9.7
@@ -126,36 +146,44 @@ dependencies:
     - pyinstaller==3.6
     - pyjwt==1.7.1
     - pyopenssl==19.1.0
+    - pyparsing==2.4.7
     - pyperclip==1.7.0
     - pypiwin32==223
     - pyrsistent==0.15.7
+    - pysha3==1.0.2
+    - pytest==4.6.11
     - python-binance==0.7.5
     - python-telegram-bot==12.4.2
     - pywin32==227
     - pywin32-ctypes==0.2.0
     - pyyaml==5.3
     - regex==2020.2.20
-    - requests==2.23.0
+    - requests==2.22.0
+    - requests-mock==1.6.0
     - rlp==1.2.0
     - rsa==4.7
     - ruamel-yaml==0.16.10
     - ruamel-yaml-clib==0.2.0
     - service-identity==18.1.0
+    - setuptools==50.3.2
     - simplejson==3.17.2
     - stringcase==1.2.0
+    - sympy==1.6
     - toml==0.10.0
     - toolz==0.10.0
     - tornado==6.0.4
+    - tox==3.13.2
     - twisted==19.10.0
     - txaio==20.1.1
     - urllib3==1.25.8
     - varint==1.0.2
     - virtualenv==20.0.8
-    - web3==5.5.1
+    - web3==5.8.0
     - websockets==8.1
     - wrapt==1.12.0
     - yarl==1.4.2
+    - zipp==3.5.0
     - zope-interface==4.7.1
     - git+https://github.com/CoinAlpha/python-signalr-client.git
-    - https://hummingbot-python.s3-us-west-2.amazonaws.com/hummingsim-20200904-cp38-cp38-win_amd64.whl
+    - https://hummingbot-python.s3.us-west-2.amazonaws.com/hummingsim-20210607-cp38-cp38-win_amd64.whl
 prefix: C:\Users\marti\Anaconda3\envs\hummingbot
diff --git a/setup/environment.yml b/setup/environment.yml
index f3fd4d9a245..67a2ea01ffa 100644
--- a/setup/environment.yml
+++ b/setup/environment.yml
@@ -1,44 +1,46 @@
 name: hummingbot
 channels:
   - conda-forge
-  - conda-canary
   - defaults
 dependencies:
   - appnope=0.1.0=py38_0
-  - blas=1.0=openblas
-  - blosc=1.16.3=hd9629dc_0
-  - bzip2=1.0.8=h1de35cc_0
-  - ca-certificates=2020.6.24=0
-  - certifi=2020.6.20=py38_0
+  - blas=1.1=openblas
+  - blosc=1.21.0=he49afe7_0
+  - bzip2=1.0.8=h0d85af4_4
+  - ca-certificates=2021.5.30=h033912b_0
+  - certifi=2021.5.30=py38h50d1736_0
   - coverage=5.5
-  - cython=0.29.15=py38h0a44026_0
-  - hdf5=1.10.4=hfa1e0ec_0
-  - intel-openmp=2019.4=233
-  - libcxx=9.0.1=1
-  - libedit=3.1.20181209=hb402a30_0
-  - libffi=3.2.1=h6de7cb9_1006
-  - libgfortran=3.0.1=h93005f0_2
-  - libopenblas=0.3.10=h0794777_0
-  - lz4-c=1.8.1.2=h1de35cc_0
-  - lzo=2.10=h362108e_2
+  - hdf5=1.10.5=nompi_h0cbb7df_1103
+  - intel-openmp=2021.2.0=hecd8cb5_564
+  - libblas=3.8.0=7_hd44dcd8_netlib
+  - libcblas=3.8.0=7_hd44dcd8_netlib
+  - libcxx=11.1.0=habf9029_0
+  - libedit=3.1.20191231=hed1e85f_2
+  - libffi=3.2.1=hb1e8313_1007
+  - libgfortran=3.0.1=0
+  - liblapack=3.8.0=7_hd44dcd8_netlib
+  - libopenblas=0.3.13=h7ddc91c_0
+  - lz4-c=1.9.3=h046ec9c_0
+  - lzo=2.10=haf1e3a3_1000
   - mock=4.0.1=py_0
   - ncurses=6.1=h0a44026_1002
-  - nomkl=3.0=0
+  - nomkl=1.0=h5ca1d4c_0
   - nose=1.3.7=py38_2
   - numexpr=2.7.1=py38h9ff8ad3_0
-  - numpy=1.18.5=py38h00fe2a6_0
+  - numpy=1.20.0=py38h64deac9_0
   - numpy-base=1.18.5=py38hc72aeb7_0
-  - openssl=1.1.1g=h1de35cc_0
-  - pandas=1.0.1=py38h6c726b0_0
-  - pip=20.0.2=py_2
+  - openblas=0.3.4=hdc02c5d_1000
+  - openssl=1.1.1k=h0d85af4_0
+  - pandas=1.2.1=py38he9f00de_0
+  - pip=21.1.2=pyhd8ed1ab_0
   - prompt_toolkit=3.0.3=py_0
   - pygments=2.5.2=py_0
-  - pytables=3.6.1=py38h4727e94_0
+  - pytables=3.6.1=py38h6f8395a_1
   - python=3.8.2=hdc38147_4_cpython
   - python-dateutil=2.8.1=py_0
+  - python_abi=3.8=1_cp38
   - pytz=2019.3=py_0
   - readline=8.0=h1de35cc_0
-  - setuptools=45.2.0=py38_0
   - six=1.14.0=py38_0
   - snappy=1.1.7=he62c110_3
   - sqlalchemy=1.3.13=py38h1de35cc_0
@@ -64,11 +66,13 @@ dependencies:
     - appdirs==1.4.3
     - asn1crypto==1.3.0
     - async-timeout==3.0.1
+    - atomicwrites==1.4.0
     - attrdict==2.0.1
     - attrs==19.3.0
     - autobahn==20.3.1
     - automat==20.2.0
     - base58==2.0.0
+    - bitstring==3.1.7
     - cachetools==4.0.0
     - cffi==1.14.0
     - cfgv==3.1.0
@@ -76,14 +80,16 @@ dependencies:
     - coincurve==13.0.0
     - constantly==15.1.0
     - cryptography==2.8
-    - cytoolz==0.10.1
-    - dateparser==0.7.4
+    - cython==3.0a7
+    - cytoolz==0.11.0
+    - dateparser==1.0.0
     - decorator==4.4.2
     - deprecated==1.2.7
     - diff-cover==5.1.2
     - distlib==0.3.0
-    - dydx-python==0.11.2
-    - dydx-v3-python==1.0.0
+    - dydx-python==0.11.3
+    - dydx-v3-python==1.0.8
+    - ecdsa==0.16.0
     - entrypoints==0.3
     - eth-abi==2.1.1
     - eth-account==0.4.0
@@ -101,7 +107,9 @@ dependencies:
     - hexbytes==0.2.0
     - hyperlink==19.0.0
     - identify==1.4.11
-    - idna==2.9
+    - idna==2.8
+    - idna-ssl==1.1.0
+    - importlib-metadata==0.23
     - incremental==17.5.0
     - ipfshttpclient==0.4.12
     - jsonschema==3.2.0
@@ -109,18 +117,24 @@ dependencies:
     - lru-dict==1.1.6
     - macholib==1.14
     - mccabe==0.6.1
+    - more-itertools==8.8.0
+    - mpmath==1.0.0
     - multiaddr==0.0.9
     - multidict==4.7.5
     - mypy-extensions==0.4.3
     - netaddr==0.7.19
     - nodeenv==1.3.5
     - objgraph==3.4.1
+    - packaging==20.9
     - parsimonious==0.8.1
+    - pluggy==0.13.1
     - pre-commit==2.1.1
     - protobuf==3.11.3
     - psutil==5.7.2
+    - py==1.10.0
     - pyasn1==0.4.8
     - pyasn1-modules==0.2.8
+    - pyblake2==1.1.2
     - pycodestyle==2.5.0
     - pycparser==2.20
     - pycryptodome==3.9.7
@@ -129,33 +143,42 @@ dependencies:
     - pyinstaller==3.6
     - pyjwt==1.7.1
     - pyopenssl==19.1.0
+    - pyparsing==2.4.7
     - pyperclip==1.7.0
     - pyrsistent==0.15.7
+    - pysha3==1.0.2
+    - pytest==4.6.11
     - python-binance==0.7.5
     - python-telegram-bot==12.4.2
     - pyyaml==5.3
     - regex==2020.2.20
-    - requests==2.23.0
+    - requests==2.22.0
+    - requests-mock==1.6.0
     - rlp==1.2.0
     - rsa==4.7
     - ruamel-yaml==0.16.10
     - ruamel-yaml-clib==0.2.0
     - service-identity==18.1.0
+    - setuptools==50.3.2
+    - signalr-client-aio==0.0.1.6.2
     - simplejson==3.17.2
     - stringcase==1.2.0
+    - sympy==1.6
     - toml==0.10.0
     - toolz==0.10.0
     - tornado==6.0.4
+    - tox==3.13.2
     - twisted==19.10.0
     - txaio==20.1.1
     - urllib3==1.25.8
     - varint==1.0.2
     - virtualenv==20.0.8
-    - web3==5.5.1
+    - web3==5.8.0
     - websockets==8.1
     - wrapt==1.12.0
     - yarl==1.4.2
+    - zipp==3.4.1
     - zope-interface==4.7.1
     - git+https://github.com/CoinAlpha/python-signalr-client.git
-    - https://hummingbot-python.s3-us-west-2.amazonaws.com/hummingsim-20200902-cp38-cp38-macosx_10_9_x86_64.whl
-prefix: /Users/martin_kou/anaconda3/envs/hummingbot
+    - https://hummingbot-python.s3-us-west-2.amazonaws.com/hummingsim-20210531-cp38-cp38-macosx_10_9_x86_64.whl
+prefix: /usr/local/Caskroom/miniconda/base/envs/hummingbot
diff --git a/test/hummingbot/core/utils/test_map_df_to_str.py b/test/hummingbot/core/utils/test_map_df_to_str.py
new file mode 100644
index 00000000000..d5881e83eaa
--- /dev/null
+++ b/test/hummingbot/core/utils/test_map_df_to_str.py
@@ -0,0 +1,16 @@
+import unittest
+import pandas as pd
+from hummingbot.core.utils import map_df_to_str
+
+
+class MapDfToStrTest(unittest.TestCase):
+
+    def test_map_df_to_str(self):
+        df = pd.DataFrame(data=[0.2, 0, 1, 100., 1.00])
+        df = map_df_to_str(df)
+        self.assertEqual(df.to_string(), "     0\n"
+                                         "0  0.2\n"
+                                         "1    0\n"
+                                         "2    1\n"
+                                         "3  100\n"
+                                         "4    1")
diff --git a/test/hummingbot/script/test_script_iterator.py b/test/hummingbot/script/test_script_iterator.py
index 8f6e9c39b39..8551e3906e5 100644
--- a/test/hummingbot/script/test_script_iterator.py
+++ b/test/hummingbot/script/test_script_iterator.py
@@ -68,7 +68,8 @@ def setUp(self):
         self.market_info = MarketTradingPairTuple(self.market, self.trading_pair,
                                                   self.base_asset, self.quote_asset)
         self.clock.add_iterator(self.market)
-        self.one_level_strategy = PureMarketMakingStrategy(
+        self.one_level_strategy = PureMarketMakingStrategy()
+        self.one_level_strategy.init_params(
             self.market_info,
             bid_spread=Decimal("0.01"),
             ask_spread=Decimal("0.01"),
@@ -78,7 +79,8 @@ def setUp(self):
             order_refresh_tolerance_pct=-1,
             minimum_spread=-1,
         )
-        self.multi_levels_strategy = PureMarketMakingStrategy(
+        self.multi_levels_strategy = PureMarketMakingStrategy()
+        self.multi_levels_strategy.init_params(
             self.market_info,
             bid_spread=Decimal("0.01"),
             ask_spread=Decimal("0.01"),
diff --git a/test/hummingbot/strategy/__init__.py b/test/hummingbot/strategy/__init__.py
index e69de29bb2d..8daf8fe12da 100644
--- a/test/hummingbot/strategy/__init__.py
+++ b/test/hummingbot/strategy/__init__.py
@@ -0,0 +1,7 @@
+from typing import Dict
+from hummingbot.client.config.config_var import ConfigVar
+
+
+def assign_config_default(config_map: Dict[str, ConfigVar]):
+    for key, value in config_map.items():
+        value.value = value.default
diff --git a/test/hummingbot/strategy/amm_arb/test_amm_arb.py b/test/hummingbot/strategy/amm_arb/test_amm_arb.py
index 40a65ce0f7d..ae8cee6d057 100644
--- a/test/hummingbot/strategy/amm_arb/test_amm_arb.py
+++ b/test/hummingbot/strategy/amm_arb/test_amm_arb.py
@@ -119,7 +119,8 @@ def setUp(self):
         self.amm_2.set_balance(base_asset, 500)
         self.amm_2.set_balance(quote_asset, 500)
         self.market_info_2 = MarketTradingPairTuple(self.amm_2, trading_pair, base_asset, quote_asset)
-        self.strategy = AmmArbStrategy(
+        self.strategy = AmmArbStrategy()
+        self.strategy.init_params(
             self.market_info_1,
             self.market_info_2,
             min_profitability=Decimal("0.01"),
@@ -235,7 +236,8 @@ def trigger_order_complete(is_buy: bool, connector: ConnectorBase, amount: Decim
     def test_non_concurrent_orders_submission(self):
         # On non concurrent orders submission, the second leg of the arb trade has to wait for the first leg order gets
         # filled.
-        self.strategy = AmmArbStrategy(
+        self.strategy = AmmArbStrategy()
+        self.strategy.init_params(
             self.market_info_1,
             self.market_info_2,
             min_profitability=Decimal("0.01"),
@@ -296,9 +298,9 @@ def test_format_status(self):
         self.strategy._arb_proposals = [ArbProposal(first_side, second_side)]
 
         expected_status = ("  Markets:\n"
-                           "    Exchange     Market    Sell Price     Buy Price     Mid Price\n"
-                           "       onion  HBOT-USDT  100.00000000  101.00000000  100.50000000\n"
-                           "      garlic  HBOT-USDT  104.00000000  105.00000000  104.50000000\n\n"
+                           "    Exchange    Market   Sell Price    Buy Price    Mid Price\n"
+                           "       onion HBOT-USDT 100.00000000 101.00000000 100.50000000\n"
+                           "      garlic HBOT-USDT 104.00000000 105.00000000 104.50000000\n\n"
                            "  Assets:\n"
                            "      Exchange Asset  Total Balance  Available Balance\n"
                            "    0    onion  HBOT            500                500\n"
diff --git a/test/hummingbot/strategy/amm_arb/test_amm_arb_start.py b/test/hummingbot/strategy/amm_arb/test_amm_arb_start.py
new file mode 100644
index 00000000000..7cbc232d86a
--- /dev/null
+++ b/test/hummingbot/strategy/amm_arb/test_amm_arb_start.py
@@ -0,0 +1,49 @@
+from decimal import Decimal
+import unittest.mock
+import hummingbot.strategy.amm_arb.start as amm_arb_start
+from hummingbot.strategy.amm_arb.amm_arb_config_map import amm_arb_config_map
+from hummingbot.strategy.amm_arb.amm_arb import AmmArbStrategy
+from test.hummingbot.strategy import assign_config_default
+
+
+class AMMArbStartTest(unittest.TestCase):
+
+    def setUp(self) -> None:
+        super().setUp()
+        self.strategy: AmmArbStrategy = None
+        self.markets = {"binance": None, "balancer": None}
+        self.assets = set()
+        self.notifications = []
+        self.log_errors = []
+        assign_config_default(amm_arb_config_map)
+        amm_arb_config_map.get("strategy").value = "amm_arb"
+        amm_arb_config_map.get("connector_1").value = "binance"
+        amm_arb_config_map.get("market_1").value = "ETH-USDT"
+        amm_arb_config_map.get("connector_2").value = "balancer"
+        amm_arb_config_map.get("market_2").value = "ETH-USDT"
+        amm_arb_config_map.get("order_amount").value = Decimal("1")
+        amm_arb_config_map.get("min_profitability").value = Decimal("10")
+
+    def _initialize_market_assets(self, market, trading_pairs):
+        pass
+
+    def _initialize_wallet(self, token_trading_pairs):
+        pass
+
+    def _initialize_markets(self, market_names):
+        pass
+
+    def _notify(self, message):
+        self.notifications.append(message)
+
+    def logger(self):
+        return self
+
+    def error(self, message, exc_info):
+        self.log_errors.append(message)
+
+    @unittest.mock.patch('hummingbot.strategy.amm_arb.amm_arb.AmmArbStrategy.add_markets')
+    def test_amm_arb_strategy_creation(self, mock):
+        amm_arb_start.start(self)
+        self.assertEqual(self.strategy._order_amount, Decimal(1))
+        self.assertEqual(self.strategy._min_profitability, Decimal("10") / Decimal("100"))
diff --git a/test/hummingbot/strategy/arbitrage/test_arbitrage.py b/test/hummingbot/strategy/arbitrage/test_arbitrage.py
index 9dde0af0263..1044162f4de 100644
--- a/test/hummingbot/strategy/arbitrage/test_arbitrage.py
+++ b/test/hummingbot/strategy/arbitrage/test_arbitrage.py
@@ -70,7 +70,8 @@ def setUp(self):
 
         self.logging_options: int = ArbitrageStrategy.OPTION_LOG_ALL
 
-        self.strategy: ArbitrageStrategy = ArbitrageStrategy(
+        self.strategy: ArbitrageStrategy = ArbitrageStrategy()
+        self.strategy.init_params(
             [self.market_pair],
             min_profitability=Decimal("0.03"),
             logging_options=self.logging_options,
@@ -141,7 +142,8 @@ def test_find_best_profitable_amount(self):
         self.assertAlmostEqual(Decimal(1.0329489291598024), profitability)
 
     def test_min_profitability_limit_1(self):
-        self.strategy: ArbitrageStrategy = ArbitrageStrategy(
+        self.strategy: ArbitrageStrategy = ArbitrageStrategy()
+        self.strategy.init_params(
             [self.market_pair],
             min_profitability=Decimal("0.04"),
             logging_options=self.logging_options,
@@ -190,7 +192,8 @@ def test_min_profitability_limit_1(self):
         self.assertAlmostEqual(Decimal(1.045), profitability)
 
     def test_min_profitability_limit_2(self):
-        self.strategy: ArbitrageStrategy = ArbitrageStrategy(
+        self.strategy: ArbitrageStrategy = ArbitrageStrategy()
+        self.strategy.init_params(
             [self.market_pair],
             min_profitability=Decimal("0.02"),
             logging_options=self.logging_options,
diff --git a/test/hummingbot/strategy/arbitrage/test_arbitrage_start.py b/test/hummingbot/strategy/arbitrage/test_arbitrage_start.py
new file mode 100644
index 00000000000..6f5f2f8e904
--- /dev/null
+++ b/test/hummingbot/strategy/arbitrage/test_arbitrage_start.py
@@ -0,0 +1,48 @@
+from decimal import Decimal
+import unittest.mock
+import hummingbot.strategy.arbitrage.start as arbitrage_start
+from hummingbot.connector.connector_base import ConnectorBase
+from hummingbot.strategy.arbitrage.arbitrage_config_map import arbitrage_config_map
+from hummingbot.strategy.arbitrage.arbitrage import ArbitrageStrategy
+from test.hummingbot.strategy import assign_config_default
+
+
+class ArbitrageStartTest(unittest.TestCase):
+
+    def setUp(self) -> None:
+        super().setUp()
+        self.strategy: ArbitrageStrategy = None
+        self.markets = {"binance": ConnectorBase(), "balancer": ConnectorBase()}
+        self.assets = set()
+        self.notifications = []
+        self.log_errors = []
+        assign_config_default(arbitrage_config_map)
+        arbitrage_config_map.get("primary_market").value = "binance"
+        arbitrage_config_map.get("secondary_market").value = "balancer"
+        arbitrage_config_map.get("primary_market_trading_pair").value = "ETH-USDT"
+        arbitrage_config_map.get("secondary_market_trading_pair").value = "ETH-USDT"
+        arbitrage_config_map.get("min_profitability").value = Decimal("10")
+        arbitrage_config_map.get("use_oracle_conversion_rate").value = False
+
+    def _initialize_market_assets(self, market, trading_pairs):
+        return [("ETH", "USDT")]
+
+    def _initialize_wallet(self, token_trading_pairs):
+        pass
+
+    def _initialize_markets(self, market_names):
+        pass
+
+    def _notify(self, message):
+        self.notifications.append(message)
+
+    def logger(self):
+        return self
+
+    def error(self, message, exc_info):
+        self.log_errors.append(message)
+
+    def test_strategy_creation(self):
+        arbitrage_start.start(self)
+        self.assertEqual(self.strategy.min_profitability, Decimal("10") / Decimal("100"))
+        self.assertEqual(self.strategy.use_oracle_conversion_rate, False)
diff --git a/test/hummingbot/strategy/avellaneda_market_making/test_avellaneda_market_making.py b/test/hummingbot/strategy/avellaneda_market_making/test_avellaneda_market_making.py
index bf9fb7a9dd4..521c897d61b 100644
--- a/test/hummingbot/strategy/avellaneda_market_making/test_avellaneda_market_making.py
+++ b/test/hummingbot/strategy/avellaneda_market_making/test_avellaneda_market_making.py
@@ -99,7 +99,8 @@ def setUp(self):
             )
         )
 
-        self.strategy: AvellanedaMarketMakingStrategy = AvellanedaMarketMakingStrategy(
+        self.strategy: AvellanedaMarketMakingStrategy = AvellanedaMarketMakingStrategy()
+        self.strategy.init_params(
             market_info=self.market_info,
             order_amount=self.order_amount,
             min_spread=self.min_spread,
@@ -646,7 +647,8 @@ def test_create_proposal_based_on_order_override(self):
 
     def test_get_logspaced_level_spreads(self):
         # Re-initialize strategy with order_level configurations
-        self.strategy = AvellanedaMarketMakingStrategy(
+        self.strategy = AvellanedaMarketMakingStrategy()
+        self.strategy.init_params(
             market_info=self.market_info,
             order_amount=self.order_amount,
             order_levels=2,
@@ -1248,7 +1250,8 @@ def test_existing_hanging_orders_are_included_in_budget_constraint(self):
         self.market.set_balance("HBOT", 50000)
 
         # Create a new strategy, with hanging orders enabled
-        self.strategy = AvellanedaMarketMakingStrategy(
+        self.strategy = AvellanedaMarketMakingStrategy()
+        self.strategy.init_params(
             market_info=self.market_info,
             order_amount=self.order_amount,
             min_spread=self.min_spread,
@@ -1310,7 +1313,8 @@ def test_not_filled_order_changed_to_hanging_order_after_refresh_time(self):
         self.market.set_balance("HBOT", 50000)
 
         # Create a new strategy, with hanging orders enabled
-        self.strategy = AvellanedaMarketMakingStrategy(
+        self.strategy = AvellanedaMarketMakingStrategy()
+        self.strategy.init_params(
             market_info=self.market_info,
             order_amount=self.order_amount,
             min_spread=self.min_spread,
diff --git a/test/hummingbot/strategy/avellaneda_market_making/test_avellaneda_market_making_start.py b/test/hummingbot/strategy/avellaneda_market_making/test_avellaneda_market_making_start.py
new file mode 100644
index 00000000000..557d5bf09db
--- /dev/null
+++ b/test/hummingbot/strategy/avellaneda_market_making/test_avellaneda_market_making_start.py
@@ -0,0 +1,101 @@
+from decimal import Decimal
+import unittest.mock
+import hummingbot.strategy.avellaneda_market_making.start as strategy_start
+from hummingbot.connector.exchange_base import ExchangeBase
+from hummingbot.strategy.avellaneda_market_making.avellaneda_market_making_config_map import (
+    avellaneda_market_making_config_map as strategy_cmap
+)
+from hummingbot.strategy.hanging_orders_tracker import HangingOrdersAggregationType
+from test.hummingbot.strategy import assign_config_default
+
+
+class AvellanedaStartTest(unittest.TestCase):
+
+    def setUp(self) -> None:
+        super().setUp()
+        self.strategy = None
+        self.markets = {"binance": ExchangeBase()}
+        self.assets = set()
+        self.notifications = []
+        self.log_errors = []
+        assign_config_default(strategy_cmap)
+        strategy_cmap.get("exchange").value = "binance"
+        strategy_cmap.get("market").value = "balancer"
+        strategy_cmap.get("order_amount").value = Decimal("1")
+        strategy_cmap.get("order_refresh_time").value = 60.
+        strategy_cmap.get("hanging_orders_enabled").value = True
+        strategy_cmap.get("hanging_orders_cancel_pct").value = Decimal("1")
+        strategy_cmap.get("hanging_orders_aggregation_type").value = "VOLUME_WEIGHTED"
+        strategy_cmap.get("parameters_based_on_spread").value = True
+        strategy_cmap.get("min_spread").value = Decimal("2")
+        strategy_cmap.get("max_spread").value = Decimal("3")
+        strategy_cmap.get("vol_to_spread_multiplier").value = Decimal("1.1")
+        strategy_cmap.get("volatility_sensibility").value = Decimal("2.2")
+        strategy_cmap.get("inventory_risk_aversion").value = Decimal("0.1")
+        strategy_cmap.get("risk_factor").value = Decimal("1.11")
+        strategy_cmap.get("order_book_depth_factor").value = Decimal("2.22")
+        strategy_cmap.get("order_amount_shape_factor").value = Decimal("3.33")
+
+        self.raise_exception_for_market_initialization = False
+
+    def _initialize_market_assets(self, market, trading_pairs):
+        return [("ETH", "USDT")]
+
+    def _initialize_wallet(self, token_trading_pairs):
+        pass
+
+    def _initialize_markets(self, market_names):
+        if self.raise_exception_for_market_initialization:
+            raise Exception("Exception for testing")
+
+    def _notify(self, message):
+        self.notifications.append(message)
+
+    def logger(self):
+        return self
+
+    def error(self, message, exc_info):
+        self.log_errors.append(message)
+
+    @unittest.mock.patch('hummingbot.strategy.avellaneda_market_making.start.HummingbotApplication')
+    def test_hanging_orders_strategy_creation(self, mock_fname):
+        mock_fname.main_application().strategy_file_name = "test.csv"
+        strategy_start.start(self)
+        self.assertEqual(self.strategy.order_amount, Decimal("1"))
+        self.assertEqual(self.strategy.order_refresh_time, 60.)
+        self.assertEqual(self.strategy.hanging_orders_tracker.aggregation_method,
+                         HangingOrdersAggregationType.VOLUME_WEIGHTED)
+        self.assertEqual(self.strategy.hanging_orders_tracker._hanging_orders_cancel_pct,
+                         Decimal("0.01"))
+        strategy_cmap.get("hanging_orders_enabled").value = False
+        strategy_start.start(self)
+        self.assertEqual(self.strategy.hanging_orders_tracker.aggregation_method,
+                         HangingOrdersAggregationType.NO_AGGREGATION)
+
+    @unittest.mock.patch('hummingbot.strategy.avellaneda_market_making.start.HummingbotApplication')
+    def test_parameters_based_on_spread_strategy_creation(self, mock_hbot):
+        mock_hbot.main_application().strategy_file_name = "test.csv"
+        strategy_start.start(self)
+        self.assertEqual(self.strategy.min_spread, Decimal("0.02"))
+        self.assertEqual(self.strategy.max_spread, Decimal("0.03"))
+        self.assertEqual(self.strategy.vol_to_spread_multiplier, Decimal("1.1"))
+        self.assertEqual(self.strategy.volatility_sensibility, Decimal("0.022"))
+        self.assertEqual(self.strategy.inventory_risk_aversion, Decimal("0.1"))
+        self.assertTrue(all(c is None for c in (self.strategy.gamma, self.strategy.kappa, self.strategy.eta)))
+        strategy_cmap.get("parameters_based_on_spread").value = False
+        strategy_start.start(self)
+        self.assertTrue(all(c is None for c in (self.strategy.min_spread, self.strategy.max_spread,
+                                                self.strategy.vol_to_spread_multiplier,
+                                                self.strategy.inventory_risk_aversion,
+                                                self.strategy.volatility_sensibility)))
+        self.assertEqual(self.strategy.gamma, Decimal("1.11"))
+        self.assertEqual(self.strategy.kappa, Decimal("2.22"))
+        self.assertEqual(self.strategy.eta, Decimal("3.33"))
+
+    def test_strategy_creation_when_something_fails(self):
+        self.raise_exception_for_market_initialization = True
+        strategy_start.start(self)
+        self.assertEqual(len(self.notifications), 1)
+        self.assertEqual(self.notifications[0], "Exception for testing")
+        self.assertEqual(len(self.log_errors), 1)
+        self.assertEqual(self.log_errors[0], "Unknown error during initialization.")
diff --git a/test/hummingbot/strategy/celo_arb/test_celo_arb.py b/test/hummingbot/strategy/celo_arb/test_celo_arb.py
index ff89e10da21..9db6947d202 100644
--- a/test/hummingbot/strategy/celo_arb/test_celo_arb.py
+++ b/test/hummingbot/strategy/celo_arb/test_celo_arb.py
@@ -78,7 +78,8 @@ def setUp(self):
         self.market_info = MarketTradingPairTuple(self.market, self.trading_pair,
                                                   self.base_asset, self.quote_asset)
         self.logging_options: int = CeloArbStrategy.OPTION_LOG_ALL
-        self.strategy = CeloArbStrategy(
+        self.strategy = CeloArbStrategy()
+        self.strategy.init_params(
             self.market_info,
             min_profitability=Decimal("0.01"),
             order_amount=Decimal("1"),
diff --git a/test/hummingbot/strategy/celo_arb/test_celo_arb_start.py b/test/hummingbot/strategy/celo_arb/test_celo_arb_start.py
new file mode 100644
index 00000000000..a826d2476e0
--- /dev/null
+++ b/test/hummingbot/strategy/celo_arb/test_celo_arb_start.py
@@ -0,0 +1,47 @@
+from decimal import Decimal
+import unittest.mock
+import hummingbot.strategy.celo_arb.start as strategy_start
+from hummingbot.connector.exchange_base import ExchangeBase
+from hummingbot.strategy.celo_arb.celo_arb_config_map import celo_arb_config_map as strategy_cmap
+from test.hummingbot.strategy import assign_config_default
+
+
+class CeloArbStartTest(unittest.TestCase):
+
+    def setUp(self) -> None:
+        super().setUp()
+        self.strategy = None
+        self.markets = {"binance": ExchangeBase()}
+        self.assets = set()
+        self.notifications = []
+        self.log_errors = []
+        assign_config_default(strategy_cmap)
+        strategy_cmap.get("secondary_exchange").value = "binance"
+        strategy_cmap.get("secondary_market").value = "CELO-USDT"
+        strategy_cmap.get("order_amount").value = Decimal("1")
+        strategy_cmap.get("min_profitability").value = Decimal("2")
+        strategy_cmap.get("celo_slippage_buffer").value = Decimal("3")
+
+    def _initialize_market_assets(self, market, trading_pairs):
+        return [("ETH", "USDT")]
+
+    def _initialize_wallet(self, token_trading_pairs):
+        pass
+
+    def _initialize_markets(self, market_names):
+        pass
+
+    def _notify(self, message):
+        self.notifications.append(message)
+
+    def logger(self):
+        return self
+
+    def error(self, message, exc_info):
+        self.log_errors.append(message)
+
+    def test_strategy_creation(self):
+        strategy_start.start(self)
+        self.assertEqual(self.strategy.order_amount, Decimal("1"))
+        self.assertEqual(self.strategy.min_profitability, Decimal("0.02"))
+        self.assertEqual(self.strategy.celo_slippage_buffer, Decimal("0.03"))
diff --git a/test/hummingbot/strategy/cross_exchange_market_making/test_cross_exchange_market_making.py b/test/hummingbot/strategy/cross_exchange_market_making/test_cross_exchange_market_making.py
index fa535f0402c..a968ddbef23 100644
--- a/test/hummingbot/strategy/cross_exchange_market_making/test_cross_exchange_market_making.py
+++ b/test/hummingbot/strategy/cross_exchange_market_making/test_cross_exchange_market_making.py
@@ -76,13 +76,15 @@ def setUp(self):
             CrossExchangeMarketMakingStrategy.OPTION_LOG_ALL
             & (~CrossExchangeMarketMakingStrategy.OPTION_LOG_NULL_ORDER_SIZE)
         )
-        self.strategy: CrossExchangeMarketMakingStrategy = CrossExchangeMarketMakingStrategy(
+        self.strategy: CrossExchangeMarketMakingStrategy = CrossExchangeMarketMakingStrategy()
+        self.strategy.init_params(
             [self.market_pair],
             order_size_portfolio_ratio_limit=Decimal("0.3"),
             min_profitability=Decimal(self.min_profitbality),
             logging_options=logging_options,
         )
-        self.strategy_with_top_depth_tolerance: CrossExchangeMarketMakingStrategy = CrossExchangeMarketMakingStrategy(
+        self.strategy_with_top_depth_tolerance: CrossExchangeMarketMakingStrategy = CrossExchangeMarketMakingStrategy()
+        self.strategy_with_top_depth_tolerance.init_params(
             [self.market_pair],
             order_size_portfolio_ratio_limit=Decimal("0.3"),
             min_profitability=Decimal(self.min_profitbality),
@@ -446,7 +448,8 @@ def test_with_conversion(self):
         self.maker_data: MockOrderBookLoader = MockOrderBookLoader("COINALPHA-QETH", "COINALPHA", "QETH")
         self.maker_data.set_balanced_order_book(1.05, 0.55, 1.55, 0.01, 10)
         self.maker_market.add_data(self.maker_data)
-        self.strategy: CrossExchangeMarketMakingStrategy = CrossExchangeMarketMakingStrategy(
+        self.strategy: CrossExchangeMarketMakingStrategy = CrossExchangeMarketMakingStrategy()
+        self.strategy.init_params(
             [self.market_pair], Decimal("0.01"),
             order_size_portfolio_ratio_limit=Decimal("0.3"),
             logging_options=self.logging_options,
@@ -493,7 +496,8 @@ def test_with_adjust_orders_enabled(self):
             MarketTradingPairTuple(self.maker_market, *self.maker_trading_pairs),
             MarketTradingPairTuple(self.taker_market, *self.taker_trading_pairs),
         )
-        self.strategy: CrossExchangeMarketMakingStrategy = CrossExchangeMarketMakingStrategy(
+        self.strategy: CrossExchangeMarketMakingStrategy = CrossExchangeMarketMakingStrategy()
+        self.strategy.init_params(
             [self.market_pair],
             order_size_portfolio_ratio_limit=Decimal("0.3"),
             min_profitability=Decimal("0.005"),
@@ -530,7 +534,8 @@ def test_with_adjust_orders_disabled(self):
             MarketTradingPairTuple(self.maker_market, *self.maker_trading_pairs),
             MarketTradingPairTuple(self.taker_market, *self.taker_trading_pairs),
         )
-        self.strategy: CrossExchangeMarketMakingStrategy = CrossExchangeMarketMakingStrategy(
+        self.strategy: CrossExchangeMarketMakingStrategy = CrossExchangeMarketMakingStrategy()
+        self.strategy.init_params(
             [self.market_pair],
             order_size_portfolio_ratio_limit=Decimal("0.3"),
             min_profitability=Decimal("0.005"),
@@ -574,7 +579,8 @@ def test_empty_maker_orderbook(self):
             MarketTradingPairTuple(self.maker_market, *self.maker_trading_pairs),
             MarketTradingPairTuple(self.taker_market, *self.taker_trading_pairs),
         )
-        self.strategy: CrossExchangeMarketMakingStrategy = CrossExchangeMarketMakingStrategy(
+        self.strategy: CrossExchangeMarketMakingStrategy = CrossExchangeMarketMakingStrategy()
+        self.strategy.init_params(
             [self.market_pair],
             order_amount=1,
             min_profitability=Decimal("0.005"),
diff --git a/test/hummingbot/strategy/cross_exchange_market_making/test_cross_exchange_market_making_start.py b/test/hummingbot/strategy/cross_exchange_market_making/test_cross_exchange_market_making_start.py
new file mode 100644
index 00000000000..125976874bd
--- /dev/null
+++ b/test/hummingbot/strategy/cross_exchange_market_making/test_cross_exchange_market_making_start.py
@@ -0,0 +1,52 @@
+from decimal import Decimal
+import unittest.mock
+import hummingbot.strategy.cross_exchange_market_making.start as strategy_start
+from hummingbot.connector.exchange_base import ExchangeBase
+from hummingbot.strategy.cross_exchange_market_making.cross_exchange_market_making_config_map import (
+    cross_exchange_market_making_config_map as strategy_cmap
+)
+from hummingbot.client.config.global_config_map import global_config_map
+from test.hummingbot.strategy import assign_config_default
+
+
+class XEMMStartTest(unittest.TestCase):
+
+    def setUp(self) -> None:
+        super().setUp()
+        self.strategy = None
+        self.markets = {"binance": ExchangeBase(), "kucoin": ExchangeBase()}
+        self.assets = set()
+        self.notifications = []
+        self.log_errors = []
+        assign_config_default(strategy_cmap)
+        strategy_cmap.get("maker_market").value = "binance"
+        strategy_cmap.get("taker_market").value = "kucoin"
+        strategy_cmap.get("maker_market_trading_pair").value = "ETH-USDT"
+        strategy_cmap.get("taker_market_trading_pair").value = "ETH-USDT"
+        strategy_cmap.get("order_amount").value = Decimal("1")
+        strategy_cmap.get("min_profitability").value = Decimal("2")
+        global_config_map.get("strategy_report_interval").value = 60.
+        strategy_cmap.get("use_oracle_conversion_rate").value = False
+
+    def _initialize_market_assets(self, market, trading_pairs):
+        return [("ETH", "USDT")]
+
+    def _initialize_wallet(self, token_trading_pairs):
+        pass
+
+    def _initialize_markets(self, market_names):
+        pass
+
+    def _notify(self, message):
+        self.notifications.append(message)
+
+    def logger(self):
+        return self
+
+    def error(self, message, exc_info):
+        self.log_errors.append(message)
+
+    def test_strategy_creation(self):
+        strategy_start.start(self)
+        self.assertEqual(self.strategy.order_amount, Decimal("1"))
+        self.assertEqual(self.strategy.min_profitability, Decimal("0.02"))
diff --git a/test/hummingbot/strategy/liquidity_mining/test_liquidity_mining.py b/test/hummingbot/strategy/liquidity_mining/test_liquidity_mining.py
index 40bccdcec4c..64eacc4fb42 100644
--- a/test/hummingbot/strategy/liquidity_mining/test_liquidity_mining.py
+++ b/test/hummingbot/strategy/liquidity_mining/test_liquidity_mining.py
@@ -77,7 +77,8 @@ def setUp(self) -> None:
         self.market.add_listener(MarketEvent.OrderFilled, self.order_fill_logger)
         self.market.add_listener(MarketEvent.OrderCancelled, self.cancel_order_logger)
 
-        self.default_strategy = LiquidityMiningStrategy(
+        self.default_strategy = LiquidityMiningStrategy()
+        self.default_strategy.init_params(
             exchange=self.market,
             market_infos=self.market_infos,
             token="ETH",
@@ -221,7 +222,8 @@ def test_budget_allocation(self, estimate_fee_mock):
         trading_pairs = list(map(lambda quote_asset: "ETH-" + quote_asset, ["USDT", "BUSD", "BTC"]))
         market, market_infos = self.create_market(trading_pairs, 100, {"USDT": usdt_balance, "BUSD": busd_balance, "ETH": eth_balance, "BTC": btc_balance})
 
-        strategy = LiquidityMiningStrategy(
+        strategy = LiquidityMiningStrategy()
+        strategy.init_params(
             exchange=market,
             market_infos=market_infos,
             token="ETH",
@@ -266,7 +268,8 @@ def test_inventory_skew(self, estimate_fee_mock):
         trading_pairs = list(map(lambda quote_asset: "ETH-" + quote_asset, ["USDT", "BUSD", "BTC"]))
         market, market_infos = self.create_market(trading_pairs, 100, {"USDT": usdt_balance, "BUSD": busd_balance, "ETH": eth_balance, "BTC": btc_balance})
 
-        skewed_base_strategy = LiquidityMiningStrategy(
+        skewed_base_strategy = LiquidityMiningStrategy()
+        skewed_base_strategy.init_params(
             exchange=market,
             market_infos=market_infos,
             token="ETH",
@@ -278,7 +281,8 @@ def test_inventory_skew(self, estimate_fee_mock):
             order_refresh_tolerance_pct=Decimal(0.1),  # tolerance of 10 % change
         )
 
-        unskewed_strategy = LiquidityMiningStrategy(
+        unskewed_strategy = LiquidityMiningStrategy()
+        unskewed_strategy.init_params(
             exchange=market,
             market_infos=market_infos,
             token="ETH",
@@ -323,7 +327,8 @@ def test_volatility(self, estimate_fee_mock, get_mid_price_mock):
         trading_pairs = list(map(lambda quote_asset: "ETH-" + quote_asset, ["USDT"]))
         market, market_infos = self.create_market(trading_pairs, 100, {"USDT": usdt_balance, "ETH": eth_balance})
 
-        strategy = LiquidityMiningStrategy(
+        strategy = LiquidityMiningStrategy()
+        strategy.init_params(
             exchange=market,
             market_infos=market_infos,
             token="ETH",
@@ -393,7 +398,8 @@ def test_strategy_sends_in_app_notifications(self, cli_class_mock, main_applicat
         hummingbot_application.notifiers.append(notifier_mock)
         main_application_function_mock.return_value = hummingbot_application
 
-        strategy = self.default_strategy = LiquidityMiningStrategy(
+        strategy = self.default_strategy = LiquidityMiningStrategy()
+        self.default_strategy.init_params(
             exchange=self.market,
             market_infos=self.market_infos,
             token="ETH",
@@ -404,7 +410,8 @@ def test_strategy_sends_in_app_notifications(self, cli_class_mock, main_applicat
             order_refresh_time=5,
             order_refresh_tolerance_pct=Decimal(0.1),  # tolerance of 10 % change
             max_order_age=3,
-            hb_app_notification=True)
+            hb_app_notification=True
+        )
 
         timestamp = self.start_timestamp + 10
         self.clock.add_iterator(strategy)
diff --git a/test/hummingbot/strategy/liquidity_mining/test_liquidity_mining_start.py b/test/hummingbot/strategy/liquidity_mining/test_liquidity_mining_start.py
new file mode 100644
index 00000000000..af794b2eb87
--- /dev/null
+++ b/test/hummingbot/strategy/liquidity_mining/test_liquidity_mining_start.py
@@ -0,0 +1,70 @@
+from decimal import Decimal
+import unittest.mock
+import hummingbot.strategy.liquidity_mining.start as strategy_start
+from hummingbot.connector.exchange_base import ExchangeBase
+from hummingbot.strategy.liquidity_mining.liquidity_mining_config_map import (
+    liquidity_mining_config_map as strategy_cmap
+)
+from test.hummingbot.strategy import assign_config_default
+
+
+class LiquidityMiningStartTest(unittest.TestCase):
+
+    def setUp(self) -> None:
+        super().setUp()
+        self.strategy = None
+        self.markets = {"binance": ExchangeBase()}
+        self.assets = set()
+        self.notifications = []
+        self.log_errors = []
+        assign_config_default(strategy_cmap)
+        strategy_cmap.get("exchange").value = "binance"
+        strategy_cmap.get("markets").value = "BTC-USDT,ETH-USDT"
+        strategy_cmap.get("token").value = "USDT"
+        strategy_cmap.get("order_amount").value = Decimal("1")
+        strategy_cmap.get("spread").value = Decimal("2")
+
+        strategy_cmap.get("inventory_skew_enabled").value = False
+        strategy_cmap.get("target_base_pct").value = Decimal("50")
+        strategy_cmap.get("order_refresh_time").value = 60.
+        strategy_cmap.get("order_refresh_tolerance_pct").value = Decimal("1.5")
+        strategy_cmap.get("inventory_range_multiplier").value = Decimal("2")
+        strategy_cmap.get("volatility_interval").value = 30
+        strategy_cmap.get("avg_volatility_period").value = 5
+        strategy_cmap.get("volatility_to_spread_multiplier").value = Decimal("1.1")
+        strategy_cmap.get("max_spread").value = Decimal("4")
+        strategy_cmap.get("max_order_age").value = 300.
+
+    def _initialize_market_assets(self, market, trading_pairs):
+        return [("ETH", "USDT")]
+
+    def _initialize_wallet(self, token_trading_pairs):
+        pass
+
+    def _initialize_markets(self, market_names):
+        pass
+
+    def _notify(self, message):
+        self.notifications.append(message)
+
+    def logger(self):
+        return self
+
+    def error(self, message, exc_info):
+        self.log_errors.append(message)
+
+    def test_strategy_creation(self):
+        strategy_start.start(self)
+        self.assertEqual(self.strategy._order_amount, Decimal("1"))
+        self.assertEqual(self.strategy._spread, Decimal("0.02"))
+
+        self.assertEqual(self.strategy._inventory_skew_enabled, False)
+        self.assertEqual(self.strategy._target_base_pct, Decimal("0.5"))
+        self.assertEqual(self.strategy._order_refresh_time, 60.)
+        self.assertEqual(self.strategy._order_refresh_tolerance_pct, Decimal("0.015"))
+        self.assertEqual(self.strategy._inventory_range_multiplier, Decimal("2"))
+        self.assertEqual(self.strategy._volatility_interval, 30)
+        self.assertEqual(self.strategy._avg_volatility_period, 5)
+        self.assertEqual(self.strategy._volatility_to_spread_multiplier, Decimal("1.1"))
+        self.assertEqual(self.strategy._max_spread, Decimal("0.04"))
+        self.assertEqual(self.strategy._max_order_age, 300.)
diff --git a/test/hummingbot/strategy/perpetual_market_making/__init__.py b/test/hummingbot/strategy/perpetual_market_making/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/test/hummingbot/strategy/perpetual_market_making/test_perpetual_market_making_start.py b/test/hummingbot/strategy/perpetual_market_making/test_perpetual_market_making_start.py
new file mode 100644
index 00000000000..ef783c47162
--- /dev/null
+++ b/test/hummingbot/strategy/perpetual_market_making/test_perpetual_market_making_start.py
@@ -0,0 +1,53 @@
+from decimal import Decimal
+import unittest.mock
+import hummingbot.strategy.perpetual_market_making.start as strategy_start
+from hummingbot.connector.exchange_base import ExchangeBase
+from hummingbot.strategy.perpetual_market_making.perpetual_market_making_config_map import (
+    perpetual_market_making_config_map as c_map
+)
+from test.hummingbot.strategy import assign_config_default
+
+
+class PerpetualMarketMakingStartTest(unittest.TestCase):
+
+    def setUp(self) -> None:
+        super().setUp()
+        self.strategy = None
+        self.markets = {"binance": ExchangeBase()}
+        self.assets = set()
+        self.notifications = []
+        self.log_errors = []
+        assign_config_default(c_map)
+        c_map.get("derivative").value = "binance"
+        c_map.get("market").value = "ETH-USDT"
+
+        c_map.get("leverage").value = Decimal("5")
+        c_map.get("order_amount").value = Decimal("1")
+        c_map.get("order_refresh_time").value = 60.
+        c_map.get("bid_spread").value = Decimal("1")
+        c_map.get("ask_spread").value = Decimal("2")
+
+    def _initialize_market_assets(self, market, trading_pairs):
+        return [("ETH", "USDT")]
+
+    def _initialize_wallet(self, token_trading_pairs):
+        pass
+
+    def _initialize_markets(self, market_names):
+        pass
+
+    def _notify(self, message):
+        self.notifications.append(message)
+
+    def logger(self):
+        return self
+
+    def error(self, message, exc_info):
+        self.log_errors.append(message)
+
+    def test_strategy_creation(self):
+        strategy_start.start(self)
+        self.assertEqual(self.strategy.order_amount, Decimal("1"))
+        self.assertEqual(self.strategy.order_refresh_time, 60.)
+        self.assertEqual(self.strategy.bid_spread, Decimal("0.01"))
+        self.assertEqual(self.strategy.ask_spread, Decimal("0.02"))
diff --git a/test/hummingbot/strategy/pure_market_making/test_pmm.py b/test/hummingbot/strategy/pure_market_making/test_pmm.py
index aaadb2fea46..87d4b8ee194 100644
--- a/test/hummingbot/strategy/pure_market_making/test_pmm.py
+++ b/test/hummingbot/strategy/pure_market_making/test_pmm.py
@@ -92,7 +92,8 @@ def setUp(self):
         self.market.add_listener(MarketEvent.OrderFilled, self.order_fill_logger)
         self.market.add_listener(MarketEvent.OrderCancelled, self.cancel_order_logger)
 
-        self.one_level_strategy = PureMarketMakingStrategy(
+        self.one_level_strategy = PureMarketMakingStrategy()
+        self.one_level_strategy.init_params(
             self.market_info,
             bid_spread=Decimal("0.01"),
             ask_spread=Decimal("0.01"),
@@ -103,7 +104,8 @@ def setUp(self):
             minimum_spread=-1
         )
 
-        self.multi_levels_strategy = PureMarketMakingStrategy(
+        self.multi_levels_strategy = PureMarketMakingStrategy()
+        self.multi_levels_strategy.init_params(
             self.market_info,
             bid_spread=Decimal("0.01"),
             ask_spread=Decimal("0.01"),
@@ -117,7 +119,8 @@ def setUp(self):
             minimum_spread=-1,
         )
 
-        self.order_override_strategy = PureMarketMakingStrategy(
+        self.order_override_strategy = PureMarketMakingStrategy()
+        self.order_override_strategy.init_params(
             self.market_info,
             bid_spread=Decimal("0.01"),
             ask_spread=Decimal("0.01"),
@@ -194,7 +197,8 @@ def test_basic_one_level(self):
         self.assertEqual(1, len(strategy.active_sells))
 
     def test_basic_one_level_price_type_own_last_trade(self):
-        strategy = PureMarketMakingStrategy(
+        strategy = PureMarketMakingStrategy()
+        strategy.init_params(
             self.market_info,
             bid_spread=Decimal("0.01"),
             ask_spread=Decimal("0.01"),
@@ -235,7 +239,8 @@ def test_basic_one_level_price_type(self):
         strategies = []
 
         for price_type in ["last_price", "best_bid", "best_ask"]:
-            strategy = PureMarketMakingStrategy(
+            strategy = PureMarketMakingStrategy()
+            strategy.init_params(
                 self.market_info,
                 bid_spread=Decimal("0.01"),
                 ask_spread=Decimal("0.01"),
@@ -363,7 +368,8 @@ def test_order_quantity_available_balance(self):
         When balance is below the specified order amount, checks if orders created
         use the remaining available balance for the order size.
         """
-        strategy = PureMarketMakingStrategy(
+        strategy = PureMarketMakingStrategy()
+        strategy.init_params(
             self.market_info,
             bid_spread=Decimal("0.01"),
             ask_spread=Decimal("0.01"),
@@ -739,7 +745,8 @@ def test_inventory_skew(self):
         self.assertEqual(Decimal("1.34865"), first_ask_order.quantity)
 
     def test_inventory_skew_multiple_orders(self):
-        strategy = PureMarketMakingStrategy(
+        strategy = PureMarketMakingStrategy()
+        strategy.init_params(
             self.market_info,
             bid_spread=Decimal("0.01"),
             ask_spread=Decimal("0.01"),
@@ -808,7 +815,8 @@ def test_inventory_skew_multiple_orders(self):
         self.assertEqual(Decimal("4.04595"), last_ask_order.quantity)
 
     def test_inventory_skew_multiple_orders_status(self):
-        strategy = PureMarketMakingStrategy(
+        strategy = PureMarketMakingStrategy()
+        strategy.init_params(
             self.market_info,
             bid_spread=Decimal("0.01"),
             ask_spread=Decimal("0.01"),
@@ -1044,7 +1052,8 @@ def setUp(self):
             self.maker_trading_pairs[1], self.maker_trading_pairs[2]
         )
 
-        self.strategy: PureMarketMakingStrategy = PureMarketMakingStrategy(
+        self.strategy: PureMarketMakingStrategy = PureMarketMakingStrategy()
+        self.strategy.init_params(
             self.market_info,
             bid_spread=Decimal(.05),
             ask_spread=Decimal(.05),
diff --git a/test/hummingbot/strategy/pure_market_making/test_pmm_ping_pong.py b/test/hummingbot/strategy/pure_market_making/test_pmm_ping_pong.py
index 17bca0ef0f3..1a2c8820511 100644
--- a/test/hummingbot/strategy/pure_market_making/test_pmm_ping_pong.py
+++ b/test/hummingbot/strategy/pure_market_making/test_pmm_ping_pong.py
@@ -73,7 +73,8 @@ def setUp(self):
         self.market.add_listener(MarketEvent.OrderCancelled, self.cancel_order_logger)
 
     def test_strategy_ping_pong_on_ask_fill(self):
-        self.strategy = PureMarketMakingStrategy(
+        self.strategy = PureMarketMakingStrategy()
+        self.strategy.init_params(
             self.market_info,
             bid_spread=Decimal("0.01"),
             ask_spread=Decimal("0.01"),
@@ -115,7 +116,8 @@ def test_strategy_ping_pong_on_ask_fill(self):
         self.assertEqual(1, len(self.strategy.active_sells))
 
     def test_strategy_ping_pong_on_bid_fill(self):
-        self.strategy = PureMarketMakingStrategy(
+        self.strategy = PureMarketMakingStrategy()
+        self.strategy.init_params(
             self.market_info,
             bid_spread=Decimal("0.01"),
             ask_spread=Decimal("0.01"),
@@ -158,7 +160,8 @@ def test_strategy_ping_pong_on_bid_fill(self):
         self.assertEqual(1, len(self.strategy.active_sells))
 
     def test_multiple_orders_ping_pong(self):
-        self.strategy = PureMarketMakingStrategy(
+        self.strategy = PureMarketMakingStrategy()
+        self.strategy.init_params(
             self.market_info,
             bid_spread=Decimal("0.01"),
             ask_spread=Decimal("0.01"),
diff --git a/test/hummingbot/strategy/pure_market_making/test_pmm_refresh_tolerance.py b/test/hummingbot/strategy/pure_market_making/test_pmm_refresh_tolerance.py
index 4e95d88d541..7177d0cd576 100644
--- a/test/hummingbot/strategy/pure_market_making/test_pmm_refresh_tolerance.py
+++ b/test/hummingbot/strategy/pure_market_making/test_pmm_refresh_tolerance.py
@@ -73,7 +73,8 @@ def setUp(self):
         self.market.add_listener(MarketEvent.OrderFilled, self.maker_order_fill_logger)
         self.market.add_listener(MarketEvent.OrderCancelled, self.cancel_order_logger)
 
-        self.one_level_strategy: PureMarketMakingStrategy = PureMarketMakingStrategy(
+        self.one_level_strategy: PureMarketMakingStrategy = PureMarketMakingStrategy()
+        self.one_level_strategy.init_params(
             self.market_info,
             bid_spread=Decimal("0.01"),
             ask_spread=Decimal("0.01"),
@@ -84,7 +85,8 @@ def setUp(self):
             hanging_orders_cancel_pct=0.05,
             order_refresh_tolerance_pct=0
         )
-        self.multi_levels_strategy: PureMarketMakingStrategy = PureMarketMakingStrategy(
+        self.multi_levels_strategy: PureMarketMakingStrategy = PureMarketMakingStrategy()
+        self.multi_levels_strategy.init_params(
             self.market_info,
             bid_spread=Decimal("0.01"),
             ask_spread=Decimal("0.01"),
@@ -95,7 +97,8 @@ def setUp(self):
             filled_order_delay=8,
             order_refresh_tolerance_pct=0
         )
-        self.hanging_order_multiple_strategy = PureMarketMakingStrategy(
+        self.hanging_order_multiple_strategy = PureMarketMakingStrategy()
+        self.hanging_order_multiple_strategy.init_params(
             self.market_info,
             bid_spread=Decimal("0.01"),
             ask_spread=Decimal("0.01"),
diff --git a/test/hummingbot/strategy/pure_market_making/test_pmm_take_if_cross.py b/test/hummingbot/strategy/pure_market_making/test_pmm_take_if_cross.py
index 7e13210db25..7a868ad64e2 100644
--- a/test/hummingbot/strategy/pure_market_making/test_pmm_take_if_cross.py
+++ b/test/hummingbot/strategy/pure_market_making/test_pmm_take_if_cross.py
@@ -92,7 +92,8 @@ def setUp(self):
         self.ext_market.add_data(self.ext_data)
         self.order_book_asset_del = OrderBookAssetPriceDelegate(self.ext_market, self.trading_pair)
 
-        self.one_level_strategy = PureMarketMakingStrategy(
+        self.one_level_strategy = PureMarketMakingStrategy()
+        self.one_level_strategy.init_params(
             self.market_info,
             bid_spread=Decimal("0.01"),
             ask_spread=Decimal("0.01"),
diff --git a/test/hummingbot/strategy/pure_market_making/test_pure_market_making_start.py b/test/hummingbot/strategy/pure_market_making/test_pure_market_making_start.py
new file mode 100644
index 00000000000..182bde9a69b
--- /dev/null
+++ b/test/hummingbot/strategy/pure_market_making/test_pure_market_making_start.py
@@ -0,0 +1,98 @@
+from decimal import Decimal
+import unittest.mock
+import hummingbot.strategy.pure_market_making.start as strategy_start
+from hummingbot.connector.exchange_base import ExchangeBase
+from hummingbot.strategy.pure_market_making.pure_market_making_config_map import (
+    pure_market_making_config_map as c_map
+)
+from hummingbot.core.event.events import PriceType
+from test.hummingbot.strategy import assign_config_default
+
+
+class PureMarketMakingStartTest(unittest.TestCase):
+
+    def setUp(self) -> None:
+        super().setUp()
+        self.strategy = None
+        self.markets = {"binance": ExchangeBase()}
+        self.assets = set()
+        self.notifications = []
+        self.log_errors = []
+        assign_config_default(c_map)
+        c_map.get("exchange").value = "binance"
+        c_map.get("market").value = "ETH-USDT"
+
+        c_map.get("order_amount").value = Decimal("1")
+        c_map.get("order_refresh_time").value = 60.
+        c_map.get("max_order_age").value = 300.
+        c_map.get("bid_spread").value = Decimal("1")
+        c_map.get("ask_spread").value = Decimal("2")
+        c_map.get("minimum_spread").value = Decimal("0.5")
+        c_map.get("price_ceiling").value = Decimal("100")
+        c_map.get("price_floor").value = Decimal("50")
+        c_map.get("ping_pong_enabled").value = False
+        c_map.get("order_levels").value = 2
+        c_map.get("order_level_amount").value = Decimal("0.5")
+        c_map.get("order_level_spread").value = Decimal("0.2")
+        c_map.get("inventory_skew_enabled").value = True
+        c_map.get("inventory_target_base_pct").value = Decimal("50")
+        c_map.get("inventory_range_multiplier").value = Decimal("2")
+        c_map.get("filled_order_delay").value = 45.
+        c_map.get("hanging_orders_enabled").value = True
+        c_map.get("hanging_orders_cancel_pct").value = Decimal("6")
+        c_map.get("order_optimization_enabled").value = False
+        c_map.get("ask_order_optimization_depth").value = Decimal("0.01")
+        c_map.get("bid_order_optimization_depth").value = Decimal("0.02")
+        c_map.get("add_transaction_costs").value = False
+        c_map.get("price_source").value = "external_market"
+        c_map.get("price_type").value = "best_bid"
+        c_map.get("price_source_exchange").value = "ascend_ex"
+        c_map.get("price_source_market").value = "ETH-DAI"
+        c_map.get("price_source_custom_api").value = "localhost.test"
+        c_map.get("order_refresh_tolerance_pct").value = Decimal("2")
+        c_map.get("order_override").value = None
+
+    def _initialize_market_assets(self, market, trading_pairs):
+        return [("ETH", "USDT")]
+
+    def _initialize_wallet(self, token_trading_pairs):
+        pass
+
+    def _initialize_markets(self, market_names):
+        pass
+
+    def _notify(self, message):
+        self.notifications.append(message)
+
+    def logger(self):
+        return self
+
+    def error(self, message, exc_info):
+        self.log_errors.append(message)
+
+    def test_strategy_creation(self):
+        strategy_start.start(self)
+        self.assertEqual(self.strategy.order_amount, Decimal("1"))
+        self.assertEqual(self.strategy.order_refresh_time, 60.)
+        self.assertEqual(self.strategy.max_order_age, 300.)
+        self.assertEqual(self.strategy.bid_spread, Decimal("0.01"))
+        self.assertEqual(self.strategy.ask_spread, Decimal("0.02"))
+        self.assertEqual(self.strategy.minimum_spread, Decimal("0.005"))
+        self.assertEqual(self.strategy.price_ceiling, Decimal("100"))
+        self.assertEqual(self.strategy.price_floor, Decimal("50"))
+        self.assertEqual(self.strategy.ping_pong_enabled, False)
+        self.assertEqual(self.strategy.order_levels, 2)
+        self.assertEqual(self.strategy.order_level_amount, Decimal("0.5"))
+        self.assertEqual(self.strategy.order_level_spread, Decimal("0.002"))
+        self.assertEqual(self.strategy.inventory_skew_enabled, True)
+        self.assertEqual(self.strategy.inventory_target_base_pct, Decimal("0.5"))
+        self.assertEqual(self.strategy.inventory_range_multiplier, Decimal("2"))
+        self.assertEqual(self.strategy.filled_order_delay, 45.)
+        self.assertEqual(self.strategy.hanging_orders_enabled, True)
+        self.assertEqual(self.strategy.hanging_orders_cancel_pct, Decimal("0.06"))
+        self.assertEqual(self.strategy.order_optimization_enabled, False)
+        self.assertEqual(self.strategy.ask_order_optimization_depth, Decimal("0.01"))
+        self.assertEqual(self.strategy.bid_order_optimization_depth, Decimal("0.02"))
+        self.assertEqual(self.strategy.add_transaction_costs_to_orders, False)
+        self.assertEqual(self.strategy.price_type, PriceType.BestBid)
+        self.assertEqual(self.strategy.order_refresh_tolerance_pct, Decimal("0.02"))
diff --git a/test/hummingbot/strategy/spot_perpetual_arbitrage/test_spot_perpetual_arbitrage.py b/test/hummingbot/strategy/spot_perpetual_arbitrage/test_spot_perpetual_arbitrage.py
index f8ec046acbd..32fcba723fb 100644
--- a/test/hummingbot/strategy/spot_perpetual_arbitrage/test_spot_perpetual_arbitrage.py
+++ b/test/hummingbot/strategy/spot_perpetual_arbitrage/test_spot_perpetual_arbitrage.py
@@ -80,9 +80,10 @@ def setUp(self):
         self.perp_connector.add_listener(MarketEvent.OrderFilled, self.order_fill_logger)
         self.perp_connector.add_listener(MarketEvent.OrderCancelled, self.cancel_order_logger)
 
-        self.strategy = SpotPerpetualArbitrageStrategy(
-            self.spot_market_info,
-            self.perp_market_info,
+        self.strategy = SpotPerpetualArbitrageStrategy()
+        self.strategy.init_params(
+            spot_market_info=self.spot_market_info,
+            derivative_market_info=self.perp_market_info,
             order_amount=Decimal("1"),
             derivative_leverage=5,
             min_divergence=Decimal("0.05"),
diff --git a/test/hummingbot/strategy/spot_perpetual_arbitrage/test_spot_perpetual_arbitrage_start.py b/test/hummingbot/strategy/spot_perpetual_arbitrage/test_spot_perpetual_arbitrage_start.py
new file mode 100644
index 00000000000..a9d82973f24
--- /dev/null
+++ b/test/hummingbot/strategy/spot_perpetual_arbitrage/test_spot_perpetual_arbitrage_start.py
@@ -0,0 +1,54 @@
+from decimal import Decimal
+import unittest.mock
+import hummingbot.strategy.spot_perpetual_arbitrage.start as strategy_start
+from hummingbot.connector.exchange_base import ExchangeBase
+from hummingbot.strategy.spot_perpetual_arbitrage.spot_perpetual_arbitrage_config_map import (
+    spot_perpetual_arbitrage_config_map as strategy_cmap
+)
+from test.hummingbot.strategy import assign_config_default
+
+
+class SpotPerpetualArbitrageStartTest(unittest.TestCase):
+
+    def setUp(self) -> None:
+        super().setUp()
+        self.strategy = None
+        self.markets = {"binance": ExchangeBase(), "kucoin": ExchangeBase()}
+        self.assets = set()
+        self.notifications = []
+        self.log_errors = []
+        assign_config_default(strategy_cmap)
+        strategy_cmap.get("spot_connector").value = "binance"
+        strategy_cmap.get("spot_market").value = "BTC-USDT"
+        strategy_cmap.get("derivative_connector").value = "kucoin"
+        strategy_cmap.get("derivative_market").value = "BTC-USDT"
+
+        strategy_cmap.get("order_amount").value = Decimal("1")
+        strategy_cmap.get("derivative_leverage").value = Decimal("2")
+        strategy_cmap.get("min_divergence").value = Decimal("10")
+        strategy_cmap.get("min_convergence").value = Decimal("1")
+
+    def _initialize_market_assets(self, market, trading_pairs):
+        return [("ETH", "USDT")]
+
+    def _initialize_wallet(self, token_trading_pairs):
+        pass
+
+    def _initialize_markets(self, market_names):
+        pass
+
+    def _notify(self, message):
+        self.notifications.append(message)
+
+    def logger(self):
+        return self
+
+    def error(self, message, exc_info):
+        self.log_errors.append(message)
+
+    def test_strategy_creation(self):
+        strategy_start.start(self)
+        self.assertEqual(self.strategy._order_amount, Decimal("1"))
+        self.assertEqual(self.strategy._derivative_leverage, Decimal("2"))
+        self.assertEqual(self.strategy._min_divergence, Decimal("0.1"))
+        self.assertEqual(self.strategy._min_convergence, Decimal("0.01"))
diff --git a/test/hummingbot/strategy/twap/test_twap.py b/test/hummingbot/strategy/twap/test_twap.py
index 8f3065bdd83..befce51c6e5 100644
--- a/test/hummingbot/strategy/twap/test_twap.py
+++ b/test/hummingbot/strategy/twap/test_twap.py
@@ -20,6 +20,7 @@
     ClockMode
 )
 from hummingbot.core.event.event_logger import EventLogger
+
 from hummingbot.core.event.events import (
     MarketEvent,
     TradeType,
@@ -399,6 +400,11 @@ def test_status_after_first_order_filled(self):
         self.clock.backtest_til(order_time_2)
         ask_order2: LimitOrder = self.limit_sell_strategy.active_asks[0][1]
 
+        base_balance = self.market_info.base_balance
+        available_base_balance = self.market.get_available_balance(self.market_info.base_asset)
+        quote_balance = self.market_info.quote_balance
+        available_quote_balance = self.market.get_available_balance(self.market_info.quote_asset)
+
         buy_not_started_status = self.limit_buy_strategy.format_status()
         expected_buy_status = ("\n  Configuration:\n"
                                "    Total amount: 2.00 COINALPHA"
@@ -410,8 +416,12 @@ def test_status_after_first_order_filled(self):
                                "    0  BacktestMarket  COINALPHA-WETH            99.5           100.5        100\n\n"
                                "  Assets:\n"
                                "             Exchange      Asset  Total Balance  Available Balance\n"
-                               "    0  BacktestMarket  COINALPHA         498.33             496.66\n"
-                               "    1  BacktestMarket       WETH       50168.67           50168.67\n\n"
+                               "    0  BacktestMarket  COINALPHA         "
+                               f"{base_balance:.2f}             "
+                               f"{available_base_balance:.2f}\n"
+                               "    1  BacktestMarket       WETH       "
+                               f"{quote_balance:.2f}           "
+                               f"{available_quote_balance:.2f}\n\n"
                                "  No active maker orders.\n\n"
                                "  Average filled orders price: 0 WETH\n"
                                "  Pending amount: 2.00 COINALPHA")
@@ -427,8 +437,12 @@ def test_status_after_first_order_filled(self):
                                 "    0  BacktestMarket  COINALPHA-WETH            99.5           100.5        100\n\n"
                                 "  Assets:\n"
                                 "             Exchange      Asset  Total Balance  Available Balance\n"
-                                "    0  BacktestMarket  COINALPHA         498.33             496.66\n"
-                                "    1  BacktestMarket       WETH       50168.67           50168.67\n\n"
+                                "    0  BacktestMarket  COINALPHA         "
+                                f"{base_balance:.2f}             "
+                                f"{available_base_balance:.2f}\n"
+                                "    1  BacktestMarket       WETH       "
+                                f"{quote_balance:.2f}           "
+                                f"{available_quote_balance:.2f}\n\n"
                                 "  Active orders:\n"
                                 "      Order ID  Type  Price Spread  Amount  Age Hang\n"
                                 f"    0  ...{ask_order2.client_order_id[-4:]}  sell    101  0.00%    1.67  n/a  n/a\n\n"


Code review comments:
diff_hunk: @@ -6,44 +6,42 @@ channels:
 dependencies:
   - _libgcc_mutex=0.1=conda_forge
   - _openmp_mutex=4.5=0_gnu
-  - blas=1.0=openblas
-  - blosc=1.16.3=hd408876_0
-  - bzip2=1.0.8=h7b6447c_0
-  - ca-certificates=2020.1.1=0
-  - certifi=2019.11.28=py38_0
+  - blas=1.1
+  - blosc=1.21.0
+  - bzip2=1.0.8
+  - ca-certificates
+  - certifi
   - coverage=5.5
-  - cython=0.29.15=py38he6710b0_0
-  - hdf5=1.10.4=hb1b8bf9_0
-  - intel-openmp=2020.0=166
+  - hdf5=1.10.5
+  - intel-openmp
   - ld_impl_linux-64=2.33.1=h53a641e_8
-  - libffi=3.2.1=he1b5a44_1006
-  - libgcc-ng=9.2.0=h24d8f2e_2
-  - libgfortran-ng=7.3.0=hdf63c60_0
-  - libgomp=9.2.0=h24d8f2e_2
-  - libopenblas=0.3.7=h5ec1e0e_6
-  - libstdcxx-ng=9.2.0=hdf63c60_2
-  - lz4-c=1.8.1.2=h14c3975_0
-  - lzo=2.10=h49e0be7_2
+  - libffi=3.2.1
+  - libgcc-ng
+  - libgfortran-ng
+  - libgomp
+  - libopenblas=0.3.13
+  - libstdcxx-ng
+  - lz4-c=1.9.3
+  - lzo=2.10
path: setup/environment-linux.yml
text: @user1:
Wouldn't it be better to include the exact version number of these dependencies.