updated requested changes in PR #6545
This commit is contained in:
parent
389ae969fc
commit
bd00f6de17
@ -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:
|
||||
|
@ -26,6 +26,54 @@ from tests.conftest import get_mock_coro, get_patched_exchange, log_has, log_has
|
||||
# Make sure to always keep one exchange here which is NOT subclassed!!
|
||||
EXCHANGES = ['bittrex', 'binance', 'kraken', 'ftx']
|
||||
|
||||
get_buy_rate_data = [
|
||||
('ask', 20, 19, 10, 0.0, 20), # Full ask side
|
||||
('ask', 20, 19, 10, 1.0, 10), # Full last side
|
||||
('ask', 20, 19, 10, 0.5, 15), # Between ask and last
|
||||
('ask', 20, 19, 10, 0.7, 13), # Between ask and last
|
||||
('ask', 20, 19, 10, 0.3, 17), # Between ask and last
|
||||
('ask', 5, 6, 10, 1.0, 5), # last bigger than ask
|
||||
('ask', 5, 6, 10, 0.5, 5), # last bigger than ask
|
||||
('ask', 20, 19, 10, None, 20), # ask_last_balance missing
|
||||
('ask', 10, 20, None, 0.5, 10), # last not available - uses ask
|
||||
('ask', 4, 5, None, 0.5, 4), # last not available - uses ask
|
||||
('ask', 4, 5, None, 1, 4), # last not available - uses ask
|
||||
('ask', 4, 5, None, 0, 4), # last not available - uses ask
|
||||
('bid', 21, 20, 10, 0.0, 20), # Full bid side
|
||||
('bid', 21, 20, 10, 1.0, 10), # Full last side
|
||||
('bid', 21, 20, 10, 0.5, 15), # Between bid and last
|
||||
('bid', 21, 20, 10, 0.7, 13), # Between bid and last
|
||||
('bid', 21, 20, 10, 0.3, 17), # Between bid and last
|
||||
('bid', 6, 5, 10, 1.0, 5), # last bigger than bid
|
||||
('bid', 21, 20, 10, None, 20), # ask_last_balance missing
|
||||
('bid', 6, 5, 10, 0.5, 5), # last bigger than bid
|
||||
('bid', 21, 20, None, 0.5, 20), # last not available - uses bid
|
||||
('bid', 6, 5, None, 0.5, 5), # last not available - uses bid
|
||||
('bid', 6, 5, None, 1, 5), # last not available - uses bid
|
||||
('bid', 6, 5, None, 0, 5), # last not available - uses bid
|
||||
]
|
||||
|
||||
get_sell_rate_data = [
|
||||
('bid', 12.0, 11.0, 11.5, 0.0, 11.0), # full bid side
|
||||
('bid', 12.0, 11.0, 11.5, 1.0, 11.5), # full last side
|
||||
('bid', 12.0, 11.0, 11.5, 0.5, 11.25), # between bid and lat
|
||||
('bid', 12.0, 11.2, 10.5, 0.0, 11.2), # Last smaller than bid
|
||||
('bid', 12.0, 11.2, 10.5, 1.0, 11.2), # Last smaller than bid - uses bid
|
||||
('bid', 12.0, 11.2, 10.5, 0.5, 11.2), # Last smaller than bid - uses bid
|
||||
('bid', 0.003, 0.002, 0.005, 0.0, 0.002),
|
||||
('bid', 0.003, 0.002, 0.005, None, 0.002),
|
||||
('ask', 12.0, 11.0, 12.5, 0.0, 12.0), # full ask side
|
||||
('ask', 12.0, 11.0, 12.5, 1.0, 12.5), # full last side
|
||||
('ask', 12.0, 11.0, 12.5, 0.5, 12.25), # between bid and lat
|
||||
('ask', 12.2, 11.2, 10.5, 0.0, 12.2), # Last smaller than ask
|
||||
('ask', 12.0, 11.0, 10.5, 1.0, 12.0), # Last smaller than ask - uses ask
|
||||
('ask', 12.0, 11.2, 10.5, 0.5, 12.0), # Last smaller than ask - uses ask
|
||||
('ask', 10.0, 11.0, 11.0, 0.0, 10.0),
|
||||
('ask', 10.11, 11.2, 11.0, 0.0, 10.11),
|
||||
('ask', 0.001, 0.002, 11.0, 0.0, 0.001),
|
||||
('ask', 0.006, 1.0, 11.0, 0.0, 0.006),
|
||||
('ask', 0.006, 1.0, 11.0, None, 0.006),
|
||||
]
|
||||
|
||||
def ccxt_exceptionhandlers(mocker, default_conf, api_mock, exchange_name,
|
||||
fun, mock_ccxt_fun, retries=API_RETRY_COUNT + 1, **kwargs):
|
||||
@ -1903,33 +1951,6 @@ def test_fetch_l2_order_book_exception(default_conf, mocker, exchange_name):
|
||||
exchange.fetch_l2_order_book(pair='ETH/BTC', limit=50)
|
||||
|
||||
|
||||
get_buy_rate_data = [
|
||||
('ask', 20, 19, 10, 0.0, 20), # Full ask side
|
||||
('ask', 20, 19, 10, 1.0, 10), # Full last side
|
||||
('ask', 20, 19, 10, 0.5, 15), # Between ask and last
|
||||
('ask', 20, 19, 10, 0.7, 13), # Between ask and last
|
||||
('ask', 20, 19, 10, 0.3, 17), # Between ask and last
|
||||
('ask', 5, 6, 10, 1.0, 5), # last bigger than ask
|
||||
('ask', 5, 6, 10, 0.5, 5), # last bigger than ask
|
||||
('ask', 20, 19, 10, None, 20), # ask_last_balance missing
|
||||
('ask', 10, 20, None, 0.5, 10), # last not available - uses ask
|
||||
('ask', 4, 5, None, 0.5, 4), # last not available - uses ask
|
||||
('ask', 4, 5, None, 1, 4), # last not available - uses ask
|
||||
('ask', 4, 5, None, 0, 4), # last not available - uses ask
|
||||
('bid', 21, 20, 10, 0.0, 20), # Full bid side
|
||||
('bid', 21, 20, 10, 1.0, 10), # Full last side
|
||||
('bid', 21, 20, 10, 0.5, 15), # Between bid and last
|
||||
('bid', 21, 20, 10, 0.7, 13), # Between bid and last
|
||||
('bid', 21, 20, 10, 0.3, 17), # Between bid and last
|
||||
('bid', 6, 5, 10, 1.0, 5), # last bigger than bid
|
||||
('bid', 21, 20, 10, None, 20), # ask_last_balance missing
|
||||
('bid', 6, 5, 10, 0.5, 5), # last bigger than bid
|
||||
('bid', 21, 20, None, 0.5, 20), # last not available - uses bid
|
||||
('bid', 6, 5, None, 0.5, 5), # last not available - uses bid
|
||||
('bid', 6, 5, None, 1, 5), # last not available - uses bid
|
||||
('bid', 6, 5, None, 0, 5), # last not available - uses bid
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("side,ask,bid,last,last_ab,expected", get_buy_rate_data)
|
||||
def test_get_buy_rate(mocker, default_conf, caplog, side, ask, bid,
|
||||
@ -1955,29 +1976,6 @@ def test_get_buy_rate(mocker, default_conf, caplog, side, ask, bid,
|
||||
assert not log_has("Using cached buy rate for ETH/BTC.", caplog)
|
||||
|
||||
|
||||
get_sell_rate_data = [
|
||||
('bid', 12.0, 11.0, 11.5, 0.0, 11.0), # full bid side
|
||||
('bid', 12.0, 11.0, 11.5, 1.0, 11.5), # full last side
|
||||
('bid', 12.0, 11.0, 11.5, 0.5, 11.25), # between bid and lat
|
||||
('bid', 12.0, 11.2, 10.5, 0.0, 11.2), # Last smaller than bid
|
||||
('bid', 12.0, 11.2, 10.5, 1.0, 11.2), # Last smaller than bid - uses bid
|
||||
('bid', 12.0, 11.2, 10.5, 0.5, 11.2), # Last smaller than bid - uses bid
|
||||
('bid', 0.003, 0.002, 0.005, 0.0, 0.002),
|
||||
('bid', 0.003, 0.002, 0.005, None, 0.002),
|
||||
('ask', 12.0, 11.0, 12.5, 0.0, 12.0), # full ask side
|
||||
('ask', 12.0, 11.0, 12.5, 1.0, 12.5), # full last side
|
||||
('ask', 12.0, 11.0, 12.5, 0.5, 12.25), # between bid and lat
|
||||
('ask', 12.2, 11.2, 10.5, 0.0, 12.2), # Last smaller than ask
|
||||
('ask', 12.0, 11.0, 10.5, 1.0, 12.0), # Last smaller than ask - uses ask
|
||||
('ask', 12.0, 11.2, 10.5, 0.5, 12.0), # Last smaller than ask - uses ask
|
||||
('ask', 10.0, 11.0, 11.0, 0.0, 10.0),
|
||||
('ask', 10.11, 11.2, 11.0, 0.0, 10.11),
|
||||
('ask', 0.001, 0.002, 11.0, 0.0, 0.001),
|
||||
('ask', 0.006, 1.0, 11.0, 0.0, 0.006),
|
||||
('ask', 0.006, 1.0, 11.0, None, 0.006),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize('side,ask,bid,last,last_ab,expected', get_sell_rate_data)
|
||||
def test_get_sell_rate(default_conf, mocker, caplog, side, bid, ask,
|
||||
last, last_ab, expected) -> None:
|
||||
@ -2108,7 +2106,7 @@ def test_get_rates_testing_buy(mocker, default_conf, caplog, side, ask, bid,
|
||||
api_mock = MagicMock()
|
||||
api_mock.fetch_l2_order_book = order_book_l2
|
||||
api_mock.fetch_ticker = MagicMock(
|
||||
return_value={'ask': ask, 'last': last, 'bid': bid})
|
||||
return_value={'ask': ask, 'last': last, 'bid': bid})
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock)
|
||||
|
||||
assert exchange.get_rates('ETH/BTC', refresh=True)[0] == expected
|
||||
@ -2148,12 +2146,12 @@ def test_get_rates_testing_sell(default_conf, mocker, caplog, side, bid, ask,
|
||||
pair = "ETH/BTC"
|
||||
|
||||
# Test regular mode
|
||||
rate = exchange.get_rate(pair, refresh=True, side="sell")
|
||||
rate = exchange.get_rates(pair, refresh=True)[1]
|
||||
assert not log_has("Using cached sell rate for ETH/BTC.", caplog)
|
||||
assert isinstance(rate, float)
|
||||
assert rate == expected
|
||||
# Use caching
|
||||
rate = exchange.get_rate(pair, refresh=False, side="sell")
|
||||
rate = exchange.get_rates(pair, refresh=False)[1]
|
||||
assert rate == expected
|
||||
assert log_has("Using cached sell rate for ETH/BTC.", caplog)
|
||||
|
||||
|
@ -467,9 +467,8 @@ def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee,
|
||||
|
||||
trades = Trade.query.all()
|
||||
for trade in trades:
|
||||
trade.open_rate = oobj.safe_price
|
||||
trade.amount = oobj.safe_amount_after_fee
|
||||
trade.recalc_open_trade_value()
|
||||
trade.orders[0] = oobj
|
||||
trade.update_trade(oobj)
|
||||
trade.update_trade(oobjs)
|
||||
trade.close_date = datetime.utcnow()
|
||||
trade.is_open = False
|
||||
@ -586,9 +585,8 @@ def test_weekly_handle(default_conf, update, ticker, limit_buy_order, fee,
|
||||
|
||||
trades = Trade.query.all()
|
||||
for trade in trades:
|
||||
trade.open_rate = oobj.safe_price
|
||||
trade.amount = oobj.safe_amount_after_fee
|
||||
trade.recalc_open_trade_value()
|
||||
trade.orders[0] = oobj
|
||||
trade.update_trade(oobj)
|
||||
trade.update_trade(oobjs)
|
||||
trade.close_date = datetime.utcnow()
|
||||
trade.is_open = False
|
||||
@ -708,9 +706,8 @@ def test_monthly_handle(default_conf, update, ticker, limit_buy_order, fee,
|
||||
|
||||
trades = Trade.query.all()
|
||||
for trade in trades:
|
||||
trade.open_rate = oobj.safe_price
|
||||
trade.amount = oobj.safe_amount_after_fee
|
||||
trade.recalc_open_trade_value()
|
||||
trade.orders[0] = oobj
|
||||
trade.update_trade(oobj)
|
||||
trade.update_trade(oobjs)
|
||||
trade.close_date = datetime.utcnow()
|
||||
trade.is_open = False
|
||||
|
@ -2075,9 +2075,9 @@ def test_check_handle_timedout_buy_usercustom(default_conf_usdt, ticker_usdt, li
|
||||
default_conf_usdt["unfilledtimeout"] = {"buy": 1400, "sell": 30}
|
||||
limit_buy_order_old['id'] = open_trade.open_order_id
|
||||
rpc_mock = patch_RPCManager(mocker)
|
||||
cancel_order_mock = MagicMock(return_value=limit_buy_order_old)
|
||||
cancel_buy_order = deepcopy(limit_buy_order_old)
|
||||
cancel_buy_order['status'] = 'canceled'
|
||||
cancel_order_mock = MagicMock(return_value=limit_buy_order_old)
|
||||
cancel_order_wr_mock = MagicMock(return_value=cancel_buy_order)
|
||||
|
||||
patch_exchange(mocker)
|
||||
@ -2085,8 +2085,8 @@ def test_check_handle_timedout_buy_usercustom(default_conf_usdt, ticker_usdt, li
|
||||
'freqtrade.exchange.Exchange',
|
||||
fetch_ticker=ticker_usdt,
|
||||
fetch_order=MagicMock(return_value=limit_buy_order_old),
|
||||
cancel_order_with_result=cancel_order_wr_mock,
|
||||
cancel_order=cancel_order_mock,
|
||||
cancel_order_with_result=cancel_order_wr_mock,
|
||||
get_fee=fee
|
||||
)
|
||||
freqtrade = FreqtradeBot(default_conf_usdt)
|
||||
@ -2129,7 +2129,9 @@ def test_check_handle_timedout_buy_usercustom(default_conf_usdt, ticker_usdt, li
|
||||
def test_check_handle_timedout_buy(default_conf_usdt, ticker_usdt, limit_buy_order_old, open_trade,
|
||||
fee, mocker) -> None:
|
||||
rpc_mock = patch_RPCManager(mocker)
|
||||
limit_buy_order_old['id'] = open_trade.open_order_id
|
||||
open_trade.open_order_id = limit_buy_order_old['id']
|
||||
order = Order.parse_from_ccxt_object(limit_buy_order_old, 'mocked', 'buy')
|
||||
open_trade.orders[0] = order
|
||||
limit_buy_cancel = deepcopy(limit_buy_order_old)
|
||||
limit_buy_cancel['status'] = 'canceled'
|
||||
cancel_order_mock = MagicMock(return_value=limit_buy_cancel)
|
||||
@ -2214,8 +2216,9 @@ def test_check_handle_timedout_buy_exception(default_conf_usdt, ticker_usdt,
|
||||
def test_check_handle_timedout_sell_usercustom(default_conf_usdt, ticker_usdt, limit_sell_order_old,
|
||||
mocker, open_trade, caplog) -> None:
|
||||
default_conf_usdt["unfilledtimeout"] = {"buy": 1440, "sell": 1440, "exit_timeout_count": 1}
|
||||
limit_sell_order_old['id'] = open_trade.open_order_id
|
||||
|
||||
open_trade.open_order_id = limit_sell_order_old['id']
|
||||
order = Order.parse_from_ccxt_object(limit_sell_order_old, 'mocked', 'sell')
|
||||
open_trade.orders[0] = order
|
||||
rpc_mock = patch_RPCManager(mocker)
|
||||
cancel_order_mock = MagicMock()
|
||||
patch_exchange(mocker)
|
||||
@ -4877,45 +4880,26 @@ def test_position_adjust2(mocker, default_conf_usdt, fee) -> None:
|
||||
assert trade.is_open is False
|
||||
|
||||
|
||||
@pytest.mark.parametrize('orders, results', [
|
||||
@pytest.mark.parametrize('data', [
|
||||
(
|
||||
(
|
||||
# side ampunt, price
|
||||
('buy', 100, 10),
|
||||
('buy', 100, 15),
|
||||
('sell', 50, 12),
|
||||
('sell', 100, 20),
|
||||
('sell', 50, 5),
|
||||
),
|
||||
(
|
||||
# amount, open_rate, stake_amount, cumulative_profit, realized_profit
|
||||
(100.0, 10.0, 1000.0, 0.0, None,),
|
||||
(200.0, 12.5, 2500.0, 0.0, None,),
|
||||
(150.0, 12.5, 1875.0, -28.0625, -28.0625,),
|
||||
(50.0, 12.5, 625.0, 713.8125, 741.875,),
|
||||
(50.0, 12.5, 625.0, 713.8125, 336.625,),
|
||||
)
|
||||
# tuple 1 - side amount, price
|
||||
# tuple 2 - amount, open_rate, stake_amount, cumulative_profit, realized_profit
|
||||
(('buy', 100, 10), (100.0, 10.0, 1000.0, 0.0, None)),
|
||||
(('buy', 100, 15), (200.0, 12.5, 2500.0, 0.0, None)),
|
||||
(('sell', 50, 12), (150.0, 12.5, 1875.0, -28.0625, -28.0625)),
|
||||
(('sell', 100, 20), (50.0, 12.5, 625.0, 713.8125, 741.875)),
|
||||
(('sell', 50, 5), (50.0, 12.5, 625.0, 713.8125, 336.625)),
|
||||
),
|
||||
(
|
||||
(
|
||||
('buy', 100, 3),
|
||||
('buy', 100, 7),
|
||||
('sell', 100, 11),
|
||||
('buy', 150, 15),
|
||||
('sell', 100, 19),
|
||||
('sell', 150, 23),
|
||||
),
|
||||
(
|
||||
(100.0, 3.0, 300.0, 0.0, None,),
|
||||
(200.0, 5.0, 1000.0, 0.0, None,),
|
||||
(100.0, 5.0, 500.0, 596.0, 596.0,),
|
||||
(250.0, 11.0, 2750.0, 596.0, 596.0,),
|
||||
(150.0, 11.0, 1650.0, 1388.5, 792.5,),
|
||||
(150.0, 11.0, 1650.0, 1388.5, 3175.75,),
|
||||
)
|
||||
),
|
||||
(('buy', 100, 3), (100.0, 3.0, 300.0, 0.0, None)),
|
||||
(('buy', 100, 7), (200.0, 5.0, 1000.0, 0.0, None)),
|
||||
(('sell', 100, 11), (100.0, 5.0, 500.0, 596.0, 596.0)),
|
||||
(('buy', 150, 15), (250.0, 11.0, 2750.0, 596.0, 596.0)),
|
||||
(('sell', 100, 19), (150.0, 11.0, 1650.0, 1388.5, 792.5)),
|
||||
(('sell', 150, 23), (150.0, 11.0, 1650.0, 1388.5, 3175.75)),
|
||||
)
|
||||
])
|
||||
def test_position_adjust3(mocker, default_conf_usdt, fee, orders, results) -> None:
|
||||
def test_position_adjust3(mocker, default_conf_usdt, fee, data) -> None:
|
||||
default_conf_usdt.update({
|
||||
"position_adjustment_enable": True,
|
||||
"dry_run": False,
|
||||
@ -4928,7 +4912,7 @@ def test_position_adjust3(mocker, default_conf_usdt, fee, orders, results) -> No
|
||||
freqtrade = FreqtradeBot(default_conf_usdt)
|
||||
trade = None
|
||||
freqtrade.strategy.confirm_trade_entry = MagicMock(return_value=True)
|
||||
for idx, (order, result) in enumerate(zip(orders, results)):
|
||||
for idx, (order, result) in enumerate(data):
|
||||
amount = order[1]
|
||||
price = order[2]
|
||||
price_mock = MagicMock(return_value=price)
|
||||
|
@ -1215,7 +1215,7 @@ def test_update_order_from_ccxt(caplog):
|
||||
'symbol': 'ETH/BTC',
|
||||
'type': 'limit',
|
||||
'price': 1234.5,
|
||||
'amount': 20.0,
|
||||
'amount': 20.0,
|
||||
'filled': 9,
|
||||
'remaining': 11,
|
||||
'status': 'open',
|
||||
@ -1641,7 +1641,7 @@ def test_recalc_trade_from_orders_ignores_bad_orders(fee):
|
||||
assert trade.open_trade_value == 2 * o1_trade_val
|
||||
assert trade.nr_of_successful_buys == 2
|
||||
|
||||
# Just to make sure sell orders are ignored, let's calculate one more time.
|
||||
# Just to make sure non partial sell orders are ignored, let's calculate one more time.
|
||||
sell1 = Order(
|
||||
ft_order_side='sell',
|
||||
ft_pair=trade.pair,
|
||||
|
Loading…
Reference in New Issue
Block a user