Coverage for django_napse/core/models/fleets/fleet.py: 71%

79 statements  

« prev     ^ index     » next       coverage.py v7.4.3, created at 2024-03-12 13:49 +0000

1import uuid 

2from datetime import datetime, timedelta 

3 

4from django.db import models 

5from django.utils.timezone import get_default_timezone 

6 

7from django_napse.core.models.bots.bot import Bot 

8from django_napse.core.models.connections.connection import Connection 

9from django_napse.core.models.fleets.managers import FleetManager 

10from django_napse.core.models.orders.order import Order 

11from django_napse.utils.errors import BotError 

12 

13 

14class Fleet(models.Model): 

15 uuid = models.UUIDField( 

16 default=uuid.uuid4, 

17 editable=False, 

18 unique=True, 

19 ) 

20 name = models.CharField( 

21 max_length=100, 

22 default="Fleet", 

23 ) 

24 exchange_account = models.ForeignKey( 

25 "ExchangeAccount", 

26 on_delete=models.CASCADE, 

27 ) 

28 running = models.BooleanField(default=False) 

29 setup_finished = models.BooleanField(default=False) 

30 created_at = models.DateTimeField( 

31 auto_now_add=True, 

32 blank=True, 

33 ) 

34 

35 objects = FleetManager() 

36 

37 def __str__(self): 

38 return f"FLEET: {self.pk=}, name={self.name}" 

39 

40 def info(self, verbose=True, beacon=""): 

41 string = "" 

42 string += f"{beacon}Fleet {self.pk}:\n" 

43 string += f"{beacon}Args:\n" 

44 string += f"{beacon}\t{self.name=}\n" 

45 string += f"{beacon}\t{self.exchange_account=}\n" 

46 string += f"{beacon}\t{self.running=}\n" 

47 string += f"{beacon}\t{self.setup_finished=}\n" 

48 

49 string += f"{beacon}Clusters:\n" 

50 new_beacon = beacon + "\t" 

51 for cluster in self.clusters.all(): 

52 string += f"{beacon}{cluster.info(verbose=False, beacon=new_beacon)}\n" 

53 

54 if verbose: # pragma: no cover 

55 print(string) 

56 return string 

57 

58 @property 

59 def testing(self): 

60 return self.exchange_account.testing 

61 

62 @property 

63 def bots(self): 

64 return Bot.objects.filter(link__cluster__fleet=self) 

65 

66 @property 

67 def value(self) -> float: 

68 """Sum value of all bots in fleet.""" 

69 connections = Connection.objects.filter(bot__in=self.bots) 

70 return sum([connection.wallet.value_market() for connection in connections]) 

71 

72 def space_frame_value(self, space) -> float: 

73 """Sum value of all bots connected to the space.""" 

74 # TODO: remove property to values and add the following lines to the new `value()` method 

75 fleet_connections = Connection.objects.filter(bot__in=self.bots) 

76 space_connections = space.wallet.connections.all() 

77 commun_connections = space_connections.intersection(fleet_connections) 

78 return sum([connection.wallet.value_market() for connection in commun_connections]) 

79 

80 def bot_clusters(self): 

81 bot_clusters = [] 

82 for cluster in self.clusters.all(): 

83 bot_clusters.append(Bot.objects.filter(link__cluster=cluster)) 

84 return bot_clusters 

85 

86 def connect_to_space(self, space): 

87 ... 

88 

89 def invest(self, space, amount, ticker): 

90 connections = [] 

91 for cluster in self.clusters.all(): 

92 connections += cluster.invest(space, amount * cluster.share, ticker) 

93 return connections 

94 

95 def bot_count(self, space=None) -> int: 

96 """Count number of bots in fleet, depends on space frame.""" 

97 query_bot = self.bots.all() 

98 if space is None: 

99 return len(query_bot) 

100 result = [] 

101 for bot in query_bot: 

102 try: 

103 bot_space = bot.space 

104 except BotError.NoSpace: 

105 continue 

106 if bot_space == self.space: 

107 result.append(bot) 

108 return len(result) 

109 

110 def get_stats(self): 

111 order_count = Order.objects.filter( # noqa: F841 

112 connection__bot__in=self.bots, 

113 created_at__gt=datetime.now(tz=get_default_timezone()) - timedelta(days=30), 

114 ).count() 

115 return { 

116 "value": self.value, 

117 "bot_count": self.bot_count(), 

118 "delta_30": 0, # TODO: Need history 

119 } 

120 

121 def delete(self) -> None: 

122 """Delete clusters & relative (template) bots.""" 

123 self.bots.delete() 

124 self.clusters.all().delete() 

125 super().delete()