Как добиться замещения лиски абстрактными подклассами с фабричным шаблоном проектирования в python? - PullRequest
0 голосов
/ 24 декабря 2018

Логика ядра стратегии зависит от того, является ли текущая дата первым днем ​​выполнения стратегии или последовательным днем, который проверяется внутри meets_condition().В случае false meets_condition() мне нужно проверить другое условие, например, has_position().Логика ядра для true meets_condition() и true has_position() отличается от true meets_condition() и false has_position().

Я успешно абстрагировал детали реализации вышеупомянутого, сделав StrategyRun в качестве абстрактного базового класса и имейте FirstDayStrategyRun, SuccessiveDayWithPosition и SuccessiveDayWithoutPositionунаследованные модули StrategyRun.

enter image description here

class StrategyRun(object):
      __metaclass__ = ABCMeta

    def __init__(self, today, strategy_start_date):
       self._today = today
       self._strategy_start_date = strategy_start_date

    @staticmethod[![enter image description here][1]][1]
    def meets_condition(strategy_start_date: str, today: datetime) -> bool:
        """
        :param strategy_start_date: The first day of strategy run
        :param today: Current day
        :return: boolean to identify first day, successive days with open positions and successive days with no
        open postions' strategy run
        """
        return False

    @abstractmethod
    def core_strategy_logic(self, portfolio_for_the_day):
        pass


class SuccessiveDayStrategyRunWithOpenPositions(StrategyRun):

    def __init__(self, strategy_start_date, today, number_of_long_shorts):
        self._today = today
        super(StrategyRun, self).__init__(today, strategy_start_date)

    @staticmethod
    def meets_condition(strategy_start_date: str, today: datetime) -> bool:
        return parser.parse(strategy_start_date).day == today.day and not get_yesterdays_positions().empty

    def core_strategy_logic(self, portfolio_for_the_day):
        **implementation**

class SuccessiveDayStrategyRunWithoutOpenPositions(StrategyRun):

    def __init__(self, strategy_start_date, today, number_of_long_shorts):
        self._today = today
        super(StrategyRun, self).__init__(today, strategy_start_date)

    @staticmethod
    def meets_condition(strategy_start_date: str, today: datetime) -> bool:
        return parser.parse(strategy_start_date).day == today.day and get_yesterdays_positions().empty

    def core_strategy_logic(self, portfolio_for_the_day):
        **implementation**

class StrategyRunner:

    def __init__(self, strategy_start_date, strategy_run_threshold):
        self._strategy_start_date = strategy_start_date
        self._today = datetime.datetime.now()

    def identify_strategy_run(self):
        for strategy_cls in StrategyRun.__subclasses__():
            try:
                if strategy_cls.meets_condition(self._strategy_start_date, self._today):
                    return strategy_cls(self._strategy_start_date, self._today)
            except KeyError:
                continue
        return UnknownStrategyRun(self.event_data)

    def run_core_logic(self):
        strategy_run = self.identify_strategy_run()
        strategy_run.core_strategy_logic(portfolio_for_the_day)

SuccessiveStrategyRunWithOpenPositions и SuccessiveStrategyRunWithoutOpenPosition должны расширять абстрактный подкласс StrategyRun, например SuccessiveStrategyRun, который имеет другой методнапример, has_position ().identify_strategy_run() в StrategyRunner должен включать этот дополнительный метод вместе со meets_condition() статическим методом для определения типа объекта.

...