Merge pull request #8909 from freqtrade/backtest_adjustment
introduce order.stake_amount
This commit is contained in:
@@ -750,7 +750,7 @@ class DigDeeperStrategy(IStrategy):
|
|||||||
# Hope you have a deep wallet!
|
# Hope you have a deep wallet!
|
||||||
try:
|
try:
|
||||||
# This returns first order stake size
|
# This returns first order stake size
|
||||||
stake_amount = filled_entries[0].cost
|
stake_amount = filled_entries[0].stake_amount
|
||||||
# This then calculates current safety order size
|
# This then calculates current safety order size
|
||||||
stake_amount = stake_amount * (1 + (count_of_entries * 0.25))
|
stake_amount = stake_amount * (1 + (count_of_entries * 0.25))
|
||||||
return stake_amount
|
return stake_amount
|
||||||
|
|||||||
@@ -141,7 +141,8 @@ Most properties here can be None as they are dependant on the exchange response.
|
|||||||
`amount` | float | Amount in base currency
|
`amount` | float | Amount in base currency
|
||||||
`filled` | float | Filled amount (in base currency)
|
`filled` | float | Filled amount (in base currency)
|
||||||
`remaining` | float | Remaining amount
|
`remaining` | float | Remaining amount
|
||||||
`cost` | float | Cost of the order - usually average * filled
|
`cost` | float | Cost of the order - usually average * filled (*Exchange dependant on futures, may contain the cost with or without leverage and may be in contracts.*)
|
||||||
|
`stake_amount` | float | Stake amount used for this order. *Added in 2023.7.*
|
||||||
`order_date` | datetime | Order creation date **use `order_date_utc` instead**
|
`order_date` | datetime | Order creation date **use `order_date_utc` instead**
|
||||||
`order_date_utc` | datetime | Order creation date (in UTC)
|
`order_date_utc` | datetime | Order creation date (in UTC)
|
||||||
`order_fill_date` | datetime | Order fill date **use `order_fill_utc` instead**
|
`order_fill_date` | datetime | Order fill date **use `order_fill_utc` instead**
|
||||||
|
|||||||
@@ -679,6 +679,7 @@ class Backtesting:
|
|||||||
remaining=amount,
|
remaining=amount,
|
||||||
cost=amount * close_rate,
|
cost=amount * close_rate,
|
||||||
)
|
)
|
||||||
|
order._trade_bt = trade
|
||||||
trade.orders.append(order)
|
trade.orders.append(order)
|
||||||
return trade
|
return trade
|
||||||
|
|
||||||
@@ -901,8 +902,9 @@ class Backtesting:
|
|||||||
amount=amount,
|
amount=amount,
|
||||||
filled=0,
|
filled=0,
|
||||||
remaining=amount,
|
remaining=amount,
|
||||||
cost=stake_amount + trade.fee_open,
|
cost=amount * propose_rate + trade.fee_open,
|
||||||
)
|
)
|
||||||
|
order._trade_bt = trade
|
||||||
trade.orders.append(order)
|
trade.orders.append(order)
|
||||||
if pos_adjust and self._get_order_filled(order.ft_price, row):
|
if pos_adjust and self._get_order_filled(order.ft_price, row):
|
||||||
order.close_bt_order(current_time, trade)
|
order.close_bt_order(current_time, trade)
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ class Order(ModelBase):
|
|||||||
Mirrors CCXT Order structure
|
Mirrors CCXT Order structure
|
||||||
"""
|
"""
|
||||||
__tablename__ = 'orders'
|
__tablename__ = 'orders'
|
||||||
|
__allow_unmapped__ = True
|
||||||
session: ClassVar[SessionType]
|
session: ClassVar[SessionType]
|
||||||
|
|
||||||
# Uniqueness should be ensured over pair, order_id
|
# Uniqueness should be ensured over pair, order_id
|
||||||
@@ -47,7 +48,8 @@ class Order(ModelBase):
|
|||||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||||
ft_trade_id: Mapped[int] = mapped_column(Integer, ForeignKey('trades.id'), index=True)
|
ft_trade_id: Mapped[int] = mapped_column(Integer, ForeignKey('trades.id'), index=True)
|
||||||
|
|
||||||
trade: Mapped["Trade"] = relationship("Trade", back_populates="orders")
|
_trade_live: Mapped["Trade"] = relationship("Trade", back_populates="orders")
|
||||||
|
_trade_bt: "LocalTrade" = None # type: ignore
|
||||||
|
|
||||||
# order_side can only be 'buy', 'sell' or 'stoploss'
|
# order_side can only be 'buy', 'sell' or 'stoploss'
|
||||||
ft_order_side: Mapped[str] = mapped_column(String(25), nullable=False)
|
ft_order_side: Mapped[str] = mapped_column(String(25), nullable=False)
|
||||||
@@ -119,6 +121,15 @@ class Order(ModelBase):
|
|||||||
def safe_amount_after_fee(self) -> float:
|
def safe_amount_after_fee(self) -> float:
|
||||||
return self.safe_filled - self.safe_fee_base
|
return self.safe_filled - self.safe_fee_base
|
||||||
|
|
||||||
|
@property
|
||||||
|
def trade(self) -> "LocalTrade":
|
||||||
|
return self._trade_bt or self._trade_live
|
||||||
|
|
||||||
|
@property
|
||||||
|
def stake_amount(self) -> float:
|
||||||
|
""" Amount in stake currency used for this order"""
|
||||||
|
return self.safe_amount * self.safe_price / self.trade.leverage
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
|
||||||
return (f"Order(id={self.id}, trade={self.ft_trade_id}, order_id={self.order_id}, "
|
return (f"Order(id={self.id}, trade={self.ft_trade_id}, order_id={self.order_id}, "
|
||||||
|
|||||||
@@ -601,6 +601,9 @@ def test_backtest__enter_trade_futures(default_conf_usdt, fee, mocker) -> None:
|
|||||||
|
|
||||||
trade = backtesting._enter_trade(pair, row=row, direction='short')
|
trade = backtesting._enter_trade(pair, row=row, direction='short')
|
||||||
assert pytest.approx(trade.liquidation_price) == 0.11787191
|
assert pytest.approx(trade.liquidation_price) == 0.11787191
|
||||||
|
assert pytest.approx(trade.orders[0].cost) == (
|
||||||
|
trade.stake_amount * trade.leverage + trade.fee_open)
|
||||||
|
assert pytest.approx(trade.orders[-1].stake_amount) == trade.stake_amount
|
||||||
|
|
||||||
# Stake-amount too high!
|
# Stake-amount too high!
|
||||||
mocker.patch(f"{EXMS}.get_min_pair_stake_amount", return_value=600.0)
|
mocker.patch(f"{EXMS}.get_min_pair_stake_amount", return_value=600.0)
|
||||||
|
|||||||
@@ -563,14 +563,14 @@ def test_calc_open_close_trade_price(
|
|||||||
trade.open_order_id = f'something-{is_short}-{lev}-{exchange}'
|
trade.open_order_id = f'something-{is_short}-{lev}-{exchange}'
|
||||||
|
|
||||||
oobj = Order.parse_from_ccxt_object(entry_order, 'ADA/USDT', trade.entry_side)
|
oobj = Order.parse_from_ccxt_object(entry_order, 'ADA/USDT', trade.entry_side)
|
||||||
oobj.trade = trade
|
oobj._trade_live = trade
|
||||||
oobj.update_from_ccxt_object(entry_order)
|
oobj.update_from_ccxt_object(entry_order)
|
||||||
trade.update_trade(oobj)
|
trade.update_trade(oobj)
|
||||||
|
|
||||||
trade.funding_fees = funding_fees
|
trade.funding_fees = funding_fees
|
||||||
|
|
||||||
oobj = Order.parse_from_ccxt_object(exit_order, 'ADA/USDT', trade.exit_side)
|
oobj = Order.parse_from_ccxt_object(exit_order, 'ADA/USDT', trade.exit_side)
|
||||||
oobj.trade = trade
|
oobj._trade_live = trade
|
||||||
oobj.update_from_ccxt_object(exit_order)
|
oobj.update_from_ccxt_object(exit_order)
|
||||||
trade.update_trade(oobj)
|
trade.update_trade(oobj)
|
||||||
|
|
||||||
|
|||||||
@@ -429,6 +429,7 @@ def test_dca_order_adjust(default_conf_usdt, ticker_usdt, leverage, fee, mocker)
|
|||||||
assert pytest.approx(trade.stop_loss) == 1.99 * (1 - 0.1 / leverage)
|
assert pytest.approx(trade.stop_loss) == 1.99 * (1 - 0.1 / leverage)
|
||||||
assert pytest.approx(trade.initial_stop_loss) == 1.96 * (1 - 0.1 / leverage)
|
assert pytest.approx(trade.initial_stop_loss) == 1.96 * (1 - 0.1 / leverage)
|
||||||
assert trade.initial_stop_loss_pct == -0.1
|
assert trade.initial_stop_loss_pct == -0.1
|
||||||
|
assert pytest.approx(trade.orders[-1].stake_amount) == trade.stake_amount
|
||||||
|
|
||||||
# 2nd order - not filling
|
# 2nd order - not filling
|
||||||
freqtrade.strategy.adjust_trade_position = MagicMock(return_value=120)
|
freqtrade.strategy.adjust_trade_position = MagicMock(return_value=120)
|
||||||
|
|||||||
Reference in New Issue
Block a user