Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/strategy-callbacks.md
Original file line number Diff line number Diff line change
Expand Up @@ -950,7 +950,8 @@ Returning any other price will cancel the existing order, and replace it with a
The trade open-date (`trade.open_date_utc`) will remain at the time of the very first order placed.
Please make sure to be aware of this - and eventually adjust your logic in other callbacks to account for this, and use the date of the first filled order instead.

If the cancellation of the original order fails, then the order will not be replaced - though the order will most likely have been canceled on exchange. Having this happen on initial entries will result in the deletion of the order, while on position adjustment orders, it'll result in the trade size remaining as is.
If the cancellation of the original order fails, then the order will not be replaced - though the order will most likely have been canceled on exchange. Having this happen on initial entries will result in the deletion of the order, while on position adjustment orders, it'll result in the trade size remaining as is.
If the order has been partially filled, the order will not be replaced. You can however use [`adjust_trade_position()`](#adjust-trade-position) to adjust the trade size to the full, expected position size, should this be necessary / desired.

!!! Warning "Regular timeout"
Entry `unfilledtimeout` mechanism (as well as `check_entry_timeout()`) takes precedence over this.
Expand Down
1 change: 1 addition & 0 deletions freqtrade/exchange/exchange.py
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ def market_is_tradable(self, market: dict[str, Any]) -> bool:
and (
self.precisionMode != TICK_SIZE
# Too low precision will falsify calculations
or market.get("precision", {}).get("price") is None
or market.get("precision", {}).get("price") > 1e-11
)
and (
Expand Down
2 changes: 1 addition & 1 deletion freqtrade/freqtradebot.py
Original file line number Diff line number Diff line change
Expand Up @@ -1695,7 +1695,7 @@ def replace_order(self, order: CcxtOrder, order_obj: Order | None, trade: Trade)
)
if not res:
self.replace_order_failed(
trade, f"Could not cancel order for {trade}, therefore not replacing."
trade, f"Could not fully cancel order for {trade}, therefore not replacing."
)
return
if adjusted_entry_price:
Expand Down
8 changes: 6 additions & 2 deletions freqtrade/strategy/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -1160,8 +1160,12 @@ def get_latest_candle(
logger.warning(f"Empty candle (OHLCV) data for pair {pair}")
return None, None

latest_date_pd = dataframe["date"].max()
latest = dataframe.loc[dataframe["date"] == latest_date_pd].iloc[-1]
try:
latest_date_pd = dataframe["date"].max()
latest = dataframe.loc[dataframe["date"] == latest_date_pd].iloc[-1]
except Exception as e:
logger.warning(f"Unable to get latest candle (OHLCV) data for pair {pair} - {e}")
return None, None
# Explicitly convert to datetime object to ensure the below comparison does not fail
latest_date: datetime = latest_date_pd.to_pydatetime()

Expand Down
2 changes: 1 addition & 1 deletion tests/freqtradebot/test_freqtradebot.py
Original file line number Diff line number Diff line change
Expand Up @@ -2053,7 +2053,7 @@ def test_adjust_entry_replace_fail(
assert len(trades) == 0
assert len(Order.session.scalars(select(Order)).all()) == 0
assert fetch_order_mock.call_count == 4
assert log_has_re(r"Could not cancel order.*, therefore not replacing\.", caplog)
assert log_has_re(r"Could not fully cancel order.*, therefore not replacing\.", caplog)

# Entry adjustment is called
assert freqtrade.strategy.adjust_entry_price.call_count == 1
Expand Down
Loading