mirror of
https://github.com/freqtrade/freqtrade.git
synced 2024-11-10 10:21:59 +00:00
Added min_stake, max_stake. Removed pair as its included in trade.
This commit is contained in:
parent
813a2cd23b
commit
0bca07a32a
|
@ -625,7 +625,7 @@ class DigDeeperStrategy(IStrategy):
|
|||
:param pair: Pair that's currently analyzed
|
||||
:param trade: trade object.
|
||||
:param current_time: datetime object, containing the current datetime
|
||||
:param current_rate: Current buy rate. Use `exchange.get_rate` if you need sell rate.
|
||||
:param current_rate: Current buy rate.
|
||||
:param current_profit: Current profit (as ratio), calculated based on current_rate.
|
||||
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
|
||||
:return float: Stake amount to adjust your trade
|
||||
|
@ -642,10 +642,7 @@ class DigDeeperStrategy(IStrategy):
|
|||
if last_candle['close'] < previous_candle['close']:
|
||||
return None
|
||||
|
||||
count_of_buys = 0
|
||||
for order in trade.orders:
|
||||
if order.ft_order_side == 'buy' and order.status == "closed":
|
||||
count_of_buys += 1
|
||||
count_of_buys = trade.nr_of_successful_buys()
|
||||
|
||||
# Allow up to 3 additional increasingly larger buys (4 in total)
|
||||
# Initial buy is 1x
|
||||
|
|
|
@ -459,7 +459,7 @@ class FreqtradeBot(LoggingMixin):
|
|||
# Walk through each pair and check if it needs changes
|
||||
for trade in Trade.get_open_trades():
|
||||
# If there is any open orders, wait for them to finish.
|
||||
if len([o for o in trade.orders if o.ft_is_open]) == 0:
|
||||
if trade.open_order_id is None:
|
||||
try:
|
||||
self.check_and_call_adjust_trade_position(trade)
|
||||
except DependencyException as exception:
|
||||
|
@ -474,11 +474,15 @@ class FreqtradeBot(LoggingMixin):
|
|||
"""
|
||||
current_rate = self.exchange.get_rate(trade.pair, refresh=True, side="buy")
|
||||
current_profit = trade.calc_profit_ratio(current_rate)
|
||||
min_stake_amount = self.exchange.get_min_pair_stake_amount(trade.pair,
|
||||
current_rate,
|
||||
self.strategy.stoploss)
|
||||
max_stake_amount = self.wallets.get_available_stake_amount()
|
||||
logger.debug(f"Calling adjust_trade_position for pair {trade.pair}")
|
||||
stake_amount = strategy_safe_wrapper(self.strategy.adjust_trade_position,
|
||||
default_retval=None)(
|
||||
pair=trade.pair, trade=trade, current_time=datetime.now(timezone.utc),
|
||||
current_rate=current_rate, current_profit=current_profit)
|
||||
trade=trade, current_time=datetime.now(timezone.utc), current_rate=current_rate,
|
||||
current_profit=current_profit, min_stake=min_stake_amount, max_stake=max_stake_amount)
|
||||
|
||||
if stake_amount is not None and stake_amount > 0.0:
|
||||
# We should increase our position
|
||||
|
|
|
@ -358,10 +358,12 @@ class Backtesting:
|
|||
) -> LocalTrade:
|
||||
|
||||
current_profit = trade.calc_profit_ratio(row[OPEN_IDX])
|
||||
min_stake = self.exchange.get_min_pair_stake_amount(trade.pair, row[OPEN_IDX], -0.1)
|
||||
max_stake = self.wallets.get_available_stake_amount()
|
||||
stake_amount = strategy_safe_wrapper(self.strategy.adjust_trade_position,
|
||||
default_retval=None)(
|
||||
pair=trade.pair, trade=trade, current_time=row[DATE_IDX].to_pydatetime(),
|
||||
current_rate=row[OPEN_IDX], current_profit=current_profit)
|
||||
trade=trade, current_time=row[DATE_IDX].to_pydatetime(), current_rate=row[OPEN_IDX],
|
||||
current_profit=current_profit, min_stake=min_stake, max_stake=max_stake)
|
||||
|
||||
# Check if we should increase our position
|
||||
if stake_amount is not None and stake_amount > 0.0:
|
||||
|
|
|
@ -384,9 +384,9 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||
"""
|
||||
return proposed_stake
|
||||
|
||||
def adjust_trade_position(self, pair: str, trade: Trade, current_time: datetime,
|
||||
current_rate: float, current_profit: float, **kwargs
|
||||
) -> Optional[float]:
|
||||
def adjust_trade_position(self, trade: Trade, current_time: datetime,
|
||||
current_rate: float, current_profit: float, min_stake: float,
|
||||
max_stake: float, **kwargs) -> Optional[float]:
|
||||
"""
|
||||
Custom trade adjustment logic, returning the stake amount that a trade should be increased.
|
||||
This means extra buy orders with additional fees.
|
||||
|
@ -395,11 +395,12 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||
|
||||
When not implemented by a strategy, returns None
|
||||
|
||||
:param pair: Pair that's currently analyzed
|
||||
:param trade: trade object.
|
||||
:param current_time: datetime object, containing the current datetime
|
||||
:param current_rate: Current buy rate. Use `exchange.get_rate` if you need sell rate.
|
||||
:param current_rate: Current buy rate.
|
||||
:param current_profit: Current profit (as ratio), calculated based on current_rate.
|
||||
:param min_stake: Minimal stake size allowed by exchange.
|
||||
:param max_stake: Balance available for trading.
|
||||
:param **kwargs: Ensure to keep this here so updates to this won't break your strategy.
|
||||
:return float: Stake amount to adjust your trade
|
||||
"""
|
||||
|
|
|
@ -162,12 +162,12 @@ class StrategyTestV2(IStrategy):
|
|||
'sell'] = 1
|
||||
return dataframe
|
||||
|
||||
def adjust_trade_position(self, pair: str, trade: Trade, current_time: datetime,
|
||||
current_rate: float, current_profit: float, **kwargs):
|
||||
def adjust_trade_position(self, trade: Trade, current_time: datetime, current_rate: float,
|
||||
current_profit: float, min_stake: float, max_stake: float, **kwargs):
|
||||
|
||||
if current_profit < -0.0075:
|
||||
try:
|
||||
return self.wallets.get_trade_stake_amount(pair, None)
|
||||
return self.wallets.get_trade_stake_amount(trade.pair, None)
|
||||
except DependencyException:
|
||||
pass
|
||||
|
||||
|
|
|
@ -259,6 +259,8 @@ def test_dca_buying(default_conf_usdt, ticker_usdt, fee, mocker) -> None:
|
|||
|
||||
assert trade.amount == trade.orders[0].amount + trade.orders[1].amount
|
||||
|
||||
assert trade.nr_of_successful_buys() == 2
|
||||
|
||||
# Sell
|
||||
patch_get_signal(freqtrade, value=(False, True, None, None))
|
||||
freqtrade.process()
|
||||
|
@ -270,3 +272,5 @@ def test_dca_buying(default_conf_usdt, ticker_usdt, fee, mocker) -> None:
|
|||
# Sold everything
|
||||
assert trade.orders[-1].side == 'sell'
|
||||
assert trade.orders[2].amount == trade.amount
|
||||
|
||||
assert trade.nr_of_successful_buys() == 2
|
||||
|
|
|
@ -1553,20 +1553,21 @@ def test_recalc_trade_from_orders_ignores_bad_orders(fee):
|
|||
assert trade.open_rate == o1_rate
|
||||
assert trade.fee_open_cost == o1_fee_cost
|
||||
assert trade.open_trade_value == o1_trade_val
|
||||
assert trade.nr_of_successful_buys() == 1
|
||||
|
||||
order2 = Order(
|
||||
ft_order_side='buy',
|
||||
ft_pair=trade.pair,
|
||||
ft_is_open=True,
|
||||
status="closed",
|
||||
status="open",
|
||||
symbol=trade.pair,
|
||||
order_type="market",
|
||||
side="buy",
|
||||
price=1,
|
||||
average=2,
|
||||
filled=0,
|
||||
remaining=4,
|
||||
cost=5,
|
||||
price=o1_rate,
|
||||
average=o1_rate,
|
||||
filled=o1_amount,
|
||||
remaining=0,
|
||||
cost=o1_cost,
|
||||
order_date=arrow.utcnow().shift(hours=-1).datetime,
|
||||
order_filled_date=arrow.utcnow().shift(hours=-1).datetime,
|
||||
)
|
||||
|
@ -1579,8 +1580,9 @@ def test_recalc_trade_from_orders_ignores_bad_orders(fee):
|
|||
assert trade.open_rate == o1_rate
|
||||
assert trade.fee_open_cost == o1_fee_cost
|
||||
assert trade.open_trade_value == o1_trade_val
|
||||
assert trade.nr_of_successful_buys() == 1
|
||||
|
||||
# Let's try with some other orders
|
||||
# Let's try with some other orders
|
||||
order3 = Order(
|
||||
ft_order_side='buy',
|
||||
ft_pair=trade.pair,
|
||||
|
@ -1606,6 +1608,34 @@ def test_recalc_trade_from_orders_ignores_bad_orders(fee):
|
|||
assert trade.open_rate == o1_rate
|
||||
assert trade.fee_open_cost == o1_fee_cost
|
||||
assert trade.open_trade_value == o1_trade_val
|
||||
assert trade.nr_of_successful_buys() == 1
|
||||
|
||||
order4 = Order(
|
||||
ft_order_side='buy',
|
||||
ft_pair=trade.pair,
|
||||
ft_is_open=False,
|
||||
status="closed",
|
||||
symbol=trade.pair,
|
||||
order_type="market",
|
||||
side="buy",
|
||||
price=o1_rate,
|
||||
average=o1_rate,
|
||||
filled=o1_amount,
|
||||
remaining=0,
|
||||
cost=o1_cost,
|
||||
order_date=arrow.utcnow().shift(hours=-1).datetime,
|
||||
order_filled_date=arrow.utcnow().shift(hours=-1).datetime,
|
||||
)
|
||||
trade.orders.append(order4)
|
||||
trade.recalc_trade_from_orders()
|
||||
|
||||
# Validate that the trade values have been changed
|
||||
assert trade.amount == 2 * o1_amount
|
||||
assert trade.stake_amount == 2 * o1_amount
|
||||
assert trade.open_rate == o1_rate
|
||||
assert trade.fee_open_cost == 2 * o1_fee_cost
|
||||
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.
|
||||
sell1 = Order(
|
||||
|
@ -1627,8 +1657,10 @@ def test_recalc_trade_from_orders_ignores_bad_orders(fee):
|
|||
trade.orders.append(sell1)
|
||||
trade.recalc_trade_from_orders()
|
||||
|
||||
assert trade.amount == o1_amount
|
||||
assert trade.stake_amount == o1_amount
|
||||
assert trade.amount == 2 * o1_amount
|
||||
assert trade.stake_amount == 2 * o1_amount
|
||||
assert trade.open_rate == o1_rate
|
||||
assert trade.fee_open_cost == o1_fee_cost
|
||||
assert trade.open_trade_value == o1_trade_val
|
||||
assert trade.fee_open_cost == 2 * o1_fee_cost
|
||||
assert trade.open_trade_value == 2 * o1_trade_val
|
||||
assert trade.nr_of_successful_buys() == 2
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user