ensure pytest passes
This commit is contained in:
parent
fb2d190865
commit
dac07c5609
30
freqtrade/freqai/spice_rack/test_config.json
Normal file
30
freqtrade/freqai/spice_rack/test_config.json
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
|
||||||
|
"freqai": {
|
||||||
|
"enabled": true,
|
||||||
|
"purge_old_models": true,
|
||||||
|
"train_period_days": 4,
|
||||||
|
"backtest_period_days": 2,
|
||||||
|
"identifier": "spicy-id",
|
||||||
|
"feature_parameters": {
|
||||||
|
"include_timeframes": [
|
||||||
|
"5m"
|
||||||
|
],
|
||||||
|
"include_corr_pairlist": ["ADA/BTC", "DASH/BTC"],
|
||||||
|
"label_period_candles": 20,
|
||||||
|
"include_shifted_candles": 1,
|
||||||
|
"DI_threshold": 0.9,
|
||||||
|
"weight_factor": 0.9,
|
||||||
|
"indicator_periods_candles": [
|
||||||
|
10
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"data_split_parameters": {
|
||||||
|
"test_size": 0,
|
||||||
|
"random_state": 1
|
||||||
|
},
|
||||||
|
"model_training_parameters": {
|
||||||
|
"n_estimators": 800
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
115
tests/strategy/strats/freqai_test_spice_rack.py
Normal file
115
tests/strategy/strats/freqai_test_spice_rack.py
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
import logging
|
||||||
|
from functools import reduce
|
||||||
|
|
||||||
|
import pandas as pd
|
||||||
|
import talib.abstract as ta
|
||||||
|
from pandas import DataFrame
|
||||||
|
|
||||||
|
from freqtrade.strategy import DecimalParameter, IntParameter, IStrategy, merge_informative_pair
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class freqai_test_spice_rack(IStrategy):
|
||||||
|
"""
|
||||||
|
Test strategy - used for testing freqAI functionalities.
|
||||||
|
DO not use in production.
|
||||||
|
"""
|
||||||
|
|
||||||
|
minimal_roi = {"0": 0.1, "240": -1}
|
||||||
|
|
||||||
|
plot_config = {
|
||||||
|
"main_plot": {},
|
||||||
|
"subplots": {
|
||||||
|
"prediction": {"prediction": {"color": "blue"}},
|
||||||
|
"target_roi": {
|
||||||
|
"target_roi": {"color": "brown"},
|
||||||
|
},
|
||||||
|
"do_predict": {
|
||||||
|
"do_predict": {"color": "brown"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
process_only_new_candles = True
|
||||||
|
stoploss = -0.05
|
||||||
|
use_exit_signal = True
|
||||||
|
startup_candle_count: int = 300
|
||||||
|
can_short = False
|
||||||
|
|
||||||
|
linear_roi_offset = DecimalParameter(
|
||||||
|
0.00, 0.02, default=0.005, space="sell", optimize=False, load=True
|
||||||
|
)
|
||||||
|
max_roi_time_long = IntParameter(0, 800, default=400, space="sell", optimize=False, load=True)
|
||||||
|
|
||||||
|
def informative_pairs(self):
|
||||||
|
whitelist_pairs = self.dp.current_whitelist()
|
||||||
|
corr_pairs = self.config["freqai"]["feature_parameters"]["include_corr_pairlist"]
|
||||||
|
informative_pairs = []
|
||||||
|
for tf in self.config["freqai"]["feature_parameters"]["include_timeframes"]:
|
||||||
|
for pair in whitelist_pairs:
|
||||||
|
informative_pairs.append((pair, tf))
|
||||||
|
for pair in corr_pairs:
|
||||||
|
if pair in whitelist_pairs:
|
||||||
|
continue # avoid duplication
|
||||||
|
informative_pairs.append((pair, tf))
|
||||||
|
return informative_pairs
|
||||||
|
|
||||||
|
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||||
|
|
||||||
|
# Example of how to use the freqai.spice_rack. User treats it the same as any
|
||||||
|
# typical talib indicator. They set a new column in their dataframe
|
||||||
|
|
||||||
|
dataframe['dissimilarity_index'] = self.freqai.spice_rack(
|
||||||
|
'DI_values', dataframe, metadata, self)
|
||||||
|
dataframe['maxima'] = self.freqai.spice_rack(
|
||||||
|
'&s-maxima', dataframe, metadata, self)
|
||||||
|
dataframe['minima'] = self.freqai.spice_rack(
|
||||||
|
'&s-minima', dataframe, metadata, self)
|
||||||
|
self.freqai.close_spice_rack() # user must close the spicerack
|
||||||
|
|
||||||
|
dataframe['rsi'] = ta.RSI(dataframe)
|
||||||
|
|
||||||
|
return dataframe
|
||||||
|
|
||||||
|
def populate_entry_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
|
||||||
|
|
||||||
|
df.loc[
|
||||||
|
(
|
||||||
|
(df['tema'] > df['tema'].shift(1)) & # Guard: tema is raising
|
||||||
|
(df['dissimilarity_index'] < 1) &
|
||||||
|
(df['maxima'] > 0.1)
|
||||||
|
),
|
||||||
|
'enter_long'] = 1
|
||||||
|
|
||||||
|
df.loc[
|
||||||
|
(
|
||||||
|
(df['tema'] < df['tema'].shift(1)) & # Guard: tema is falling
|
||||||
|
(df['dissimilarity_index'] < 1) &
|
||||||
|
(df['minima'] > 0.1)
|
||||||
|
),
|
||||||
|
'enter_short'] = 1
|
||||||
|
|
||||||
|
return df
|
||||||
|
|
||||||
|
def populate_exit_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
|
||||||
|
|
||||||
|
df.loc[
|
||||||
|
(
|
||||||
|
(df['tema'] < df['tema'].shift(1)) & # Guard: tema is falling
|
||||||
|
(df['dissimilarity_index'] < 1) &
|
||||||
|
(df['maxima'] > 0.1)
|
||||||
|
),
|
||||||
|
|
||||||
|
'exit_long'] = 1
|
||||||
|
|
||||||
|
df.loc[
|
||||||
|
(
|
||||||
|
(df['tema'] > df['tema'].shift(1)) & # Guard: tema is raising
|
||||||
|
(df['dissimilarity_index'] < 1) &
|
||||||
|
(df['minima'] > 0.1)
|
||||||
|
),
|
||||||
|
'exit_short'] = 1
|
||||||
|
|
||||||
|
return df
|
@ -34,7 +34,7 @@ def test_search_all_strategies_no_failed():
|
|||||||
directory = Path(__file__).parent / "strats"
|
directory = Path(__file__).parent / "strats"
|
||||||
strategies = StrategyResolver.search_all_objects(directory, enum_failed=False)
|
strategies = StrategyResolver.search_all_objects(directory, enum_failed=False)
|
||||||
assert isinstance(strategies, list)
|
assert isinstance(strategies, list)
|
||||||
assert len(strategies) == 9
|
assert len(strategies) == 10
|
||||||
assert isinstance(strategies[0], dict)
|
assert isinstance(strategies[0], dict)
|
||||||
|
|
||||||
|
|
||||||
@ -42,10 +42,10 @@ def test_search_all_strategies_with_failed():
|
|||||||
directory = Path(__file__).parent / "strats"
|
directory = Path(__file__).parent / "strats"
|
||||||
strategies = StrategyResolver.search_all_objects(directory, enum_failed=True)
|
strategies = StrategyResolver.search_all_objects(directory, enum_failed=True)
|
||||||
assert isinstance(strategies, list)
|
assert isinstance(strategies, list)
|
||||||
assert len(strategies) == 10
|
assert len(strategies) == 11
|
||||||
# with enum_failed=True search_all_objects() shall find 2 good strategies
|
# with enum_failed=True search_all_objects() shall find 2 good strategies
|
||||||
# and 1 which fails to load
|
# and 1 which fails to load
|
||||||
assert len([x for x in strategies if x['class'] is not None]) == 9
|
assert len([x for x in strategies if x['class'] is not None]) == 10
|
||||||
assert len([x for x in strategies if x['class'] is None]) == 1
|
assert len([x for x in strategies if x['class'] is None]) == 1
|
||||||
|
|
||||||
directory = Path(__file__).parent / "strats_nonexistingdir"
|
directory = Path(__file__).parent / "strats_nonexistingdir"
|
||||||
|
Loading…
Reference in New Issue
Block a user