Merge branch 'develop' into dev-merge-rl
This commit is contained in:
@@ -2282,7 +2282,7 @@ def tickers():
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def result(testdatadir):
|
||||
def dataframe_1m(testdatadir):
|
||||
with (testdatadir / 'UNITTEST_BTC-1m.json').open('r') as data_file:
|
||||
return ohlcv_to_dataframe(json.load(data_file), '1m', pair="UNITTEST/BTC",
|
||||
fill_missing=True)
|
||||
|
@@ -18,8 +18,8 @@ from tests.conftest import log_has, log_has_re
|
||||
from tests.data.test_history import _clean_test_file
|
||||
|
||||
|
||||
def test_dataframe_correct_columns(result):
|
||||
assert result.columns.tolist() == ['date', 'open', 'high', 'low', 'close', 'volume']
|
||||
def test_dataframe_correct_columns(dataframe_1m):
|
||||
assert dataframe_1m.columns.tolist() == ['date', 'open', 'high', 'low', 'close', 'volume']
|
||||
|
||||
|
||||
def test_ohlcv_to_dataframe(ohlcv_history_list, caplog):
|
||||
|
@@ -23,7 +23,7 @@ from tests.exchange.test_exchange import ccxt_exceptionhandlers
|
||||
def test_stoploss_order_binance(default_conf, mocker, limitratio, expected, side, trademode):
|
||||
api_mock = MagicMock()
|
||||
order_id = 'test_prod_buy_{}'.format(randint(0, 10 ** 6))
|
||||
order_type = 'stop_loss_limit' if trademode == TradingMode.SPOT else 'stop'
|
||||
order_type = 'stop_loss_limit' if trademode == TradingMode.SPOT else 'limit'
|
||||
|
||||
api_mock.create_order = MagicMock(return_value={
|
||||
'id': order_id,
|
||||
@@ -45,12 +45,15 @@ def test_stoploss_order_binance(default_conf, mocker, limitratio, expected, side
|
||||
amount=1,
|
||||
stop_price=190,
|
||||
side=side,
|
||||
order_types={'stoploss_on_exchange_limit_ratio': 1.05},
|
||||
order_types={'stoploss': 'limit', 'stoploss_on_exchange_limit_ratio': 1.05},
|
||||
leverage=1.0
|
||||
)
|
||||
|
||||
api_mock.create_order.reset_mock()
|
||||
order_types = {} if limitratio is None else {'stoploss_on_exchange_limit_ratio': limitratio}
|
||||
order_types = {'stoploss': 'limit'}
|
||||
if limitratio is not None:
|
||||
order_types.update({'stoploss_on_exchange_limit_ratio': limitratio})
|
||||
|
||||
order = exchange.stoploss(
|
||||
pair='ETH/BTC',
|
||||
amount=1,
|
||||
|
@@ -297,7 +297,7 @@ class TestCCXTExchange():
|
||||
def test_ccxt__async_get_candle_history(self, exchange):
|
||||
exchange, exchangename = exchange
|
||||
# For some weired reason, this test returns random lengths for bittrex.
|
||||
if not exchange._ft_has['ohlcv_has_history'] or exchangename in ('bittrex', 'gateio'):
|
||||
if not exchange._ft_has['ohlcv_has_history'] or exchangename in ('bittrex'):
|
||||
return
|
||||
pair = EXCHANGES[exchangename]['pair']
|
||||
timeframe = EXCHANGES[exchangename]['timeframe']
|
||||
|
@@ -472,7 +472,7 @@ def test_load_leverage_tiers_okx(default_conf, mocker, markets, tmpdir, caplog,
|
||||
|
||||
api_mock.fetch_market_leverage_tiers.call_count == 0
|
||||
# 2 day passes ...
|
||||
time_machine.move_to(datetime.now() + timedelta(days=2))
|
||||
time_machine.move_to(datetime.now() + timedelta(weeks=5))
|
||||
exchange.load_leverage_tiers()
|
||||
|
||||
assert log_has(logmsg, caplog)
|
||||
|
@@ -8,6 +8,7 @@ import pytest
|
||||
from freqtrade.configuration import TimeRange
|
||||
from freqtrade.data.dataprovider import DataProvider
|
||||
from freqtrade.freqai.data_kitchen import FreqaiDataKitchen
|
||||
from freqtrade.plugins.pairlistmanager import PairListManager
|
||||
from tests.conftest import get_patched_exchange, log_has_re
|
||||
from tests.freqai.conftest import get_patched_freqai_strategy
|
||||
|
||||
@@ -127,6 +128,7 @@ def test_extract_data_and_train_model_MultiTargets(mocker, freqai_conf, model):
|
||||
@pytest.mark.parametrize('model', [
|
||||
'LightGBMClassifier',
|
||||
'CatboostClassifier',
|
||||
'XGBoostClassifier',
|
||||
])
|
||||
def test_extract_data_and_train_model_Classifiers(mocker, freqai_conf, model):
|
||||
if is_arm() and model == 'CatboostClassifier':
|
||||
@@ -342,3 +344,62 @@ def test_principal_component_analysis(mocker, freqai_conf):
|
||||
assert Path(freqai.dk.data_path / f"{freqai.dk.model_filename}_pca_object.pkl")
|
||||
|
||||
shutil.rmtree(Path(freqai.dk.full_path))
|
||||
|
||||
|
||||
def test_plot_feature_importance(mocker, freqai_conf):
|
||||
|
||||
from freqtrade.freqai.utils import plot_feature_importance
|
||||
|
||||
freqai_conf.update({"timerange": "20180110-20180130"})
|
||||
freqai_conf.get("freqai", {}).get("feature_parameters", {}).update(
|
||||
{"princpial_component_analysis": "true"})
|
||||
|
||||
strategy = get_patched_freqai_strategy(mocker, freqai_conf)
|
||||
exchange = get_patched_exchange(mocker, freqai_conf)
|
||||
strategy.dp = DataProvider(freqai_conf, exchange)
|
||||
strategy.freqai_info = freqai_conf.get("freqai", {})
|
||||
freqai = strategy.freqai
|
||||
freqai.live = True
|
||||
freqai.dk = FreqaiDataKitchen(freqai_conf)
|
||||
timerange = TimeRange.parse_timerange("20180110-20180130")
|
||||
freqai.dd.load_all_pair_histories(timerange, freqai.dk)
|
||||
|
||||
freqai.dd.pair_dict = MagicMock()
|
||||
|
||||
data_load_timerange = TimeRange.parse_timerange("20180110-20180130")
|
||||
new_timerange = TimeRange.parse_timerange("20180120-20180130")
|
||||
|
||||
freqai.extract_data_and_train_model(
|
||||
new_timerange, "ADA/BTC", strategy, freqai.dk, data_load_timerange)
|
||||
|
||||
model = freqai.dd.load_data("ADA/BTC", freqai.dk)
|
||||
|
||||
plot_feature_importance(model, "ADA/BTC", freqai.dk)
|
||||
|
||||
assert Path(freqai.dk.data_path / f"{freqai.dk.model_filename}.html")
|
||||
|
||||
shutil.rmtree(Path(freqai.dk.full_path))
|
||||
|
||||
|
||||
@pytest.mark.parametrize('timeframes,corr_pairs', [
|
||||
(['5m'], ['ADA/BTC', 'DASH/BTC']),
|
||||
(['5m'], ['ADA/BTC', 'DASH/BTC', 'ETH/USDT']),
|
||||
(['5m', '15m'], ['ADA/BTC', 'DASH/BTC', 'ETH/USDT']),
|
||||
])
|
||||
def test_freqai_informative_pairs(mocker, freqai_conf, timeframes, corr_pairs):
|
||||
freqai_conf['freqai']['feature_parameters'].update({
|
||||
'include_timeframes': timeframes,
|
||||
'include_corr_pairlist': corr_pairs,
|
||||
|
||||
})
|
||||
strategy = get_patched_freqai_strategy(mocker, freqai_conf)
|
||||
exchange = get_patched_exchange(mocker, freqai_conf)
|
||||
pairlists = PairListManager(exchange, freqai_conf)
|
||||
strategy.dp = DataProvider(freqai_conf, exchange, pairlists)
|
||||
pairlist = strategy.dp.current_whitelist()
|
||||
|
||||
pairs_a = strategy.informative_pairs()
|
||||
assert len(pairs_a) == 0
|
||||
pairs_b = strategy.gather_informative_pairs()
|
||||
# we expect unique pairs * timeframes
|
||||
assert len(pairs_b) == len(set(pairlist + corr_pairs)) * len(timeframes)
|
||||
|
@@ -922,6 +922,45 @@ def test_in_strategy_auto_hyperopt_with_parallel(mocker, hyperopt_conf, tmpdir,
|
||||
hyperopt.start()
|
||||
|
||||
|
||||
def test_in_strategy_auto_hyperopt_per_epoch(mocker, hyperopt_conf, tmpdir, fee) -> None:
|
||||
patch_exchange(mocker)
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
(Path(tmpdir) / 'hyperopt_results').mkdir(parents=True)
|
||||
|
||||
hyperopt_conf.update({
|
||||
'strategy': 'HyperoptableStrategy',
|
||||
'user_data_dir': Path(tmpdir),
|
||||
'hyperopt_random_state': 42,
|
||||
'spaces': ['all'],
|
||||
'epochs': 3,
|
||||
'analyze_per_epoch': True,
|
||||
})
|
||||
go = mocker.patch('freqtrade.optimize.hyperopt.Hyperopt.generate_optimizer',
|
||||
return_value={
|
||||
'loss': 0.05,
|
||||
'results_explanation': 'foo result', 'params': {},
|
||||
'results_metrics': generate_result_metrics(),
|
||||
})
|
||||
hyperopt = Hyperopt(hyperopt_conf)
|
||||
hyperopt.backtesting.exchange.get_max_leverage = MagicMock(return_value=1.0)
|
||||
assert isinstance(hyperopt.custom_hyperopt, HyperOptAuto)
|
||||
assert isinstance(hyperopt.backtesting.strategy.buy_rsi, IntParameter)
|
||||
assert hyperopt.backtesting.strategy.bot_loop_started is True
|
||||
|
||||
assert hyperopt.backtesting.strategy.buy_rsi.in_space is True
|
||||
assert hyperopt.backtesting.strategy.buy_rsi.value == 35
|
||||
assert hyperopt.backtesting.strategy.sell_rsi.value == 74
|
||||
assert hyperopt.backtesting.strategy.protection_cooldown_lookback.value == 30
|
||||
buy_rsi_range = hyperopt.backtesting.strategy.buy_rsi.range
|
||||
assert isinstance(buy_rsi_range, range)
|
||||
# Range from 0 - 50 (inclusive)
|
||||
assert len(list(buy_rsi_range)) == 51
|
||||
|
||||
hyperopt.start()
|
||||
# backtesting should be called 3 times (once per epoch)
|
||||
assert go.call_count == 3
|
||||
|
||||
|
||||
def test_SKDecimal():
|
||||
space = SKDecimal(1, 2, decimals=2)
|
||||
assert 1.5 in space
|
||||
|
@@ -467,6 +467,10 @@ def test_VolumePairList_refresh_empty(mocker, markets_empty, whitelist_conf):
|
||||
{"method": "RangeStabilityFilter", "lookback_days": 10,
|
||||
"max_rate_of_change": 0.01, "refresh_period": 1440}],
|
||||
"BTC", []), # All removed because of max_rate_of_change being 0.017
|
||||
([{"method": "StaticPairList"},
|
||||
{"method": "RangeStabilityFilter", "lookback_days": 10,
|
||||
"min_rate_of_change": 0.018, "max_rate_of_change": 0.02, "refresh_period": 1440}],
|
||||
"BTC", []), # All removed - limits are above the highest change_rate
|
||||
([{"method": "StaticPairList"},
|
||||
{"method": "VolatilityFilter", "lookback_days": 3,
|
||||
"min_volatility": 0.002, "max_volatility": 0.004, "refresh_period": 1440}],
|
||||
|
@@ -82,6 +82,21 @@ def test_send_msg_telegram_disabled(mocker, default_conf, caplog) -> None:
|
||||
assert telegram_mock.call_count == 0
|
||||
|
||||
|
||||
def test_send_msg_telegram_error(mocker, default_conf, caplog) -> None:
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg', side_effect=ValueError())
|
||||
|
||||
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||
rpc_manager = RPCManager(freqtradebot)
|
||||
rpc_manager.send_msg({
|
||||
'type': RPCMessageType.STATUS,
|
||||
'status': 'test'
|
||||
})
|
||||
|
||||
assert log_has("Sending rpc message: {'type': status, 'status': 'test'}", caplog)
|
||||
assert log_has("Exception occurred within RPC module telegram", caplog)
|
||||
|
||||
|
||||
def test_process_msg_queue(mocker, default_conf, caplog) -> None:
|
||||
telegram_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg')
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram._init')
|
||||
|
@@ -959,6 +959,7 @@ def test_telegram_forceexit_handle(default_conf, update, ticker, fee,
|
||||
'gain': 'profit',
|
||||
'leverage': 1.0,
|
||||
'limit': 1.173e-05,
|
||||
'order_rate': 1.173e-05,
|
||||
'amount': 91.07468123,
|
||||
'order_type': 'limit',
|
||||
'open_rate': 1.098e-05,
|
||||
@@ -1031,6 +1032,7 @@ def test_telegram_force_exit_down_handle(default_conf, update, ticker, fee,
|
||||
'gain': 'loss',
|
||||
'leverage': 1.0,
|
||||
'limit': 1.043e-05,
|
||||
'order_rate': 1.043e-05,
|
||||
'amount': 91.07468123,
|
||||
'order_type': 'limit',
|
||||
'open_rate': 1.098e-05,
|
||||
@@ -1092,6 +1094,7 @@ def test_forceexit_all_handle(default_conf, update, ticker, fee, mocker) -> None
|
||||
'pair': 'ETH/BTC',
|
||||
'gain': 'loss',
|
||||
'leverage': 1.0,
|
||||
'order_rate': 1.099e-05,
|
||||
'limit': 1.099e-05,
|
||||
'amount': 91.07468123,
|
||||
'order_type': 'limit',
|
||||
@@ -1744,7 +1747,7 @@ def test_send_msg_enter_notification(default_conf, mocker, caplog, message_type,
|
||||
'exchange': 'Binance',
|
||||
'pair': 'ETH/BTC',
|
||||
'leverage': leverage,
|
||||
'limit': 1.099e-05,
|
||||
'open_rate': 1.099e-05,
|
||||
'order_type': 'limit',
|
||||
'direction': enter,
|
||||
'stake_amount': 0.01465333,
|
||||
@@ -1915,7 +1918,7 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None:
|
||||
'leverage': 1.0,
|
||||
'direction': 'Long',
|
||||
'gain': 'loss',
|
||||
'limit': 3.201e-05,
|
||||
'order_rate': 3.201e-05,
|
||||
'amount': 1333.3333333333335,
|
||||
'order_type': 'market',
|
||||
'open_rate': 7.5e-05,
|
||||
@@ -1950,7 +1953,7 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None:
|
||||
'pair': 'KEY/ETH',
|
||||
'direction': 'Long',
|
||||
'gain': 'loss',
|
||||
'limit': 3.201e-05,
|
||||
'order_rate': 3.201e-05,
|
||||
'amount': 1333.3333333333335,
|
||||
'order_type': 'market',
|
||||
'open_rate': 7.5e-05,
|
||||
@@ -1989,7 +1992,7 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None:
|
||||
'pair': 'KEY/ETH',
|
||||
'direction': 'Long',
|
||||
'gain': 'loss',
|
||||
'limit': 3.201e-05,
|
||||
'order_rate': 3.201e-05,
|
||||
'amount': 1333.3333333333335,
|
||||
'order_type': 'market',
|
||||
'open_rate': 7.5e-05,
|
||||
@@ -2162,7 +2165,7 @@ def test_send_msg_buy_notification_no_fiat(
|
||||
'exchange': 'Binance',
|
||||
'pair': 'ETH/BTC',
|
||||
'leverage': leverage,
|
||||
'limit': 1.099e-05,
|
||||
'open_rate': 1.099e-05,
|
||||
'order_type': 'limit',
|
||||
'direction': enter,
|
||||
'stake_amount': 0.01465333,
|
||||
@@ -2205,7 +2208,7 @@ def test_send_msg_sell_notification_no_fiat(
|
||||
'gain': 'loss',
|
||||
'leverage': leverage,
|
||||
'direction': direction,
|
||||
'limit': 3.201e-05,
|
||||
'order_rate': 3.201e-05,
|
||||
'amount': 1333.3333333333335,
|
||||
'order_type': 'limit',
|
||||
'open_rate': 7.5e-05,
|
||||
|
@@ -43,19 +43,6 @@ class freqai_test_multimodel_strat(IStrategy):
|
||||
)
|
||||
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_any_indicators(
|
||||
self, pair, df, tf, informative=None, set_generalized_indicators=False
|
||||
):
|
||||
|
@@ -43,19 +43,6 @@ class freqai_test_strat(IStrategy):
|
||||
)
|
||||
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_any_indicators(
|
||||
self, pair, df, tf, informative=None, set_generalized_indicators=False
|
||||
):
|
||||
|
@@ -21,14 +21,14 @@ def test_strategy_test_v3_structure():
|
||||
(True, 'short'),
|
||||
(False, 'long'),
|
||||
])
|
||||
def test_strategy_test_v3(result, fee, is_short, side):
|
||||
def test_strategy_test_v3(dataframe_1m, fee, is_short, side):
|
||||
strategy = StrategyTestV3({})
|
||||
|
||||
metadata = {'pair': 'ETH/BTC'}
|
||||
assert type(strategy.minimal_roi) is dict
|
||||
assert type(strategy.stoploss) is float
|
||||
assert type(strategy.timeframe) is str
|
||||
indicators = strategy.populate_indicators(result, metadata)
|
||||
indicators = strategy.populate_indicators(dataframe_1m, metadata)
|
||||
assert type(indicators) is DataFrame
|
||||
assert type(strategy.populate_buy_trend(indicators, metadata)) is DataFrame
|
||||
assert type(strategy.populate_sell_trend(indicators, metadata)) is DataFrame
|
||||
|
@@ -53,7 +53,7 @@ def test_search_all_strategies_with_failed():
|
||||
assert len(strategies) == 0
|
||||
|
||||
|
||||
def test_load_strategy(default_conf, result):
|
||||
def test_load_strategy(default_conf, dataframe_1m):
|
||||
default_conf.update({'strategy': 'SampleStrategy',
|
||||
'strategy_path': str(Path(__file__).parents[2] / 'freqtrade/templates')
|
||||
})
|
||||
@@ -61,22 +61,22 @@ def test_load_strategy(default_conf, result):
|
||||
assert isinstance(strategy.__source__, str)
|
||||
assert 'class SampleStrategy' in strategy.__source__
|
||||
assert isinstance(strategy.__file__, str)
|
||||
assert 'rsi' in strategy.advise_indicators(result, {'pair': 'ETH/BTC'})
|
||||
assert 'rsi' in strategy.advise_indicators(dataframe_1m, {'pair': 'ETH/BTC'})
|
||||
|
||||
|
||||
def test_load_strategy_base64(result, caplog, default_conf):
|
||||
def test_load_strategy_base64(dataframe_1m, caplog, default_conf):
|
||||
filepath = Path(__file__).parents[2] / 'freqtrade/templates/sample_strategy.py'
|
||||
encoded_string = urlsafe_b64encode(filepath.read_bytes()).decode("utf-8")
|
||||
default_conf.update({'strategy': 'SampleStrategy:{}'.format(encoded_string)})
|
||||
|
||||
strategy = StrategyResolver.load_strategy(default_conf)
|
||||
assert 'rsi' in strategy.advise_indicators(result, {'pair': 'ETH/BTC'})
|
||||
assert 'rsi' in strategy.advise_indicators(dataframe_1m, {'pair': 'ETH/BTC'})
|
||||
# Make sure strategy was loaded from base64 (using temp directory)!!
|
||||
assert log_has_re(r"Using resolved strategy SampleStrategy from '"
|
||||
r".*(/|\\).*(/|\\)SampleStrategy\.py'\.\.\.", caplog)
|
||||
|
||||
|
||||
def test_load_strategy_invalid_directory(result, caplog, default_conf):
|
||||
def test_load_strategy_invalid_directory(caplog, default_conf):
|
||||
default_conf['strategy'] = 'StrategyTestV3'
|
||||
extra_dir = Path.cwd() / 'some/path'
|
||||
with pytest.raises(OperationalException):
|
||||
@@ -104,7 +104,7 @@ def test_load_strategy_noname(default_conf):
|
||||
|
||||
@pytest.mark.filterwarnings("ignore:deprecated")
|
||||
@pytest.mark.parametrize('strategy_name', ['StrategyTestV2'])
|
||||
def test_strategy_pre_v3(result, default_conf, strategy_name):
|
||||
def test_strategy_pre_v3(dataframe_1m, default_conf, strategy_name):
|
||||
default_conf.update({'strategy': strategy_name})
|
||||
|
||||
strategy = StrategyResolver.load_strategy(default_conf)
|
||||
@@ -118,7 +118,7 @@ def test_strategy_pre_v3(result, default_conf, strategy_name):
|
||||
assert strategy.timeframe == '5m'
|
||||
assert default_conf['timeframe'] == '5m'
|
||||
|
||||
df_indicators = strategy.advise_indicators(result, metadata=metadata)
|
||||
df_indicators = strategy.advise_indicators(dataframe_1m, metadata=metadata)
|
||||
assert 'adx' in df_indicators
|
||||
|
||||
dataframe = strategy.advise_entry(df_indicators, metadata=metadata)
|
||||
@@ -417,24 +417,24 @@ def test_call_deprecated_function(default_conf):
|
||||
StrategyResolver.load_strategy(default_conf)
|
||||
|
||||
|
||||
def test_strategy_interface_versioning(result, default_conf):
|
||||
def test_strategy_interface_versioning(dataframe_1m, default_conf):
|
||||
default_conf.update({'strategy': 'StrategyTestV2'})
|
||||
strategy = StrategyResolver.load_strategy(default_conf)
|
||||
metadata = {'pair': 'ETH/BTC'}
|
||||
|
||||
assert strategy.INTERFACE_VERSION == 2
|
||||
|
||||
indicator_df = strategy.advise_indicators(result, metadata=metadata)
|
||||
indicator_df = strategy.advise_indicators(dataframe_1m, metadata=metadata)
|
||||
assert isinstance(indicator_df, DataFrame)
|
||||
assert 'adx' in indicator_df.columns
|
||||
|
||||
enterdf = strategy.advise_entry(result, metadata=metadata)
|
||||
enterdf = strategy.advise_entry(dataframe_1m, metadata=metadata)
|
||||
assert isinstance(enterdf, DataFrame)
|
||||
|
||||
assert 'buy' not in enterdf.columns
|
||||
assert 'enter_long' in enterdf.columns
|
||||
|
||||
exitdf = strategy.advise_exit(result, metadata=metadata)
|
||||
exitdf = strategy.advise_exit(dataframe_1m, metadata=metadata)
|
||||
assert isinstance(exitdf, DataFrame)
|
||||
assert 'sell' not in exitdf
|
||||
assert 'exit_long' in exitdf
|
||||
|
@@ -1427,6 +1427,7 @@ def test_handle_stoploss_on_exchange_trailing(
|
||||
trade.is_open = True
|
||||
trade.open_order_id = None
|
||||
trade.stoploss_order_id = 100
|
||||
trade.stoploss_last_update = arrow.utcnow().shift(minutes=-20).datetime
|
||||
|
||||
stoploss_order_hanging = MagicMock(return_value={
|
||||
'id': 100,
|
||||
@@ -1456,7 +1457,7 @@ def test_handle_stoploss_on_exchange_trailing(
|
||||
)
|
||||
|
||||
cancel_order_mock = MagicMock()
|
||||
stoploss_order_mock = MagicMock(return_value={'id': 13434334})
|
||||
stoploss_order_mock = MagicMock(return_value={'id': 'so1'})
|
||||
mocker.patch('freqtrade.exchange.Binance.cancel_stoploss_order', cancel_order_mock)
|
||||
mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss_order_mock)
|
||||
|
||||
@@ -1569,6 +1570,7 @@ def test_handle_stoploss_on_exchange_trailing_error(
|
||||
assert stoploss.call_count == 1
|
||||
|
||||
# Fail creating stoploss order
|
||||
trade.stoploss_last_update = arrow.utcnow().shift(minutes=-601).datetime
|
||||
caplog.clear()
|
||||
cancel_mock = mocker.patch("freqtrade.exchange.Binance.cancel_stoploss_order", MagicMock())
|
||||
mocker.patch("freqtrade.exchange.Binance.stoploss", side_effect=ExchangeError())
|
||||
@@ -1657,6 +1659,7 @@ def test_handle_stoploss_on_exchange_custom_stop(
|
||||
trade.is_open = True
|
||||
trade.open_order_id = None
|
||||
trade.stoploss_order_id = 100
|
||||
trade.stoploss_last_update = arrow.utcnow().shift(minutes=-601).datetime
|
||||
|
||||
stoploss_order_hanging = MagicMock(return_value={
|
||||
'id': 100,
|
||||
@@ -1685,7 +1688,7 @@ def test_handle_stoploss_on_exchange_custom_stop(
|
||||
)
|
||||
|
||||
cancel_order_mock = MagicMock()
|
||||
stoploss_order_mock = MagicMock(return_value={'id': 13434334})
|
||||
stoploss_order_mock = MagicMock(return_value={'id': 'so1'})
|
||||
mocker.patch('freqtrade.exchange.Binance.cancel_stoploss_order', cancel_order_mock)
|
||||
mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss_order_mock)
|
||||
|
||||
@@ -1727,8 +1730,7 @@ def test_handle_stoploss_on_exchange_custom_stop(
|
||||
assert freqtrade.handle_trade(trade) is True
|
||||
|
||||
|
||||
def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog,
|
||||
limit_order) -> None:
|
||||
def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, limit_order) -> None:
|
||||
|
||||
enter_order = limit_order['buy']
|
||||
exit_order = limit_order['sell']
|
||||
@@ -1784,6 +1786,7 @@ def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog,
|
||||
trade.is_open = True
|
||||
trade.open_order_id = None
|
||||
trade.stoploss_order_id = 100
|
||||
trade.stoploss_last_update = arrow.utcnow()
|
||||
|
||||
stoploss_order_hanging = MagicMock(return_value={
|
||||
'id': 100,
|
||||
@@ -3253,6 +3256,7 @@ def test_execute_trade_exit_up(default_conf_usdt, ticker_usdt, fee, ticker_usdt_
|
||||
'pair': 'ETH/USDT',
|
||||
'gain': 'profit',
|
||||
'limit': 2.0 if is_short else 2.2,
|
||||
'order_rate': 2.0 if is_short else 2.2,
|
||||
'amount': pytest.approx(amt),
|
||||
'order_type': 'limit',
|
||||
'buy_tag': None,
|
||||
@@ -3318,6 +3322,7 @@ def test_execute_trade_exit_down(default_conf_usdt, ticker_usdt, fee, ticker_usd
|
||||
'leverage': 1.0,
|
||||
'gain': 'loss',
|
||||
'limit': 2.2 if is_short else 2.01,
|
||||
'order_rate': 2.2 if is_short else 2.01,
|
||||
'amount': pytest.approx(29.70297029) if is_short else 30.0,
|
||||
'order_type': 'limit',
|
||||
'buy_tag': None,
|
||||
@@ -3402,6 +3407,7 @@ def test_execute_trade_exit_custom_exit_price(
|
||||
'leverage': 1.0,
|
||||
'gain': profit_or_loss,
|
||||
'limit': limit,
|
||||
'order_rate': limit,
|
||||
'amount': pytest.approx(amount),
|
||||
'order_type': 'limit',
|
||||
'buy_tag': None,
|
||||
@@ -3473,6 +3479,7 @@ def test_execute_trade_exit_down_stoploss_on_exchange_dry_run(
|
||||
'leverage': 1.0,
|
||||
'gain': 'loss',
|
||||
'limit': 2.02 if is_short else 1.98,
|
||||
'order_rate': 2.02 if is_short else 1.98,
|
||||
'amount': pytest.approx(29.70297029 if is_short else 30.0),
|
||||
'order_type': 'limit',
|
||||
'buy_tag': None,
|
||||
@@ -3738,6 +3745,7 @@ def test_execute_trade_exit_market_order(
|
||||
'leverage': 1.0,
|
||||
'gain': profit_or_loss,
|
||||
'limit': limit,
|
||||
'order_rate': limit,
|
||||
'amount': pytest.approx(amount),
|
||||
'order_type': 'market',
|
||||
'buy_tag': None,
|
||||
|
@@ -521,4 +521,4 @@ def test_dca_exiting(default_conf_usdt, ticker_usdt, fee, mocker, caplog) -> Non
|
||||
assert trade.orders[-1].ft_order_side == 'sell'
|
||||
assert pytest.approx(trade.stake_amount) == 40.198
|
||||
assert trade.is_open
|
||||
assert log_has_re('Amount to sell is 0.0 due to exchange limits - not selling.', caplog)
|
||||
assert log_has_re('Amount to exit is 0.0 due to exchange limits - not exiting.', caplog)
|
||||
|
@@ -184,8 +184,8 @@ def test_render_template_fallback(mocker):
|
||||
templatefile='subtemplates/indicators_does-not-exist.j2',)
|
||||
|
||||
val = render_template_with_fallback(
|
||||
templatefile='subtemplates/indicators_does-not-exist.j2',
|
||||
templatefallbackfile='subtemplates/indicators_minimal.j2',
|
||||
templatefile='strategy_subtemplates/indicators_does-not-exist.j2',
|
||||
templatefallbackfile='strategy_subtemplates/indicators_minimal.j2',
|
||||
)
|
||||
assert isinstance(val, str)
|
||||
assert 'if self.dp' in val
|
||||
|
Reference in New Issue
Block a user