check for max stake limit in freqtradebot and backtesting
This commit is contained in:
parent
55d91f018f
commit
6b6b35ac1c
@ -543,12 +543,19 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
min_stake_amount = self.exchange.get_min_pair_stake_amount(trade.pair,
|
min_stake_amount = self.exchange.get_min_pair_stake_amount(trade.pair,
|
||||||
current_rate,
|
current_rate,
|
||||||
self.strategy.stoploss)
|
self.strategy.stoploss)
|
||||||
max_stake_amount = self.wallets.get_available_stake_amount()
|
max_stake_amount = self.exchange.get_max_pair_stake_amount(trade.pair,
|
||||||
|
current_rate,
|
||||||
|
self.strategy.stoploss)
|
||||||
|
if max_stake_amount is None:
|
||||||
|
# * Should never be executed
|
||||||
|
raise OperationalException(f'max_stake_amount is None for {trade}')
|
||||||
|
stake_available = self.wallets.get_available_stake_amount()
|
||||||
logger.debug(f"Calling adjust_trade_position for pair {trade.pair}")
|
logger.debug(f"Calling adjust_trade_position for pair {trade.pair}")
|
||||||
stake_amount = strategy_safe_wrapper(self.strategy.adjust_trade_position,
|
stake_amount = strategy_safe_wrapper(self.strategy.adjust_trade_position,
|
||||||
default_retval=None)(
|
default_retval=None)(
|
||||||
trade=trade, current_time=datetime.now(timezone.utc), current_rate=current_rate,
|
trade=trade, current_time=datetime.now(timezone.utc), current_rate=current_rate,
|
||||||
current_profit=current_profit, min_stake=min_stake_amount, max_stake=max_stake_amount)
|
current_profit=current_profit, min_stake=min_stake_amount,
|
||||||
|
max_stake=min(max_stake_amount, stake_available))
|
||||||
|
|
||||||
if stake_amount is not None and stake_amount > 0.0:
|
if stake_amount is not None and stake_amount > 0.0:
|
||||||
# We should increase our position
|
# We should increase our position
|
||||||
@ -845,15 +852,20 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
# We do however also need min-stake to determine leverage, therefore this is ignored as
|
# We do however also need min-stake to determine leverage, therefore this is ignored as
|
||||||
# edge-case for now.
|
# edge-case for now.
|
||||||
min_stake_amount = self.exchange.get_min_pair_stake_amount(
|
min_stake_amount = self.exchange.get_min_pair_stake_amount(
|
||||||
pair, enter_limit_requested, self.strategy.stoploss,)
|
pair, enter_limit_requested, self.strategy.stoploss)
|
||||||
|
max_stake_amount = self.exchange.get_max_pair_stake_amount(
|
||||||
|
pair, enter_limit_requested, self.strategy.stoploss)
|
||||||
|
|
||||||
if not self.edge and trade is None:
|
if not self.edge and trade is None:
|
||||||
max_stake_amount = self.wallets.get_available_stake_amount()
|
stake_available = self.wallets.get_available_stake_amount()
|
||||||
|
if max_stake_amount is None:
|
||||||
|
# * Should never be executed
|
||||||
|
raise OperationalException(f'max_stake_amount is None for {trade}')
|
||||||
stake_amount = strategy_safe_wrapper(self.strategy.custom_stake_amount,
|
stake_amount = strategy_safe_wrapper(self.strategy.custom_stake_amount,
|
||||||
default_retval=stake_amount)(
|
default_retval=stake_amount)(
|
||||||
pair=pair, current_time=datetime.now(timezone.utc),
|
pair=pair, current_time=datetime.now(timezone.utc),
|
||||||
current_rate=enter_limit_requested, proposed_stake=stake_amount,
|
current_rate=enter_limit_requested, proposed_stake=stake_amount,
|
||||||
min_stake=min_stake_amount, max_stake=max_stake_amount,
|
min_stake=min_stake_amount, max_stake=min(max_stake_amount, stake_available),
|
||||||
entry_tag=entry_tag, side=trade_side
|
entry_tag=entry_tag, side=trade_side
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -413,11 +413,16 @@ class Backtesting:
|
|||||||
|
|
||||||
current_profit = trade.calc_profit_ratio(row[OPEN_IDX])
|
current_profit = trade.calc_profit_ratio(row[OPEN_IDX])
|
||||||
min_stake = self.exchange.get_min_pair_stake_amount(trade.pair, row[OPEN_IDX], -0.1)
|
min_stake = self.exchange.get_min_pair_stake_amount(trade.pair, row[OPEN_IDX], -0.1)
|
||||||
max_stake = self.wallets.get_available_stake_amount()
|
max_stake = self.exchange.get_max_pair_stake_amount(trade.pair, row[OPEN_IDX], -0.1)
|
||||||
|
if max_stake is None:
|
||||||
|
# * Should never be executed
|
||||||
|
raise OperationalException(f'max_stake_amount is None for {trade}')
|
||||||
|
stake_available = self.wallets.get_available_stake_amount()
|
||||||
stake_amount = strategy_safe_wrapper(self.strategy.adjust_trade_position,
|
stake_amount = strategy_safe_wrapper(self.strategy.adjust_trade_position,
|
||||||
default_retval=None)(
|
default_retval=None)(
|
||||||
trade=trade, current_time=row[DATE_IDX].to_pydatetime(), current_rate=row[OPEN_IDX],
|
trade=trade, current_time=row[DATE_IDX].to_pydatetime(), current_rate=row[OPEN_IDX],
|
||||||
current_profit=current_profit, min_stake=min_stake, max_stake=max_stake)
|
current_profit=current_profit, min_stake=min_stake,
|
||||||
|
max_stake=min(max_stake, stake_available))
|
||||||
|
|
||||||
# Check if we should increase our position
|
# Check if we should increase our position
|
||||||
if stake_amount is not None and stake_amount > 0.0:
|
if stake_amount is not None and stake_amount > 0.0:
|
||||||
@ -551,7 +556,11 @@ class Backtesting:
|
|||||||
propose_rate = min(max(propose_rate, row[LOW_IDX]), row[HIGH_IDX])
|
propose_rate = min(max(propose_rate, row[LOW_IDX]), row[HIGH_IDX])
|
||||||
|
|
||||||
min_stake_amount = self.exchange.get_min_pair_stake_amount(pair, propose_rate, -0.05) or 0
|
min_stake_amount = self.exchange.get_min_pair_stake_amount(pair, propose_rate, -0.05) or 0
|
||||||
max_stake_amount = self.wallets.get_available_stake_amount()
|
max_stake_amount = self.exchange.get_max_pair_stake_amount(pair, propose_rate, -0.05) or 0
|
||||||
|
if max_stake_amount is None:
|
||||||
|
# * Should never be executed
|
||||||
|
raise OperationalException(f'max_stake_amount is None for {trade}')
|
||||||
|
stake_available = self.wallets.get_available_stake_amount()
|
||||||
|
|
||||||
pos_adjust = trade is not None
|
pos_adjust = trade is not None
|
||||||
if not pos_adjust:
|
if not pos_adjust:
|
||||||
@ -563,7 +572,8 @@ class Backtesting:
|
|||||||
stake_amount = strategy_safe_wrapper(self.strategy.custom_stake_amount,
|
stake_amount = strategy_safe_wrapper(self.strategy.custom_stake_amount,
|
||||||
default_retval=stake_amount)(
|
default_retval=stake_amount)(
|
||||||
pair=pair, current_time=current_time, current_rate=propose_rate,
|
pair=pair, current_time=current_time, current_rate=propose_rate,
|
||||||
proposed_stake=stake_amount, min_stake=min_stake_amount, max_stake=max_stake_amount,
|
proposed_stake=stake_amount, min_stake=min_stake_amount,
|
||||||
|
max_stake=min(stake_available, max_stake_amount),
|
||||||
entry_tag=entry_tag, side=direction)
|
entry_tag=entry_tag, side=direction)
|
||||||
|
|
||||||
stake_amount = self.wallets.validate_stake_amount(pair, stake_amount, min_stake_amount)
|
stake_amount = self.wallets.validate_stake_amount(pair, stake_amount, min_stake_amount)
|
||||||
|
@ -587,7 +587,7 @@ def get_markets():
|
|||||||
'limits': {
|
'limits': {
|
||||||
'amount': {
|
'amount': {
|
||||||
'min': 0.01,
|
'min': 0.01,
|
||||||
'max': 1000,
|
'max': 100000000,
|
||||||
},
|
},
|
||||||
'price': {
|
'price': {
|
||||||
'min': None,
|
'min': None,
|
||||||
@ -622,7 +622,7 @@ def get_markets():
|
|||||||
'limits': {
|
'limits': {
|
||||||
'amount': {
|
'amount': {
|
||||||
'min': 0.01,
|
'min': 0.01,
|
||||||
'max': 1000,
|
'max': 100000000,
|
||||||
},
|
},
|
||||||
'price': {
|
'price': {
|
||||||
'min': None,
|
'min': None,
|
||||||
@ -690,7 +690,7 @@ def get_markets():
|
|||||||
'limits': {
|
'limits': {
|
||||||
'amount': {
|
'amount': {
|
||||||
'min': 0.01,
|
'min': 0.01,
|
||||||
'max': 1000,
|
'max': 100000000,
|
||||||
},
|
},
|
||||||
'price': {
|
'price': {
|
||||||
'min': None,
|
'min': None,
|
||||||
@ -725,7 +725,7 @@ def get_markets():
|
|||||||
'limits': {
|
'limits': {
|
||||||
'amount': {
|
'amount': {
|
||||||
'min': 0.01,
|
'min': 0.01,
|
||||||
'max': 1000,
|
'max': 100000000,
|
||||||
},
|
},
|
||||||
'price': {
|
'price': {
|
||||||
'min': None,
|
'min': None,
|
||||||
@ -760,7 +760,7 @@ def get_markets():
|
|||||||
'limits': {
|
'limits': {
|
||||||
'amount': {
|
'amount': {
|
||||||
'min': 0.01,
|
'min': 0.01,
|
||||||
'max': 1000,
|
'max': 100000000,
|
||||||
},
|
},
|
||||||
'price': {
|
'price': {
|
||||||
'min': None,
|
'min': None,
|
||||||
@ -988,7 +988,7 @@ def get_markets():
|
|||||||
'limits': {
|
'limits': {
|
||||||
'amount': {
|
'amount': {
|
||||||
'min': 0.01,
|
'min': 0.01,
|
||||||
'max': 1000,
|
'max': 100000000000,
|
||||||
},
|
},
|
||||||
'price': {
|
'price': {
|
||||||
'min': None,
|
'min': None,
|
||||||
|
@ -609,6 +609,7 @@ def test_backtest_results(default_conf, fee, mocker, caplog, data) -> None:
|
|||||||
|
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_fee", return_value=0.0)
|
mocker.patch("freqtrade.exchange.Exchange.get_fee", return_value=0.0)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||||
|
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||||
mocker.patch("freqtrade.exchange.Binance.get_max_leverage", return_value=100)
|
mocker.patch("freqtrade.exchange.Binance.get_max_leverage", return_value=100)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
frame = _build_backtest_dataframe(data.data)
|
frame = _build_backtest_dataframe(data.data)
|
||||||
|
@ -500,6 +500,7 @@ def test_backtest__enter_trade(default_conf, fee, mocker) -> None:
|
|||||||
default_conf['use_sell_signal'] = False
|
default_conf['use_sell_signal'] = False
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||||
|
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
default_conf['stake_amount'] = 'unlimited'
|
default_conf['stake_amount'] = 'unlimited'
|
||||||
default_conf['max_open_trades'] = 2
|
default_conf['max_open_trades'] = 2
|
||||||
@ -566,6 +567,7 @@ def test_backtest__get_sell_trade_entry(default_conf, fee, mocker) -> None:
|
|||||||
default_conf['use_sell_signal'] = False
|
default_conf['use_sell_signal'] = False
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||||
|
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
default_conf['timeframe_detail'] = '1m'
|
default_conf['timeframe_detail'] = '1m'
|
||||||
default_conf['max_open_trades'] = 2
|
default_conf['max_open_trades'] = 2
|
||||||
@ -659,6 +661,7 @@ def test_backtest_one(default_conf, fee, mocker, testdatadir) -> None:
|
|||||||
default_conf['use_sell_signal'] = False
|
default_conf['use_sell_signal'] = False
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||||
|
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
backtesting = Backtesting(default_conf)
|
backtesting = Backtesting(default_conf)
|
||||||
backtesting._set_strategy(backtesting.strategylist[0])
|
backtesting._set_strategy(backtesting.strategylist[0])
|
||||||
@ -724,6 +727,7 @@ def test_backtest_1min_timeframe(default_conf, fee, mocker, testdatadir) -> None
|
|||||||
default_conf['use_sell_signal'] = False
|
default_conf['use_sell_signal'] = False
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||||
|
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
backtesting = Backtesting(default_conf)
|
backtesting = Backtesting(default_conf)
|
||||||
backtesting._set_strategy(backtesting.strategylist[0])
|
backtesting._set_strategy(backtesting.strategylist[0])
|
||||||
@ -772,6 +776,7 @@ def test_backtest_pricecontours_protections(default_conf, fee, mocker, testdatad
|
|||||||
default_conf['enable_protections'] = True
|
default_conf['enable_protections'] = True
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||||
|
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||||
tests = [
|
tests = [
|
||||||
['sine', 9],
|
['sine', 9],
|
||||||
['raise', 10],
|
['raise', 10],
|
||||||
@ -806,6 +811,7 @@ def test_backtest_pricecontours(default_conf, fee, mocker, testdatadir,
|
|||||||
default_conf['enable_protections'] = True
|
default_conf['enable_protections'] = True
|
||||||
|
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||||
|
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||||
# While buy-signals are unrealistic, running backtesting
|
# While buy-signals are unrealistic, running backtesting
|
||||||
# over and over again should not cause different results
|
# over and over again should not cause different results
|
||||||
@ -846,6 +852,7 @@ def test_backtest_only_sell(mocker, default_conf, testdatadir):
|
|||||||
|
|
||||||
def test_backtest_alternate_buy_sell(default_conf, fee, mocker, testdatadir):
|
def test_backtest_alternate_buy_sell(default_conf, fee, mocker, testdatadir):
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||||
|
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||||
backtest_conf = _make_backtest_conf(mocker, conf=default_conf,
|
backtest_conf = _make_backtest_conf(mocker, conf=default_conf,
|
||||||
pair='UNITTEST/BTC', datadir=testdatadir)
|
pair='UNITTEST/BTC', datadir=testdatadir)
|
||||||
@ -892,6 +899,7 @@ def test_backtest_multi_pair(default_conf, fee, mocker, tres, pair, testdatadir)
|
|||||||
return dataframe
|
return dataframe
|
||||||
|
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||||
|
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ def test_backtest_position_adjustment(default_conf, fee, mocker, testdatadir) ->
|
|||||||
default_conf['use_sell_signal'] = False
|
default_conf['use_sell_signal'] = False
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||||
|
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
default_conf.update({
|
default_conf.update({
|
||||||
"stake_amount": 100.0,
|
"stake_amount": 100.0,
|
||||||
|
Loading…
Reference in New Issue
Block a user