Add "nr_of_successfull_entries"
This commit is contained in:
parent
5c9dddb7f3
commit
bcfa73d492
@ -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`.
|
||||
`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"
|
||||
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.
|
||||
@ -663,7 +665,7 @@ class DigDeeperStrategy(IStrategy):
|
||||
return None
|
||||
|
||||
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)
|
||||
# Initial buy is 1x
|
||||
# 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
|
||||
stake_amount = filled_buys[0].cost
|
||||
# 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
|
||||
except Exception as exception:
|
||||
return None
|
||||
|
@ -510,7 +510,7 @@ class FreqtradeBot(LoggingMixin):
|
||||
"""
|
||||
# TODO-lev: Check what changes are necessary for DCA in relation to shorts.
|
||||
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:
|
||||
logger.debug(f"Max adjustment entries for {trade.pair} has been reached.")
|
||||
return
|
||||
|
@ -464,11 +464,11 @@ class Backtesting:
|
||||
|
||||
# Check if we need to adjust our current positions
|
||||
if self.strategy.position_adjustment_enable:
|
||||
check_adjust_buy = True
|
||||
check_adjust_entry = True
|
||||
if self.strategy.max_entry_position_adjustment > -1:
|
||||
count_of_buys = trade.nr_of_successful_buys
|
||||
check_adjust_buy = (count_of_buys <= self.strategy.max_entry_position_adjustment)
|
||||
if check_adjust_buy:
|
||||
entry_count = trade.nr_of_successful_entries
|
||||
check_adjust_entry = (entry_count <= self.strategy.max_entry_position_adjustment)
|
||||
if check_adjust_entry:
|
||||
trade = self._get_adjust_trade_entry_for_candle(trade, sell_row)
|
||||
|
||||
sell_candle_time: datetime = sell_row[DATE_IDX].to_pydatetime()
|
||||
@ -729,7 +729,7 @@ class Backtesting:
|
||||
for pair in open_trades.keys():
|
||||
if len(open_trades[pair]) > 0:
|
||||
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
|
||||
continue
|
||||
sell_row = data[pair][-1]
|
||||
@ -782,7 +782,7 @@ class Backtesting:
|
||||
if timedout:
|
||||
if order.side == 'buy':
|
||||
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.
|
||||
return True
|
||||
else:
|
||||
|
@ -889,6 +889,8 @@ class LocalTrade():
|
||||
total_stake += tmp_price * tmp_amount
|
||||
|
||||
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.stake_amount = total_stake
|
||||
self.amount = total_amount
|
||||
@ -936,10 +938,28 @@ class LocalTrade():
|
||||
(o.filled or 0) > 0 and
|
||||
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
|
||||
def nr_of_successful_buys(self) -> int:
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
|
||||
@ -949,6 +969,7 @@ class LocalTrade():
|
||||
def nr_of_successful_sells(self) -> int:
|
||||
"""
|
||||
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 len(self.select_filled_orders('sell'))
|
||||
|
@ -261,11 +261,11 @@ class RPC:
|
||||
profit_str
|
||||
]
|
||||
if self._config.get('position_adjustment_enable', False):
|
||||
max_buy_str = ''
|
||||
max_entry_str = ''
|
||||
if self._config.get('max_entry_position_adjustment', -1) > 0:
|
||||
max_buy_str = f"/{self._config['max_entry_position_adjustment'] + 1}"
|
||||
filled_buys = trade.nr_of_successful_buys
|
||||
detail_trade.append(f"{filled_buys}{max_buy_str}")
|
||||
max_entry_str = f"/{self._config['max_entry_position_adjustment'] + 1}"
|
||||
filled_entries = trade.nr_of_successful_entries
|
||||
detail_trade.append(f"{filled_entries}{max_entry_str}")
|
||||
trades_list.append(detail_trade)
|
||||
profitcol = "Profit"
|
||||
if self._fiat_converter:
|
||||
|
@ -2418,6 +2418,7 @@ def test_recalc_trade_from_orders_ignores_bad_orders(fee):
|
||||
assert trade.fee_open_cost == o1_fee_cost
|
||||
assert trade.open_trade_value == o1_trade_val
|
||||
assert trade.nr_of_successful_buys == 1
|
||||
assert trade.nr_of_successful_entries == 1
|
||||
|
||||
order2 = Order(
|
||||
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.open_trade_value == 3 * o1_trade_val
|
||||
assert trade.nr_of_successful_buys == 3
|
||||
assert trade.nr_of_successful_entries == 3
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_persistence")
|
||||
|
Loading…
Reference in New Issue
Block a user