Merge pull request #4775 from freqtrade/fix_wallet_unlimited

Fix wallet unlimited
This commit is contained in:
Matthias
2021-04-24 15:54:06 +02:00
committed by GitHub
8 changed files with 59 additions and 53 deletions

View File

@@ -473,8 +473,7 @@ class FreqtradeBot(LoggingMixin):
(buy, sell) = self.strategy.get_signal(pair, self.strategy.timeframe, analyzed_df)
if buy and not sell:
stake_amount = self.wallets.get_trade_stake_amount(pair, self.get_free_open_trades(),
self.edge)
stake_amount = self.wallets.get_trade_stake_amount(pair, self.edge)
if not stake_amount:
logger.debug(f"Stake amount is 0, ignoring possible trade for {pair}.")
return False

View File

@@ -273,11 +273,9 @@ class Backtesting:
return None
def _enter_trade(self, pair: str, row: List, max_open_trades: int,
open_trade_count: int) -> Optional[LocalTrade]:
def _enter_trade(self, pair: str, row: List) -> Optional[LocalTrade]:
try:
stake_amount = self.wallets.get_trade_stake_amount(
pair, max_open_trades - open_trade_count, None)
stake_amount = self.wallets.get_trade_stake_amount(pair, None)
except DependencyException:
return None
min_stake_amount = self.exchange.get_min_pair_stake_amount(pair, row[OPEN_IDX], -0.05)
@@ -388,7 +386,7 @@ class Backtesting:
and tmp != end_date
and row[BUY_IDX] == 1 and row[SELL_IDX] != 1
and not PairLocks.is_pair_locked(pair, row[DATE_IDX])):
trade = self._enter_trade(pair, row, max_open_trades, open_trade_count_start)
trade = self._enter_trade(pair, row)
if trade:
# TODO: hacky workaround to avoid opening > max_open_trades
# This emulates previous behaviour - not sure if this is correct

View File

@@ -607,8 +607,7 @@ class RPC:
raise RPCException(f'position for {pair} already open - id: {trade.id}')
# gen stake amount
stakeamount = self._freqtrade.wallets.get_trade_stake_amount(
pair, self._freqtrade.get_free_open_trades())
stakeamount = self._freqtrade.wallets.get_trade_stake_amount(pair)
# execute buy
if self._freqtrade.execute_buy(pair, stakeamount, price, forcebuy=True):

View File

@@ -130,14 +130,13 @@ class Wallets:
def get_all_balances(self) -> Dict[str, Any]:
return self._wallets
def _get_available_stake_amount(self) -> float:
def _get_available_stake_amount(self, val_tied_up: float) -> float:
"""
Return the total currently available balance in stake currency,
respecting tradable_balance_ratio.
Calculated as
(<open_trade stakes> + free amount ) * tradable_balance_ratio - <open_trade stakes>
(<open_trade stakes> + free amount) * tradable_balance_ratio - <open_trade stakes>
"""
val_tied_up = Trade.total_open_trades_stakes()
# Ensure <tradable_balance_ratio>% is used from the overall balance
# Otherwise we'd risk lowering stakes with each open trade.
@@ -146,26 +145,26 @@ class Wallets:
self._config['tradable_balance_ratio']) - val_tied_up
return available_amount
def _calculate_unlimited_stake_amount(self, free_open_trades: int) -> float:
def _calculate_unlimited_stake_amount(self, available_amount: float,
val_tied_up: float) -> float:
"""
Calculate stake amount for "unlimited" stake amount
:return: 0 if max number of trades reached, else stake_amount to use.
"""
if not free_open_trades:
if self._config['max_open_trades'] == 0:
return 0
available_amount = self._get_available_stake_amount()
possible_stake = (available_amount + val_tied_up) / self._config['max_open_trades']
# Theoretical amount can be above available amount - therefore limit to available amount!
return min(possible_stake, available_amount)
return available_amount / free_open_trades
def _check_available_stake_amount(self, stake_amount: float) -> float:
def _check_available_stake_amount(self, stake_amount: float, available_amount: float) -> float:
"""
Check if stake amount can be fulfilled with the available balance
for the stake currency
:return: float: Stake amount
:raise: DependencyException if balance is lower than stake-amount
"""
available_amount = self._get_available_stake_amount()
if self._config['amend_last_stake_amount']:
# Remaining amount needs to be at least stake_amount * last_stake_amount_min_ratio
@@ -183,7 +182,7 @@ class Wallets:
return stake_amount
def get_trade_stake_amount(self, pair: str, free_open_trades: int, edge=None) -> float:
def get_trade_stake_amount(self, pair: str, edge=None) -> float:
"""
Calculate stake amount for the trade
:return: float: Stake amount
@@ -192,17 +191,20 @@ class Wallets:
stake_amount: float
# Ensure wallets are uptodate.
self.update()
val_tied_up = Trade.total_open_trades_stakes()
available_amount = self._get_available_stake_amount(val_tied_up)
if edge:
stake_amount = edge.stake_amount(
pair,
self.get_free(self._config['stake_currency']),
self.get_total(self._config['stake_currency']),
Trade.total_open_trades_stakes()
val_tied_up
)
else:
stake_amount = self._config['stake_amount']
if stake_amount == UNLIMITED_STAKE_AMOUNT:
stake_amount = self._calculate_unlimited_stake_amount(free_open_trades)
stake_amount = self._calculate_unlimited_stake_amount(
available_amount, val_tied_up)
return self._check_available_stake_amount(stake_amount)
return self._check_available_stake_amount(stake_amount, available_amount)