Skip to content

Commit 52374b3

Browse files
committed
adds numpy.NaN => np.nan conversion to the strategy updater since numpy2.0 changed that, now it throws errors.
To adjust more of those we can now easily expand on it. This includes aliases for imports as well.
1 parent 3ecc9c3 commit 52374b3

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

freqtrade/strategy/strategyupdater.py

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@ class StrategyUpdater:
3939
"sell": "exit",
4040
}
4141

42+
# Update function names.
43+
# example: `np.NaN` was removed in the NumPy 2.0 release. Use `np.nan` instead.
44+
module_replacements = {
45+
"numpy": {
46+
"aliases": set(),
47+
"replacements": [
48+
("NaN", "nan"),
49+
],
50+
}
51+
}
52+
4253
# create a dictionary that maps the old column names to the new ones
4354
rename_dict = {"buy": "enter_long", "sell": "exit_long", "buy_tag": "enter_tag"}
4455

@@ -153,16 +164,24 @@ def visit_arguments(self, node):
153164
def visit_Name(self, node):
154165
# if the name is in the mapping, update it
155166
node.id = self.check_dict(StrategyUpdater.name_mapping, node.id)
167+
168+
for mod, info in StrategyUpdater.module_replacements.items():
169+
for old_attr, new_attr in info["replacements"]:
170+
if node.id == old_attr:
171+
node.id = new_attr
156172
return node
157173

158174
def visit_Import(self, node):
159-
# do not update the names in import statements
175+
for alias in node.names:
176+
if alias.name in StrategyUpdater.module_replacements:
177+
as_name = alias.asname or alias.name
178+
StrategyUpdater.module_replacements[alias.name]["aliases"].add(as_name)
160179
return node
161180

162181
def visit_ImportFrom(self, node):
163-
# if hasattr(node, "module"):
164-
# if node.module == "freqtrade.strategy.hyper":
165-
# node.module = "freqtrade.strategy"
182+
if node.module in StrategyUpdater.module_replacements:
183+
mod = node.module
184+
StrategyUpdater.module_replacements[node.module]["aliases"].add(mod)
166185
return node
167186

168187
def visit_If(self, node: ast_comments.If):
@@ -182,6 +201,12 @@ def visit_Attribute(self, node):
182201
and node.attr == "nr_of_successful_buys"
183202
):
184203
node.attr = "nr_of_successful_entries"
204+
if isinstance(node.value, ast_comments.Name):
205+
for mod, info in StrategyUpdater.module_replacements.items():
206+
if node.value.id in info["aliases"]:
207+
for old_attr, new_attr in info["replacements"]:
208+
if node.attr == old_attr:
209+
node.attr = new_attr
185210
return node
186211

187212
def visit_ClassDef(self, node):

tests/test_strategy_updater.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,10 @@ def test_strategy_updater_methods(default_conf, caplog) -> None:
4242
instance_strategy_updater = StrategyUpdater()
4343
modified_code1 = instance_strategy_updater.update_code(
4444
"""
45+
import numpy as np
4546
class testClass(IStrategy):
4647
def populate_buy_trend():
48+
some_variable = np.NaN
4749
pass
4850
def populate_sell_trend():
4951
pass
@@ -62,6 +64,7 @@ def custom_sell():
6264
assert "check_exit_timeout" in modified_code1
6365
assert "custom_exit" in modified_code1
6466
assert "INTERFACE_VERSION = 3" in modified_code1
67+
assert "np.nan" in modified_code1
6568

6669

6770
def test_strategy_updater_params(default_conf, caplog) -> None:

0 commit comments

Comments
 (0)