Miscellaneous funding fee changes. Abandoning for a new method of tracking funding fee
This commit is contained in:
parent
b7891485b3
commit
194bb24a55
@ -1,6 +1,6 @@
|
|||||||
""" Binance exchange subclass """
|
""" Binance exchange subclass """
|
||||||
import logging
|
import logging
|
||||||
from typing import Dict
|
from typing import Dict, Optional
|
||||||
|
|
||||||
import ccxt
|
import ccxt
|
||||||
|
|
||||||
@ -89,3 +89,17 @@ class Binance(Exchange):
|
|||||||
f'Could not place sell order due to {e.__class__.__name__}. Message: {e}') from e
|
f'Could not place sell order due to {e.__class__.__name__}. Message: {e}') from e
|
||||||
except ccxt.BaseError as e:
|
except ccxt.BaseError as e:
|
||||||
raise OperationalException(e) from e
|
raise OperationalException(e) from e
|
||||||
|
|
||||||
|
# https://www.binance.com/en/support/faq/360033525031
|
||||||
|
def get_funding_fee(
|
||||||
|
self,
|
||||||
|
contract_size: float,
|
||||||
|
mark_price: float,
|
||||||
|
rate: Optional[float],
|
||||||
|
# index_price: float,
|
||||||
|
# interest_rate: float
|
||||||
|
):
|
||||||
|
assert isinstance(rate, float)
|
||||||
|
nominal_value = mark_price * contract_size
|
||||||
|
adjustment = nominal_value * rate
|
||||||
|
return adjustment
|
||||||
|
@ -1516,6 +1516,20 @@ class Exchange:
|
|||||||
self._async_get_trade_history(pair=pair, since=since,
|
self._async_get_trade_history(pair=pair, since=since,
|
||||||
until=until, from_id=from_id))
|
until=until, from_id=from_id))
|
||||||
|
|
||||||
|
def fetch_funding_rates(self):
|
||||||
|
return self._api.fetch_funding_rates()
|
||||||
|
|
||||||
|
# https://www.binance.com/en/support/faq/360033525031
|
||||||
|
def get_funding_fee(
|
||||||
|
self,
|
||||||
|
contract_size: float,
|
||||||
|
mark_price: float,
|
||||||
|
rate: Optional[float],
|
||||||
|
# index_price: float,
|
||||||
|
# interest_rate: float
|
||||||
|
):
|
||||||
|
raise OperationalException(f"{self.name} has not implemented get_funding_rate")
|
||||||
|
|
||||||
|
|
||||||
def is_exchange_known_ccxt(exchange_name: str, ccxt_module: CcxtModuleType = None) -> bool:
|
def is_exchange_known_ccxt(exchange_name: str, ccxt_module: CcxtModuleType = None) -> bool:
|
||||||
return exchange_name in ccxt_exchanges(ccxt_module)
|
return exchange_name in ccxt_exchanges(ccxt_module)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
""" FTX exchange subclass """
|
""" FTX exchange subclass """
|
||||||
import logging
|
import logging
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
import ccxt
|
import ccxt
|
||||||
|
|
||||||
@ -152,3 +152,18 @@ class Ftx(Exchange):
|
|||||||
if order['type'] == 'stop':
|
if order['type'] == 'stop':
|
||||||
return safe_value_fallback2(order, order, 'id_stop', 'id')
|
return safe_value_fallback2(order, order, 'id_stop', 'id')
|
||||||
return order['id']
|
return order['id']
|
||||||
|
|
||||||
|
# https://help.ftx.com/hc/en-us/articles/360027946571-Funding
|
||||||
|
def get_funding_fee(
|
||||||
|
self,
|
||||||
|
contract_size: float,
|
||||||
|
mark_price: float,
|
||||||
|
rate: Optional[float],
|
||||||
|
# index_price: float,
|
||||||
|
# interest_rate: float
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Always paid in USD on FTX # TODO: How do we account for this
|
||||||
|
"""
|
||||||
|
(contract_size * mark_price) / 24
|
||||||
|
return
|
||||||
|
@ -3,6 +3,7 @@ from typing import List
|
|||||||
|
|
||||||
import schedule
|
import schedule
|
||||||
|
|
||||||
|
from freqtrade.exchange import Exchange
|
||||||
from freqtrade.persistence import Trade
|
from freqtrade.persistence import Trade
|
||||||
|
|
||||||
|
|
||||||
@ -16,10 +17,14 @@ class FundingFee:
|
|||||||
"07:59:45",
|
"07:59:45",
|
||||||
"15:59:45",
|
"15:59:45",
|
||||||
]
|
]
|
||||||
|
exchange: Exchange
|
||||||
|
|
||||||
# FTX
|
# FTX
|
||||||
# begin_times = every hour
|
# begin_times = every hour
|
||||||
|
|
||||||
|
def __init__(self, exchange: Exchange):
|
||||||
|
self.exchange = exchange
|
||||||
|
|
||||||
def _is_time_between(self, begin_time, end_time):
|
def _is_time_between(self, begin_time, end_time):
|
||||||
# If check time is not given, default to current UTC time
|
# If check time is not given, default to current UTC time
|
||||||
check_time = datetime.utcnow().time()
|
check_time = datetime.utcnow().time()
|
||||||
@ -28,27 +33,30 @@ class FundingFee:
|
|||||||
else: # crosses midnight
|
else: # crosses midnight
|
||||||
return check_time >= begin_time or check_time <= end_time
|
return check_time >= begin_time or check_time <= end_time
|
||||||
|
|
||||||
def _apply_funding_fees(self, num_of: int = 1):
|
def _apply_current_funding_fees(self):
|
||||||
if num_of == 0:
|
funding_rates = self.exchange.fetch_funding_rates()
|
||||||
return
|
|
||||||
for trade in self.trades:
|
for trade in self.trades:
|
||||||
trade.adjust_funding_fee(self._calculate(trade.amount) * num_of)
|
funding_rate = funding_rates[trade.pair]
|
||||||
|
self._apply_fee_to_trade(funding_rate, trade)
|
||||||
|
|
||||||
def _calculate(self, amount):
|
def _apply_fee_to_trade(self, funding_rate: dict, trade: Trade):
|
||||||
# TODO-futures: implement
|
|
||||||
# TODO-futures: Check how other exchages do it and adjust accordingly
|
|
||||||
# https://www.binance.com/en/support/faq/360033525031
|
|
||||||
# mark_price =
|
|
||||||
# contract_size = maybe trade.amount
|
|
||||||
# funding_rate = # https://www.binance.com/en/futures/funding-history/0
|
|
||||||
# nominal_value = mark_price * contract_size
|
|
||||||
# adjustment = nominal_value * funding_rate
|
|
||||||
# return adjustment
|
|
||||||
|
|
||||||
# FTX - paid in USD(always)
|
amount = trade.amount
|
||||||
# position size * TWAP of((future - index) / index) / 24
|
mark_price = funding_rate['markPrice']
|
||||||
# https: // help.ftx.com/hc/en-us/articles/360027946571-Funding
|
rate = funding_rate['fundingRate']
|
||||||
return
|
# index_price = funding_rate['indexPrice']
|
||||||
|
# interest_rate = funding_rate['interestRate']
|
||||||
|
|
||||||
|
funding_fee = self.exchange.get_funding_fee(
|
||||||
|
amount,
|
||||||
|
mark_price,
|
||||||
|
rate,
|
||||||
|
# interest_rate
|
||||||
|
# index_price,
|
||||||
|
)
|
||||||
|
|
||||||
|
trade.adjust_funding_fee(funding_fee)
|
||||||
|
|
||||||
def initial_funding_fee(self, amount) -> float:
|
def initial_funding_fee(self, amount) -> float:
|
||||||
# A funding fee interval is applied immediately if within 30s of an iterval
|
# A funding fee interval is applied immediately if within 30s of an iterval
|
||||||
|
Loading…
Reference in New Issue
Block a user