Expect stake_amount, not actual amount of pair from strategy for DCA.

This commit is contained in:
Reigo Reinmets 2021-12-10 20:42:24 +02:00
parent b2c2852f86
commit c179951cca
4 changed files with 25 additions and 22 deletions

View File

@ -476,15 +476,15 @@ class FreqtradeBot(LoggingMixin):
sell_rate = self.exchange.get_rate(trade.pair, refresh=True, side="sell") sell_rate = self.exchange.get_rate(trade.pair, refresh=True, side="sell")
current_profit = trade.calc_profit_ratio(sell_rate) 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), pair=trade.pair, trade=trade, current_time=datetime.now(timezone.utc),
current_rate=sell_rate, current_profit=current_profit) 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 # 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 # We should decrease our position
# TODO: Selling part of the trade not implemented yet. # TODO: Selling part of the trade not implemented yet.
return return
@ -492,7 +492,7 @@ class FreqtradeBot(LoggingMixin):
return 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 Executes a buy order for the given pair using specific amount
:param pair: pair for which we want to create a buy order :param pair: pair for which we want to create a buy order
@ -514,7 +514,9 @@ class FreqtradeBot(LoggingMixin):
min_stake_amount = self.exchange.get_min_pair_stake_amount(pair, enter_limit_requested, min_stake_amount = self.exchange.get_min_pair_stake_amount(pair, enter_limit_requested,
self.strategy.stoploss) 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: if not stake_amount:
logger.info(f'Additional order failed to get stake amount for pair {pair}, amount={amount}, price={enter_limit_requested}') logger.info(f'Additional order failed to get stake amount for pair {pair}, amount={amount}, price={enter_limit_requested}')
@ -522,8 +524,8 @@ class FreqtradeBot(LoggingMixin):
logger.debug(f'Executing additional order: amount={amount}, stake={stake_amount}, price={enter_limit_requested}') logger.debug(f'Executing additional order: amount={amount}, stake={stake_amount}, price={enter_limit_requested}')
amount = self.exchange.amount_to_precision(pair, amount) order_type = 'market'
order = self.exchange.create_order(pair=pair, ordertype="market", side="buy", order = self.exchange.create_order(pair=pair, ordertype=order_type, side="buy",
amount=amount, rate=enter_limit_requested, amount=amount, rate=enter_limit_requested,
time_in_force=time_in_force) time_in_force=time_in_force)
order_obj = Order.parse_from_ccxt_object(order, pair, 'buy') order_obj = Order.parse_from_ccxt_object(order, pair, 'buy')
@ -567,7 +569,7 @@ class FreqtradeBot(LoggingMixin):
# Updating wallets # Updating wallets
self.wallets.update() self.wallets.update()
self._notify_enter(trade, 'market') self._notify_enter(trade, order_type)
return True return True

View File

@ -350,25 +350,24 @@ class Backtesting:
else: else:
return sell_row[OPEN_IDX] return sell_row[OPEN_IDX]
def _get_adjust_trade_entry_for_candle(self, trade: LocalTrade, sell_row: Tuple) -> Optional[LocalTrade]: def _get_adjust_trade_entry_for_candle(self, trade: LocalTrade, row: Tuple) -> Optional[LocalTrade]:
current_rate = sell_row[OPEN_IDX] current_rate = row[OPEN_IDX]
sell_candle_time = sell_row[DATE_IDX].to_pydatetime() sell_candle_time = row[DATE_IDX].to_pydatetime()
current_profit = trade.calc_profit_ratio(current_rate) 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, pair=trade.pair, trade=trade, current_time=sell_candle_time,
current_rate=current_rate, current_profit=current_profit) current_rate=current_rate, current_profit=current_profit)
# Check if we should increase our position # Check if we should increase our position
if amount_to_adjust is not None and amount_to_adjust > 0.0: if stake_amount is not None and stake_amount > 0.0:
return self._execute_trade_position_change(trade, sell_row, amount_to_adjust) return self._execute_trade_position_change(trade, row, stake_amount)
return trade return trade
def _execute_trade_position_change(self, trade: LocalTrade, row: Tuple, 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] current_price = row[OPEN_IDX]
stake_amount = current_price * amount_to_adjust
propose_rate = min(max(current_price, row[LOW_IDX]), row[HIGH_IDX]) propose_rate = min(max(current_price, row[LOW_IDX]), row[HIGH_IDX])
available_amount = self.wallets.get_available_stake_amount() 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}") logger.debug(f"{trade.pair} adjustment failed, amount ended up being zero {amount}")
return trade return trade
order = Order( buy_order = Order(
ft_is_open=False, ft_is_open=False,
ft_pair=trade.pair, ft_pair=trade.pair,
symbol=trade.pair, symbol=trade.pair,
@ -398,8 +397,9 @@ class Backtesting:
amount=amount, amount=amount,
cost=stake_amount cost=stake_amount
) )
trade.orders.append(order) trade.orders.append(buy_order)
trade.recalc_trade_from_orders() trade.recalc_trade_from_orders()
self.wallets.update(); self.wallets.update();
return trade return trade

View File

@ -587,6 +587,7 @@ class LocalTrade():
self.amount = total_amount self.amount = total_amount
self.fee_open_cost = self.fee_open * self.stake_amount self.fee_open_cost = self.fee_open * self.stake_amount
self.recalc_open_trade_value() 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]: def select_order(self, order_side: str, is_open: Optional[bool]) -> Optional[Order]:

View File

@ -386,7 +386,7 @@ class IStrategy(ABC, HyperStrategyMixin):
current_time: datetime, current_rate: float, current_profit: float, current_time: datetime, current_rate: float, current_profit: float,
**kwargs) -> Optional[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/ 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_rate: Rate, calculated based on pricing settings in ask_strategy.
:param current_profit: Current profit (as ratio), calculated based on current_rate. :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. :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 return None