From c179951cca4f87bf0aae5ce6a1f7afa492ee3902 Mon Sep 17 00:00:00 2001 From: Reigo Reinmets Date: Fri, 10 Dec 2021 20:42:24 +0200 Subject: [PATCH] Expect stake_amount, not actual amount of pair from strategy for DCA. --- freqtrade/freqtradebot.py | 22 ++++++++++++---------- freqtrade/optimize/backtesting.py | 20 ++++++++++---------- freqtrade/persistence/models.py | 1 + freqtrade/strategy/interface.py | 4 ++-- 4 files changed, 25 insertions(+), 22 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index b4503fe01..7bce1d084 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -476,15 +476,15 @@ class FreqtradeBot(LoggingMixin): sell_rate = self.exchange.get_rate(trade.pair, refresh=True, side="sell") current_profit = trade.calc_profit_ratio(sell_rate) - amount_to_adjust = strategy_safe_wrapper(self.strategy.adjust_trade_position, default_retval=None)( + stake_to_adjust = strategy_safe_wrapper(self.strategy.adjust_trade_position, default_retval=None)( pair=trade.pair, trade=trade, current_time=datetime.now(timezone.utc), current_rate=sell_rate, current_profit=current_profit) - if amount_to_adjust != None and amount_to_adjust > 0.0: + if stake_to_adjust != None and stake_to_adjust > 0.0: # We should increase our position - self.execute_trade_position_change(trade.pair, amount_to_adjust, trade) + self.execute_trade_position_change(trade.pair, stake_to_adjust, trade) - if amount_to_adjust != None and amount_to_adjust < 0.0: + if stake_to_adjust != None and stake_to_adjust < 0.0: # We should decrease our position # TODO: Selling part of the trade not implemented yet. return @@ -492,7 +492,7 @@ class FreqtradeBot(LoggingMixin): return - def execute_trade_position_change(self, pair: str, amount: float, trade: Trade): + def execute_trade_position_change(self, pair: str, stake_amount: float, trade: Trade): """ Executes a buy order for the given pair using specific amount :param pair: pair for which we want to create a buy order @@ -514,16 +514,18 @@ class FreqtradeBot(LoggingMixin): min_stake_amount = self.exchange.get_min_pair_stake_amount(pair, enter_limit_requested, self.strategy.stoploss) - stake_amount = self.wallets.validate_stake_amount(pair, (amount * enter_limit_requested), min_stake_amount) + stake_amount = self.wallets.validate_stake_amount(pair, stake_amount, min_stake_amount) + + amount = self.exchange.amount_to_precision(pair, stake_amount / enter_limit_requested) if not stake_amount: logger.info(f'Additional order failed to get stake amount for pair {pair}, amount={amount}, price={enter_limit_requested}') return False - + logger.debug(f'Executing additional order: amount={amount}, stake={stake_amount}, price={enter_limit_requested}') - amount = self.exchange.amount_to_precision(pair, amount) - order = self.exchange.create_order(pair=pair, ordertype="market", side="buy", + order_type = 'market' + order = self.exchange.create_order(pair=pair, ordertype=order_type, side="buy", amount=amount, rate=enter_limit_requested, time_in_force=time_in_force) order_obj = Order.parse_from_ccxt_object(order, pair, 'buy') @@ -567,7 +569,7 @@ class FreqtradeBot(LoggingMixin): # Updating wallets self.wallets.update() - self._notify_enter(trade, 'market') + self._notify_enter(trade, order_type) return True diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index b5277c216..2b6314ad6 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -350,25 +350,24 @@ class Backtesting: else: return sell_row[OPEN_IDX] - def _get_adjust_trade_entry_for_candle(self, trade: LocalTrade, sell_row: Tuple) -> Optional[LocalTrade]: - current_rate = sell_row[OPEN_IDX] - sell_candle_time = sell_row[DATE_IDX].to_pydatetime() + def _get_adjust_trade_entry_for_candle(self, trade: LocalTrade, row: Tuple) -> Optional[LocalTrade]: + current_rate = row[OPEN_IDX] + sell_candle_time = row[DATE_IDX].to_pydatetime() current_profit = trade.calc_profit_ratio(current_rate) - amount_to_adjust = strategy_safe_wrapper(self.strategy.adjust_trade_position, default_retval=None)( + stake_amount = strategy_safe_wrapper(self.strategy.adjust_trade_position, default_retval=None)( pair=trade.pair, trade=trade, current_time=sell_candle_time, current_rate=current_rate, current_profit=current_profit) # Check if we should increase our position - if amount_to_adjust is not None and amount_to_adjust > 0.0: - return self._execute_trade_position_change(trade, sell_row, amount_to_adjust) + if stake_amount is not None and stake_amount > 0.0: + return self._execute_trade_position_change(trade, row, stake_amount) return trade def _execute_trade_position_change(self, trade: LocalTrade, row: Tuple, - amount_to_adjust: float) -> Optional[LocalTrade]: + stake_amount: float) -> Optional[LocalTrade]: current_price = row[OPEN_IDX] - stake_amount = current_price * amount_to_adjust propose_rate = min(max(current_price, row[LOW_IDX]), row[HIGH_IDX]) available_amount = self.wallets.get_available_stake_amount() @@ -385,7 +384,7 @@ class Backtesting: logger.debug(f"{trade.pair} adjustment failed, amount ended up being zero {amount}") return trade - order = Order( + buy_order = Order( ft_is_open=False, ft_pair=trade.pair, symbol=trade.pair, @@ -398,8 +397,9 @@ class Backtesting: amount=amount, cost=stake_amount ) - trade.orders.append(order) + trade.orders.append(buy_order) trade.recalc_trade_from_orders() + self.wallets.update(); return trade diff --git a/freqtrade/persistence/models.py b/freqtrade/persistence/models.py index 74b4cf627..3c9b69ac2 100644 --- a/freqtrade/persistence/models.py +++ b/freqtrade/persistence/models.py @@ -587,6 +587,7 @@ class LocalTrade(): self.amount = total_amount self.fee_open_cost = self.fee_open * self.stake_amount self.recalc_open_trade_value() + self.adjust_stop_loss(self.open_rate, self.stop_loss_pct) def select_order(self, order_side: str, is_open: Optional[bool]) -> Optional[Order]: diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index fead93190..57ccdef31 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -386,7 +386,7 @@ class IStrategy(ABC, HyperStrategyMixin): current_time: datetime, current_rate: float, current_profit: float, **kwargs) -> Optional[float]: """ - Custom trade adjustment logic, returning the amount that a trade shold be either increased or decreased. + Custom trade adjustment logic, returning the stake amount that a trade shold be either increased or decreased. For full documentation please go to https://www.freqtrade.io/en/latest/strategy-advanced/ @@ -398,7 +398,7 @@ class IStrategy(ABC, HyperStrategyMixin): :param current_rate: Rate, calculated based on pricing settings in ask_strategy. :param current_profit: Current profit (as ratio), calculated based on current_rate. :param **kwargs: Ensure to keep this here so updates to this won't break your strategy. - :return float: Amount to adjust your trade (buy more or sell some) + :return float: Stake amount to adjust your trade """ return None