Skip to content

Commit 6ade86c

Browse files
author
DUYN
committed
initial base Strategy setup
1 parent 7157113 commit 6ade86c

File tree

7 files changed

+189
-203
lines changed

7 files changed

+189
-203
lines changed

bot/strategies/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from bot.strategies.strategy.strategy import Strategy
2+
from bot.strategies.strategy.strategy import ObservableStrategy
3+
from bot.strategies.strategy_executor import StrategyExecutor
4+
5+
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import logging
2+
from pandas import DataFrame
3+
from typing import Dict, Any, List
4+
from abc import ABC, abstractmethod
5+
from collections import namedtuple
6+
7+
from bot.utils import DataSource
8+
from bot.events.observer import Observer
9+
from bot.events.observable import Observable
10+
11+
logger = logging.getLogger(__name__)
12+
13+
14+
class Strategy(ABC):
15+
16+
def start(self, data_sources: List[DataSource]) -> None:
17+
logger.info("running strategy {}".format(self.get_id))
18+
# def __init__(self):
19+
# self._apply_populate_data: bool = True
20+
# self._apply_buy_advice: bool = True
21+
# self._apply_sell_advice: bool = True
22+
# self._analyzed_data: DataFrame = None
23+
# self._meta_data: Dict[str, Any] = None
24+
# self._data_sources = None
25+
#
26+
# @abstractmethod
27+
# def validate_data(self, data_provider_id: str, raw_data: DataFrame) -> bool:
28+
# """
29+
# Use this function to validate the raw data in the given DataFrame.
30+
# When this hook returns false, the strategy will be skipped
31+
# :return: True, if data can be used to apply strategy, else False
32+
# """
33+
# pass
34+
#
35+
# @abstractmethod
36+
# def populate_data(self, raw_data: List[DataSource]) -> DataFrame:
37+
# """
38+
# Use this function to change the raw data DataFrame. If not used, consider changing the flag
39+
# 'apply_populate_data' to False.
40+
# :return: custom populated DataFrame
41+
# """
42+
#
43+
# @abstractmethod
44+
# def get_buy_advice(self, populated_data: DataFrame, data: List[DataSource], meta_data: Dict) -> DataFrame:
45+
# """
46+
# Use this function to change the raw data DataFrame. If not used, consider changing the flag
47+
# 'apply_populate_data' to False.
48+
# :return: custom populated DataFrame
49+
# """
50+
# pass
51+
#
52+
# @abstractmethod
53+
# def get_sell_advice(self, data: List[DataSource], meta_data: Dict) -> DataFrame:
54+
# """
55+
# Use this function to change the raw data DataFrame. If not used, consider changing the flag
56+
# 'apply_populate_data' to False.
57+
# :return: custom populated DataFrame
58+
# """
59+
# pass
60+
#
61+
# @property
62+
# def apply_populate_data(self) -> bool:
63+
# return self._apply_populate_data
64+
#
65+
# @apply_populate_data.setter
66+
# def apply_populate_data(self, flag: bool) -> None:
67+
# self._apply_populate_data = flag
68+
#
69+
# @property
70+
# def apply_buy_advice(self) -> bool:
71+
# return self._apply_buy_advice
72+
#
73+
# @apply_buy_advice.setter
74+
# def apply_buy_advice(self, flag: bool) -> None:
75+
# self._apply_buy_advice = flag
76+
#
77+
# @property
78+
# def apply_sell_advice(self) -> bool:
79+
# return self._apply_sell_advice
80+
#
81+
# @apply_sell_advice.setter
82+
# def apply_sell_advice(self, flag: bool) -> None:
83+
# self._apply_sell_advice = flag
84+
85+
@abstractmethod
86+
def get_id(self) -> str:
87+
pass
88+
89+
# def _extract_sell_indicators(self, data: DataFrame) -> List[Dict[str, Any]]:
90+
# pass
91+
#
92+
# def _extract_buy_indicators(self, data: DataFrame) -> List[Dict[str, Any]]:
93+
# pass
94+
#
95+
# def populate_meta_data(self) -> Dict[str, Any]:
96+
# pass
97+
#
98+
# def start(self, raw_data_sources: List[DataSource]) -> None:
99+
# logger.info("Start strategy {}".format(self.get_id()))
100+
#
101+
# self._data_sources = raw_data_sources
102+
# meta_data = self.populate_meta_data()
103+
#
104+
# populated_data = self.populate_data(raw_data_sources)
105+
# data = self.get_buy_advice(populated_data, raw_data_sources, meta_data)
106+
# data = self.get_sell_advice(populated_data, raw_data_sources, meta_data)
107+
#
108+
# self._analyzed_data = data
109+
# self._meta_data = meta_data
110+
111+
112+
class ObservableStrategy(Observable, Strategy):
113+
114+
def __init__(self, subject_strategy: Strategy):
115+
super(ObservableStrategy, self).__init__()
116+
self._subject_strategy = subject_strategy
117+
118+
# def validate_data(self, data_provider_id: str, raw_data: DataFrame) -> bool:
119+
# return self._subject_strategy.validate_data(data_provider_id, raw_data)
120+
#
121+
# def populate_data(self, raw_data: DataFrame) -> DataFrame:
122+
# return self._subject_strategy.populate_data(raw_data)
123+
#
124+
# def get_buy_advice(self, data: DataFrame, meta_data: Dict) -> DataFrame:
125+
# return self._subject_strategy.get_buy_advice(data, meta_data)
126+
#
127+
# def get_sell_advice(self, data: DataFrame, meta_data: Dict) -> DataFrame:
128+
# return self._subject_strategy.get_sell_advice(data, meta_data)
129+
130+
def get_id(self) -> str:
131+
return self._subject_strategy.get_id()
132+
133+
def add_observer(self, observer: Observer) -> None:
134+
super(ObservableStrategy, self).add_observer(observer)
135+
136+
def remove_observer(self, observer: Observer) -> None:
137+
super(ObservableStrategy, self).remove_observer(observer)

bot/strategies/strategy/template/__init__.py

Whitespace-only changes.
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
from typing import List, Tuple
2+
3+
from bot import OperationalException
4+
from bot.executors import WorkerExecutor
5+
from bot.events.observable import Observable
6+
from bot.strategies import ObservableStrategy
7+
from bot.utils import StoppableThread, DataSource
8+
9+
10+
class StrategyExecutor(WorkerExecutor):
11+
12+
def __init__(self, strategies: List[ObservableStrategy] = None):
13+
super(StrategyExecutor, self).__init__()
14+
15+
self._registered_strategies: List[ObservableStrategy] = []
16+
17+
self._data_sources: List[DataSource] = []
18+
19+
if strategies is not None:
20+
self._registered_strategies = strategies
21+
22+
@property
23+
def data_sources(self) -> List[DataSource]:
24+
return self.data_sources
25+
26+
@data_sources.setter
27+
def data_sources(self, data_sources: List[DataSource]) -> None:
28+
self._data_sources = data_sources
29+
30+
def start(self):
31+
32+
if self.data_sources is None:
33+
raise OperationalException("Can't run strategies without data sources")
34+
35+
super(StrategyExecutor, self).start()
36+
37+
def create_jobs(self) -> List[Tuple[Observable, StoppableThread]]:
38+
jobs: List[Tuple[Observable, StoppableThread]] = []
39+
40+
for strategy in self.registered_strategies:
41+
jobs.append((strategy, StoppableThread(target=strategy.start, kwargs={"data_sources": self.data_sources})))
42+
43+
return jobs
44+
45+
@property
46+
def registered_strategies(self) -> List[ObservableStrategy]:
47+
return self._registered_strategies

bot/strategy/strategy.py

Lines changed: 0 additions & 141 deletions
This file was deleted.

bot/strategy/strategy_manager.py

Lines changed: 0 additions & 62 deletions
This file was deleted.

0 commit comments

Comments
 (0)