Remove Singleton from Strategy()

This commit is contained in:
Gerald Lonlas 2018-02-06 20:22:17 -08:00
parent 4da033c7a2
commit db67b10605
5 changed files with 30 additions and 40 deletions

View File

@ -33,8 +33,7 @@ class Analyze(object):
self.logger = Logger(name=__name__).get_logger() self.logger = Logger(name=__name__).get_logger()
self.config = config self.config = config
self.strategy = Strategy() self.strategy = Strategy(self.config)
self.strategy.init(self.config)
@staticmethod @staticmethod
def parse_ticker_dataframe(ticker: list) -> DataFrame: 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 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. or your hyperopt configuration, otherwise you will waste your memory and CPU usage.
""" """
return self.strategy.populate_indicators(dataframe=dataframe) return self.strategy.populate_indicators(dataframe=dataframe)
def populate_buy_trend(self, dataframe: 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 Calculates current signal based several technical analysis indicators
:param pair: pair in format BTC_ANT or BTC-ANT :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 :return: (Buy, Sell) A bool-tuple indicating buy/sell signal
""" """
ticker_hist = get_ticker_history(pair, interval) ticker_hist = get_ticker_history(pair, interval)
@ -188,3 +187,11 @@ class Analyze(object):
float(current_profit) * 100.0 float(current_profit) * 100.0
) )
return False 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()}

View File

@ -14,6 +14,7 @@ class Constants(object):
TICKER_INTERVAL = 5 # min TICKER_INTERVAL = 5 # min
HYPEROPT_EPOCH = 100 # epochs HYPEROPT_EPOCH = 100 # epochs
RETRY_TIMEOUT = 30 # sec RETRY_TIMEOUT = 30 # sec
DEFAULT_STRATEGY = 'default_strategy'
# Required json-schema for user specified config # Required json-schema for user specified config
CONF_SCHEMA = { CONF_SCHEMA = {

View File

@ -3,12 +3,12 @@
""" """
This module load custom strategies This module load custom strategies
""" """
import importlib
import os import os
import sys import sys
import logging
import importlib
from pandas import DataFrame from pandas import DataFrame
from freqtrade.logger import Logger
from freqtrade.constants import Constants
from freqtrade.strategy.interface import IStrategy from freqtrade.strategy.interface import IStrategy
@ -19,32 +19,19 @@ class Strategy(object):
""" """
This class contains all the logic to load custom strategy class This class contains all the logic to load custom strategy class
""" """
__instance = None def __init__(self, config: dict={}) -> 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:
""" """
Load the custom class from config parameter Load the custom class from config parameter
:param config: :param config:
:return: :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 # Verify the strategy is in the configuration, otherwise fallback to the default strategy
if 'strategy' in config: if 'strategy' in config:
strategy = config['strategy'] strategy = config['strategy']
else: else:
strategy = self.DEFAULT_STRATEGY strategy = Constants.DEFAULT_STRATEGY
# Load the strategy # Load the strategy
self._load_strategy(strategy) self._load_strategy(strategy)

View File

@ -21,7 +21,6 @@ def test_search_strategy():
def test_strategy_structure(): def test_strategy_structure():
assert hasattr(Strategy, 'init')
assert hasattr(Strategy, 'populate_indicators') assert hasattr(Strategy, 'populate_indicators')
assert hasattr(Strategy, 'populate_buy_trend') assert hasattr(Strategy, 'populate_buy_trend')
assert hasattr(Strategy, 'populate_sell_trend') assert hasattr(Strategy, 'populate_sell_trend')
@ -53,8 +52,7 @@ def test_load_not_found_strategy(caplog):
def test_strategy(result): def test_strategy(result):
strategy = Strategy() strategy = Strategy({'strategy': 'default_strategy'})
strategy.init({'strategy': 'default_strategy'})
assert hasattr(strategy.custom_strategy, 'minimal_roi') assert hasattr(strategy.custom_strategy, 'minimal_roi')
assert strategy.minimal_roi['0'] == 0.04 assert strategy.minimal_roi['0'] == 0.04
@ -82,8 +80,7 @@ def test_strategy_override_minimal_roi(caplog):
"0": 0.5 "0": 0.5
} }
} }
strategy = Strategy() strategy = Strategy(config)
strategy.init(config)
assert hasattr(strategy.custom_strategy, 'minimal_roi') assert hasattr(strategy.custom_strategy, 'minimal_roi')
assert strategy.minimal_roi['0'] == 0.5 assert strategy.minimal_roi['0'] == 0.5
@ -99,8 +96,7 @@ def test_strategy_override_stoploss(caplog):
'strategy': 'default_strategy', 'strategy': 'default_strategy',
'stoploss': -0.5 'stoploss': -0.5
} }
strategy = Strategy() strategy = Strategy(config)
strategy.init(config)
assert hasattr(strategy.custom_strategy, 'stoploss') assert hasattr(strategy.custom_strategy, 'stoploss')
assert strategy.stoploss == -0.5 assert strategy.stoploss == -0.5
@ -117,8 +113,7 @@ def test_strategy_override_ticker_interval(caplog):
'strategy': 'default_strategy', 'strategy': 'default_strategy',
'ticker_interval': 60 'ticker_interval': 60
} }
strategy = Strategy() strategy = Strategy(config)
strategy.init(config)
assert hasattr(strategy.custom_strategy, 'ticker_interval') assert hasattr(strategy.custom_strategy, 'ticker_interval')
assert strategy.ticker_interval == 60 assert strategy.ticker_interval == 60
@ -138,8 +133,7 @@ def test_strategy_fallback_default_strategy():
def test_strategy_singleton(): def test_strategy_singleton():
strategy1 = Strategy() strategy1 = Strategy({'strategy': 'default_strategy'})
strategy1.init({'strategy': 'default_strategy'})
assert hasattr(strategy1.custom_strategy, 'minimal_roi') assert hasattr(strategy1.custom_strategy, 'minimal_roi')
assert strategy1.minimal_roi['0'] == 0.04 assert strategy1.minimal_roi['0'] == 0.04

View File

@ -10,13 +10,14 @@ def test_constant_object() -> None:
Test the Constants object has the mandatory Constants Test the Constants object has the mandatory Constants
:return: None :return: None
""" """
constant = Constants() assert hasattr(Constants, 'CONF_SCHEMA')
assert hasattr(constant, 'CONF_SCHEMA') assert hasattr(Constants, 'DYNAMIC_WHITELIST')
assert hasattr(constant, 'DYNAMIC_WHITELIST') assert hasattr(Constants, 'PROCESS_THROTTLE_SECS')
assert hasattr(constant, 'PROCESS_THROTTLE_SECS') assert hasattr(Constants, 'TICKER_INTERVAL')
assert hasattr(constant, 'TICKER_INTERVAL') assert hasattr(Constants, 'HYPEROPT_EPOCH')
assert hasattr(constant, 'HYPEROPT_EPOCH') assert hasattr(Constants, 'RETRY_TIMEOUT')
assert hasattr(constant, 'RETRY_TIMEOUT') assert hasattr(Constants, 'DEFAULT_STRATEGY')
def test_conf_schema() -> None: def test_conf_schema() -> None: