From db67b106059803b72586b034e435c2cf7d2e844f Mon Sep 17 00:00:00 2001 From: Gerald Lonlas Date: Tue, 6 Feb 2018 20:22:17 -0800 Subject: [PATCH] Remove Singleton from Strategy() --- freqtrade/analyze.py | 13 +++++++++--- freqtrade/constants.py | 1 + freqtrade/strategy/strategy.py | 25 ++++++----------------- freqtrade/tests/strategy/test_strategy.py | 16 +++++---------- freqtrade/tests/test_constants.py | 15 +++++++------- 5 files changed, 30 insertions(+), 40 deletions(-) diff --git a/freqtrade/analyze.py b/freqtrade/analyze.py index a1ed09824..f3126d723 100644 --- a/freqtrade/analyze.py +++ b/freqtrade/analyze.py @@ -33,8 +33,7 @@ class Analyze(object): self.logger = Logger(name=__name__).get_logger() self.config = config - self.strategy = Strategy() - self.strategy.init(self.config) + self.strategy = Strategy(self.config) @staticmethod def parse_ticker_dataframe(ticker: list) -> DataFrame: @@ -60,7 +59,6 @@ class Analyze(object): you are using. Let uncomment only the indicator you are using in your strategies or your hyperopt configuration, otherwise you will waste your memory and CPU usage. """ - return self.strategy.populate_indicators(dataframe=dataframe) def populate_buy_trend(self, dataframe: DataFrame) -> DataFrame: @@ -97,6 +95,7 @@ class Analyze(object): """ Calculates current signal based several technical analysis indicators :param pair: pair in format BTC_ANT or BTC-ANT + :param interval: Interval to use (in min) :return: (Buy, Sell) A bool-tuple indicating buy/sell signal """ ticker_hist = get_ticker_history(pair, interval) @@ -188,3 +187,11 @@ class Analyze(object): float(current_profit) * 100.0 ) return False + + + def tickerdata_to_dataframe(self, tickerdata: Dict[str, List]) -> Dict[str, DataFrame]: + """ + Creates a dataframe and populates indicators for given ticker data + """ + return {pair: self.populate_indicators(self.parse_ticker_dataframe(pair_data)) + for pair, pair_data in tickerdata.items()} \ No newline at end of file diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 765a4fe3e..a3f91d774 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -14,6 +14,7 @@ class Constants(object): TICKER_INTERVAL = 5 # min HYPEROPT_EPOCH = 100 # epochs RETRY_TIMEOUT = 30 # sec + DEFAULT_STRATEGY = 'default_strategy' # Required json-schema for user specified config CONF_SCHEMA = { diff --git a/freqtrade/strategy/strategy.py b/freqtrade/strategy/strategy.py index 7ea8e81ac..8333beea7 100644 --- a/freqtrade/strategy/strategy.py +++ b/freqtrade/strategy/strategy.py @@ -3,12 +3,12 @@ """ This module load custom strategies """ +import importlib import os import sys -import logging -import importlib - from pandas import DataFrame +from freqtrade.logger import Logger +from freqtrade.constants import Constants from freqtrade.strategy.interface import IStrategy @@ -19,32 +19,19 @@ class Strategy(object): """ This class contains all the logic to load custom strategy class """ - __instance = None - - DEFAULT_STRATEGY = 'default_strategy' - - def __new__(cls) -> object: - """ - Used to create the Singleton - :return: Strategy object - """ - if Strategy.__instance is None: - Strategy.__instance = object.__new__(cls) - return Strategy.__instance - - def init(self, config: dict) -> None: + def __init__(self, config: dict={}) -> None: """ Load the custom class from config parameter :param config: :return: """ - self.logger = logging.getLogger(__name__) + self.logger = Logger(name=__name__).get_logger() # Verify the strategy is in the configuration, otherwise fallback to the default strategy if 'strategy' in config: strategy = config['strategy'] else: - strategy = self.DEFAULT_STRATEGY + strategy = Constants.DEFAULT_STRATEGY # Load the strategy self._load_strategy(strategy) diff --git a/freqtrade/tests/strategy/test_strategy.py b/freqtrade/tests/strategy/test_strategy.py index 890718d60..8c099b502 100644 --- a/freqtrade/tests/strategy/test_strategy.py +++ b/freqtrade/tests/strategy/test_strategy.py @@ -21,7 +21,6 @@ def test_search_strategy(): def test_strategy_structure(): - assert hasattr(Strategy, 'init') assert hasattr(Strategy, 'populate_indicators') assert hasattr(Strategy, 'populate_buy_trend') assert hasattr(Strategy, 'populate_sell_trend') @@ -53,8 +52,7 @@ def test_load_not_found_strategy(caplog): def test_strategy(result): - strategy = Strategy() - strategy.init({'strategy': 'default_strategy'}) + strategy = Strategy({'strategy': 'default_strategy'}) assert hasattr(strategy.custom_strategy, 'minimal_roi') assert strategy.minimal_roi['0'] == 0.04 @@ -82,8 +80,7 @@ def test_strategy_override_minimal_roi(caplog): "0": 0.5 } } - strategy = Strategy() - strategy.init(config) + strategy = Strategy(config) assert hasattr(strategy.custom_strategy, 'minimal_roi') assert strategy.minimal_roi['0'] == 0.5 @@ -99,8 +96,7 @@ def test_strategy_override_stoploss(caplog): 'strategy': 'default_strategy', 'stoploss': -0.5 } - strategy = Strategy() - strategy.init(config) + strategy = Strategy(config) assert hasattr(strategy.custom_strategy, 'stoploss') assert strategy.stoploss == -0.5 @@ -117,8 +113,7 @@ def test_strategy_override_ticker_interval(caplog): 'strategy': 'default_strategy', 'ticker_interval': 60 } - strategy = Strategy() - strategy.init(config) + strategy = Strategy(config) assert hasattr(strategy.custom_strategy, 'ticker_interval') assert strategy.ticker_interval == 60 @@ -138,8 +133,7 @@ def test_strategy_fallback_default_strategy(): def test_strategy_singleton(): - strategy1 = Strategy() - strategy1.init({'strategy': 'default_strategy'}) + strategy1 = Strategy({'strategy': 'default_strategy'}) assert hasattr(strategy1.custom_strategy, 'minimal_roi') assert strategy1.minimal_roi['0'] == 0.04 diff --git a/freqtrade/tests/test_constants.py b/freqtrade/tests/test_constants.py index e50fbb880..4c94926bc 100644 --- a/freqtrade/tests/test_constants.py +++ b/freqtrade/tests/test_constants.py @@ -10,13 +10,14 @@ def test_constant_object() -> None: Test the Constants object has the mandatory Constants :return: None """ - constant = Constants() - assert hasattr(constant, 'CONF_SCHEMA') - assert hasattr(constant, 'DYNAMIC_WHITELIST') - assert hasattr(constant, 'PROCESS_THROTTLE_SECS') - assert hasattr(constant, 'TICKER_INTERVAL') - assert hasattr(constant, 'HYPEROPT_EPOCH') - assert hasattr(constant, 'RETRY_TIMEOUT') + assert hasattr(Constants, 'CONF_SCHEMA') + assert hasattr(Constants, 'DYNAMIC_WHITELIST') + assert hasattr(Constants, 'PROCESS_THROTTLE_SECS') + assert hasattr(Constants, 'TICKER_INTERVAL') + assert hasattr(Constants, 'HYPEROPT_EPOCH') + assert hasattr(Constants, 'RETRY_TIMEOUT') + assert hasattr(Constants, 'DEFAULT_STRATEGY') + def test_conf_schema() -> None: