Merge pull request #6658 from mkavinkumar1/rename-enter-side
renamed enter-side
This commit is contained in:
commit
916764d4f2
@ -665,7 +665,7 @@ class DigDeeperStrategy(IStrategy):
|
|||||||
if last_candle['close'] < previous_candle['close']:
|
if last_candle['close'] < previous_candle['close']:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
filled_entries = trade.select_filled_orders(trade.enter_side)
|
filled_entries = trade.select_filled_orders(trade.entry_side)
|
||||||
count_of_entries = trade.nr_of_successful_entries
|
count_of_entries = trade.nr_of_successful_entries
|
||||||
# Allow up to 3 additional increasingly larger buys (4 in total)
|
# Allow up to 3 additional increasingly larger buys (4 in total)
|
||||||
# Initial buy is 1x
|
# Initial buy is 1x
|
||||||
|
@ -27,7 +27,7 @@ You can use the quick summary as checklist. Please refer to the detailed section
|
|||||||
* [New column `enter_short` and corresponding new column `exit_short`](#populate_sell_trend)
|
* [New column `enter_short` and corresponding new column `exit_short`](#populate_sell_trend)
|
||||||
* trade-object now has the following new properties:
|
* trade-object now has the following new properties:
|
||||||
* `is_short`
|
* `is_short`
|
||||||
* `enter_side`
|
* `entry_side`
|
||||||
* `exit_side`
|
* `exit_side`
|
||||||
* `trade_direction`
|
* `trade_direction`
|
||||||
* renamed: `sell_reason` -> `exit_reason`
|
* renamed: `sell_reason` -> `exit_reason`
|
||||||
|
@ -330,12 +330,12 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
|
|
||||||
trades: List[Trade] = Trade.get_open_trades_without_assigned_fees()
|
trades: List[Trade] = Trade.get_open_trades_without_assigned_fees()
|
||||||
for trade in trades:
|
for trade in trades:
|
||||||
if trade.is_open and not trade.fee_updated(trade.enter_side):
|
if trade.is_open and not trade.fee_updated(trade.entry_side):
|
||||||
order = trade.select_order(trade.enter_side, False)
|
order = trade.select_order(trade.entry_side, False)
|
||||||
open_order = trade.select_order(trade.enter_side, True)
|
open_order = trade.select_order(trade.entry_side, True)
|
||||||
if order and open_order is None:
|
if order and open_order is None:
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Updating {trade.enter_side}-fee on trade {trade}"
|
f"Updating {trade.entry_side}-fee on trade {trade}"
|
||||||
f"for order {order.order_id}."
|
f"for order {order.order_id}."
|
||||||
)
|
)
|
||||||
self.update_trade_state(trade, order.order_id, send_msg=False)
|
self.update_trade_state(trade, order.order_id, send_msg=False)
|
||||||
@ -364,7 +364,7 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
if fo and fo['status'] == 'open':
|
if fo and fo['status'] == 'open':
|
||||||
# Assume this as the open order
|
# Assume this as the open order
|
||||||
trade.open_order_id = order.order_id
|
trade.open_order_id = order.order_id
|
||||||
elif order.ft_order_side == trade.enter_side:
|
elif order.ft_order_side == trade.entry_side:
|
||||||
if fo and fo['status'] == 'open':
|
if fo and fo['status'] == 'open':
|
||||||
trade.open_order_id = order.order_id
|
trade.open_order_id = order.order_id
|
||||||
if fo:
|
if fo:
|
||||||
@ -549,9 +549,9 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
order_book_bids = order_book_data_frame['b_size'].sum()
|
order_book_bids = order_book_data_frame['b_size'].sum()
|
||||||
order_book_asks = order_book_data_frame['a_size'].sum()
|
order_book_asks = order_book_data_frame['a_size'].sum()
|
||||||
|
|
||||||
enter_side = order_book_bids if side == SignalDirection.LONG else order_book_asks
|
entry_side = order_book_bids if side == SignalDirection.LONG else order_book_asks
|
||||||
exit_side = order_book_asks if side == SignalDirection.LONG else order_book_bids
|
exit_side = order_book_asks if side == SignalDirection.LONG else order_book_bids
|
||||||
bids_ask_delta = enter_side / exit_side
|
bids_ask_delta = entry_side / exit_side
|
||||||
|
|
||||||
bids = f"Bids: {order_book_bids}"
|
bids = f"Bids: {order_book_bids}"
|
||||||
asks = f"Asks: {order_book_asks}"
|
asks = f"Asks: {order_book_asks}"
|
||||||
@ -1136,7 +1136,7 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
fully_cancelled = self.update_trade_state(trade, trade.open_order_id, order)
|
fully_cancelled = self.update_trade_state(trade, trade.open_order_id, order)
|
||||||
is_entering = order['side'] == trade.enter_side
|
is_entering = order['side'] == trade.entry_side
|
||||||
not_closed = order['status'] == 'open' or fully_cancelled
|
not_closed = order['status'] == 'open' or fully_cancelled
|
||||||
max_timeouts = self.config.get('unfilledtimeout', {}).get('exit_timeout_count', 0)
|
max_timeouts = self.config.get('unfilledtimeout', {}).get('exit_timeout_count', 0)
|
||||||
|
|
||||||
@ -1177,7 +1177,7 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
logger.info('Cannot query order for %s due to %s', trade, traceback.format_exc())
|
logger.info('Cannot query order for %s due to %s', trade, traceback.format_exc())
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if order['side'] == trade.enter_side:
|
if order['side'] == trade.entry_side:
|
||||||
self.handle_cancel_enter(trade, order, constants.CANCEL_REASON['ALL_CANCELLED'])
|
self.handle_cancel_enter(trade, order, constants.CANCEL_REASON['ALL_CANCELLED'])
|
||||||
|
|
||||||
elif order['side'] == trade.exit_side:
|
elif order['side'] == trade.exit_side:
|
||||||
@ -1216,7 +1216,7 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
corder = order
|
corder = order
|
||||||
reason = constants.CANCEL_REASON['CANCELLED_ON_EXCHANGE']
|
reason = constants.CANCEL_REASON['CANCELLED_ON_EXCHANGE']
|
||||||
|
|
||||||
side = trade.enter_side.capitalize()
|
side = trade.entry_side.capitalize()
|
||||||
logger.info('%s order %s for %s.', side, reason, trade)
|
logger.info('%s order %s for %s.', side, reason, trade)
|
||||||
|
|
||||||
# Using filled to determine the filled amount
|
# Using filled to determine the filled amount
|
||||||
@ -1247,7 +1247,7 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
self.update_trade_state(trade, trade.open_order_id, corder)
|
self.update_trade_state(trade, trade.open_order_id, corder)
|
||||||
|
|
||||||
trade.open_order_id = None
|
trade.open_order_id = None
|
||||||
logger.info(f'Partial {trade.enter_side} order timeout for {trade}.')
|
logger.info(f'Partial {trade.entry_side} order timeout for {trade}.')
|
||||||
reason += f", {constants.CANCEL_REASON['PARTIALLY_FILLED']}"
|
reason += f", {constants.CANCEL_REASON['PARTIALLY_FILLED']}"
|
||||||
|
|
||||||
self.wallets.update()
|
self.wallets.update()
|
||||||
@ -1577,7 +1577,7 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
|
|
||||||
if order['status'] in constants.NON_OPEN_EXCHANGE_STATES:
|
if order['status'] in constants.NON_OPEN_EXCHANGE_STATES:
|
||||||
# If a entry order was closed, force update on stoploss on exchange
|
# If a entry order was closed, force update on stoploss on exchange
|
||||||
if order.get('side', None) == trade.enter_side:
|
if order.get('side', None) == trade.entry_side:
|
||||||
trade = self.cancel_stoploss_on_exchange(trade)
|
trade = self.cancel_stoploss_on_exchange(trade)
|
||||||
# TODO: Margin will need to use interest_rate as well.
|
# TODO: Margin will need to use interest_rate as well.
|
||||||
# interest_rate = self.exchange.get_interest_rate()
|
# interest_rate = self.exchange.get_interest_rate()
|
||||||
|
@ -774,8 +774,8 @@ class Backtesting:
|
|||||||
ft_pair=trade.pair,
|
ft_pair=trade.pair,
|
||||||
order_id=str(self.order_id_counter),
|
order_id=str(self.order_id_counter),
|
||||||
symbol=trade.pair,
|
symbol=trade.pair,
|
||||||
ft_order_side=trade.enter_side,
|
ft_order_side=trade.entry_side,
|
||||||
side=trade.enter_side,
|
side=trade.entry_side,
|
||||||
order_type=order_type,
|
order_type=order_type,
|
||||||
status="open",
|
status="open",
|
||||||
order_date=current_time,
|
order_date=current_time,
|
||||||
@ -857,7 +857,7 @@ class Backtesting:
|
|||||||
|
|
||||||
timedout = self.strategy.ft_check_timed_out(trade, order, current_time)
|
timedout = self.strategy.ft_check_timed_out(trade, order, current_time)
|
||||||
if timedout:
|
if timedout:
|
||||||
if order.side == trade.enter_side:
|
if order.side == trade.entry_side:
|
||||||
self.timedout_entry_orders += 1
|
self.timedout_entry_orders += 1
|
||||||
if trade.nr_of_successful_entries == 0:
|
if trade.nr_of_successful_entries == 0:
|
||||||
# Remove trade due to entry timeout expiration.
|
# Remove trade due to entry timeout expiration.
|
||||||
@ -972,7 +972,7 @@ class Backtesting:
|
|||||||
|
|
||||||
for trade in list(open_trades[pair]):
|
for trade in list(open_trades[pair]):
|
||||||
# 3. Process entry orders.
|
# 3. Process entry orders.
|
||||||
order = trade.select_order(trade.enter_side, is_open=True)
|
order = trade.select_order(trade.entry_side, is_open=True)
|
||||||
if order and self._get_order_filled(order.price, row):
|
if order and self._get_order_filled(order.price, row):
|
||||||
order.close_bt_order(current_time)
|
order.close_bt_order(current_time)
|
||||||
trade.open_order_id = None
|
trade.open_order_id = None
|
||||||
|
@ -372,6 +372,12 @@ class LocalTrade():
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def enter_side(self) -> str:
|
def enter_side(self) -> str:
|
||||||
|
""" DEPRECATED, please use entry_side instead"""
|
||||||
|
# TODO: Please remove me after 2022.5
|
||||||
|
return self.entry_side
|
||||||
|
|
||||||
|
@property
|
||||||
|
def entry_side(self) -> str:
|
||||||
if self.is_short:
|
if self.is_short:
|
||||||
return "sell"
|
return "sell"
|
||||||
else:
|
else:
|
||||||
@ -412,7 +418,7 @@ class LocalTrade():
|
|||||||
|
|
||||||
def to_json(self) -> Dict[str, Any]:
|
def to_json(self) -> Dict[str, Any]:
|
||||||
filled_orders = self.select_filled_orders()
|
filled_orders = self.select_filled_orders()
|
||||||
orders = [order.to_json(self.enter_side) for order in filled_orders]
|
orders = [order.to_json(self.entry_side) for order in filled_orders]
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'trade_id': self.id,
|
'trade_id': self.id,
|
||||||
@ -601,7 +607,7 @@ class LocalTrade():
|
|||||||
|
|
||||||
logger.info(f'Updating trade (id={self.id}) ...')
|
logger.info(f'Updating trade (id={self.id}) ...')
|
||||||
|
|
||||||
if order.ft_order_side == self.enter_side:
|
if order.ft_order_side == self.entry_side:
|
||||||
# Update open rate and actual amount
|
# Update open rate and actual amount
|
||||||
self.open_rate = order.safe_price
|
self.open_rate = order.safe_price
|
||||||
self.amount = order.safe_amount_after_fee
|
self.amount = order.safe_amount_after_fee
|
||||||
@ -650,7 +656,7 @@ class LocalTrade():
|
|||||||
"""
|
"""
|
||||||
Update Fee parameters. Only acts once per side
|
Update Fee parameters. Only acts once per side
|
||||||
"""
|
"""
|
||||||
if self.enter_side == side and self.fee_open_currency is None:
|
if self.entry_side == side and self.fee_open_currency is None:
|
||||||
self.fee_open_cost = fee_cost
|
self.fee_open_cost = fee_cost
|
||||||
self.fee_open_currency = fee_currency
|
self.fee_open_currency = fee_currency
|
||||||
if fee_rate is not None:
|
if fee_rate is not None:
|
||||||
@ -667,7 +673,7 @@ class LocalTrade():
|
|||||||
"""
|
"""
|
||||||
Verify if this side (buy / sell) has already been updated
|
Verify if this side (buy / sell) has already been updated
|
||||||
"""
|
"""
|
||||||
if self.enter_side == side:
|
if self.entry_side == side:
|
||||||
return self.fee_open_currency is not None
|
return self.fee_open_currency is not None
|
||||||
elif self.exit_side == side:
|
elif self.exit_side == side:
|
||||||
return self.fee_close_currency is not None
|
return self.fee_close_currency is not None
|
||||||
@ -840,7 +846,7 @@ class LocalTrade():
|
|||||||
def recalc_trade_from_orders(self):
|
def recalc_trade_from_orders(self):
|
||||||
# We need at least 2 entry orders for averaging amounts and rates.
|
# We need at least 2 entry orders for averaging amounts and rates.
|
||||||
# TODO: this condition could probably be removed
|
# TODO: this condition could probably be removed
|
||||||
if len(self.select_filled_orders(self.enter_side)) < 2:
|
if len(self.select_filled_orders(self.entry_side)) < 2:
|
||||||
self.stake_amount = self.amount * self.open_rate / self.leverage
|
self.stake_amount = self.amount * self.open_rate / self.leverage
|
||||||
|
|
||||||
# Just in case, still recalc open trade value
|
# Just in case, still recalc open trade value
|
||||||
@ -851,7 +857,7 @@ class LocalTrade():
|
|||||||
total_stake = 0.0
|
total_stake = 0.0
|
||||||
for o in self.orders:
|
for o in self.orders:
|
||||||
if (o.ft_is_open or
|
if (o.ft_is_open or
|
||||||
(o.ft_order_side != self.enter_side) or
|
(o.ft_order_side != self.entry_side) or
|
||||||
(o.status not in NON_OPEN_EXCHANGE_STATES)):
|
(o.status not in NON_OPEN_EXCHANGE_STATES)):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -919,7 +925,7 @@ class LocalTrade():
|
|||||||
:return: int count of entry orders that have been filled for this trade.
|
:return: int count of entry orders that have been filled for this trade.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return len(self.select_filled_orders(self.enter_side))
|
return len(self.select_filled_orders(self.entry_side))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def nr_of_successful_exits(self) -> int:
|
def nr_of_successful_exits(self) -> int:
|
||||||
|
@ -695,7 +695,7 @@ class RPC:
|
|||||||
if trade.open_order_id:
|
if trade.open_order_id:
|
||||||
order = self._freqtrade.exchange.fetch_order(trade.open_order_id, trade.pair)
|
order = self._freqtrade.exchange.fetch_order(trade.open_order_id, trade.pair)
|
||||||
|
|
||||||
if order['side'] == trade.enter_side:
|
if order['side'] == trade.entry_side:
|
||||||
fully_canceled = self._freqtrade.handle_cancel_enter(
|
fully_canceled = self._freqtrade.handle_cancel_enter(
|
||||||
trade, order, CANCEL_REASON['FORCE_EXIT'])
|
trade, order, CANCEL_REASON['FORCE_EXIT'])
|
||||||
|
|
||||||
|
@ -233,11 +233,11 @@ class Telegram(RPCHandler):
|
|||||||
is_fill = msg['type'] in [RPCMessageType.ENTRY_FILL]
|
is_fill = msg['type'] in [RPCMessageType.ENTRY_FILL]
|
||||||
emoji = '\N{CHECK MARK}' if is_fill else '\N{LARGE BLUE CIRCLE}'
|
emoji = '\N{CHECK MARK}' if is_fill else '\N{LARGE BLUE CIRCLE}'
|
||||||
|
|
||||||
enter_side = ({'enter': 'Long', 'entered': 'Longed'} if msg['direction'] == 'Long'
|
entry_side = ({'enter': 'Long', 'entered': 'Longed'} if msg['direction'] == 'Long'
|
||||||
else {'enter': 'Short', 'entered': 'Shorted'})
|
else {'enter': 'Short', 'entered': 'Shorted'})
|
||||||
message = (
|
message = (
|
||||||
f"{emoji} *{msg['exchange']}:*"
|
f"{emoji} *{msg['exchange']}:*"
|
||||||
f" {enter_side['entered'] if is_fill else enter_side['enter']} {msg['pair']}"
|
f" {entry_side['entered'] if is_fill else entry_side['enter']} {msg['pair']}"
|
||||||
f" (#{msg['trade_id']})\n"
|
f" (#{msg['trade_id']})\n"
|
||||||
)
|
)
|
||||||
message += f"*Enter Tag:* `{msg['enter_tag']}`\n" if msg.get('enter_tag', None) else ""
|
message += f"*Enter Tag:* `{msg['enter_tag']}`\n" if msg.get('enter_tag', None) else ""
|
||||||
|
@ -1044,7 +1044,7 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||||||
FT Internal method.
|
FT Internal method.
|
||||||
Check if timeout is active, and if the order is still open and timed out
|
Check if timeout is active, and if the order is still open and timed out
|
||||||
"""
|
"""
|
||||||
side = 'entry' if order.ft_order_side == trade.enter_side else 'exit'
|
side = 'entry' if order.ft_order_side == trade.entry_side else 'exit'
|
||||||
|
|
||||||
timeout = self.config.get('unfilledtimeout', {}).get(side)
|
timeout = self.config.get('unfilledtimeout', {}).get(side)
|
||||||
if timeout is not None:
|
if timeout is not None:
|
||||||
|
@ -6,7 +6,7 @@ from freqtrade.persistence.models import Order, Trade
|
|||||||
MOCK_TRADE_COUNT = 6
|
MOCK_TRADE_COUNT = 6
|
||||||
|
|
||||||
|
|
||||||
def enter_side(is_short: bool):
|
def entry_side(is_short: bool):
|
||||||
return "sell" if is_short else "buy"
|
return "sell" if is_short else "buy"
|
||||||
|
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ def mock_order_1(is_short: bool):
|
|||||||
'id': f'1234_{direc(is_short)}',
|
'id': f'1234_{direc(is_short)}',
|
||||||
'symbol': 'ETH/BTC',
|
'symbol': 'ETH/BTC',
|
||||||
'status': 'closed',
|
'status': 'closed',
|
||||||
'side': enter_side(is_short),
|
'side': entry_side(is_short),
|
||||||
'type': 'limit',
|
'type': 'limit',
|
||||||
'price': 0.123,
|
'price': 0.123,
|
||||||
'average': 0.123,
|
'average': 0.123,
|
||||||
@ -50,7 +50,7 @@ def mock_trade_1(fee, is_short: bool):
|
|||||||
timeframe=5,
|
timeframe=5,
|
||||||
is_short=is_short
|
is_short=is_short
|
||||||
)
|
)
|
||||||
o = Order.parse_from_ccxt_object(mock_order_1(is_short), 'ETH/BTC', enter_side(is_short))
|
o = Order.parse_from_ccxt_object(mock_order_1(is_short), 'ETH/BTC', entry_side(is_short))
|
||||||
trade.orders.append(o)
|
trade.orders.append(o)
|
||||||
return trade
|
return trade
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ def mock_order_2(is_short: bool):
|
|||||||
'id': f'1235_{direc(is_short)}',
|
'id': f'1235_{direc(is_short)}',
|
||||||
'symbol': 'ETC/BTC',
|
'symbol': 'ETC/BTC',
|
||||||
'status': 'closed',
|
'status': 'closed',
|
||||||
'side': enter_side(is_short),
|
'side': entry_side(is_short),
|
||||||
'type': 'limit',
|
'type': 'limit',
|
||||||
'price': 0.123,
|
'price': 0.123,
|
||||||
'amount': 123.0,
|
'amount': 123.0,
|
||||||
@ -109,7 +109,7 @@ def mock_trade_2(fee, is_short: bool):
|
|||||||
close_date=datetime.now(tz=timezone.utc) - timedelta(minutes=2),
|
close_date=datetime.now(tz=timezone.utc) - timedelta(minutes=2),
|
||||||
is_short=is_short
|
is_short=is_short
|
||||||
)
|
)
|
||||||
o = Order.parse_from_ccxt_object(mock_order_2(is_short), 'ETC/BTC', enter_side(is_short))
|
o = Order.parse_from_ccxt_object(mock_order_2(is_short), 'ETC/BTC', entry_side(is_short))
|
||||||
trade.orders.append(o)
|
trade.orders.append(o)
|
||||||
o = Order.parse_from_ccxt_object(mock_order_2_sell(is_short), 'ETC/BTC', exit_side(is_short))
|
o = Order.parse_from_ccxt_object(mock_order_2_sell(is_short), 'ETC/BTC', exit_side(is_short))
|
||||||
trade.orders.append(o)
|
trade.orders.append(o)
|
||||||
@ -121,7 +121,7 @@ def mock_order_3(is_short: bool):
|
|||||||
'id': f'41231a12a_{direc(is_short)}',
|
'id': f'41231a12a_{direc(is_short)}',
|
||||||
'symbol': 'XRP/BTC',
|
'symbol': 'XRP/BTC',
|
||||||
'status': 'closed',
|
'status': 'closed',
|
||||||
'side': enter_side(is_short),
|
'side': entry_side(is_short),
|
||||||
'type': 'limit',
|
'type': 'limit',
|
||||||
'price': 0.05,
|
'price': 0.05,
|
||||||
'amount': 123.0,
|
'amount': 123.0,
|
||||||
@ -169,7 +169,7 @@ def mock_trade_3(fee, is_short: bool):
|
|||||||
close_date=datetime.now(tz=timezone.utc),
|
close_date=datetime.now(tz=timezone.utc),
|
||||||
is_short=is_short
|
is_short=is_short
|
||||||
)
|
)
|
||||||
o = Order.parse_from_ccxt_object(mock_order_3(is_short), 'XRP/BTC', enter_side(is_short))
|
o = Order.parse_from_ccxt_object(mock_order_3(is_short), 'XRP/BTC', entry_side(is_short))
|
||||||
trade.orders.append(o)
|
trade.orders.append(o)
|
||||||
o = Order.parse_from_ccxt_object(mock_order_3_sell(is_short), 'XRP/BTC', exit_side(is_short))
|
o = Order.parse_from_ccxt_object(mock_order_3_sell(is_short), 'XRP/BTC', exit_side(is_short))
|
||||||
trade.orders.append(o)
|
trade.orders.append(o)
|
||||||
@ -181,7 +181,7 @@ def mock_order_4(is_short: bool):
|
|||||||
'id': f'prod_buy_{direc(is_short)}_12345',
|
'id': f'prod_buy_{direc(is_short)}_12345',
|
||||||
'symbol': 'ETC/BTC',
|
'symbol': 'ETC/BTC',
|
||||||
'status': 'open',
|
'status': 'open',
|
||||||
'side': enter_side(is_short),
|
'side': entry_side(is_short),
|
||||||
'type': 'limit',
|
'type': 'limit',
|
||||||
'price': 0.123,
|
'price': 0.123,
|
||||||
'amount': 123.0,
|
'amount': 123.0,
|
||||||
@ -210,7 +210,7 @@ def mock_trade_4(fee, is_short: bool):
|
|||||||
timeframe=5,
|
timeframe=5,
|
||||||
is_short=is_short
|
is_short=is_short
|
||||||
)
|
)
|
||||||
o = Order.parse_from_ccxt_object(mock_order_4(is_short), 'ETC/BTC', enter_side(is_short))
|
o = Order.parse_from_ccxt_object(mock_order_4(is_short), 'ETC/BTC', entry_side(is_short))
|
||||||
trade.orders.append(o)
|
trade.orders.append(o)
|
||||||
return trade
|
return trade
|
||||||
|
|
||||||
@ -220,7 +220,7 @@ def mock_order_5(is_short: bool):
|
|||||||
'id': f'prod_buy_{direc(is_short)}_3455',
|
'id': f'prod_buy_{direc(is_short)}_3455',
|
||||||
'symbol': 'XRP/BTC',
|
'symbol': 'XRP/BTC',
|
||||||
'status': 'closed',
|
'status': 'closed',
|
||||||
'side': enter_side(is_short),
|
'side': entry_side(is_short),
|
||||||
'type': 'limit',
|
'type': 'limit',
|
||||||
'price': 0.123,
|
'price': 0.123,
|
||||||
'amount': 123.0,
|
'amount': 123.0,
|
||||||
@ -264,7 +264,7 @@ def mock_trade_5(fee, is_short: bool):
|
|||||||
timeframe=5,
|
timeframe=5,
|
||||||
is_short=is_short
|
is_short=is_short
|
||||||
)
|
)
|
||||||
o = Order.parse_from_ccxt_object(mock_order_5(is_short), 'XRP/BTC', enter_side(is_short))
|
o = Order.parse_from_ccxt_object(mock_order_5(is_short), 'XRP/BTC', entry_side(is_short))
|
||||||
trade.orders.append(o)
|
trade.orders.append(o)
|
||||||
o = Order.parse_from_ccxt_object(mock_order_5_stoploss(is_short), 'XRP/BTC', 'stoploss')
|
o = Order.parse_from_ccxt_object(mock_order_5_stoploss(is_short), 'XRP/BTC', 'stoploss')
|
||||||
trade.orders.append(o)
|
trade.orders.append(o)
|
||||||
@ -276,7 +276,7 @@ def mock_order_6(is_short: bool):
|
|||||||
'id': f'prod_buy_{direc(is_short)}_6',
|
'id': f'prod_buy_{direc(is_short)}_6',
|
||||||
'symbol': 'LTC/BTC',
|
'symbol': 'LTC/BTC',
|
||||||
'status': 'closed',
|
'status': 'closed',
|
||||||
'side': enter_side(is_short),
|
'side': entry_side(is_short),
|
||||||
'type': 'limit',
|
'type': 'limit',
|
||||||
'price': 0.15,
|
'price': 0.15,
|
||||||
'amount': 2.0,
|
'amount': 2.0,
|
||||||
@ -320,7 +320,7 @@ def mock_trade_6(fee, is_short: bool):
|
|||||||
timeframe=5,
|
timeframe=5,
|
||||||
is_short=is_short
|
is_short=is_short
|
||||||
)
|
)
|
||||||
o = Order.parse_from_ccxt_object(mock_order_6(is_short), 'LTC/BTC', enter_side(is_short))
|
o = Order.parse_from_ccxt_object(mock_order_6(is_short), 'LTC/BTC', entry_side(is_short))
|
||||||
trade.orders.append(o)
|
trade.orders.append(o)
|
||||||
o = Order.parse_from_ccxt_object(mock_order_6_sell(is_short), 'LTC/BTC', exit_side(is_short))
|
o = Order.parse_from_ccxt_object(mock_order_6_sell(is_short), 'LTC/BTC', exit_side(is_short))
|
||||||
trade.orders.append(o)
|
trade.orders.append(o)
|
||||||
|
@ -183,7 +183,7 @@ class StrategyTestV3(IStrategy):
|
|||||||
current_profit: float, min_stake: float, max_stake: float, **kwargs):
|
current_profit: float, min_stake: float, max_stake: float, **kwargs):
|
||||||
|
|
||||||
if current_profit < -0.0075:
|
if current_profit < -0.0075:
|
||||||
orders = trade.select_filled_orders(trade.enter_side)
|
orders = trade.select_filled_orders(trade.entry_side)
|
||||||
return round(orders[0].cost, 0)
|
return round(orders[0].cost, 0)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
@ -25,7 +25,7 @@ from freqtrade.worker import Worker
|
|||||||
from tests.conftest import (create_mock_trades, get_patched_freqtradebot, get_patched_worker,
|
from tests.conftest import (create_mock_trades, get_patched_freqtradebot, get_patched_worker,
|
||||||
log_has, log_has_re, patch_edge, patch_exchange, patch_get_signal,
|
log_has, log_has_re, patch_edge, patch_exchange, patch_get_signal,
|
||||||
patch_wallet, patch_whitelist)
|
patch_wallet, patch_whitelist)
|
||||||
from tests.conftest_trades import (MOCK_TRADE_COUNT, enter_side, exit_side, mock_order_1,
|
from tests.conftest_trades import (MOCK_TRADE_COUNT, entry_side, exit_side, mock_order_1,
|
||||||
mock_order_2, mock_order_2_sell, mock_order_3, mock_order_3_sell,
|
mock_order_2, mock_order_2_sell, mock_order_3, mock_order_3_sell,
|
||||||
mock_order_4, mock_order_5_stoploss, mock_order_6_sell)
|
mock_order_4, mock_order_5_stoploss, mock_order_6_sell)
|
||||||
|
|
||||||
@ -303,7 +303,7 @@ def test_create_trade(default_conf_usdt, ticker_usdt, limit_order,
|
|||||||
|
|
||||||
# Simulate fulfilled LIMIT_BUY order for trade
|
# Simulate fulfilled LIMIT_BUY order for trade
|
||||||
oobj = Order.parse_from_ccxt_object(
|
oobj = Order.parse_from_ccxt_object(
|
||||||
limit_order[enter_side(is_short)], 'ADA/USDT', enter_side(is_short))
|
limit_order[entry_side(is_short)], 'ADA/USDT', entry_side(is_short))
|
||||||
trade.update_trade(oobj)
|
trade.update_trade(oobj)
|
||||||
|
|
||||||
assert trade.open_rate == open_rate
|
assert trade.open_rate == open_rate
|
||||||
@ -341,7 +341,7 @@ def test_create_trade_minimal_amount(
|
|||||||
) -> None:
|
) -> None:
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
enter_mock = MagicMock(return_value=limit_order_open[enter_side(is_short)])
|
enter_mock = MagicMock(return_value=limit_order_open[entry_side(is_short)])
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
fetch_ticker=ticker_usdt,
|
fetch_ticker=ticker_usdt,
|
||||||
@ -537,8 +537,8 @@ def test_process_trade_creation(default_conf_usdt, ticker_usdt, limit_order, lim
|
|||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
fetch_ticker=ticker_usdt,
|
fetch_ticker=ticker_usdt,
|
||||||
create_order=MagicMock(return_value=limit_order_open[enter_side(is_short)]),
|
create_order=MagicMock(return_value=limit_order_open[entry_side(is_short)]),
|
||||||
fetch_order=MagicMock(return_value=limit_order[enter_side(is_short)]),
|
fetch_order=MagicMock(return_value=limit_order[entry_side(is_short)]),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
)
|
)
|
||||||
freqtrade = FreqtradeBot(default_conf_usdt)
|
freqtrade = FreqtradeBot(default_conf_usdt)
|
||||||
@ -751,8 +751,8 @@ def test_execute_entry(mocker, default_conf_usdt, fee, limit_order,
|
|||||||
(10 - (2 / 1)) / (1 - (0.01 + 0.0006)) = 8.085708510208207
|
(10 - (2 / 1)) / (1 - (0.01 + 0.0006)) = 8.085708510208207
|
||||||
"""
|
"""
|
||||||
# TODO: Split this test into multiple tests to improve readability
|
# TODO: Split this test into multiple tests to improve readability
|
||||||
open_order = limit_order_open[enter_side(is_short)]
|
open_order = limit_order_open[entry_side(is_short)]
|
||||||
order = limit_order[enter_side(is_short)]
|
order = limit_order[entry_side(is_short)]
|
||||||
default_conf_usdt['trading_mode'] = trading_mode
|
default_conf_usdt['trading_mode'] = trading_mode
|
||||||
default_conf_usdt['liquidation_buffer'] = liq_buffer
|
default_conf_usdt['liquidation_buffer'] = liq_buffer
|
||||||
leverage = 1.0 if trading_mode == 'spot' else 5.0
|
leverage = 1.0 if trading_mode == 'spot' else 5.0
|
||||||
@ -975,7 +975,7 @@ def test_execute_entry_confirm_error(mocker, default_conf_usdt, fee, limit_order
|
|||||||
'ask': 2.2,
|
'ask': 2.2,
|
||||||
'last': 1.9
|
'last': 1.9
|
||||||
}),
|
}),
|
||||||
create_order=MagicMock(return_value=limit_order[enter_side(is_short)]),
|
create_order=MagicMock(return_value=limit_order[entry_side(is_short)]),
|
||||||
get_rate=MagicMock(return_value=0.11),
|
get_rate=MagicMock(return_value=0.11),
|
||||||
get_min_pair_stake_amount=MagicMock(return_value=1),
|
get_min_pair_stake_amount=MagicMock(return_value=1),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
@ -986,11 +986,11 @@ def test_execute_entry_confirm_error(mocker, default_conf_usdt, fee, limit_order
|
|||||||
freqtrade.strategy.confirm_trade_entry = MagicMock(side_effect=ValueError)
|
freqtrade.strategy.confirm_trade_entry = MagicMock(side_effect=ValueError)
|
||||||
assert freqtrade.execute_entry(pair, stake_amount)
|
assert freqtrade.execute_entry(pair, stake_amount)
|
||||||
|
|
||||||
limit_order[enter_side(is_short)]['id'] = '222'
|
limit_order[entry_side(is_short)]['id'] = '222'
|
||||||
freqtrade.strategy.confirm_trade_entry = MagicMock(side_effect=Exception)
|
freqtrade.strategy.confirm_trade_entry = MagicMock(side_effect=Exception)
|
||||||
assert freqtrade.execute_entry(pair, stake_amount)
|
assert freqtrade.execute_entry(pair, stake_amount)
|
||||||
|
|
||||||
limit_order[enter_side(is_short)]['id'] = '2223'
|
limit_order[entry_side(is_short)]['id'] = '2223'
|
||||||
freqtrade.strategy.confirm_trade_entry = MagicMock(return_value=True)
|
freqtrade.strategy.confirm_trade_entry = MagicMock(return_value=True)
|
||||||
assert freqtrade.execute_entry(pair, stake_amount)
|
assert freqtrade.execute_entry(pair, stake_amount)
|
||||||
|
|
||||||
@ -1010,7 +1010,7 @@ def test_execute_entry_min_leverage(mocker, default_conf_usdt, fee, limit_order,
|
|||||||
'ask': 2.2,
|
'ask': 2.2,
|
||||||
'last': 1.9
|
'last': 1.9
|
||||||
}),
|
}),
|
||||||
create_order=MagicMock(return_value=limit_order[enter_side(is_short)]),
|
create_order=MagicMock(return_value=limit_order[entry_side(is_short)]),
|
||||||
get_rate=MagicMock(return_value=0.11),
|
get_rate=MagicMock(return_value=0.11),
|
||||||
# Minimum stake-amount is ~5$
|
# Minimum stake-amount is ~5$
|
||||||
get_maintenance_ratio_and_amt=MagicMock(return_value=(0.0, 0.0)),
|
get_maintenance_ratio_and_amt=MagicMock(return_value=(0.0, 0.0)),
|
||||||
@ -1032,7 +1032,7 @@ def test_execute_entry_min_leverage(mocker, default_conf_usdt, fee, limit_order,
|
|||||||
def test_add_stoploss_on_exchange(mocker, default_conf_usdt, limit_order, is_short) -> None:
|
def test_add_stoploss_on_exchange(mocker, default_conf_usdt, limit_order, is_short) -> None:
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
order = limit_order[enter_side(is_short)]
|
order = limit_order[entry_side(is_short)]
|
||||||
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.handle_trade', MagicMock(return_value=True))
|
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.handle_trade', MagicMock(return_value=True))
|
||||||
mocker.patch('freqtrade.exchange.Exchange.fetch_order', return_value=order)
|
mocker.patch('freqtrade.exchange.Exchange.fetch_order', return_value=order)
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=[])
|
mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=[])
|
||||||
@ -1062,7 +1062,7 @@ def test_add_stoploss_on_exchange(mocker, default_conf_usdt, limit_order, is_sho
|
|||||||
def test_handle_stoploss_on_exchange(mocker, default_conf_usdt, fee, caplog, is_short,
|
def test_handle_stoploss_on_exchange(mocker, default_conf_usdt, fee, caplog, is_short,
|
||||||
limit_order) -> None:
|
limit_order) -> None:
|
||||||
stoploss = MagicMock(return_value={'id': 13434334})
|
stoploss = MagicMock(return_value={'id': 13434334})
|
||||||
enter_order = limit_order[enter_side(is_short)]
|
enter_order = limit_order[entry_side(is_short)]
|
||||||
exit_order = limit_order[exit_side(is_short)]
|
exit_order = limit_order[exit_side(is_short)]
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
@ -1217,7 +1217,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf_usdt, fee, caplog, is_
|
|||||||
def test_handle_sle_cancel_cant_recreate(mocker, default_conf_usdt, fee, caplog, is_short,
|
def test_handle_sle_cancel_cant_recreate(mocker, default_conf_usdt, fee, caplog, is_short,
|
||||||
limit_order) -> None:
|
limit_order) -> None:
|
||||||
# Sixth case: stoploss order was cancelled but couldn't create new one
|
# Sixth case: stoploss order was cancelled but couldn't create new one
|
||||||
enter_order = limit_order[enter_side(is_short)]
|
enter_order = limit_order[entry_side(is_short)]
|
||||||
exit_order = limit_order[exit_side(is_short)]
|
exit_order = limit_order[exit_side(is_short)]
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
@ -1260,7 +1260,7 @@ def test_handle_sle_cancel_cant_recreate(mocker, default_conf_usdt, fee, caplog,
|
|||||||
def test_create_stoploss_order_invalid_order(
|
def test_create_stoploss_order_invalid_order(
|
||||||
mocker, default_conf_usdt, caplog, fee, is_short, limit_order, limit_order_open
|
mocker, default_conf_usdt, caplog, fee, is_short, limit_order, limit_order_open
|
||||||
):
|
):
|
||||||
open_order = limit_order_open[enter_side(is_short)]
|
open_order = limit_order_open[entry_side(is_short)]
|
||||||
order = limit_order[exit_side(is_short)]
|
order = limit_order[exit_side(is_short)]
|
||||||
rpc_mock = patch_RPCManager(mocker)
|
rpc_mock = patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
@ -1325,7 +1325,7 @@ def test_create_stoploss_order_insufficient_funds(
|
|||||||
'last': 1.9
|
'last': 1.9
|
||||||
}),
|
}),
|
||||||
create_order=MagicMock(side_effect=[
|
create_order=MagicMock(side_effect=[
|
||||||
limit_order[enter_side(is_short)],
|
limit_order[entry_side(is_short)],
|
||||||
exit_order,
|
exit_order,
|
||||||
]),
|
]),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
@ -1364,7 +1364,7 @@ def test_handle_stoploss_on_exchange_trailing(
|
|||||||
mocker, default_conf_usdt, fee, is_short, bid, ask, limit_order, stop_price, amt, hang_price
|
mocker, default_conf_usdt, fee, is_short, bid, ask, limit_order, stop_price, amt, hang_price
|
||||||
) -> None:
|
) -> None:
|
||||||
# When trailing stoploss is set
|
# When trailing stoploss is set
|
||||||
enter_order = limit_order[enter_side(is_short)]
|
enter_order = limit_order[entry_side(is_short)]
|
||||||
exit_order = limit_order[exit_side(is_short)]
|
exit_order = limit_order[exit_side(is_short)]
|
||||||
stoploss = MagicMock(return_value={'id': 13434334})
|
stoploss = MagicMock(return_value={'id': 13434334})
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
@ -1485,7 +1485,7 @@ def test_handle_stoploss_on_exchange_trailing(
|
|||||||
def test_handle_stoploss_on_exchange_trailing_error(
|
def test_handle_stoploss_on_exchange_trailing_error(
|
||||||
mocker, default_conf_usdt, fee, caplog, limit_order, is_short
|
mocker, default_conf_usdt, fee, caplog, limit_order, is_short
|
||||||
) -> None:
|
) -> None:
|
||||||
enter_order = limit_order[enter_side(is_short)]
|
enter_order = limit_order[entry_side(is_short)]
|
||||||
exit_order = limit_order[exit_side(is_short)]
|
exit_order = limit_order[exit_side(is_short)]
|
||||||
# When trailing stoploss is set
|
# When trailing stoploss is set
|
||||||
stoploss = MagicMock(return_value={'id': 13434334})
|
stoploss = MagicMock(return_value={'id': 13434334})
|
||||||
@ -1593,7 +1593,7 @@ def test_stoploss_on_exchange_price_rounding(
|
|||||||
def test_handle_stoploss_on_exchange_custom_stop(
|
def test_handle_stoploss_on_exchange_custom_stop(
|
||||||
mocker, default_conf_usdt, fee, is_short, limit_order
|
mocker, default_conf_usdt, fee, is_short, limit_order
|
||||||
) -> None:
|
) -> None:
|
||||||
enter_order = limit_order[enter_side(is_short)]
|
enter_order = limit_order[entry_side(is_short)]
|
||||||
exit_order = limit_order[exit_side(is_short)]
|
exit_order = limit_order[exit_side(is_short)]
|
||||||
# When trailing stoploss is set
|
# When trailing stoploss is set
|
||||||
stoploss = MagicMock(return_value={'id': 13434334})
|
stoploss = MagicMock(return_value={'id': 13434334})
|
||||||
@ -1860,10 +1860,10 @@ def test_exit_positions(mocker, default_conf_usdt, limit_order, is_short, caplog
|
|||||||
|
|
||||||
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.handle_trade', MagicMock(return_value=True))
|
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.handle_trade', MagicMock(return_value=True))
|
||||||
mocker.patch('freqtrade.exchange.Exchange.fetch_order',
|
mocker.patch('freqtrade.exchange.Exchange.fetch_order',
|
||||||
return_value=limit_order[enter_side(is_short)])
|
return_value=limit_order[entry_side(is_short)])
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=[])
|
mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=[])
|
||||||
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_real_amount',
|
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_real_amount',
|
||||||
return_value=limit_order[enter_side(is_short)]['amount'])
|
return_value=limit_order[entry_side(is_short)]['amount'])
|
||||||
|
|
||||||
trade = MagicMock()
|
trade = MagicMock()
|
||||||
trade.is_short = is_short
|
trade.is_short = is_short
|
||||||
@ -1886,7 +1886,7 @@ def test_exit_positions(mocker, default_conf_usdt, limit_order, is_short, caplog
|
|||||||
@pytest.mark.parametrize("is_short", [False, True])
|
@pytest.mark.parametrize("is_short", [False, True])
|
||||||
def test_exit_positions_exception(mocker, default_conf_usdt, limit_order, caplog, is_short) -> None:
|
def test_exit_positions_exception(mocker, default_conf_usdt, limit_order, caplog, is_short) -> None:
|
||||||
freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt)
|
freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt)
|
||||||
order = limit_order[enter_side(is_short)]
|
order = limit_order[entry_side(is_short)]
|
||||||
mocker.patch('freqtrade.exchange.Exchange.fetch_order', return_value=order)
|
mocker.patch('freqtrade.exchange.Exchange.fetch_order', return_value=order)
|
||||||
|
|
||||||
trade = MagicMock()
|
trade = MagicMock()
|
||||||
@ -1909,7 +1909,7 @@ def test_exit_positions_exception(mocker, default_conf_usdt, limit_order, caplog
|
|||||||
@pytest.mark.parametrize("is_short", [False, True])
|
@pytest.mark.parametrize("is_short", [False, True])
|
||||||
def test_update_trade_state(mocker, default_conf_usdt, limit_order, is_short, caplog) -> None:
|
def test_update_trade_state(mocker, default_conf_usdt, limit_order, is_short, caplog) -> None:
|
||||||
freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt)
|
freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt)
|
||||||
order = limit_order[enter_side(is_short)]
|
order = limit_order[entry_side(is_short)]
|
||||||
|
|
||||||
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.handle_trade', MagicMock(return_value=True))
|
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.handle_trade', MagicMock(return_value=True))
|
||||||
mocker.patch('freqtrade.exchange.Exchange.fetch_order', return_value=order)
|
mocker.patch('freqtrade.exchange.Exchange.fetch_order', return_value=order)
|
||||||
@ -1930,7 +1930,7 @@ def test_update_trade_state(mocker, default_conf_usdt, limit_order, is_short, ca
|
|||||||
leverage=1,
|
leverage=1,
|
||||||
)
|
)
|
||||||
trade.orders.append(Order(
|
trade.orders.append(Order(
|
||||||
ft_order_side=enter_side(is_short),
|
ft_order_side=entry_side(is_short),
|
||||||
price=0.01,
|
price=0.01,
|
||||||
order_id=order_id,
|
order_id=order_id,
|
||||||
|
|
||||||
@ -1980,7 +1980,7 @@ def test_update_trade_state_withorderdict(
|
|||||||
default_conf_usdt, trades_for_order, limit_order, fee, mocker, initial_amount,
|
default_conf_usdt, trades_for_order, limit_order, fee, mocker, initial_amount,
|
||||||
has_rounding_fee, is_short, caplog
|
has_rounding_fee, is_short, caplog
|
||||||
):
|
):
|
||||||
order = limit_order[enter_side(is_short)]
|
order = limit_order[entry_side(is_short)]
|
||||||
trades_for_order[0]['amount'] = initial_amount
|
trades_for_order[0]['amount'] = initial_amount
|
||||||
order_id = "oid_123456"
|
order_id = "oid_123456"
|
||||||
order['id'] = order_id
|
order['id'] = order_id
|
||||||
@ -2006,7 +2006,7 @@ def test_update_trade_state_withorderdict(
|
|||||||
)
|
)
|
||||||
trade.orders.append(
|
trade.orders.append(
|
||||||
Order(
|
Order(
|
||||||
ft_order_side=enter_side(is_short),
|
ft_order_side=entry_side(is_short),
|
||||||
ft_pair=trade.pair,
|
ft_pair=trade.pair,
|
||||||
ft_is_open=True,
|
ft_is_open=True,
|
||||||
order_id=order_id,
|
order_id=order_id,
|
||||||
@ -2026,7 +2026,7 @@ def test_update_trade_state_withorderdict(
|
|||||||
@pytest.mark.parametrize("is_short", [False, True])
|
@pytest.mark.parametrize("is_short", [False, True])
|
||||||
def test_update_trade_state_exception(mocker, default_conf_usdt, is_short, limit_order,
|
def test_update_trade_state_exception(mocker, default_conf_usdt, is_short, limit_order,
|
||||||
caplog) -> None:
|
caplog) -> None:
|
||||||
order = limit_order[enter_side(is_short)]
|
order = limit_order[entry_side(is_short)]
|
||||||
freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt)
|
freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt)
|
||||||
mocker.patch('freqtrade.exchange.Exchange.fetch_order', return_value=order)
|
mocker.patch('freqtrade.exchange.Exchange.fetch_order', return_value=order)
|
||||||
|
|
||||||
@ -2107,7 +2107,7 @@ def test_handle_trade(
|
|||||||
default_conf_usdt, limit_order_open, limit_order, fee, mocker, is_short, close_profit
|
default_conf_usdt, limit_order_open, limit_order, fee, mocker, is_short, close_profit
|
||||||
) -> None:
|
) -> None:
|
||||||
open_order = limit_order_open[exit_side(is_short)]
|
open_order = limit_order_open[exit_side(is_short)]
|
||||||
enter_order = limit_order[enter_side(is_short)]
|
enter_order = limit_order[entry_side(is_short)]
|
||||||
exit_order = limit_order[exit_side(is_short)]
|
exit_order = limit_order[exit_side(is_short)]
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
@ -2134,7 +2134,7 @@ def test_handle_trade(
|
|||||||
assert trade
|
assert trade
|
||||||
|
|
||||||
time.sleep(0.01) # Race condition fix
|
time.sleep(0.01) # Race condition fix
|
||||||
oobj = Order.parse_from_ccxt_object(enter_order, enter_order['symbol'], enter_side(is_short))
|
oobj = Order.parse_from_ccxt_object(enter_order, enter_order['symbol'], entry_side(is_short))
|
||||||
trade.update_trade(oobj)
|
trade.update_trade(oobj)
|
||||||
assert trade.is_open is True
|
assert trade.is_open is True
|
||||||
freqtrade.wallets.update()
|
freqtrade.wallets.update()
|
||||||
@ -2235,7 +2235,7 @@ def test_handle_overlapping_signals(
|
|||||||
def test_handle_trade_roi(default_conf_usdt, ticker_usdt, limit_order_open, fee, mocker, caplog,
|
def test_handle_trade_roi(default_conf_usdt, ticker_usdt, limit_order_open, fee, mocker, caplog,
|
||||||
is_short) -> None:
|
is_short) -> None:
|
||||||
|
|
||||||
open_order = limit_order_open[enter_side(is_short)]
|
open_order = limit_order_open[entry_side(is_short)]
|
||||||
|
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
|
|
||||||
@ -2278,7 +2278,7 @@ def test_handle_trade_use_sell_signal(
|
|||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
enter_open_order = limit_order_open[exit_side(is_short)]
|
enter_open_order = limit_order_open[exit_side(is_short)]
|
||||||
exit_open_order = limit_order_open[enter_side(is_short)]
|
exit_open_order = limit_order_open[entry_side(is_short)]
|
||||||
|
|
||||||
# use_sell_signal is True buy default
|
# use_sell_signal is True buy default
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
@ -2320,7 +2320,7 @@ def test_close_trade(
|
|||||||
) -> None:
|
) -> None:
|
||||||
open_order = limit_order_open[exit_side(is_short)]
|
open_order = limit_order_open[exit_side(is_short)]
|
||||||
enter_order = limit_order[exit_side(is_short)]
|
enter_order = limit_order[exit_side(is_short)]
|
||||||
exit_order = limit_order[enter_side(is_short)]
|
exit_order = limit_order[entry_side(is_short)]
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
@ -2766,7 +2766,7 @@ def test_check_handle_timedout_partial_fee(
|
|||||||
assert trades[0].amount == (limit_buy_order_old_partial['amount'] -
|
assert trades[0].amount == (limit_buy_order_old_partial['amount'] -
|
||||||
limit_buy_order_old_partial['remaining']) - 0.023
|
limit_buy_order_old_partial['remaining']) - 0.023
|
||||||
assert trades[0].open_order_id is None
|
assert trades[0].open_order_id is None
|
||||||
assert trades[0].fee_updated(open_trade.enter_side)
|
assert trades[0].fee_updated(open_trade.entry_side)
|
||||||
assert pytest.approx(trades[0].fee_open) == 0.001
|
assert pytest.approx(trades[0].fee_open) == 0.001
|
||||||
|
|
||||||
|
|
||||||
@ -2853,8 +2853,8 @@ def test_check_handle_timedout_exception(default_conf_usdt, ticker_usdt, open_tr
|
|||||||
def test_handle_cancel_enter(mocker, caplog, default_conf_usdt, limit_order, is_short) -> None:
|
def test_handle_cancel_enter(mocker, caplog, default_conf_usdt, limit_order, is_short) -> None:
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
l_order = limit_order[enter_side(is_short)]
|
l_order = limit_order[entry_side(is_short)]
|
||||||
cancel_buy_order = deepcopy(limit_order[enter_side(is_short)])
|
cancel_buy_order = deepcopy(limit_order[entry_side(is_short)])
|
||||||
cancel_buy_order['status'] = 'canceled'
|
cancel_buy_order['status'] = 'canceled'
|
||||||
del cancel_buy_order['filled']
|
del cancel_buy_order['filled']
|
||||||
|
|
||||||
@ -2868,7 +2868,7 @@ def test_handle_cancel_enter(mocker, caplog, default_conf_usdt, limit_order, is_
|
|||||||
trade.pair = 'LTC/USDT'
|
trade.pair = 'LTC/USDT'
|
||||||
trade.open_rate = 200
|
trade.open_rate = 200
|
||||||
trade.is_short = False
|
trade.is_short = False
|
||||||
trade.enter_side = "buy"
|
trade.entry_side = "buy"
|
||||||
l_order['filled'] = 0.0
|
l_order['filled'] = 0.0
|
||||||
l_order['status'] = 'open'
|
l_order['status'] = 'open'
|
||||||
reason = CANCEL_REASON['TIMEOUT']
|
reason = CANCEL_REASON['TIMEOUT']
|
||||||
@ -2896,7 +2896,7 @@ def test_handle_cancel_enter(mocker, caplog, default_conf_usdt, limit_order, is_
|
|||||||
assert log_has_re(r"Order .* for .* not cancelled.", caplog)
|
assert log_has_re(r"Order .* for .* not cancelled.", caplog)
|
||||||
# min_pair_stake empty should not crash
|
# min_pair_stake empty should not crash
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_min_pair_stake_amount', return_value=None)
|
mocker.patch('freqtrade.exchange.Exchange.get_min_pair_stake_amount', return_value=None)
|
||||||
assert not freqtrade.handle_cancel_enter(trade, limit_order[enter_side(is_short)], reason)
|
assert not freqtrade.handle_cancel_enter(trade, limit_order[entry_side(is_short)], reason)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("is_short", [False, True])
|
@pytest.mark.parametrize("is_short", [False, True])
|
||||||
@ -2915,11 +2915,11 @@ def test_handle_cancel_enter_exchanges(mocker, caplog, default_conf_usdt, is_sho
|
|||||||
reason = CANCEL_REASON['TIMEOUT']
|
reason = CANCEL_REASON['TIMEOUT']
|
||||||
trade = MagicMock()
|
trade = MagicMock()
|
||||||
trade.pair = 'LTC/ETH'
|
trade.pair = 'LTC/ETH'
|
||||||
trade.enter_side = "sell" if is_short else "buy"
|
trade.entry_side = "sell" if is_short else "buy"
|
||||||
assert freqtrade.handle_cancel_enter(trade, limit_buy_order_canceled_empty, reason)
|
assert freqtrade.handle_cancel_enter(trade, limit_buy_order_canceled_empty, reason)
|
||||||
assert cancel_order_mock.call_count == 0
|
assert cancel_order_mock.call_count == 0
|
||||||
assert log_has_re(
|
assert log_has_re(
|
||||||
f'{trade.enter_side.capitalize()} order fully cancelled. '
|
f'{trade.entry_side.capitalize()} order fully cancelled. '
|
||||||
r'Removing .* from database\.',
|
r'Removing .* from database\.',
|
||||||
caplog
|
caplog
|
||||||
)
|
)
|
||||||
@ -2937,7 +2937,7 @@ def test_handle_cancel_enter_corder_empty(mocker, default_conf_usdt, limit_order
|
|||||||
cancelorder) -> None:
|
cancelorder) -> None:
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
l_order = limit_order[enter_side(is_short)]
|
l_order = limit_order[entry_side(is_short)]
|
||||||
cancel_order_mock = MagicMock(return_value=cancelorder)
|
cancel_order_mock = MagicMock(return_value=cancelorder)
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
@ -2949,9 +2949,9 @@ def test_handle_cancel_enter_corder_empty(mocker, default_conf_usdt, limit_order
|
|||||||
|
|
||||||
trade = MagicMock()
|
trade = MagicMock()
|
||||||
trade.pair = 'LTC/USDT'
|
trade.pair = 'LTC/USDT'
|
||||||
trade.enter_side = "buy"
|
trade.entry_side = "buy"
|
||||||
trade.open_rate = 200
|
trade.open_rate = 200
|
||||||
trade.enter_side = "buy"
|
trade.entry_side = "buy"
|
||||||
l_order['filled'] = 0.0
|
l_order['filled'] = 0.0
|
||||||
l_order['status'] = 'open'
|
l_order['status'] = 'open'
|
||||||
reason = CANCEL_REASON['TIMEOUT']
|
reason = CANCEL_REASON['TIMEOUT']
|
||||||
@ -3642,7 +3642,7 @@ def test_sell_profit_only(
|
|||||||
fee, mocker, profit_only, bid, ask, handle_first, handle_second, exit_type) -> None:
|
fee, mocker, profit_only, bid, ask, handle_first, handle_second, exit_type) -> None:
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
eside = enter_side(is_short)
|
eside = entry_side(is_short)
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
fetch_ticker=MagicMock(return_value={
|
fetch_ticker=MagicMock(return_value={
|
||||||
@ -3803,7 +3803,7 @@ def test_ignore_roi_if_buy_signal(default_conf_usdt, limit_order, limit_order_op
|
|||||||
fee, mocker) -> None:
|
fee, mocker) -> None:
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
eside = enter_side(is_short)
|
eside = entry_side(is_short)
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
fetch_ticker=MagicMock(return_value={
|
fetch_ticker=MagicMock(return_value={
|
||||||
@ -3863,7 +3863,7 @@ def test_trailing_stop_loss(default_conf_usdt, limit_order_open,
|
|||||||
'last': 2.0
|
'last': 2.0
|
||||||
}),
|
}),
|
||||||
create_order=MagicMock(side_effect=[
|
create_order=MagicMock(side_effect=[
|
||||||
limit_order_open[enter_side(is_short)],
|
limit_order_open[entry_side(is_short)],
|
||||||
{'id': 1234553382},
|
{'id': 1234553382},
|
||||||
]),
|
]),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
@ -3921,10 +3921,10 @@ def test_trailing_stop_loss_positive(
|
|||||||
default_conf_usdt, limit_order, limit_order_open,
|
default_conf_usdt, limit_order, limit_order_open,
|
||||||
offset, fee, caplog, mocker, trail_if_reached, second_sl, is_short
|
offset, fee, caplog, mocker, trail_if_reached, second_sl, is_short
|
||||||
) -> None:
|
) -> None:
|
||||||
enter_price = limit_order[enter_side(is_short)]['price']
|
enter_price = limit_order[entry_side(is_short)]['price']
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
eside = enter_side(is_short)
|
eside = entry_side(is_short)
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
fetch_ticker=MagicMock(return_value={
|
fetch_ticker=MagicMock(return_value={
|
||||||
@ -4020,7 +4020,7 @@ def test_disable_ignore_roi_if_buy_signal(default_conf_usdt, limit_order, limit_
|
|||||||
is_short, fee, mocker) -> None:
|
is_short, fee, mocker) -> None:
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
eside = enter_side(is_short)
|
eside = entry_side(is_short)
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
fetch_ticker=MagicMock(return_value={
|
fetch_ticker=MagicMock(return_value={
|
||||||
@ -4424,7 +4424,7 @@ def test_order_book_depth_of_market(
|
|||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
fetch_ticker=ticker_usdt,
|
fetch_ticker=ticker_usdt,
|
||||||
create_order=MagicMock(return_value=limit_order_open[enter_side(is_short)]),
|
create_order=MagicMock(return_value=limit_order_open[entry_side(is_short)]),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -4449,7 +4449,7 @@ def test_order_book_depth_of_market(
|
|||||||
|
|
||||||
# Simulate fulfilled LIMIT_BUY order for trade
|
# Simulate fulfilled LIMIT_BUY order for trade
|
||||||
oobj = Order.parse_from_ccxt_object(
|
oobj = Order.parse_from_ccxt_object(
|
||||||
limit_order_open[enter_side(is_short)], 'ADA/USDT', enter_side(is_short))
|
limit_order_open[entry_side(is_short)], 'ADA/USDT', entry_side(is_short))
|
||||||
trade.update_trade(oobj)
|
trade.update_trade(oobj)
|
||||||
|
|
||||||
assert trade.open_rate == ticker_usdt.return_value[ticker_side]
|
assert trade.open_rate == ticker_usdt.return_value[ticker_side]
|
||||||
@ -4638,7 +4638,7 @@ def test_cancel_all_open_orders(mocker, default_conf_usdt, fee, limit_order, lim
|
|||||||
side_effect=[
|
side_effect=[
|
||||||
ExchangeError(),
|
ExchangeError(),
|
||||||
limit_order[exit_side(is_short)],
|
limit_order[exit_side(is_short)],
|
||||||
limit_order_open[enter_side(is_short)],
|
limit_order_open[entry_side(is_short)],
|
||||||
limit_order_open[exit_side(is_short)],
|
limit_order_open[exit_side(is_short)],
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@ -4751,7 +4751,7 @@ def test_update_closed_trades_without_assigned_fees(mocker, default_conf_usdt, f
|
|||||||
for trade in trades:
|
for trade in trades:
|
||||||
if trade.is_open:
|
if trade.is_open:
|
||||||
# Exclude Trade 4 - as the order is still open.
|
# Exclude Trade 4 - as the order is still open.
|
||||||
if trade.select_order(enter_side(is_short), False):
|
if trade.select_order(entry_side(is_short), False):
|
||||||
assert trade.fee_open_cost is not None
|
assert trade.fee_open_cost is not None
|
||||||
assert trade.fee_open_currency is not None
|
assert trade.fee_open_currency is not None
|
||||||
else:
|
else:
|
||||||
@ -5008,7 +5008,7 @@ def test_update_funding_fees(
|
|||||||
# SETUP
|
# SETUP
|
||||||
time_machine.move_to("2021-09-01 00:00:00 +00:00")
|
time_machine.move_to("2021-09-01 00:00:00 +00:00")
|
||||||
|
|
||||||
open_order = limit_order_open[enter_side(is_short)]
|
open_order = limit_order_open[entry_side(is_short)]
|
||||||
open_exit_order = limit_order_open[exit_side(is_short)]
|
open_exit_order = limit_order_open[exit_side(is_short)]
|
||||||
bid = 0.11
|
bid = 0.11
|
||||||
enter_rate_mock = MagicMock(return_value=bid)
|
enter_rate_mock = MagicMock(return_value=bid)
|
||||||
|
@ -76,7 +76,7 @@ def test_init_dryrun_db(default_conf, tmpdir):
|
|||||||
@pytest.mark.parametrize('is_short', [False, True])
|
@pytest.mark.parametrize('is_short', [False, True])
|
||||||
@pytest.mark.usefixtures("init_persistence")
|
@pytest.mark.usefixtures("init_persistence")
|
||||||
def test_enter_exit_side(fee, is_short):
|
def test_enter_exit_side(fee, is_short):
|
||||||
enter_side, exit_side = ("sell", "buy") if is_short else ("buy", "sell")
|
entry_side, exit_side = ("sell", "buy") if is_short else ("buy", "sell")
|
||||||
trade = Trade(
|
trade = Trade(
|
||||||
id=2,
|
id=2,
|
||||||
pair='ADA/USDT',
|
pair='ADA/USDT',
|
||||||
@ -92,7 +92,7 @@ def test_enter_exit_side(fee, is_short):
|
|||||||
leverage=2.0,
|
leverage=2.0,
|
||||||
trading_mode=margin
|
trading_mode=margin
|
||||||
)
|
)
|
||||||
assert trade.enter_side == enter_side
|
assert trade.entry_side == entry_side
|
||||||
assert trade.exit_side == exit_side
|
assert trade.exit_side == exit_side
|
||||||
assert trade.trade_direction == 'short' if is_short else 'long'
|
assert trade.trade_direction == 'short' if is_short else 'long'
|
||||||
|
|
||||||
@ -456,7 +456,7 @@ def test_update_limit_order(fee, caplog, limit_buy_order_usdt, limit_sell_order_
|
|||||||
|
|
||||||
enter_order = limit_sell_order_usdt if is_short else limit_buy_order_usdt
|
enter_order = limit_sell_order_usdt if is_short else limit_buy_order_usdt
|
||||||
exit_order = limit_buy_order_usdt if is_short else limit_sell_order_usdt
|
exit_order = limit_buy_order_usdt if is_short else limit_sell_order_usdt
|
||||||
enter_side, exit_side = ("sell", "buy") if is_short else ("buy", "sell")
|
entry_side, exit_side = ("sell", "buy") if is_short else ("buy", "sell")
|
||||||
|
|
||||||
trade = Trade(
|
trade = Trade(
|
||||||
id=2,
|
id=2,
|
||||||
@ -479,13 +479,13 @@ def test_update_limit_order(fee, caplog, limit_buy_order_usdt, limit_sell_order_
|
|||||||
assert trade.close_date is None
|
assert trade.close_date is None
|
||||||
|
|
||||||
trade.open_order_id = 'something'
|
trade.open_order_id = 'something'
|
||||||
oobj = Order.parse_from_ccxt_object(enter_order, 'ADA/USDT', enter_side)
|
oobj = Order.parse_from_ccxt_object(enter_order, 'ADA/USDT', entry_side)
|
||||||
trade.update_trade(oobj)
|
trade.update_trade(oobj)
|
||||||
assert trade.open_order_id is None
|
assert trade.open_order_id is None
|
||||||
assert trade.open_rate == open_rate
|
assert trade.open_rate == open_rate
|
||||||
assert trade.close_profit is None
|
assert trade.close_profit is None
|
||||||
assert trade.close_date is None
|
assert trade.close_date is None
|
||||||
assert log_has_re(f"LIMIT_{enter_side.upper()} has been fulfilled for "
|
assert log_has_re(f"LIMIT_{entry_side.upper()} has been fulfilled for "
|
||||||
r"Trade\(id=2, pair=ADA/USDT, amount=30.00000000, "
|
r"Trade\(id=2, pair=ADA/USDT, amount=30.00000000, "
|
||||||
f"is_short={is_short}, leverage={lev}, open_rate={open_rate}0000000, "
|
f"is_short={is_short}, leverage={lev}, open_rate={open_rate}0000000, "
|
||||||
r"open_since=.*\).",
|
r"open_since=.*\).",
|
||||||
@ -2135,19 +2135,19 @@ def test_select_order(fee, is_short):
|
|||||||
trades = Trade.get_trades().all()
|
trades = Trade.get_trades().all()
|
||||||
|
|
||||||
# Open buy order, no sell order
|
# Open buy order, no sell order
|
||||||
order = trades[0].select_order(trades[0].enter_side, True)
|
order = trades[0].select_order(trades[0].entry_side, True)
|
||||||
assert order is None
|
assert order is None
|
||||||
order = trades[0].select_order(trades[0].enter_side, False)
|
order = trades[0].select_order(trades[0].entry_side, False)
|
||||||
assert order is not None
|
assert order is not None
|
||||||
order = trades[0].select_order(trades[0].exit_side, None)
|
order = trades[0].select_order(trades[0].exit_side, None)
|
||||||
assert order is None
|
assert order is None
|
||||||
|
|
||||||
# closed buy order, and open sell order
|
# closed buy order, and open sell order
|
||||||
order = trades[1].select_order(trades[1].enter_side, True)
|
order = trades[1].select_order(trades[1].entry_side, True)
|
||||||
assert order is None
|
assert order is None
|
||||||
order = trades[1].select_order(trades[1].enter_side, False)
|
order = trades[1].select_order(trades[1].entry_side, False)
|
||||||
assert order is not None
|
assert order is not None
|
||||||
order = trades[1].select_order(trades[1].enter_side, None)
|
order = trades[1].select_order(trades[1].entry_side, None)
|
||||||
assert order is not None
|
assert order is not None
|
||||||
order = trades[1].select_order(trades[1].exit_side, True)
|
order = trades[1].select_order(trades[1].exit_side, True)
|
||||||
assert order is None
|
assert order is None
|
||||||
@ -2155,15 +2155,15 @@ def test_select_order(fee, is_short):
|
|||||||
assert order is not None
|
assert order is not None
|
||||||
|
|
||||||
# Has open buy order
|
# Has open buy order
|
||||||
order = trades[3].select_order(trades[3].enter_side, True)
|
order = trades[3].select_order(trades[3].entry_side, True)
|
||||||
assert order is not None
|
assert order is not None
|
||||||
order = trades[3].select_order(trades[3].enter_side, False)
|
order = trades[3].select_order(trades[3].entry_side, False)
|
||||||
assert order is None
|
assert order is None
|
||||||
|
|
||||||
# Open sell order
|
# Open sell order
|
||||||
order = trades[4].select_order(trades[4].enter_side, True)
|
order = trades[4].select_order(trades[4].entry_side, True)
|
||||||
assert order is None
|
assert order is None
|
||||||
order = trades[4].select_order(trades[4].enter_side, False)
|
order = trades[4].select_order(trades[4].entry_side, False)
|
||||||
assert order is not None
|
assert order is not None
|
||||||
|
|
||||||
trades[4].orders[1].ft_order_side = trades[4].exit_side
|
trades[4].orders[1].ft_order_side = trades[4].exit_side
|
||||||
@ -2386,7 +2386,7 @@ def test_recalc_trade_from_orders_ignores_bad_orders(fee, is_short):
|
|||||||
o1_cost = o1_amount * o1_rate
|
o1_cost = o1_amount * o1_rate
|
||||||
o1_fee_cost = o1_cost * fee.return_value
|
o1_fee_cost = o1_cost * fee.return_value
|
||||||
o1_trade_val = o1_cost - o1_fee_cost if is_short else o1_cost + o1_fee_cost
|
o1_trade_val = o1_cost - o1_fee_cost if is_short else o1_cost + o1_fee_cost
|
||||||
enter_side = "sell" if is_short else "buy"
|
entry_side = "sell" if is_short else "buy"
|
||||||
exit_side = "buy" if is_short else "sell"
|
exit_side = "buy" if is_short else "sell"
|
||||||
|
|
||||||
trade = Trade(
|
trade = Trade(
|
||||||
@ -2402,16 +2402,16 @@ def test_recalc_trade_from_orders_ignores_bad_orders(fee, is_short):
|
|||||||
is_short=is_short,
|
is_short=is_short,
|
||||||
leverage=1.0,
|
leverage=1.0,
|
||||||
)
|
)
|
||||||
trade.update_fee(o1_fee_cost, 'BNB', fee.return_value, enter_side)
|
trade.update_fee(o1_fee_cost, 'BNB', fee.return_value, entry_side)
|
||||||
# Check with 1 order
|
# Check with 1 order
|
||||||
order1 = Order(
|
order1 = Order(
|
||||||
ft_order_side=enter_side,
|
ft_order_side=entry_side,
|
||||||
ft_pair=trade.pair,
|
ft_pair=trade.pair,
|
||||||
ft_is_open=False,
|
ft_is_open=False,
|
||||||
status="closed",
|
status="closed",
|
||||||
symbol=trade.pair,
|
symbol=trade.pair,
|
||||||
order_type="market",
|
order_type="market",
|
||||||
side=enter_side,
|
side=entry_side,
|
||||||
price=o1_rate,
|
price=o1_rate,
|
||||||
average=o1_rate,
|
average=o1_rate,
|
||||||
filled=o1_amount,
|
filled=o1_amount,
|
||||||
@ -2432,13 +2432,13 @@ def test_recalc_trade_from_orders_ignores_bad_orders(fee, is_short):
|
|||||||
assert trade.nr_of_successful_entries == 1
|
assert trade.nr_of_successful_entries == 1
|
||||||
|
|
||||||
order2 = Order(
|
order2 = Order(
|
||||||
ft_order_side=enter_side,
|
ft_order_side=entry_side,
|
||||||
ft_pair=trade.pair,
|
ft_pair=trade.pair,
|
||||||
ft_is_open=True,
|
ft_is_open=True,
|
||||||
status="open",
|
status="open",
|
||||||
symbol=trade.pair,
|
symbol=trade.pair,
|
||||||
order_type="market",
|
order_type="market",
|
||||||
side=enter_side,
|
side=entry_side,
|
||||||
price=o1_rate,
|
price=o1_rate,
|
||||||
average=o1_rate,
|
average=o1_rate,
|
||||||
filled=o1_amount,
|
filled=o1_amount,
|
||||||
@ -2460,13 +2460,13 @@ def test_recalc_trade_from_orders_ignores_bad_orders(fee, is_short):
|
|||||||
|
|
||||||
# Let's try with some other orders
|
# Let's try with some other orders
|
||||||
order3 = Order(
|
order3 = Order(
|
||||||
ft_order_side=enter_side,
|
ft_order_side=entry_side,
|
||||||
ft_pair=trade.pair,
|
ft_pair=trade.pair,
|
||||||
ft_is_open=False,
|
ft_is_open=False,
|
||||||
status="cancelled",
|
status="cancelled",
|
||||||
symbol=trade.pair,
|
symbol=trade.pair,
|
||||||
order_type="market",
|
order_type="market",
|
||||||
side=enter_side,
|
side=entry_side,
|
||||||
price=1,
|
price=1,
|
||||||
average=2,
|
average=2,
|
||||||
filled=0,
|
filled=0,
|
||||||
@ -2487,13 +2487,13 @@ def test_recalc_trade_from_orders_ignores_bad_orders(fee, is_short):
|
|||||||
assert trade.nr_of_successful_entries == 1
|
assert trade.nr_of_successful_entries == 1
|
||||||
|
|
||||||
order4 = Order(
|
order4 = Order(
|
||||||
ft_order_side=enter_side,
|
ft_order_side=entry_side,
|
||||||
ft_pair=trade.pair,
|
ft_pair=trade.pair,
|
||||||
ft_is_open=False,
|
ft_is_open=False,
|
||||||
status="closed",
|
status="closed",
|
||||||
symbol=trade.pair,
|
symbol=trade.pair,
|
||||||
order_type="market",
|
order_type="market",
|
||||||
side=enter_side,
|
side=entry_side,
|
||||||
price=o1_rate,
|
price=o1_rate,
|
||||||
average=o1_rate,
|
average=o1_rate,
|
||||||
filled=o1_amount,
|
filled=o1_amount,
|
||||||
@ -2542,13 +2542,13 @@ def test_recalc_trade_from_orders_ignores_bad_orders(fee, is_short):
|
|||||||
|
|
||||||
# Check with 1 order
|
# Check with 1 order
|
||||||
order_noavg = Order(
|
order_noavg = Order(
|
||||||
ft_order_side=enter_side,
|
ft_order_side=entry_side,
|
||||||
ft_pair=trade.pair,
|
ft_pair=trade.pair,
|
||||||
ft_is_open=False,
|
ft_is_open=False,
|
||||||
status="closed",
|
status="closed",
|
||||||
symbol=trade.pair,
|
symbol=trade.pair,
|
||||||
order_type="market",
|
order_type="market",
|
||||||
side=enter_side,
|
side=entry_side,
|
||||||
price=o1_rate,
|
price=o1_rate,
|
||||||
average=None,
|
average=None,
|
||||||
filled=o1_amount,
|
filled=o1_amount,
|
||||||
|
Loading…
Reference in New Issue
Block a user