Update funding_fee formula to correctly calculate fees for long trades

This commit is contained in:
Matthias
2022-01-17 19:59:33 +01:00
parent f26cd19146
commit a0c0c4dcbe
5 changed files with 32 additions and 12 deletions

View File

@@ -1885,6 +1885,7 @@ class Exchange:
self,
pair: str,
amount: float,
is_short: bool,
open_date: datetime,
close_date: Optional[datetime] = None
) -> float:
@@ -1894,6 +1895,7 @@ class Exchange:
Only used during dry-run or if the exchange does not provide a funding_rates endpoint.
:param pair: The quote/base pair of the trade
:param amount: The quantity of the trade
:param is_short: trade direction
:param open_date: The date and time that the trade started
:param close_date: The date and time that the trade ended
"""
@@ -1928,6 +1930,7 @@ class Exchange:
return self.calculate_funding_fees(
funding_mark_rates,
amount=amount,
is_short=is_short,
open_date=open_date,
close_date=close_date
)
@@ -1946,6 +1949,7 @@ class Exchange:
self,
df: DataFrame,
amount: float,
is_short: bool,
open_date: datetime,
close_date: Optional[datetime] = None,
time_in_ratio: Optional[float] = None
@@ -1955,6 +1959,7 @@ class Exchange:
:param df: Dataframe containing combined funding and mark rates
as `open_fund` and `open_mark`.
:param amount: The quantity of the trade
:param is_short: trade direction
:param open_date: The date and time that the trade started
:param close_date: The date and time that the trade ended
:param time_in_ratio: Not used by most exchange classes
@@ -1965,19 +1970,23 @@ class Exchange:
df = df[(df['date'] >= open_date) & (df['date'] <= close_date)]
fees = sum(df['open_fund'] * df['open_mark'] * amount)
return fees
# Negate fees for longs as funding_fees expects it this way based on live endpoints.
return fees if is_short else -fees
def get_funding_fees(self, pair: str, amount: float, open_date: datetime) -> float:
def get_funding_fees(
self, pair: str, amount: float, is_short: bool, open_date: datetime) -> float:
"""
Fetch funding fees, either from the exchange (live) or calculates them
based on funding rate/mark price history
:param pair: The quote/base pair of the trade
:param is_short: trade direction
:param amount: Trade amount
:param open_date: Open date of the trade
"""
if self.trading_mode == TradingMode.FUTURES:
if self._config['dry_run']:
funding_fees = self._fetch_and_calculate_funding_fees(pair, amount, open_date)
funding_fees = self._fetch_and_calculate_funding_fees(
pair, amount, is_short, open_date)
else:
funding_fees = self._get_funding_fees_from_exchange(pair, open_date)
return funding_fees

View File

@@ -163,6 +163,7 @@ class Kraken(Exchange):
self,
df: DataFrame,
amount: float,
is_short: bool,
open_date: datetime,
close_date: Optional[datetime] = None,
time_in_ratio: Optional[float] = None
@@ -176,6 +177,7 @@ class Kraken(Exchange):
:param df: Dataframe containing combined funding and mark rates
as `open_fund` and `open_mark`.
:param amount: The quantity of the trade
:param is_short: trade direction
:param open_date: The date and time that the trade started
:param close_date: The date and time that the trade ended
:param time_in_ratio: Not used by most exchange classes

View File

@@ -273,9 +273,10 @@ class FreqtradeBot(LoggingMixin):
trades = Trade.get_open_trades()
for trade in trades:
funding_fees = self.exchange.get_funding_fees(
trade.pair,
trade.amount,
trade.open_date
pair=trade.pair,
amount=trade.amount,
is_short=trade.is_short,
open_date=trade.open_date
)
trade.funding_fees = funding_fees
else:
@@ -741,7 +742,8 @@ class FreqtradeBot(LoggingMixin):
# Fee is applied twice because we make a LIMIT_BUY and LIMIT_SELL
fee = self.exchange.get_fee(symbol=pair, taker_or_maker='maker')
open_date = datetime.now(timezone.utc)
funding_fees = self.exchange.get_funding_fees(pair, amount, open_date)
funding_fees = self.exchange.get_funding_fees(
pair=pair, amount=amount, is_short=is_short, open_date=open_date)
# This is a new trade
if trade is None:
trade = Trade(
@@ -1379,9 +1381,10 @@ class FreqtradeBot(LoggingMixin):
:return: True if it succeeds (supported) False (not supported)
"""
trade.funding_fees = self.exchange.get_funding_fees(
trade.pair,
trade.amount,
trade.open_date
pair=trade.pair,
amount=trade.amount,
is_short=trade.is_short,
open_date=trade.open_date,
)
exit_type = 'sell'
if sell_reason.sell_type in (SellType.STOP_LOSS, SellType.TRAILING_STOP_LOSS):

View File

@@ -495,6 +495,7 @@ class Backtesting:
trade.funding_fees = self.exchange.calculate_funding_fees(
self.futures_data[trade.pair],
amount=trade.amount,
is_short=trade.is_short,
open_date=trade.open_date_utc,
close_date=sell_candle_time,
)