Skip to content

Commit 6d9e0ad

Browse files
committed
Removed deepcopy uses and replaced with Candle clean_copy
1 parent 45df61a commit 6d9e0ad

File tree

9 files changed

+50
-33
lines changed

9 files changed

+50
-33
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ The project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html
1111
*Release Date: -**
1212

1313
- Added as_list and as_dict method's to Candle
14+
- Added clean_copy to Candle to copy core values to new Candle object
15+
- Will remove indicators/sub_indicators
16+
- Default used when appending new Candle
17+
18+
- Optimisation
19+
- Removed use of 'deepcopy' for 'clean_copy'
1420

1521
## 2.0.1
1622

hexital/core/candle.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,9 @@ def from_lists(candles: List[list]) -> List[Candle]:
269269
"""
270270
return [Candle.from_list(candle) for candle in candles]
271271

272+
def clean_copy(self) -> Candle:
273+
return Candle.from_list(self.as_list())
274+
272275
def set_collapsed_timestamp(self, timestamp: datetime):
273276
if not self._start_timestamp:
274277
self._start_timestamp = self.timestamp

hexital/core/candle_manager.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from __future__ import annotations
22

3-
from copy import deepcopy
43
from datetime import datetime, timedelta
54
from functools import cmp_to_key
65
from typing import List, Optional, Set
@@ -45,7 +44,7 @@ def __init__(
4544
self.timeframe_fill = timeframe_fill
4645
self.candlestick = candlestick
4746

48-
self._tasks(True)
47+
self._tasks()
4948

5049
def __eq__(self, other) -> bool:
5150
if not isinstance(other, CandleManager):
@@ -70,10 +69,7 @@ def name(self) -> str:
7069
def name(self, name: str):
7170
self._name = name
7271

73-
def _tasks(self, to_sort: Optional[bool] = False):
74-
if to_sort:
75-
self.sort_candles()
76-
72+
def _tasks(self):
7773
self.collapse_candles()
7874
self.convert_candles()
7975
self.trim_candles()
@@ -115,11 +111,14 @@ def append(self, candles: Candle | List[Candle] | dict | List[dict] | list | Lis
115111
if last_timestamp and candle.timestamp < last_timestamp:
116112
to_sort = True
117113
if not candle.timeframe or not self.timeframe:
118-
self.candles.append(deepcopy(candle))
114+
self.candles.append(candle.clean_copy())
119115
elif candle.timeframe <= self.timeframe:
120-
self.candles.append(deepcopy(candle))
116+
self.candles.append(candle.clean_copy())
117+
118+
if to_sort:
119+
self.sort_candles()
121120

122-
self._tasks(to_sort)
121+
self._tasks()
123122

124123
def sort_candles(self, candles: Optional[List[Candle]] = None):
125124
"""Sorts Candles in order of timestamp, accounts for collapsing"""

hexital/core/hexital.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from copy import copy, deepcopy
1+
from copy import copy
22
from datetime import timedelta
33
from importlib import import_module
44
from typing import Dict, List, Optional, Set
@@ -166,7 +166,7 @@ def append(
166166
timeframe_name = self._parse_timeframe(timeframe)
167167

168168
if timeframe_name and self._candles.get(timeframe_name):
169-
self._candles[timeframe_name].append(deepcopy(candles))
169+
self._candles[timeframe_name].append(candles)
170170
else:
171171
for candle_manager in self._candles.values():
172172
candle_manager.append(candles)
@@ -240,12 +240,13 @@ def _validate_indicators(self, indicators: List[dict | Indicator]) -> Dict[str,
240240
indicator.candle_manager = self._candles[indicator.timeframe]
241241
else:
242242
manager = CandleManager(
243-
deepcopy(self._candles[DEFAULT_CANDLES]).candles,
243+
[],
244244
candle_life=self.candle_life,
245245
timeframe=indicator._timeframe if indicator._timeframe else self._timeframe,
246246
timeframe_fill=self.timeframe_fill,
247247
candlestick=self.candlestick,
248248
)
249+
manager.append(self._candles[DEFAULT_CANDLES].candles)
249250
self._candles[manager.name] = manager
250251
indicator.candle_manager = self._candles[manager.name]
251252

@@ -261,15 +262,17 @@ def _build_indicator(self, raw_indicator: dict) -> Indicator:
261262
if indicator_class:
262263
return indicator_class(**indicator)
263264
else:
264-
raise InvalidIndicator(f"Indicator {indicator_name} does not exist. [{indicator}]")
265+
raise InvalidIndicator(
266+
f"Indicator {indicator_name} does not exist. [{raw_indicator}]"
267+
)
265268

266269
elif indicator.get("analysis") and isinstance(indicator.get("analysis"), str):
267270
analysis_name = indicator.pop("analysis")
268271
analysis_class = getattr(import_module("hexital.analysis"), analysis_name, None)
269272

270273
if not analysis_class:
271274
raise InvalidAnalysis(
272-
f"analysis {analysis_name} does not exist in patterns or movements. [{indicator}]"
275+
f"analysis {analysis_name} does not exist in patterns or movements. [{raw_indicator}]"
273276
)
274277

275278
return Amorph(analysis=analysis_class, **indicator)

hexital/core/indicator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from __future__ import annotations
22

33
from abc import ABC, abstractmethod
4-
from copy import deepcopy
4+
from copy import copy
55
from dataclasses import dataclass, field
66
from datetime import timedelta
77
from typing import Dict, List, Optional, TypeVar
@@ -164,7 +164,7 @@ def settings(self) -> dict:
164164
elif name == "timeframe" and self._candles.timeframe is not None:
165165
output[name] = timedelta_to_str(self._candles.timeframe)
166166
elif not name.startswith("_") and value is not None:
167-
output[name] = deepcopy(value)
167+
output[name] = copy(value)
168168

169169
return output
170170

hexital/indicators/amorph.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import inspect
2-
from copy import deepcopy
2+
from copy import copy
33
from typing import Callable, Optional
44

55
from hexital.core.indicator import Indicator
@@ -45,7 +45,7 @@ def settings(self) -> dict:
4545
if name == "timeframe_fill" and self.timeframe is None:
4646
continue
4747
if not name.startswith("_") and value:
48-
output[name] = deepcopy(value)
48+
output[name] = copy(value)
4949

5050
return output
5151

tests/core/test_candle_manager.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,16 @@ def test_append_candle(self, minimal_candles):
1515
manager = CandleManager()
1616
manager.append(new_candle)
1717

18-
assert manager.candles == [new_candle]
18+
assert manager.candles == [
19+
Candle(
20+
open=2424,
21+
high=10767,
22+
low=13115,
23+
close=13649,
24+
volume=15750,
25+
timestamp=datetime(2023, 6, 1, 9, 19),
26+
)
27+
]
1928

2029
def test_append_list_nada(self):
2130
manager = CandleManager()
@@ -28,14 +37,23 @@ def test_append_candle_list(self, minimal_candles):
2837
manager = CandleManager()
2938
manager.append(minimal_candles)
3039

31-
assert manager.candles == minimal_candles
40+
assert manager.candles == [cdl.clean_copy() for cdl in minimal_candles]
3241

3342
@pytest.mark.usefixtures("minimal_candles")
3443
def test_append_candle_list_single(self, minimal_candles):
3544
manager = CandleManager()
3645
manager.append([minimal_candles[0]])
3746

38-
assert manager.candles == [minimal_candles[0]]
47+
assert manager.candles == [
48+
Candle(
49+
open=17213,
50+
high=2395,
51+
low=7813,
52+
close=3615,
53+
volume=19661,
54+
timestamp=datetime(2023, 6, 1, 9, 0, 10),
55+
)
56+
]
3957

4058
def test_append_dict(self):
4159
manager = CandleManager()

tests/core/test_hexital.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -271,8 +271,6 @@ def test_hextial_timerange(minimal_candles):
271271
low=1903,
272272
close=6255,
273273
volume=31307,
274-
indicators={"ATR": 1900, "MinTR": 1902, "NATR": {"nested": 1901}},
275-
sub_indicators={"SATR": 1910, "SSATR": {"nested": 1911}},
276274
timestamp=datetime(2023, 6, 1, 9, 18),
277275
),
278276
Candle(
@@ -281,8 +279,6 @@ def test_hextial_timerange(minimal_candles):
281279
low=13115,
282280
close=13649,
283281
volume=15750,
284-
indicators={"ATR": 2000, "MinTR": 2002, "NATR": {"nested": 2001}},
285-
sub_indicators={"SATR": 2010, "SSATR": {"nested": 2011}},
286282
timestamp=datetime(2023, 6, 1, 9, 19),
287283
),
288284
]

tests/core/test_indicator.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -178,12 +178,8 @@ def test_candle_timerange(minimal_candles):
178178
close=6255,
179179
volume=31307,
180180
indicators={
181-
"ATR": 1900,
182181
"Fake_10": 100.0,
183-
"MinTR": 1902,
184-
"NATR": {"nested": 1901},
185182
},
186-
sub_indicators={"SATR": 1910, "SSATR": {"nested": 1911}},
187183
timestamp=datetime(2023, 6, 1, 9, 18),
188184
),
189185
Candle(
@@ -193,12 +189,8 @@ def test_candle_timerange(minimal_candles):
193189
close=13649,
194190
volume=15750,
195191
indicators={
196-
"ATR": 2000,
197192
"Fake_10": 100.0,
198-
"MinTR": 2002,
199-
"NATR": {"nested": 2001},
200193
},
201-
sub_indicators={"SATR": 2010, "SSATR": {"nested": 2011}},
202194
timestamp=datetime(2023, 6, 1, 9, 19),
203195
),
204196
]

0 commit comments

Comments
 (0)