Coverage for django_napse/core/models/bots/implementations/turbo_dca/strategy.py: 91%

45 statements  

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

1import math 

2 

3from django.db import models 

4 

5from django_napse.core.models.bots.architectures.single_pair import SinglePairArchitecture 

6from django_napse.core.models.bots.implementations.turbo_dca.config import TurboDCABotConfig 

7from django_napse.core.models.bots.plugins import LBOPlugin, MBPPlugin, SBVPlugin 

8from django_napse.core.models.bots.strategy import Strategy 

9from django_napse.utils.constants import SIDES 

10 

11 

12class TurboDCAStrategy(Strategy): 

13 variable_last_buy_date = models.DateTimeField(null=True, blank=True) 

14 

15 def __str__(self) -> str: 

16 return f"TURBO DCA BOT STRATEGY: {self.pk=}" 

17 

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

19 string = "" 

20 string += f"{beacon}Strategy ({self.pk=}):\n" 

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

22 string += f"{beacon}\t{self.config=}\n" 

23 string += f"{beacon}\t{self.architecture=}\n" 

24 if verbose: # pragma: no cover 

25 print(string) 

26 return string 

27 

28 @classmethod 

29 def config_class(cls): 

30 return TurboDCABotConfig 

31 

32 @classmethod 

33 def architecture_class(cls): 

34 return SinglePairArchitecture 

35 

36 @classmethod 

37 def plugin_classes(cls): 

38 return [MBPPlugin, LBOPlugin, SBVPlugin] 

39 

40 def give_order(self, data: dict) -> list[dict]: 

41 controller = data["controllers"]["main"] 

42 if ( 

43 self.variable_last_buy_date is None 

44 or data["candles"][controller]["current"]["open_time"] - self.variable_last_buy_date >= data["config"]["timeframe"] 

45 ): 

46 mbp = data["connection_data"][data["connection"]]["connection_specific_args"]["mbp"].get_value() 

47 lbo = data["connection_data"][data["connection"]]["connection_specific_args"]["lbo"].get_value() 

48 sbv = data["connection_data"][data["connection"]]["connection_specific_args"]["sbv"].get_value() 

49 available_base = data["connection_data"][data["connection"]]["wallet"]["currencies"].get(controller.base, {"amount": 0})["amount"] 

50 available_quote = data["connection_data"][data["connection"]]["wallet"]["currencies"].get(controller.quote, {"amount": 0})["amount"] 

51 mbp = mbp if mbp is not None else math.inf 

52 sbv = sbv if sbv is not None else available_quote 

53 current_price = data["candles"][controller]["latest"]["close"] 

54 amount = data["config"]["percentage"] * sbv / 100 

55 if lbo == 0 or current_price < mbp: 

56 return [ 

57 { 

58 "controller": controller, 

59 "ArchitectureModifications": [], 

60 "StrategyModifications": [ 

61 { 

62 "key": "last_buy_date", 

63 "value": str(data["candles"][controller]["current"]["open_time"]), 

64 "target_type": "datetime", 

65 "ignore_failed_order": False, 

66 }, 

67 ], 

68 "ConnectionModifications": [], 

69 "connection": data["connection"], 

70 "asked_for_amount": amount, 

71 "asked_for_ticker": controller.quote, 

72 "pair": controller.pair, 

73 "price": data["candles"][controller]["latest"]["close"], 

74 "side": SIDES.BUY, 

75 }, 

76 ] 

77 if current_price > mbp: 

78 return [ 

79 { 

80 "controller": controller, 

81 "ArchitectureModifications": [], 

82 "StrategyModifications": [ 

83 { 

84 "key": "last_buy_date", 

85 "value": str(data["candles"][controller]["current"]["open_time"]), 

86 "target_type": "datetime", 

87 "ignore_failed_order": False, 

88 }, 

89 ], 

90 "ConnectionModifications": [], 

91 "connection": data["connection"], 

92 "asked_for_amount": available_base, 

93 "asked_for_ticker": controller.base, 

94 "pair": controller.pair, 

95 "price": data["candles"][controller]["latest"]["close"], 

96 "side": SIDES.SELL, 

97 }, 

98 ] 

99 return [ 

100 { 

101 "controller": controller, 

102 "ArchitectureModifications": [], 

103 "StrategyModifications": [ 

104 { 

105 "key": "last_buy_date", 

106 "value": str(data["candles"][controller]["current"]["open_time"]), 

107 "target_type": "datetime", 

108 "ignore_failed_order": False, 

109 }, 

110 ], 

111 "ConnectionModifications": [], 

112 "connection": data["connection"], 

113 "asked_for_amount": 0, 

114 "asked_for_ticker": controller.quote, 

115 "pair": controller.pair, 

116 "price": data["candles"][controller]["latest"]["close"], 

117 "side": SIDES.KEEP, 

118 }, 

119 ] 

120 return [ 

121 { 

122 "controller": controller, 

123 "ArchitectureModifications": [], 

124 "StrategyModifications": [], 

125 "ConnectionModifications": [], 

126 "connection": data["connection"], 

127 "asked_for_amount": 0, 

128 "asked_for_ticker": controller.quote, 

129 "pair": controller.pair, 

130 "price": data["candles"][controller]["latest"]["close"], 

131 "side": SIDES.KEEP, 

132 }, 

133 ]