12
12
# See the License for the specific language governing permissions and
13
13
# limitations under the License.
14
14
15
- from datetime import datetime , timedelta
15
+ from datetime import datetime , timedelta , timezone
16
16
from typing import Any , Dict , List , Optional , Set
17
17
18
18
import pytest
19
19
from prezzemolo .vertex import Vertex
20
20
from rp2 .rp2_decimal import RP2Decimal
21
+ from rp2 .rp2_error import RP2ValueError
21
22
22
23
from dali .abstract_ccxt_pair_converter_plugin import (
24
+ _BINANCE ,
25
+ _COINBASE_PRO ,
26
+ _ONE_HOUR ,
27
+ _SIX_HOUR ,
28
+ _TIME_GRANULARITY ,
29
+ _TIME_GRANULARITY_DICT ,
23
30
MARKET_PADDING_IN_WEEKS ,
24
31
AbstractCcxtPairConverterPlugin ,
25
32
)
@@ -74,10 +81,11 @@ def unoptimized_graph(self, vertex_list: Dict[str, Vertex[str]]) -> MappedGraph[
74
81
75
82
@pytest .fixture
76
83
def historical_bars (self ) -> Dict [str , HistoricalBar ]:
84
+ now_time = datetime .now (timezone .utc )
77
85
return {
78
86
MARKET_START : HistoricalBar (
79
87
duration = timedelta (weeks = 1 ),
80
- timestamp = datetime ( 2023 , 1 , 1 ) ,
88
+ timestamp = now_time ,
81
89
open = RP2Decimal ("1.0" ),
82
90
high = RP2Decimal ("2.0" ),
83
91
low = RP2Decimal ("0.5" ),
@@ -86,7 +94,7 @@ def historical_bars(self) -> Dict[str, HistoricalBar]:
86
94
),
87
95
ONE_WEEK_EARLIER : HistoricalBar (
88
96
duration = timedelta (weeks = 1 ),
89
- timestamp = datetime ( 2023 , 1 , 1 ) - timedelta (weeks = 1 ),
97
+ timestamp = now_time - timedelta (weeks = 1 ),
90
98
open = RP2Decimal ("1.1" ),
91
99
high = RP2Decimal ("2.1" ),
92
100
low = RP2Decimal ("0.6" ),
@@ -116,7 +124,7 @@ def test_retrieve_historical_bars(
116
124
plugin = MockAbstractCcxtPairConverterPlugin (Keyword .HISTORICAL_PRICE_HIGH .value )
117
125
unoptimized_assets : Set [str ] = {"A" , "B" }
118
126
optimization_candidates : Set [Vertex [str ]] = {vertex_list ["A" ], vertex_list ["B" ], vertex_list ["C" ]}
119
- week_start_date = datetime ( 2023 , 1 , 1 )
127
+ week_start_date = historical_bars [ MARKET_START ]. timestamp
120
128
121
129
mocker .patch .object (plugin , "_AbstractCcxtPairConverterPlugin__exchange_markets" , {TEST_EXCHANGE : TEST_MARKETS })
122
130
@@ -148,7 +156,7 @@ def find_historical_bars_side_effect(
148
156
149
157
def test_generate_optimizations (self , historical_bars : Dict [str , HistoricalBar ]) -> None :
150
158
plugin = MockAbstractCcxtPairConverterPlugin (Keyword .HISTORICAL_PRICE_HIGH .value )
151
- week_start_date = datetime ( 2023 , 1 , 1 )
159
+ week_start_date = historical_bars [ MARKET_START ]. timestamp
152
160
153
161
child_bars = {"A" : {"B" : [historical_bars [MARKET_START ], historical_bars [ONE_WEEK_EARLIER ]]}}
154
162
@@ -193,3 +201,40 @@ def test_refine_and_finalize_optimizations(self) -> None:
193
201
assert refined_optimizations [datetime (2023 , 1 , 4 )]["A" ]["C" ] == 1.0
194
202
assert refined_optimizations [datetime (2023 , 1 , 4 )]["D" ]["F" ] == 1.0
195
203
assert "E" not in refined_optimizations [datetime (2023 , 1 , 4 )]["D" ]
204
+
205
+ def test_initialize_retry_count (self ) -> None :
206
+ plugin = MockAbstractCcxtPairConverterPlugin (Keyword .HISTORICAL_PRICE_HIGH .value )
207
+
208
+ assert plugin ._initialize_retry_count (_BINANCE , _ONE_HOUR ) == _TIME_GRANULARITY .index (_ONE_HOUR ) # pylint: disable=protected-access
209
+ assert plugin ._initialize_retry_count (_COINBASE_PRO , _SIX_HOUR ) == _TIME_GRANULARITY_DICT [_COINBASE_PRO ].index ( # pylint: disable=protected-access
210
+ _SIX_HOUR
211
+ )
212
+ with pytest .raises (RP2ValueError ):
213
+ # Binance does not support 6 hour granularity
214
+ assert plugin ._initialize_retry_count (_BINANCE , _SIX_HOUR ) # pylint: disable=protected-access
215
+ assert plugin ._initialize_retry_count (_COINBASE_PRO , "invalid" ) # pylint: disable=protected-access
216
+
217
+ def test_find_historical_bars_guard_clause (self , mocker : Any , historical_bars : Dict [str , HistoricalBar ]) -> None :
218
+ plugin = MockAbstractCcxtPairConverterPlugin (Keyword .HISTORICAL_PRICE_HIGH .value )
219
+
220
+ mocker .patch .object (plugin , "_get_bundle_from_cache" , return_value = [historical_bars [MARKET_START ]])
221
+
222
+ bars = plugin .find_historical_bars ("A" , "B" , datetime (2023 , 1 , 1 ), TEST_EXCHANGE , True )
223
+
224
+ assert bars
225
+ assert len (bars ) == 1
226
+ assert bars [0 ] == historical_bars [MARKET_START ]
227
+
228
+ # To be enabled when _fetch_historical_bars is implemented
229
+ def disabled_test_find_historical_bars_add_to_cache (self , mocker : Any , historical_bars : Dict [str , HistoricalBar ]) -> None :
230
+ plugin = MockAbstractCcxtPairConverterPlugin (Keyword .HISTORICAL_PRICE_HIGH .value )
231
+
232
+ mocker .patch .object (plugin , "_get_bundle_from_cache" , return_value = historical_bars [ONE_WEEK_EARLIER ])
233
+ mocker .patch .object (plugin , "_fetch_historical_bars" , return_value = [historical_bars [MARKET_START ]]) # function that calls the API
234
+
235
+ bars = plugin .find_historical_bars ("A" , "B" , datetime (2023 , 1 , 1 ), TEST_EXCHANGE , True )
236
+
237
+ assert bars
238
+ assert len (bars ) == 2
239
+ assert bars [0 ] == historical_bars [ONE_WEEK_EARLIER ]
240
+ assert bars [1 ] == historical_bars [MARKET_START ]
0 commit comments