Coverage for django_napse/core/models/bots/strategy.py: 48%
52 statements
« prev ^ index » next coverage.py v7.4.3, created at 2024-03-12 13:49 +0000
« prev ^ index » next coverage.py v7.4.3, created at 2024-03-12 13:49 +0000
1from __future__ import annotations
3from django.db import models
5from django_napse.core.models.bots.managers.strategy import StrategyManager
6from django_napse.utils.findable_class import FindableClass
9class Strategy(models.Model, FindableClass):
10 """Define the bot's buying and selling logic."""
12 config = models.OneToOneField("BotConfig", on_delete=models.CASCADE, related_name="strategy")
13 architecture = models.OneToOneField("Architecture", on_delete=models.CASCADE, related_name="strategy")
15 objects = StrategyManager()
17 def __str__(self) -> str: # pragma: no cover
18 return f"STRATEGY {self.pk}"
20 def info(self, verbose: bool = True, beacon: str = "") -> str: # noqa: FBT001, FBT002
21 """Return info on the Strategy."""
22 string = ""
23 string += f"{beacon}Strategy {self.pk}:\n"
24 string += f"{beacon}Args:\n"
25 string += f"{beacon}\t{self.config=}\n"
26 string += f"{beacon}\t{self.architecture=}\n"
28 if verbose:
29 print(string)
30 return string
32 def give_order(self, data: dict) -> list[dict]: # noqa
33 if self.__class__ == Strategy:
34 error_msg = "give_order not implemented for the Strategy base class, please implement it in a subclass."
35 else:
36 error_msg = f"give_order not implemented for the Strategy base class, please implement it in the {self.__class__} class."
37 raise NotImplementedError(error_msg)
39 @classmethod
40 def plugin_classes(cls) -> list:
41 """Return the list of all strategy's plugins."""
42 return []
44 @classmethod
45 def achitecture_class(cls): # noqa
46 if cls == Strategy:
47 error_msg = "achitecture_class not implemented for the Strategy base class, please implement it in a subclass."
48 else:
49 error_msg = f"achitecture_class not implemented for the Strategy base class, please implement it in the {cls} class."
50 raise NotImplementedError(error_msg)
52 @classmethod
53 def config_class(cls): # noqa
54 if cls == Strategy:
55 error_msg = "config_class not implemented for the Strategy base class, please implement it in a subclass."
56 else:
57 error_msg = f"config_class not implemented for the Strategy base class, please implement it in the {cls} class."
58 raise NotImplementedError(error_msg)
60 @classmethod
61 def architecture_class(cls) -> "Architecture": # noqa: F821
62 """Return the class of the associated architecture."""
63 return cls._meta.get_field("architecture").related_model
65 @property
66 def variables(self) -> dict[str, any]:
67 """Return variables of a strategy."""
68 self = self.find(self.pk)
69 variables = {}
70 for variable in self._meta.get_fields():
71 if variable.name.startswith("variable_"):
72 variables[variable.name[8:]] = getattr(self, variable.name)
73 return variables
75 def connect(self, connection): # noqa
76 return
78 def copy(self) -> Strategy:
79 """Return a copy of the Strategy."""
80 return self.find().__class__.objects.create(
81 config=self.config.find().duplicate_immutable(),
82 architecture=self.architecture.find().copy(),
83 )