added checks for python3.8 or lower since ast_comments.unparse() needs python 3.9 or higher.
testing with python 3.8 would make the build fail tests, skipping it there.
This commit is contained in:
		| @@ -1,4 +1,5 @@ | ||||
| import logging | ||||
| import sys | ||||
| import time | ||||
| from pathlib import Path | ||||
| from typing import Any, Dict | ||||
| @@ -19,28 +20,34 @@ def start_strategy_update(args: Dict[str, Any]) -> None: | ||||
|     :return: None | ||||
|     """ | ||||
|  | ||||
|     config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) | ||||
|     if sys.version_info <= (3, 8): | ||||
|         print("This code requires Python 3.9 or higher. " | ||||
|               "We cannot continue. " | ||||
|               "Please upgrade your python version to use this command.") | ||||
|  | ||||
|     strategy_objs = StrategyResolver.search_all_objects( | ||||
|         config, enum_failed=False, recursive=config.get('recursive_strategy_search', False)) | ||||
|  | ||||
|     filtered_strategy_objs = [] | ||||
|     if 'strategy_list' in args: | ||||
|         for args_strategy in args['strategy_list']: | ||||
|             for strategy_obj in strategy_objs: | ||||
|                 if (strategy_obj['name'] == args_strategy | ||||
|                         and strategy_obj not in filtered_strategy_objs): | ||||
|                     filtered_strategy_objs.append(strategy_obj) | ||||
|                     break | ||||
|  | ||||
|         for filtered_strategy_obj in filtered_strategy_objs: | ||||
|             start_conversion(filtered_strategy_obj, config) | ||||
|     else: | ||||
|         processed_locations = set() | ||||
|         for strategy_obj in strategy_objs: | ||||
|             if strategy_obj['location'] not in processed_locations: | ||||
|                 processed_locations.add(strategy_obj['location']) | ||||
|                 start_conversion(strategy_obj, config) | ||||
|         config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) | ||||
|  | ||||
|         strategy_objs = StrategyResolver.search_all_objects( | ||||
|             config, enum_failed=False, recursive=config.get('recursive_strategy_search', False)) | ||||
|  | ||||
|         filtered_strategy_objs = [] | ||||
|         if 'strategy_list' in args: | ||||
|             for args_strategy in args['strategy_list']: | ||||
|                 for strategy_obj in strategy_objs: | ||||
|                     if (strategy_obj['name'] == args_strategy | ||||
|                             and strategy_obj not in filtered_strategy_objs): | ||||
|                         filtered_strategy_objs.append(strategy_obj) | ||||
|                         break | ||||
|  | ||||
|             for filtered_strategy_obj in filtered_strategy_objs: | ||||
|                 start_conversion(filtered_strategy_obj, config) | ||||
|         else: | ||||
|             processed_locations = set() | ||||
|             for strategy_obj in strategy_objs: | ||||
|                 if strategy_obj['location'] not in processed_locations: | ||||
|                     processed_locations.add(strategy_obj['location']) | ||||
|                     start_conversion(strategy_obj, config) | ||||
|  | ||||
|  | ||||
| def start_conversion(strategy_obj, config): | ||||
|   | ||||
| @@ -1,130 +1,135 @@ | ||||
| # pragma pylint: disable=missing-docstring, protected-access, invalid-name | ||||
|  | ||||
| import sys | ||||
|  | ||||
| from freqtrade.strategy.strategyupdater import StrategyUpdater | ||||
|  | ||||
|  | ||||
| def test_strategy_updater(default_conf, caplog) -> None: | ||||
|     instance_strategy_updater = StrategyUpdater() | ||||
|     modified_code1 = instance_strategy_updater.update_code(""" | ||||
| class testClass(IStrategy): | ||||
|     def populate_buy_trend(): | ||||
|         pass | ||||
|     def populate_sell_trend(): | ||||
|         pass | ||||
|     def check_buy_timeout(): | ||||
|         pass | ||||
|     def check_sell_timeout(): | ||||
|         pass | ||||
|     def custom_sell(): | ||||
|         pass | ||||
| """) | ||||
|     modified_code2 = instance_strategy_updater.update_code(""" | ||||
| ticker_interval = '15m' | ||||
| buy_some_parameter = IntParameter(space='buy') | ||||
| sell_some_parameter = IntParameter(space='sell') | ||||
| """) | ||||
|     modified_code3 = instance_strategy_updater.update_code(""" | ||||
| use_sell_signal = True | ||||
| sell_profit_only = True | ||||
| sell_profit_offset = True | ||||
| ignore_roi_if_buy_signal = True | ||||
| forcebuy_enable = True | ||||
| """) | ||||
|     modified_code4 = instance_strategy_updater.update_code(""" | ||||
| dataframe.loc[reduce(lambda x, y: x & y, conditions), ["buy", "buy_tag"]] = (1, "buy_signal_1") | ||||
| dataframe.loc[reduce(lambda x, y: x & y, conditions), 'sell'] = 1 | ||||
| """) | ||||
|     modified_code5 = instance_strategy_updater.update_code(""" | ||||
| def confirm_trade_exit(sell_reason: str): | ||||
|     pass | ||||
|     if sys.version_info <= (3, 8): | ||||
|         print("skipped tests since python version is 3.8 or lower.") | ||||
|     else: | ||||
|         instance_strategy_updater = StrategyUpdater() | ||||
|         modified_code1 = instance_strategy_updater.update_code(""" | ||||
|     class testClass(IStrategy): | ||||
|         def populate_buy_trend(): | ||||
|             pass | ||||
|         def populate_sell_trend(): | ||||
|             pass | ||||
|         def check_buy_timeout(): | ||||
|             pass | ||||
|         def check_sell_timeout(): | ||||
|             pass | ||||
|         def custom_sell(): | ||||
|             pass | ||||
|     """) | ||||
|     modified_code6 = instance_strategy_updater.update_code(""" | ||||
| order_time_in_force = { | ||||
|     'buy': 'gtc', | ||||
|     'sell': 'ioc' | ||||
| } | ||||
| order_types = { | ||||
|     'buy': 'limit', | ||||
|     'sell': 'market', | ||||
|     'stoploss': 'market', | ||||
|     'stoploss_on_exchange': False | ||||
| } | ||||
| unfilledtimeout = { | ||||
|     'buy': 1, | ||||
|     'sell': 2 | ||||
| } | ||||
| """) | ||||
|  | ||||
|     modified_code7 = instance_strategy_updater.update_code(""" | ||||
| def confirm_trade_exit(sell_reason): | ||||
|     if (sell_reason == 'stop_loss'): | ||||
|         modified_code2 = instance_strategy_updater.update_code(""" | ||||
|     ticker_interval = '15m' | ||||
|     buy_some_parameter = IntParameter(space='buy') | ||||
|     sell_some_parameter = IntParameter(space='sell') | ||||
|     """) | ||||
|         modified_code3 = instance_strategy_updater.update_code(""" | ||||
|     use_sell_signal = True | ||||
|     sell_profit_only = True | ||||
|     sell_profit_offset = True | ||||
|     ignore_roi_if_buy_signal = True | ||||
|     forcebuy_enable = True | ||||
|     """) | ||||
|         modified_code4 = instance_strategy_updater.update_code(""" | ||||
|     dataframe.loc[reduce(lambda x, y: x & y, conditions), ["buy", "buy_tag"]] = (1, "buy_signal_1") | ||||
|     dataframe.loc[reduce(lambda x, y: x & y, conditions), 'sell'] = 1 | ||||
|     """) | ||||
|         modified_code5 = instance_strategy_updater.update_code(""" | ||||
|     def confirm_trade_exit(sell_reason: str): | ||||
|         pass | ||||
| """) | ||||
|     modified_code8 = instance_strategy_updater.update_code(""" | ||||
| sell_reason == 'sell_signal' | ||||
| sell_reason == 'force_sell' | ||||
| sell_reason == 'emergency_sell' | ||||
| """) | ||||
|     modified_code9 = instance_strategy_updater.update_code(""" | ||||
| # This is the 1st comment | ||||
| import talib.abstract as ta | ||||
| # This is the 2nd comment | ||||
| import freqtrade.vendor.qtpylib.indicators as qtpylib | ||||
|  | ||||
|  | ||||
| class someStrategy(IStrategy): | ||||
|     # This is the 3rd comment | ||||
|     # This attribute will be overridden if the config file contains "minimal_roi" | ||||
|     minimal_roi = { | ||||
|         "0": 0.50 | ||||
|         """) | ||||
|         modified_code6 = instance_strategy_updater.update_code(""" | ||||
|     order_time_in_force = { | ||||
|         'buy': 'gtc', | ||||
|         'sell': 'ioc' | ||||
|     } | ||||
|     order_types = { | ||||
|         'buy': 'limit', | ||||
|         'sell': 'market', | ||||
|         'stoploss': 'market', | ||||
|         'stoploss_on_exchange': False | ||||
|     } | ||||
|     unfilledtimeout = { | ||||
|         'buy': 1, | ||||
|         'sell': 2 | ||||
|     } | ||||
|     """) | ||||
|  | ||||
|     # This is the 4th comment | ||||
|     stoploss = -0.1 | ||||
| """) | ||||
|     # currently still missing: | ||||
|     # Webhook terminology, Telegram notification settings, Strategy/Config settings | ||||
|         modified_code7 = instance_strategy_updater.update_code(""" | ||||
|     def confirm_trade_exit(sell_reason): | ||||
|         if (sell_reason == 'stop_loss'): | ||||
|             pass | ||||
|     """) | ||||
|         modified_code8 = instance_strategy_updater.update_code(""" | ||||
|     sell_reason == 'sell_signal' | ||||
|     sell_reason == 'force_sell' | ||||
|     sell_reason == 'emergency_sell' | ||||
|     """) | ||||
|         modified_code9 = instance_strategy_updater.update_code(""" | ||||
|     # This is the 1st comment | ||||
|     import talib.abstract as ta | ||||
|     # This is the 2nd comment | ||||
|     import freqtrade.vendor.qtpylib.indicators as qtpylib | ||||
|  | ||||
|     assert "populate_entry_trend" in modified_code1 | ||||
|     assert "populate_exit_trend" in modified_code1 | ||||
|     assert "check_entry_timeout" in modified_code1 | ||||
|     assert "check_exit_timeout" in modified_code1 | ||||
|     assert "custom_exit" in modified_code1 | ||||
|     assert "INTERFACE_VERSION = 3" in modified_code1 | ||||
|  | ||||
|     assert "timeframe" in modified_code2 | ||||
|     # check for not editing hyperopt spaces | ||||
|     assert "space='buy'" in modified_code2 | ||||
|     assert "space='sell'" in modified_code2 | ||||
|     class someStrategy(IStrategy): | ||||
|         # This is the 3rd comment | ||||
|         # This attribute will be overridden if the config file contains "minimal_roi" | ||||
|         minimal_roi = { | ||||
|             "0": 0.50 | ||||
|         } | ||||
|  | ||||
|     assert "use_exit_signal" in modified_code3 | ||||
|     assert "exit_profit_only" in modified_code3 | ||||
|     assert "exit_profit_offset" in modified_code3 | ||||
|     assert "ignore_roi_if_entry_signal" in modified_code3 | ||||
|     assert "force_entry_enable" in modified_code3 | ||||
|         # This is the 4th comment | ||||
|         stoploss = -0.1 | ||||
|     """) | ||||
|         # currently still missing: | ||||
|         # Webhook terminology, Telegram notification settings, Strategy/Config settings | ||||
|  | ||||
|     assert "enter_long" in modified_code4 | ||||
|     assert "exit_long" in modified_code4 | ||||
|     assert "enter_tag" in modified_code4 | ||||
|         assert "populate_entry_trend" in modified_code1 | ||||
|         assert "populate_exit_trend" in modified_code1 | ||||
|         assert "check_entry_timeout" in modified_code1 | ||||
|         assert "check_exit_timeout" in modified_code1 | ||||
|         assert "custom_exit" in modified_code1 | ||||
|         assert "INTERFACE_VERSION = 3" in modified_code1 | ||||
|  | ||||
|     assert "exit_reason" in modified_code5 | ||||
|         assert "timeframe" in modified_code2 | ||||
|         # check for not editing hyperopt spaces | ||||
|         assert "space='buy'" in modified_code2 | ||||
|         assert "space='sell'" in modified_code2 | ||||
|  | ||||
|     assert "'entry': 'gtc'" in modified_code6 | ||||
|     assert "'exit': 'ioc'" in modified_code6 | ||||
|     assert "'entry': 'limit'" in modified_code6 | ||||
|     assert "'exit': 'market'" in modified_code6 | ||||
|     assert "'entry': 1" in modified_code6 | ||||
|     assert "'exit': 2" in modified_code6 | ||||
|         assert "use_exit_signal" in modified_code3 | ||||
|         assert "exit_profit_only" in modified_code3 | ||||
|         assert "exit_profit_offset" in modified_code3 | ||||
|         assert "ignore_roi_if_entry_signal" in modified_code3 | ||||
|         assert "force_entry_enable" in modified_code3 | ||||
|  | ||||
|     assert "exit_reason" in modified_code7 | ||||
|     assert "exit_reason == 'stop_loss'" in modified_code7 | ||||
|         assert "enter_long" in modified_code4 | ||||
|         assert "exit_long" in modified_code4 | ||||
|         assert "enter_tag" in modified_code4 | ||||
|  | ||||
|     # those tests currently don't work, next in line. | ||||
|     assert "exit_signal" in modified_code8 | ||||
|     assert "exit_reason" in modified_code8 | ||||
|     assert "force_exit" in modified_code8 | ||||
|     assert "emergency_exit" in modified_code8 | ||||
|         assert "exit_reason" in modified_code5 | ||||
|  | ||||
|     assert "This is the 1st comment" in modified_code9 | ||||
|     assert "This is the 2nd comment" in modified_code9 | ||||
|     assert "This is the 3rd comment" in modified_code9 | ||||
|         assert "'entry': 'gtc'" in modified_code6 | ||||
|         assert "'exit': 'ioc'" in modified_code6 | ||||
|         assert "'entry': 'limit'" in modified_code6 | ||||
|         assert "'exit': 'market'" in modified_code6 | ||||
|         assert "'entry': 1" in modified_code6 | ||||
|         assert "'exit': 2" in modified_code6 | ||||
|  | ||||
|         assert "exit_reason" in modified_code7 | ||||
|         assert "exit_reason == 'stop_loss'" in modified_code7 | ||||
|  | ||||
|         # those tests currently don't work, next in line. | ||||
|         assert "exit_signal" in modified_code8 | ||||
|         assert "exit_reason" in modified_code8 | ||||
|         assert "force_exit" in modified_code8 | ||||
|         assert "emergency_exit" in modified_code8 | ||||
|  | ||||
|         assert "This is the 1st comment" in modified_code9 | ||||
|         assert "This is the 2nd comment" in modified_code9 | ||||
|         assert "This is the 3rd comment" in modified_code9 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user