Merge pull request #7093 from freqtrade/fix/gate_futures_stoposs
gateio futures - several fixes
This commit is contained in:
commit
004bf31142
@ -79,6 +79,7 @@ class Exchange:
|
||||
"ccxt_futures_name": "swap",
|
||||
"fee_cost_in_contracts": False, # Fee cost needs contract conversion
|
||||
"needs_trading_fees": False, # use fetch_trading_fees to cache fees
|
||||
"order_props_in_contracts": ['amount', 'cost', 'filled', 'remaining'],
|
||||
}
|
||||
_ft_has: Dict = {}
|
||||
_ft_has_futures: Dict = {}
|
||||
@ -425,7 +426,7 @@ class Exchange:
|
||||
if 'symbol' in order and order['symbol'] is not None:
|
||||
contract_size = self._get_contract_size(order['symbol'])
|
||||
if contract_size != 1:
|
||||
for prop in ['amount', 'cost', 'filled', 'remaining']:
|
||||
for prop in self._ft_has.get('order_props_in_contracts', []):
|
||||
if prop in order and order[prop] is not None:
|
||||
order[prop] = order[prop] * contract_size
|
||||
return order
|
||||
@ -823,7 +824,7 @@ class Exchange:
|
||||
'price': rate,
|
||||
'average': rate,
|
||||
'amount': _amount,
|
||||
'cost': _amount * rate / leverage,
|
||||
'cost': _amount * rate,
|
||||
'type': ordertype,
|
||||
'side': side,
|
||||
'filled': 0,
|
||||
@ -1648,7 +1649,7 @@ class Exchange:
|
||||
fee_curr = fee.get('currency')
|
||||
if fee_curr is None:
|
||||
return None
|
||||
fee_cost = fee['cost']
|
||||
fee_cost = float(fee['cost'])
|
||||
if self._ft_has['fee_cost_in_contracts']:
|
||||
# Convert cost via "contracts" conversion
|
||||
fee_cost = self._contracts_to_amount(symbol, fee['cost'])
|
||||
@ -1656,7 +1657,7 @@ class Exchange:
|
||||
# Calculate fee based on order details
|
||||
if fee_curr == self.get_pair_base_currency(symbol):
|
||||
# Base currency - divide by amount
|
||||
return round(fee['cost'] / amount, 8)
|
||||
return round(fee_cost / amount, 8)
|
||||
elif fee_curr == self.get_pair_quote_currency(symbol):
|
||||
# Quote currency - divide by cost
|
||||
return round(fee_cost / cost, 8) if cost else None
|
||||
@ -1687,7 +1688,7 @@ class Exchange:
|
||||
:param amount: Amount of the order
|
||||
:return: Tuple with cost, currency, rate of the given fee dict
|
||||
"""
|
||||
return (fee['cost'],
|
||||
return (float(fee['cost']),
|
||||
fee['currency'],
|
||||
self.calculate_fee_rate(
|
||||
fee,
|
||||
|
@ -1,12 +1,13 @@
|
||||
""" Gate.io exchange subclass """
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
|
||||
from freqtrade.constants import BuySell
|
||||
from freqtrade.enums import MarginMode, TradingMode
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.exchange import Exchange
|
||||
from freqtrade.misc import safe_value_fallback2
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -34,6 +35,7 @@ class Gateio(Exchange):
|
||||
_ft_has_futures: Dict = {
|
||||
"needs_trading_fees": True,
|
||||
"fee_cost_in_contracts": False, # Set explicitly to false for clarity
|
||||
"order_props_in_contracts": ['amount', 'filled', 'remaining'],
|
||||
}
|
||||
|
||||
_supported_trading_mode_margin_pairs: List[Tuple[TradingMode, MarginMode]] = [
|
||||
@ -96,12 +98,29 @@ class Gateio(Exchange):
|
||||
}
|
||||
return trades
|
||||
|
||||
def get_order_id_conditional(self, order: Dict[str, Any]) -> str:
|
||||
if self.trading_mode == TradingMode.FUTURES:
|
||||
return safe_value_fallback2(order, order, 'id_stop', 'id')
|
||||
return order['id']
|
||||
|
||||
def fetch_stoploss_order(self, order_id: str, pair: str, params: Dict = {}) -> Dict:
|
||||
return self.fetch_order(
|
||||
order = self.fetch_order(
|
||||
order_id=order_id,
|
||||
pair=pair,
|
||||
params={'stop': True}
|
||||
)
|
||||
if self.trading_mode == TradingMode.FUTURES:
|
||||
if order['status'] == 'closed':
|
||||
# Places a real order - which we need to fetch explicitly.
|
||||
new_orderid = order.get('info', {}).get('trade_id')
|
||||
if new_orderid:
|
||||
order1 = self.fetch_order(order_id=new_orderid, pair=pair, params=params)
|
||||
order1['id_stop'] = order1['id']
|
||||
order1['id'] = order_id
|
||||
order1['stopPrice'] = order.get('stopPrice')
|
||||
|
||||
return order1
|
||||
return order
|
||||
|
||||
def cancel_stoploss_order(self, order_id: str, pair: str, params: Dict = {}) -> Dict:
|
||||
return self.cancel_order(
|
||||
|
@ -332,6 +332,8 @@ class FreqtradeBot(LoggingMixin):
|
||||
if not trade.is_open and not trade.fee_updated(trade.exit_side):
|
||||
# Get sell fee
|
||||
order = trade.select_order(trade.exit_side, False)
|
||||
if not order:
|
||||
order = trade.select_order('stoploss', False)
|
||||
if order:
|
||||
logger.info(
|
||||
f"Updating {trade.exit_side}-fee on trade {trade}"
|
||||
|
@ -1135,7 +1135,7 @@ def test_create_dry_run_order(default_conf, mocker, side, exchange_name, leverag
|
||||
assert order["symbol"] == "ETH/BTC"
|
||||
assert order["amount"] == 1
|
||||
assert order["leverage"] == leverage
|
||||
assert order["cost"] == 1 * 200 / leverage
|
||||
assert order["cost"] == 1 * 200
|
||||
|
||||
|
||||
@pytest.mark.parametrize("side,startprice,endprice", [
|
||||
|
@ -53,6 +53,25 @@ def test_fetch_stoploss_order_gateio(default_conf, mocker):
|
||||
assert fetch_order_mock.call_args_list[0][1]['pair'] == 'ETH/BTC'
|
||||
assert fetch_order_mock.call_args_list[0][1]['params'] == {'stop': True}
|
||||
|
||||
default_conf['trading_mode'] = 'futures'
|
||||
default_conf['margin_mode'] = 'isolated'
|
||||
|
||||
exchange = get_patched_exchange(mocker, default_conf, id='gateio')
|
||||
|
||||
exchange.fetch_order = MagicMock(return_value={
|
||||
'status': 'closed',
|
||||
'id': '1234',
|
||||
'stopPrice': 5.62,
|
||||
'info': {
|
||||
'trade_id': '222555'
|
||||
}
|
||||
})
|
||||
|
||||
exchange.fetch_stoploss_order('1234', 'ETH/BTC')
|
||||
assert exchange.fetch_order.call_count == 2
|
||||
assert exchange.fetch_order.call_args_list[0][1]['order_id'] == '1234'
|
||||
assert exchange.fetch_order.call_args_list[1][1]['order_id'] == '222555'
|
||||
|
||||
|
||||
def test_cancel_stoploss_order_gateio(default_conf, mocker):
|
||||
exchange = get_patched_exchange(mocker, default_conf, id='gateio')
|
||||
|
Loading…
Reference in New Issue
Block a user