updated requested changes in PR #6545
This commit is contained in:
@@ -1181,7 +1181,8 @@ class Exchange:
|
||||
buy_rate = None
|
||||
sell_rate = None
|
||||
if not refresh:
|
||||
buy_rate, sell_rate = self._buy_rate_cache.get(pair), self._sell_rate_cache.get(pair)
|
||||
buy_rate = self._buy_rate_cache.get(pair)
|
||||
sell_rate = self._sell_rate_cache.get(pair)
|
||||
if buy_rate:
|
||||
logger.debug(f"Using cached buy rate for {pair}.")
|
||||
if sell_rate:
|
||||
|
||||
@@ -485,7 +485,7 @@ class FreqtradeBot(LoggingMixin):
|
||||
return
|
||||
else:
|
||||
logger.debug("Max adjustment entries is set to unlimited.")
|
||||
self.execute_entry(trade.pair, stake_amount, trade=trade)
|
||||
self.execute_entry(trade.pair, stake_amount, current_entry_rate, trade=trade)
|
||||
|
||||
if stake_amount is not None and stake_amount < 0.0:
|
||||
# We should decrease our position
|
||||
@@ -631,10 +631,6 @@ class FreqtradeBot(LoggingMixin):
|
||||
trade.open_order_id = order_id
|
||||
|
||||
trade.orders.append(order_obj)
|
||||
if pos_adjust:
|
||||
trade.recalc_trade_from_orders()
|
||||
else:
|
||||
trade.recalc_open_trade_value()
|
||||
Trade.query.session.add(trade)
|
||||
Trade.commit()
|
||||
|
||||
@@ -1142,16 +1138,18 @@ class FreqtradeBot(LoggingMixin):
|
||||
trade.open_order_id = None
|
||||
trade.sell_reason = None
|
||||
cancelled = True
|
||||
self.wallets.update()
|
||||
else:
|
||||
# TODO: figure out how to handle partially complete sell orders
|
||||
reason = constants.CANCEL_REASON['PARTIALLY_FILLED_KEEP_OPEN']
|
||||
cancelled = False
|
||||
|
||||
self.wallets.update()
|
||||
order_obj = Order.parse_from_ccxt_object(order, trade.pair, 'sell')
|
||||
sub_trade = order_obj.amount != trade.amount
|
||||
self._notify_exit_cancel(
|
||||
trade,
|
||||
order_type=self.strategy.order_types['sell'],
|
||||
reason=reason
|
||||
reason=reason, sub_trade=sub_trade, order=order_obj
|
||||
)
|
||||
return cancelled
|
||||
|
||||
@@ -1189,7 +1187,7 @@ class FreqtradeBot(LoggingMixin):
|
||||
exit_tag: Optional[str] = None,
|
||||
ordertype: Optional[str] = None,
|
||||
sub_trade_amt: float = None,
|
||||
) -> bool:
|
||||
) -> bool:
|
||||
"""
|
||||
Executes a trade exit for the given trade and limit
|
||||
:param trade: Trade instance
|
||||
@@ -1279,7 +1277,7 @@ class FreqtradeBot(LoggingMixin):
|
||||
current_rate = self.exchange.get_rate(
|
||||
trade.pair, refresh=False, side="sell") if not fill else None
|
||||
|
||||
# second condtion is for mypy only; order will always be passed during sub trade
|
||||
# second condition is for mypy only; order will always be passed during sub trade
|
||||
if sub_trade and order is not None:
|
||||
amount = order.safe_filled
|
||||
profit_rate = order.safe_price
|
||||
@@ -1327,7 +1325,7 @@ class FreqtradeBot(LoggingMixin):
|
||||
self.rpc.send_msg(msg)
|
||||
|
||||
def _notify_exit_cancel(self, trade: Trade, order_type: str, reason: str,
|
||||
sub_trade: bool = False) -> None:
|
||||
sub_trade: bool = False, order: Order=None) -> None:
|
||||
"""
|
||||
Sends rpc notification when a sell cancel occurred.
|
||||
"""
|
||||
@@ -1350,7 +1348,7 @@ class FreqtradeBot(LoggingMixin):
|
||||
'gain': gain,
|
||||
'limit': profit_rate or 0,
|
||||
'order_type': order_type,
|
||||
'amount': trade.amount,
|
||||
'amount': order.safe_amount_after_fee,
|
||||
'open_rate': trade.open_rate,
|
||||
'current_rate': current_rate,
|
||||
'profit_amount': profit_trade,
|
||||
@@ -1419,7 +1417,7 @@ class FreqtradeBot(LoggingMixin):
|
||||
trade.update_trade(order_obj)
|
||||
Trade.commit()
|
||||
|
||||
if order['status'] in constants.NON_OPEN_EXCHANGE_STATES:
|
||||
if order.get('status') in constants.NON_OPEN_EXCHANGE_STATES:
|
||||
# If a buy order was closed, force update on stoploss on exchange
|
||||
if order.get('side', None) == 'buy':
|
||||
trade = self.cancel_stoploss_on_exchange(trade)
|
||||
|
||||
@@ -383,8 +383,7 @@ class Backtesting:
|
||||
|
||||
def _get_adjust_trade_entry_for_candle(self, trade: LocalTrade, row: Tuple
|
||||
) -> LocalTrade:
|
||||
current_entry_rate = current_exit_rate = row[OPEN_IDX]
|
||||
current_rate = current_entry_rate
|
||||
current_rate = row[OPEN_IDX]
|
||||
|
||||
current_profit = trade.calc_profit_ratio(current_rate)
|
||||
min_stake = self.exchange.get_min_pair_stake_amount(trade.pair, current_rate, -0.1)
|
||||
@@ -393,7 +392,7 @@ class Backtesting:
|
||||
default_retval=None)(
|
||||
trade=trade, current_time=row[DATE_IDX].to_pydatetime(), current_rate=current_rate,
|
||||
current_profit=current_profit, min_stake=min_stake, max_stake=max_stake,
|
||||
current_entry_rate=current_entry_rate, current_exit_rate=current_exit_rate)
|
||||
current_entry_rate=current_rate, current_exit_rate=current_rate)
|
||||
|
||||
# Check if we should increase our position
|
||||
if stake_amount is not None and stake_amount > 0.0:
|
||||
@@ -403,9 +402,8 @@ class Backtesting:
|
||||
return pos_trade
|
||||
|
||||
if stake_amount is not None and stake_amount < 0.0:
|
||||
amount = -stake_amount / current_rate
|
||||
amount = abs(stake_amount) / current_rate
|
||||
if amount > trade.amount:
|
||||
logger.info(f"Amount is higher than available. {amount} > {trade.amount}")
|
||||
return trade
|
||||
pos_trade = self._exit_trade(trade, row, current_rate, amount)
|
||||
if pos_trade is not None:
|
||||
@@ -441,29 +439,29 @@ class Backtesting:
|
||||
|
||||
trade_dur = int((trade.close_date_utc - trade.open_date_utc).total_seconds() // 60)
|
||||
try:
|
||||
closerate = self._get_close_rate(sell_row, trade, sell, trade_dur)
|
||||
close_rate = self._get_close_rate(sell_row, trade, sell, trade_dur)
|
||||
except ValueError:
|
||||
return None
|
||||
# call the custom exit price,with default value as previous closerate
|
||||
current_profit = trade.calc_profit_ratio(closerate)
|
||||
# call the custom exit price,with default value as previous close_rate
|
||||
current_profit = trade.calc_profit_ratio(close_rate)
|
||||
order_type = self.strategy.order_types['sell']
|
||||
if sell.sell_type in (SellType.SELL_SIGNAL, SellType.CUSTOM_SELL):
|
||||
# Custom exit pricing only for sell-signals
|
||||
if order_type == 'limit':
|
||||
closerate = strategy_safe_wrapper(self.strategy.custom_exit_price,
|
||||
default_retval=closerate)(
|
||||
close_rate = strategy_safe_wrapper(self.strategy.custom_exit_price,
|
||||
default_retval=close_rate)(
|
||||
pair=trade.pair, trade=trade,
|
||||
current_time=sell_candle_time,
|
||||
proposed_rate=closerate, current_profit=current_profit)
|
||||
proposed_rate=close_rate, current_profit=current_profit)
|
||||
# We can't place orders lower than current low.
|
||||
# freqtrade does not support this in live, and the order would fill immediately
|
||||
closerate = max(closerate, sell_row[LOW_IDX])
|
||||
close_rate = max(close_rate, sell_row[LOW_IDX])
|
||||
# Confirm trade exit:
|
||||
time_in_force = self.strategy.order_time_in_force['sell']
|
||||
|
||||
if not strategy_safe_wrapper(self.strategy.confirm_trade_exit, default_retval=True)(
|
||||
pair=trade.pair, trade=trade, order_type='limit', amount=trade.amount,
|
||||
rate=closerate,
|
||||
rate=close_rate,
|
||||
time_in_force=time_in_force,
|
||||
sell_reason=sell.sell_reason,
|
||||
current_time=sell_candle_time):
|
||||
@@ -480,15 +478,16 @@ class Backtesting:
|
||||
):
|
||||
trade.sell_reason = sell_row[EXIT_TAG_IDX]
|
||||
|
||||
return self._exit_trade(trade, sell_row, closerate)
|
||||
return self._exit_trade(trade, sell_row, close_rate)
|
||||
|
||||
return None
|
||||
|
||||
def _exit_trade(self, trade: LocalTrade, sell_row: Tuple,
|
||||
closerate: float, amount: float = None) -> Optional[LocalTrade]:
|
||||
close_rate: float, amount: float = None) -> Optional[LocalTrade]:
|
||||
self.order_id_counter += 1
|
||||
sell_candle_time = sell_row[DATE_IDX].to_pydatetime()
|
||||
order_type = self.strategy.order_types['sell']
|
||||
amount = amount or trade.amount
|
||||
order = Order(
|
||||
id=self.order_id_counter,
|
||||
ft_trade_id=trade.id,
|
||||
@@ -502,12 +501,12 @@ class Backtesting:
|
||||
side="sell",
|
||||
order_type=order_type,
|
||||
status="open",
|
||||
price=closerate,
|
||||
average=closerate,
|
||||
amount=amount or trade.amount,
|
||||
price=close_rate,
|
||||
average=close_rate,
|
||||
amount=amount,
|
||||
filled=0,
|
||||
remaining=trade.amount,
|
||||
cost=trade.amount * closerate,
|
||||
remaining=amount,
|
||||
cost=amount * close_rate,
|
||||
)
|
||||
trade.orders.append(order)
|
||||
return trade
|
||||
|
||||
@@ -882,8 +882,8 @@ class IStrategy(ABC, HyperStrategyMixin):
|
||||
|
||||
return strategy_safe_wrapper(time_method,
|
||||
default_retval=False)(
|
||||
pair=trade.pair, trade=trade, order=order,
|
||||
current_time=current_time)
|
||||
pair=trade.pair, trade=trade, order=order,
|
||||
current_time=current_time)
|
||||
|
||||
def advise_all_indicators(self, data: Dict[str, DataFrame]) -> Dict[str, DataFrame]:
|
||||
"""
|
||||
|
||||
@@ -249,7 +249,7 @@ class Wallets:
|
||||
|
||||
if min_stake_amount is not None and min_stake_amount > max_stake_amount:
|
||||
if self._log:
|
||||
logger.warning("Minimum stake amount > available balance.")
|
||||
logger.warning(f"Minimum stake amount > available balance.{min_stake_amount} > {max_stake_amount}")
|
||||
return 0
|
||||
if min_stake_amount is not None and stake_amount < min_stake_amount:
|
||||
if self._log:
|
||||
|
||||
Reference in New Issue
Block a user