diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index 6a2251d65..db47b07c9 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -2,6 +2,8 @@ import json import logging from datetime import datetime +from decimal import Decimal +from math import ceil from pathlib import Path from typing import Dict, List, Optional, Tuple @@ -358,3 +360,23 @@ class Binance(Exchange): else: raise OperationalException( "Freqtrade only supports isolated futures for leverage trading") + + @classmethod + def interest( + cls, + borrowed: Decimal, + rate: Decimal, + hours: Decimal + ) -> Decimal: + """ + Equation to calculate interest on margin trades + + :param borrowed: The amount of currency being borrowed + :param rate: The rate of interest (i.e daily interest rate) + :param hours: The time in hours that the currency has been borrowed for + + Returns: The amount of interest owed (currency matches borrowed) + """ + twenty_four = Decimal(24.0) + + return borrowed * rate * ceil(hours)/twenty_four diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index dd247c160..cc111005a 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -8,6 +8,7 @@ import inspect import logging from copy import deepcopy from datetime import datetime, timedelta, timezone +from decimal import Decimal from math import ceil from typing import Any, Dict, List, Literal, Optional, Tuple, Union @@ -2160,6 +2161,28 @@ class Exchange: raise OperationalException( "Freqtrade only supports isolated futures for leverage trading") + @classmethod + def interest( + cls, + borrowed: Decimal, + rate: Decimal, + hours: Decimal + ) -> Decimal: + """ + Equation to calculate interest on margin trades + + :param borrowed: The amount of currency being borrowed + :param rate: The rate of interest (i.e daily interest rate) + :param hours: The time in hours that the currency has been borrowed for + + Raises: + OperationalException: Raised if freqtrade does + not support margin trading for this exchange + + Returns: The amount of interest owed (currency matches borrowed) + """ + raise OperationalException('interest not implemented for ' + cls.__name__) + def is_exchange_known_ccxt(exchange_name: str, ccxt_module: CcxtModuleType = None) -> bool: return exchange_name in ccxt_exchanges(ccxt_module) diff --git a/freqtrade/exchange/ftx.py b/freqtrade/exchange/ftx.py index be2e19c66..c26cd7614 100644 --- a/freqtrade/exchange/ftx.py +++ b/freqtrade/exchange/ftx.py @@ -1,5 +1,7 @@ """ FTX exchange subclass """ import logging +from decimal import Decimal +from math import ceil from typing import Any, Dict, List, Tuple import ccxt @@ -162,3 +164,25 @@ class Ftx(Exchange): if order['type'] == 'stop': return safe_value_fallback2(order, order, 'id_stop', 'id') return order['id'] + + @classmethod + def interest( + cls, + borrowed: Decimal, + rate: Decimal, + hours: Decimal + ) -> Decimal: + """ + Equation to calculate interest on margin trades + + :param borrowed: The amount of currency being borrowed + :param rate: The rate of interest (i.e daily interest rate) + :param hours: The time in hours that the currency has been borrowed for + + Returns: The amount of interest owed (currency matches borrowed) + """ + twenty_four = Decimal(24.0) + + # As Explained under #Interest rates section in + # https://help.ftx.com/hc/en-us/articles/360053007671-Spot-Margin-Trading-Explainer + return borrowed * rate * ceil(hours)/twenty_four diff --git a/freqtrade/exchange/kraken.py b/freqtrade/exchange/kraken.py index 0c3fe4e7b..672aa99a9 100644 --- a/freqtrade/exchange/kraken.py +++ b/freqtrade/exchange/kraken.py @@ -1,6 +1,8 @@ """ Kraken exchange subclass """ import logging from datetime import datetime +from decimal import Decimal +from math import ceil from typing import Any, Dict, List, Optional, Tuple import ccxt @@ -206,3 +208,26 @@ class Kraken(Exchange): fees = sum(df['open_fund'] * df['open_mark'] * amount * time_in_ratio) return fees if is_short else -fees + + @classmethod + def interest( + cls, + borrowed: Decimal, + rate: Decimal, + hours: Decimal + ) -> Decimal: + """ + Equation to calculate interest on margin trades + + :param borrowed: The amount of currency being borrowed + :param rate: The rate of interest (i.e daily interest rate) + :param hours: The time in hours that the currency has been borrowed for + + Returns: The amount of interest owed (currency matches borrowed) + """ + + one = Decimal(1.0) + four = Decimal(4.0) + + # Rounded based on https://kraken-fees-calculator.github.io/ + return borrowed * rate * (one+ceil(hours/four)) diff --git a/freqtrade/leverage/__init__.py b/freqtrade/leverage/__init__.py deleted file mode 100644 index ae78f4722..000000000 --- a/freqtrade/leverage/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# flake8: noqa: F401 -from freqtrade.leverage.interest import interest diff --git a/freqtrade/leverage/interest.py b/freqtrade/leverage/interest.py deleted file mode 100644 index ff375b05e..000000000 --- a/freqtrade/leverage/interest.py +++ /dev/null @@ -1,43 +0,0 @@ -from decimal import Decimal -from math import ceil - -from freqtrade.exceptions import OperationalException - - -one = Decimal(1.0) -four = Decimal(4.0) -twenty_four = Decimal(24.0) - - -def interest( - exchange_name: str, - borrowed: Decimal, - rate: Decimal, - hours: Decimal -) -> Decimal: - """ - Equation to calculate interest on margin trades - - :param exchange_name: The exchanged being trading on - :param borrowed: The amount of currency being borrowed - :param rate: The rate of interest (i.e daily interest rate) - :param hours: The time in hours that the currency has been borrowed for - - Raises: - OperationalException: Raised if freqtrade does - not support margin trading for this exchange - - Returns: The amount of interest owed (currency matches borrowed) - """ - exchange_name = exchange_name.lower() - if exchange_name == "binance": - return borrowed * rate * ceil(hours)/twenty_four - elif exchange_name == "kraken": - # Rounded based on https://kraken-fees-calculator.github.io/ - return borrowed * rate * (one+ceil(hours/four)) - elif exchange_name == "ftx": - # As Explained under #Interest rates section in - # https://help.ftx.com/hc/en-us/articles/360053007671-Spot-Margin-Trading-Explainer - return borrowed * rate * ceil(hours)/twenty_four - else: - raise OperationalException(f"Leverage not available on {exchange_name} with freqtrade")