refactor(krakenfutures): drop resolved trigger price workaround
This commit is contained in:
@@ -17,7 +17,6 @@ from freqtrade.exceptions import (
|
||||
from freqtrade.exchange.common import API_FETCH_ORDER_RETRY_COUNT, retrier
|
||||
from freqtrade.exchange.exchange import Exchange
|
||||
from freqtrade.exchange.exchange_types import CcxtBalances, CcxtOrder, FtHas
|
||||
from freqtrade.misc import safe_value_nested
|
||||
from freqtrade.util.datetime_helpers import dt_from_ts
|
||||
|
||||
|
||||
@@ -134,39 +133,21 @@ class Krakenfutures(Exchange):
|
||||
return None
|
||||
|
||||
def _order_contracts_to_amount(self, order: CcxtOrder) -> CcxtOrder:
|
||||
"""Normalize order and apply Kraken Futures-specific fixes.
|
||||
|
||||
This override applies all CCXT workarounds by calling _adjust_krakenfutures_order
|
||||
after the base class normalization. This ensures all orders (including those
|
||||
from create_order that fill immediately) get correct prices and fees.
|
||||
"""
|
||||
"""Normalize order and apply Kraken Futures-specific order corrections."""
|
||||
order = super()._order_contracts_to_amount(order)
|
||||
return self._adjust_krakenfutures_order(order)
|
||||
|
||||
def _adjust_krakenfutures_order(self, order: CcxtOrder) -> CcxtOrder:
|
||||
"""Apply Kraken Futures-specific order corrections.
|
||||
|
||||
Fixes CCXT parsing issues:
|
||||
1. triggerPrice nested in info.order.priceTriggerOptions (not extracted)
|
||||
2. average set to limitPrice instead of actual fill price
|
||||
|
||||
For filled terminal orders, we ALWAYS fetch trades and compute VWAP because
|
||||
CCXT's average is unreliable.
|
||||
For filled terminal orders, always fetch trades and compute VWAP because
|
||||
CCXT's average is still unreliable.
|
||||
|
||||
See: https://github.com/ccxt/ccxt/issues/27996
|
||||
"""
|
||||
# Fix 1: Extract nested triggerPrice for stoploss orders
|
||||
if order.get("triggerPrice") is None and order.get("stopPrice") is None:
|
||||
trigger = safe_value_nested(order, "info.order.priceTriggerOptions.triggerPrice")
|
||||
if trigger is not None:
|
||||
trigger_float = self._safe_float(trigger)
|
||||
if trigger_float is not None:
|
||||
order["triggerPrice"] = trigger_float
|
||||
order["stopPrice"] = trigger_float
|
||||
|
||||
filled = self._safe_float(order.get("filled")) or 0.0
|
||||
if order.get("status") in ("canceled", "closed") and filled > 0:
|
||||
# Fix 2: Compute VWAP and cost for filled orders
|
||||
# Compute VWAP and cost for filled orders.
|
||||
trades = self.get_trades_for_order(
|
||||
order["id"], order["symbol"], since=dt_from_ts(order["timestamp"])
|
||||
)
|
||||
|
||||
@@ -36,75 +36,6 @@ def test_krakenfutures_ft_has_overrides():
|
||||
assert ft_has["stop_price_type_field"] == "triggerSignal"
|
||||
|
||||
|
||||
# --- _order_contracts_to_amount trigger price fix tests ---
|
||||
|
||||
|
||||
def test_krakenfutures_order_contracts_fixes_missing_trigger_price(mocker, default_conf):
|
||||
"""Extract triggerPrice from info.order.priceTriggerOptions when CCXT misses it."""
|
||||
ex = get_patched_exchange(mocker, default_conf, exchange="krakenfutures")
|
||||
order = {
|
||||
"id": "abc",
|
||||
"symbol": "BTC/USD:USD",
|
||||
"triggerPrice": None,
|
||||
"stopPrice": None,
|
||||
"info": {
|
||||
"order": {
|
||||
"type": "TRIGGER_ORDER",
|
||||
"priceTriggerOptions": {
|
||||
"triggerPrice": 71641,
|
||||
"triggerSignal": "LAST_PRICE",
|
||||
},
|
||||
},
|
||||
"status": "TRIGGER_PLACED",
|
||||
},
|
||||
}
|
||||
result = ex._order_contracts_to_amount(order)
|
||||
assert result["triggerPrice"] == 71641.0
|
||||
assert result["stopPrice"] == 71641.0
|
||||
|
||||
|
||||
def test_krakenfutures_order_contracts_preserves_existing_trigger_price(mocker, default_conf):
|
||||
"""Don't overwrite triggerPrice when CCXT already parsed it correctly."""
|
||||
ex = get_patched_exchange(mocker, default_conf, exchange="krakenfutures")
|
||||
order = {
|
||||
"id": "abc",
|
||||
"symbol": "BTC/USD:USD",
|
||||
"triggerPrice": 70000.0,
|
||||
"stopPrice": 70000.0,
|
||||
"info": {
|
||||
"order": {
|
||||
"priceTriggerOptions": {
|
||||
"triggerPrice": 71641,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
result = ex._order_contracts_to_amount(order)
|
||||
assert result["triggerPrice"] == 70000.0
|
||||
assert result["stopPrice"] == 70000.0
|
||||
|
||||
|
||||
def test_krakenfutures_order_contracts_no_trigger_options(mocker, default_conf):
|
||||
"""Regular (non-trigger) orders should pass through unchanged."""
|
||||
ex = get_patched_exchange(mocker, default_conf, exchange="krakenfutures")
|
||||
order = {
|
||||
"id": "abc",
|
||||
"symbol": "BTC/USD:USD",
|
||||
"triggerPrice": None,
|
||||
"stopPrice": None,
|
||||
"info": {
|
||||
"order": {
|
||||
"type": "lmt",
|
||||
"orderId": "abc",
|
||||
},
|
||||
"status": "placed",
|
||||
},
|
||||
}
|
||||
result = ex._order_contracts_to_amount(order)
|
||||
assert result["triggerPrice"] is None
|
||||
assert result["stopPrice"] is None
|
||||
|
||||
|
||||
# --- _adjust_krakenfutures_order average price tests ---
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user