Add "nr_of_successfull_entries"

This commit is contained in:
Matthias 2022-02-13 15:10:09 +01:00
parent 5c9dddb7f3
commit bcfa73d492
6 changed files with 38 additions and 13 deletions

View File

@ -593,6 +593,8 @@ Additional orders also result in additional fees and those orders don't count to
This callback is **not** called when there is an open order (either buy or sell) waiting for execution, or when you have reached the maximum amount of extra buys that you have set on `max_entry_position_adjustment`. This callback is **not** called when there is an open order (either buy or sell) waiting for execution, or when you have reached the maximum amount of extra buys that you have set on `max_entry_position_adjustment`.
`adjust_trade_position()` is called very frequently for the duration of a trade, so you must keep your implementation as performant as possible. `adjust_trade_position()` is called very frequently for the duration of a trade, so you must keep your implementation as performant as possible.
Position adjustments will always be applied in the direction of the trade, so a positive value will always increase your position, no matter if it's a long or short trade.
!!! Note "About stake size" !!! Note "About stake size"
Using fixed stake size means it will be the amount used for the first order, just like without position adjustment. Using fixed stake size means it will be the amount used for the first order, just like without position adjustment.
If you wish to buy additional orders with DCA, then make sure to leave enough funds in the wallet for that. If you wish to buy additional orders with DCA, then make sure to leave enough funds in the wallet for that.
@ -663,7 +665,7 @@ class DigDeeperStrategy(IStrategy):
return None return None
filled_buys = trade.select_filled_orders('buy') filled_buys = trade.select_filled_orders('buy')
count_of_buys = trade.nr_of_successful_buys 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
# If that falls to -5% profit, we buy 1.25x more, average profit should increase to roughly -2.2% # If that falls to -5% profit, we buy 1.25x more, average profit should increase to roughly -2.2%
@ -676,7 +678,7 @@ class DigDeeperStrategy(IStrategy):
# This returns first order stake size # This returns first order stake size
stake_amount = filled_buys[0].cost stake_amount = filled_buys[0].cost
# This then calculates current safety order size # This then calculates current safety order size
stake_amount = stake_amount * (1 + (count_of_buys * 0.25)) stake_amount = stake_amount * (1 + (count_of_entries * 0.25))
return stake_amount return stake_amount
except Exception as exception: except Exception as exception:
return None return None

View File

@ -510,7 +510,7 @@ class FreqtradeBot(LoggingMixin):
""" """
# TODO-lev: Check what changes are necessary for DCA in relation to shorts. # TODO-lev: Check what changes are necessary for DCA in relation to shorts.
if self.strategy.max_entry_position_adjustment > -1: if self.strategy.max_entry_position_adjustment > -1:
count_of_buys = trade.nr_of_successful_buys count_of_buys = trade.nr_of_successful_entries
if count_of_buys > self.strategy.max_entry_position_adjustment: if count_of_buys > self.strategy.max_entry_position_adjustment:
logger.debug(f"Max adjustment entries for {trade.pair} has been reached.") logger.debug(f"Max adjustment entries for {trade.pair} has been reached.")
return return

View File

@ -464,11 +464,11 @@ class Backtesting:
# Check if we need to adjust our current positions # Check if we need to adjust our current positions
if self.strategy.position_adjustment_enable: if self.strategy.position_adjustment_enable:
check_adjust_buy = True check_adjust_entry = True
if self.strategy.max_entry_position_adjustment > -1: if self.strategy.max_entry_position_adjustment > -1:
count_of_buys = trade.nr_of_successful_buys entry_count = trade.nr_of_successful_entries
check_adjust_buy = (count_of_buys <= self.strategy.max_entry_position_adjustment) check_adjust_entry = (entry_count <= self.strategy.max_entry_position_adjustment)
if check_adjust_buy: if check_adjust_entry:
trade = self._get_adjust_trade_entry_for_candle(trade, sell_row) trade = self._get_adjust_trade_entry_for_candle(trade, sell_row)
sell_candle_time: datetime = sell_row[DATE_IDX].to_pydatetime() sell_candle_time: datetime = sell_row[DATE_IDX].to_pydatetime()
@ -729,7 +729,7 @@ class Backtesting:
for pair in open_trades.keys(): for pair in open_trades.keys():
if len(open_trades[pair]) > 0: if len(open_trades[pair]) > 0:
for trade in open_trades[pair]: for trade in open_trades[pair]:
if trade.open_order_id and trade.nr_of_successful_buys == 0: if trade.open_order_id and trade.nr_of_successful_entries == 0:
# Ignore trade if buy-order did not fill yet # Ignore trade if buy-order did not fill yet
continue continue
sell_row = data[pair][-1] sell_row = data[pair][-1]
@ -782,7 +782,7 @@ class Backtesting:
if timedout: if timedout:
if order.side == 'buy': if order.side == 'buy':
self.timedout_entry_orders += 1 self.timedout_entry_orders += 1
if trade.nr_of_successful_buys == 0: if trade.nr_of_successful_entries == 0:
# Remove trade due to buy timeout expiration. # Remove trade due to buy timeout expiration.
return True return True
else: else:

View File

@ -889,6 +889,8 @@ class LocalTrade():
total_stake += tmp_price * tmp_amount total_stake += tmp_price * tmp_amount
if total_amount > 0: if total_amount > 0:
# TODO-lev: This should update leverage as well -
# as averaged trades might have different leverage
self.open_rate = total_stake / total_amount self.open_rate = total_stake / total_amount
self.stake_amount = total_stake self.stake_amount = total_stake
self.amount = total_amount self.amount = total_amount
@ -936,10 +938,28 @@ class LocalTrade():
(o.filled or 0) > 0 and (o.filled or 0) > 0 and
o.status in NON_OPEN_EXCHANGE_STATES] o.status in NON_OPEN_EXCHANGE_STATES]
@property
def nr_of_successful_entries(self) -> int:
"""
Helper function to count the number of entry orders that have been filled.
:return: int count of entry orders that have been filled for this trade.
"""
return len(self.select_filled_orders(self.enter_side))
@property
def nr_of_successful_exits(self) -> int:
"""
Helper function to count the number of exit orders that have been filled.
:return: int count of exit orders that have been filled for this trade.
"""
return len(self.select_filled_orders(self.exit_side))
@property @property
def nr_of_successful_buys(self) -> int: def nr_of_successful_buys(self) -> int:
""" """
Helper function to count the number of buy orders that have been filled. Helper function to count the number of buy orders that have been filled.
WARNING: Please use nr_of_successful_entries for short support.
:return: int count of buy orders that have been filled for this trade. :return: int count of buy orders that have been filled for this trade.
""" """
@ -949,6 +969,7 @@ class LocalTrade():
def nr_of_successful_sells(self) -> int: def nr_of_successful_sells(self) -> int:
""" """
Helper function to count the number of sell orders that have been filled. Helper function to count the number of sell orders that have been filled.
WARNING: Please use nr_of_successful_exits for short support.
:return: int count of sell orders that have been filled for this trade. :return: int count of sell orders that have been filled for this trade.
""" """
return len(self.select_filled_orders('sell')) return len(self.select_filled_orders('sell'))

View File

@ -261,11 +261,11 @@ class RPC:
profit_str profit_str
] ]
if self._config.get('position_adjustment_enable', False): if self._config.get('position_adjustment_enable', False):
max_buy_str = '' max_entry_str = ''
if self._config.get('max_entry_position_adjustment', -1) > 0: if self._config.get('max_entry_position_adjustment', -1) > 0:
max_buy_str = f"/{self._config['max_entry_position_adjustment'] + 1}" max_entry_str = f"/{self._config['max_entry_position_adjustment'] + 1}"
filled_buys = trade.nr_of_successful_buys filled_entries = trade.nr_of_successful_entries
detail_trade.append(f"{filled_buys}{max_buy_str}") detail_trade.append(f"{filled_entries}{max_entry_str}")
trades_list.append(detail_trade) trades_list.append(detail_trade)
profitcol = "Profit" profitcol = "Profit"
if self._fiat_converter: if self._fiat_converter:

View File

@ -2418,6 +2418,7 @@ def test_recalc_trade_from_orders_ignores_bad_orders(fee):
assert trade.fee_open_cost == o1_fee_cost assert trade.fee_open_cost == o1_fee_cost
assert trade.open_trade_value == o1_trade_val assert trade.open_trade_value == o1_trade_val
assert trade.nr_of_successful_buys == 1 assert trade.nr_of_successful_buys == 1
assert trade.nr_of_successful_entries == 1
order2 = Order( order2 = Order(
ft_order_side='buy', ft_order_side='buy',
@ -2554,6 +2555,7 @@ def test_recalc_trade_from_orders_ignores_bad_orders(fee):
assert trade.fee_open_cost == 3 * o1_fee_cost assert trade.fee_open_cost == 3 * o1_fee_cost
assert trade.open_trade_value == 3 * o1_trade_val assert trade.open_trade_value == 3 * o1_trade_val
assert trade.nr_of_successful_buys == 3 assert trade.nr_of_successful_buys == 3
assert trade.nr_of_successful_entries == 3
@pytest.mark.usefixtures("init_persistence") @pytest.mark.usefixtures("init_persistence")