Call leverage before custom_stake_amount to properly determine min-stake-amount
This commit is contained in:
parent
35607ae03b
commit
b292f28b35
@ -42,8 +42,8 @@ By default, loop runs every few seconds (`internals.process_throttle_secs`) and
|
|||||||
* Check if trade-slots are still available (if `max_open_trades` is reached).
|
* Check if trade-slots are still available (if `max_open_trades` is reached).
|
||||||
* Verifies buy signal trying to enter new positions.
|
* Verifies buy signal trying to enter new positions.
|
||||||
* Determine buy-price based on `bid_strategy` configuration setting, or by using the `custom_entry_price()` callback.
|
* Determine buy-price based on `bid_strategy` configuration setting, or by using the `custom_entry_price()` callback.
|
||||||
* Determine stake size by calling the `custom_stake_amount()` callback.
|
|
||||||
* In Margin and Futures mode, `leverage()` strategy callback is called to determine the desired leverage.
|
* In Margin and Futures mode, `leverage()` strategy callback is called to determine the desired leverage.
|
||||||
|
* Determine stake size by calling the `custom_stake_amount()` callback.
|
||||||
* Before a buy order is placed, `confirm_trade_entry()` strategy callback is called.
|
* Before a buy order is placed, `confirm_trade_entry()` strategy callback is called.
|
||||||
|
|
||||||
This loop will be repeated again and again until the bot is stopped.
|
This loop will be repeated again and again until the bot is stopped.
|
||||||
@ -59,8 +59,8 @@ This loop will be repeated again and again until the bot is stopped.
|
|||||||
* Loops per candle simulating entry and exit points.
|
* Loops per candle simulating entry and exit points.
|
||||||
* Confirm trade buy / sell (calls `confirm_trade_entry()` and `confirm_trade_exit()` if implemented in the strategy).
|
* Confirm trade buy / sell (calls `confirm_trade_entry()` and `confirm_trade_exit()` if implemented in the strategy).
|
||||||
* Call `custom_entry_price()` (if implemented in the strategy) to determine entry price (Prices are moved to be within the opening candle).
|
* Call `custom_entry_price()` (if implemented in the strategy) to determine entry price (Prices are moved to be within the opening candle).
|
||||||
* Determine stake size by calling the `custom_stake_amount()` callback.
|
|
||||||
* In Margin and Futures mode, `leverage()` strategy callback is called to determine the desired leverage.
|
* In Margin and Futures mode, `leverage()` strategy callback is called to determine the desired leverage.
|
||||||
|
* Determine stake size by calling the `custom_stake_amount()` callback.
|
||||||
* Check position adjustments for open trades if enabled and call `adjust_trade_position()` to determine if an additional order is requested.
|
* Check position adjustments for open trades if enabled and call `adjust_trade_position()` to determine if an additional order is requested.
|
||||||
* Call `custom_stoploss()` and `custom_sell()` to find custom exit points.
|
* Call `custom_stoploss()` and `custom_sell()` to find custom exit points.
|
||||||
* For sells based on sell-signal and custom-sell: Call `custom_exit_price()` to determine exit price (Prices are moved to be within the closing candle).
|
* For sells based on sell-signal and custom-sell: Call `custom_exit_price()` to determine exit price (Prices are moved to be within the closing candle).
|
||||||
|
@ -600,26 +600,12 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
trade_side = 'short' if is_short else 'long'
|
trade_side = 'short' if is_short else 'long'
|
||||||
pos_adjust = trade is not None
|
pos_adjust = trade is not None
|
||||||
|
|
||||||
enter_limit_requested, stake_amount = self.get_valid_enter_price_and_stake(
|
enter_limit_requested, stake_amount, leverage = self.get_valid_enter_price_and_stake(
|
||||||
pair, price, stake_amount, side, trade_side, enter_tag, trade)
|
pair, price, stake_amount, side, trade_side, enter_tag, trade)
|
||||||
|
|
||||||
if not stake_amount:
|
if not stake_amount:
|
||||||
return False
|
return False
|
||||||
if not pos_adjust:
|
|
||||||
max_leverage = self.exchange.get_max_leverage(pair, stake_amount)
|
|
||||||
leverage = strategy_safe_wrapper(self.strategy.leverage, default_retval=1.0)(
|
|
||||||
pair=pair,
|
|
||||||
current_time=datetime.now(timezone.utc),
|
|
||||||
current_rate=enter_limit_requested,
|
|
||||||
proposed_leverage=1.0,
|
|
||||||
max_leverage=max_leverage,
|
|
||||||
side=trade_side,
|
|
||||||
) if self.trading_mode != TradingMode.SPOT else 1.0
|
|
||||||
# Cap leverage between 1.0 and max_leverage.
|
|
||||||
leverage = min(max(leverage, 1.0), max_leverage)
|
|
||||||
else:
|
|
||||||
# Changing leverage currently not possible
|
|
||||||
leverage = trade.leverage if trade else 1.0
|
|
||||||
if pos_adjust:
|
if pos_adjust:
|
||||||
logger.info(f"Position adjust: about to create a new order for {pair} with stake: "
|
logger.info(f"Position adjust: about to create a new order for {pair} with stake: "
|
||||||
f"{stake_amount} for {trade}")
|
f"{stake_amount} for {trade}")
|
||||||
@ -775,7 +761,7 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
side: str, trade_side: str,
|
side: str, trade_side: str,
|
||||||
entry_tag: Optional[str],
|
entry_tag: Optional[str],
|
||||||
trade: Optional[Trade]
|
trade: Optional[Trade]
|
||||||
) -> Tuple[float, float]:
|
) -> Tuple[float, float, float]:
|
||||||
|
|
||||||
if price:
|
if price:
|
||||||
enter_limit_requested = price
|
enter_limit_requested = price
|
||||||
@ -792,13 +778,30 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
if not enter_limit_requested:
|
if not enter_limit_requested:
|
||||||
raise PricingError(f'Could not determine {side} price.')
|
raise PricingError(f'Could not determine {side} price.')
|
||||||
|
|
||||||
|
if trade is None:
|
||||||
|
max_leverage = self.exchange.get_max_leverage(pair, stake_amount)
|
||||||
|
leverage = strategy_safe_wrapper(self.strategy.leverage, default_retval=1.0)(
|
||||||
|
pair=pair,
|
||||||
|
current_time=datetime.now(timezone.utc),
|
||||||
|
current_rate=enter_limit_requested,
|
||||||
|
proposed_leverage=1.0,
|
||||||
|
max_leverage=max_leverage,
|
||||||
|
side=trade_side,
|
||||||
|
) if self.trading_mode != TradingMode.SPOT else 1.0
|
||||||
|
# Cap leverage between 1.0 and max_leverage.
|
||||||
|
leverage = min(max(leverage, 1.0), max_leverage)
|
||||||
|
else:
|
||||||
|
# Changing leverage currently not possible
|
||||||
|
leverage = trade.leverage if trade else 1.0
|
||||||
|
|
||||||
# Min-stake-amount should actually include Leverage - this way our "minimal"
|
# Min-stake-amount should actually include Leverage - this way our "minimal"
|
||||||
# stake- amount might be higher than necessary.
|
# stake- amount might be higher than necessary.
|
||||||
# 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, leverage)
|
||||||
max_stake_amount = self.exchange.get_max_pair_stake_amount(pair, enter_limit_requested)
|
max_stake_amount = self.exchange.get_max_pair_stake_amount(
|
||||||
|
pair, enter_limit_requested, leverage)
|
||||||
|
|
||||||
if not self.edge and trade is None:
|
if not self.edge and trade is None:
|
||||||
stake_available = self.wallets.get_available_stake_amount()
|
stake_available = self.wallets.get_available_stake_amount()
|
||||||
@ -817,7 +820,7 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
max_stake_amount=max_stake_amount,
|
max_stake_amount=max_stake_amount,
|
||||||
)
|
)
|
||||||
|
|
||||||
return enter_limit_requested, stake_amount
|
return enter_limit_requested, stake_amount, leverage
|
||||||
|
|
||||||
def _notify_enter(self, trade: Trade, order: Dict, order_type: Optional[str] = None,
|
def _notify_enter(self, trade: Trade, order: Dict, order_type: Optional[str] = None,
|
||||||
fill: bool = False) -> None:
|
fill: bool = False) -> None:
|
||||||
|
@ -656,11 +656,27 @@ class Backtesting:
|
|||||||
else:
|
else:
|
||||||
propose_rate = min(propose_rate, row[HIGH_IDX])
|
propose_rate = min(propose_rate, row[HIGH_IDX])
|
||||||
|
|
||||||
min_stake_amount = self.exchange.get_min_pair_stake_amount(pair, propose_rate, -0.05) or 0
|
pos_adjust = trade is not None
|
||||||
max_stake_amount = self.exchange.get_max_pair_stake_amount(pair, propose_rate)
|
|
||||||
|
if not pos_adjust:
|
||||||
|
max_leverage = self.exchange.get_max_leverage(pair, stake_amount)
|
||||||
|
leverage = strategy_safe_wrapper(self.strategy.leverage, default_retval=1.0)(
|
||||||
|
pair=pair,
|
||||||
|
current_time=current_time,
|
||||||
|
current_rate=row[OPEN_IDX],
|
||||||
|
proposed_leverage=1.0,
|
||||||
|
max_leverage=max_leverage,
|
||||||
|
side=direction,
|
||||||
|
) if self._can_short else 1.0
|
||||||
|
# Cap leverage between 1.0 and max_leverage.
|
||||||
|
leverage = min(max(leverage, 1.0), max_leverage)
|
||||||
|
|
||||||
|
min_stake_amount = self.exchange.get_min_pair_stake_amount(
|
||||||
|
pair, propose_rate, -0.05, leverage=leverage) or 0
|
||||||
|
max_stake_amount = self.exchange.get_max_pair_stake_amount(
|
||||||
|
pair, propose_rate, leverage=leverage)
|
||||||
stake_available = self.wallets.get_available_stake_amount()
|
stake_available = self.wallets.get_available_stake_amount()
|
||||||
|
|
||||||
pos_adjust = trade is not None
|
|
||||||
if not pos_adjust:
|
if not pos_adjust:
|
||||||
try:
|
try:
|
||||||
stake_amount = self.wallets.get_trade_stake_amount(pair, None, update=False)
|
stake_amount = self.wallets.get_trade_stake_amount(pair, None, update=False)
|
||||||
@ -689,18 +705,6 @@ class Backtesting:
|
|||||||
time_in_force = self.strategy.order_time_in_force['entry']
|
time_in_force = self.strategy.order_time_in_force['entry']
|
||||||
|
|
||||||
if not pos_adjust:
|
if not pos_adjust:
|
||||||
max_leverage = self.exchange.get_max_leverage(pair, stake_amount)
|
|
||||||
leverage = strategy_safe_wrapper(self.strategy.leverage, default_retval=1.0)(
|
|
||||||
pair=pair,
|
|
||||||
current_time=current_time,
|
|
||||||
current_rate=row[OPEN_IDX],
|
|
||||||
proposed_leverage=1.0,
|
|
||||||
max_leverage=max_leverage,
|
|
||||||
side=direction,
|
|
||||||
) if self._can_short else 1.0
|
|
||||||
# Cap leverage between 1.0 and max_leverage.
|
|
||||||
leverage = min(max(leverage, 1.0), max_leverage)
|
|
||||||
|
|
||||||
# Confirm trade entry:
|
# Confirm trade entry:
|
||||||
if not strategy_safe_wrapper(self.strategy.confirm_trade_entry, default_retval=True)(
|
if not strategy_safe_wrapper(self.strategy.confirm_trade_entry, default_retval=True)(
|
||||||
pair=pair, order_type=order_type, amount=stake_amount, rate=propose_rate,
|
pair=pair, order_type=order_type, amount=stake_amount, rate=propose_rate,
|
||||||
|
Loading…
Reference in New Issue
Block a user