Add test for backtesting _enter_trade
This commit is contained in:
		| @@ -22,8 +22,7 @@ from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds | |||||||
| from freqtrade.mixins import LoggingMixin | from freqtrade.mixins import LoggingMixin | ||||||
| from freqtrade.optimize.optimize_reports import (generate_backtest_stats, show_backtest_results, | from freqtrade.optimize.optimize_reports import (generate_backtest_stats, show_backtest_results, | ||||||
|                                                  store_backtest_stats) |                                                  store_backtest_stats) | ||||||
| from freqtrade.persistence import PairLocks, Trade | from freqtrade.persistence import LocalTrade, PairLocks, Trade | ||||||
| from freqtrade.persistence.models import LocalTrade |  | ||||||
| from freqtrade.plugins.pairlistmanager import PairListManager | from freqtrade.plugins.pairlistmanager import PairListManager | ||||||
| from freqtrade.plugins.protectionmanager import ProtectionManager | from freqtrade.plugins.protectionmanager import ProtectionManager | ||||||
| from freqtrade.resolvers import ExchangeResolver, StrategyResolver | from freqtrade.resolvers import ExchangeResolver, StrategyResolver | ||||||
| @@ -267,13 +266,13 @@ class Backtesting: | |||||||
|  |  | ||||||
|         return None |         return None | ||||||
|  |  | ||||||
|     def _enter_trade(self, pair: str, row, max_open_trades: int, |     def _enter_trade(self, pair: str, row: List, max_open_trades: int, | ||||||
|                      open_trade_count: int) -> Optional[LocalTrade]: |                      open_trade_count: int) -> Optional[LocalTrade]: | ||||||
|         try: |         try: | ||||||
|             stake_amount = self.wallets.get_trade_stake_amount( |             stake_amount = self.wallets.get_trade_stake_amount( | ||||||
|                 pair, max_open_trades - open_trade_count, None) |                 pair, max_open_trades - open_trade_count, None) | ||||||
|         except DependencyException: |         except DependencyException: | ||||||
|             stake_amount = 0 |             return None | ||||||
|         min_stake_amount = self.exchange.get_min_pair_stake_amount(pair, row[OPEN_IDX], -0.05) |         min_stake_amount = self.exchange.get_min_pair_stake_amount(pair, row[OPEN_IDX], -0.05) | ||||||
|         if stake_amount and (not min_stake_amount or stake_amount > min_stake_amount): |         if stake_amount and (not min_stake_amount or stake_amount > min_stake_amount): | ||||||
|             # print(f"{pair}, {stake_amount}") |             # print(f"{pair}, {stake_amount}") | ||||||
|   | |||||||
| @@ -301,7 +301,6 @@ def test_calculate_csum(testdatadir): | |||||||
|     assert csum_min1 == csum_min + 5 |     assert csum_min1 == csum_min + 5 | ||||||
|     assert csum_max1 == csum_max + 5 |     assert csum_max1 == csum_max + 5 | ||||||
|  |  | ||||||
|  |  | ||||||
|     with pytest.raises(ValueError, match='Trade dataframe empty.'): |     with pytest.raises(ValueError, match='Trade dataframe empty.'): | ||||||
|         csum_min, csum_max = calculate_csum(DataFrame()) |         csum_min, csum_max = calculate_csum(DataFrame()) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -17,8 +17,9 @@ from freqtrade.data.btanalysis import BT_DATA_COLUMNS, evaluate_result_multi | |||||||
| from freqtrade.data.converter import clean_ohlcv_dataframe | from freqtrade.data.converter import clean_ohlcv_dataframe | ||||||
| from freqtrade.data.dataprovider import DataProvider | from freqtrade.data.dataprovider import DataProvider | ||||||
| from freqtrade.data.history import get_timerange | from freqtrade.data.history import get_timerange | ||||||
| from freqtrade.exceptions import OperationalException | from freqtrade.exceptions import DependencyException, OperationalException | ||||||
| from freqtrade.optimize.backtesting import Backtesting | from freqtrade.optimize.backtesting import Backtesting | ||||||
|  | from freqtrade.persistence import LocalTrade | ||||||
| from freqtrade.resolvers import StrategyResolver | from freqtrade.resolvers import StrategyResolver | ||||||
| from freqtrade.state import RunMode | from freqtrade.state import RunMode | ||||||
| from freqtrade.strategy.interface import SellType | from freqtrade.strategy.interface import SellType | ||||||
| @@ -447,6 +448,44 @@ def test_backtesting_pairlist_list(default_conf, mocker, caplog, testdatadir, ti | |||||||
|         Backtesting(default_conf) |         Backtesting(default_conf) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def test_backtest__enter_trade(default_conf, fee, mocker, testdatadir) -> None: | ||||||
|  |     default_conf['ask_strategy']['use_sell_signal'] = False | ||||||
|  |     mocker.patch('freqtrade.exchange.Exchange.get_fee', fee) | ||||||
|  |     mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001) | ||||||
|  |     patch_exchange(mocker) | ||||||
|  |     default_conf['stake_amount'] = 'unlimited' | ||||||
|  |     backtesting = Backtesting(default_conf) | ||||||
|  |     pair = 'UNITTEST/BTC' | ||||||
|  |     row = [ | ||||||
|  |         pd.Timestamp(year=2020, month=1, day=1, hour=5, minute=0), | ||||||
|  |         1,  # Sell | ||||||
|  |         0.001,  # Open | ||||||
|  |         0.0011,  # Close | ||||||
|  |         0,  # Sell | ||||||
|  |         0.00099,  # Low | ||||||
|  |         0.0012,  # High | ||||||
|  |     ] | ||||||
|  |     trade = backtesting._enter_trade(pair, row=row, max_open_trades=2, open_trade_count=0) | ||||||
|  |     assert isinstance(trade, LocalTrade) | ||||||
|  |     assert trade.stake_amount == 495 | ||||||
|  |  | ||||||
|  |     trade = backtesting._enter_trade(pair, row=row, max_open_trades=2, open_trade_count=2) | ||||||
|  |     assert trade is None | ||||||
|  |  | ||||||
|  |     # Stake-amount too high! | ||||||
|  |     mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=600.0) | ||||||
|  |  | ||||||
|  |     trade = backtesting._enter_trade(pair, row=row, max_open_trades=2, open_trade_count=0) | ||||||
|  |     assert trade is None | ||||||
|  |  | ||||||
|  |     # Stake-amount too high! | ||||||
|  |     mocker.patch("freqtrade.wallets.Wallets.get_trade_stake_amount", | ||||||
|  |                  side_effect=DependencyException) | ||||||
|  |  | ||||||
|  |     trade = backtesting._enter_trade(pair, row=row, max_open_trades=2, open_trade_count=0) | ||||||
|  |     assert trade is None | ||||||
|  |  | ||||||
|  |  | ||||||
| def test_backtest_one(default_conf, fee, mocker, testdatadir) -> None: | def test_backtest_one(default_conf, fee, mocker, testdatadir) -> None: | ||||||
|     default_conf['ask_strategy']['use_sell_signal'] = False |     default_conf['ask_strategy']['use_sell_signal'] = False | ||||||
|     mocker.patch('freqtrade.exchange.Exchange.get_fee', fee) |     mocker.patch('freqtrade.exchange.Exchange.get_fee', fee) | ||||||
|   | |||||||
| @@ -1,12 +1,11 @@ | |||||||
| # pragma pylint: disable=missing-docstring, C0103 | # pragma pylint: disable=missing-docstring, C0103 | ||||||
| from types import FunctionType |  | ||||||
| import logging | import logging | ||||||
|  | from types import FunctionType | ||||||
| from unittest.mock import MagicMock | from unittest.mock import MagicMock | ||||||
|  |  | ||||||
| import arrow | import arrow | ||||||
| import pytest | import pytest | ||||||
| from sqlalchemy import create_engine | from sqlalchemy import create_engine | ||||||
| from sqlalchemy.sql.schema import Column |  | ||||||
|  |  | ||||||
| from freqtrade import constants | from freqtrade import constants | ||||||
| from freqtrade.exceptions import DependencyException, OperationalException | from freqtrade.exceptions import DependencyException, OperationalException | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user