Added skeleton functions for maintenance margin

This commit is contained in:
Sam Germain 2021-07-29 16:05:42 -06:00
parent dad98d43be
commit 34ddf7bfa9
8 changed files with 83 additions and 1 deletions

View File

@ -1,5 +1,6 @@
# flake8: noqa: F401
from freqtrade.enums.backteststate import BacktestState
from freqtrade.enums.maintenancemarginformula import MaintenanceMarginFormula
from freqtrade.enums.rpcmessagetype import RPCMessageType
from freqtrade.enums.runmode import NON_UTIL_MODES, OPTIMIZE_MODES, TRADING_MODES, RunMode
from freqtrade.enums.selltype import SellType

View File

@ -0,0 +1,26 @@
from enum import Enum
from freqtrade.exceptions import OperationalException
class MaintenanceMarginFormula(Enum):
"""Equations to calculate maintenance margin"""
BINANCE = "BINANCE"
FTX = "FTX"
KRAKEN = "KRAKEN"
# TODO: Add arguments
def __call__(self):
if self.name == "BINANCE":
raise OperationalException("Cross margin not available on this exchange with freqtrade")
# TODO: return This formula
# https://www.binance.com/en/support/faq/f6b010588e55413aa58b7d63ee0125ed
elif self.name == "FTX":
# TODO: Implement
raise OperationalException("Cross margin not available on this exchange with freqtrade")
elif self.name == "KRAKEN":
# TODO: Implement
raise OperationalException("Cross margin not available on this exchange with freqtrade")
# https://support.kraken.com/hc/en-us/articles/203325763-Margin-Call-Level-and-Margin-Liquidation-Level
else:
raise OperationalException("Cross margin not available on this exchange with freqtrade")

View File

@ -3,7 +3,7 @@ import logging
from typing import Dict
import ccxt
from freqtrade.enums import MaintenanceMarginFormula
from freqtrade.exceptions import (DDosProtection, InsufficientFundsError, InvalidOrderException,
OperationalException, TemporaryError)
from freqtrade.exchange import Exchange
@ -24,6 +24,8 @@ class Binance(Exchange):
"l2_limit_range": [5, 10, 20, 50, 100, 500, 1000],
}
maintenance_margin_formula = MaintenanceMarginFormula.BINANCE
def stoploss_adjust(self, stop_loss: float, order: Dict) -> bool:
"""
Verify stop_loss against stoploss-order value (limit or price)

View File

@ -21,6 +21,7 @@ from pandas import DataFrame
from freqtrade.constants import DEFAULT_AMOUNT_RESERVE_PERCENT, ListPairsWithTimeframes
from freqtrade.data.converter import ohlcv_to_dataframe, trades_dict_to_list
from freqtrade.enums import MaintenanceMarginFormula
from freqtrade.exceptions import (DDosProtection, ExchangeError, InsufficientFundsError,
InvalidOrderException, OperationalException, PricingError,
RetryableOrderError, TemporaryError)
@ -68,6 +69,7 @@ class Exchange:
"l2_limit_range_required": True, # Allow Empty L2 limit (kucoin)
}
_ft_has: Dict = {}
maintenance_margin_formula: MaintenanceMarginFormula
def __init__(self, config: Dict[str, Any], validate: bool = True) -> None:
"""

View File

@ -4,6 +4,7 @@ from typing import Any, Dict
import ccxt
from freqtrade.enums import MaintenanceMarginFormula
from freqtrade.exceptions import (DDosProtection, InsufficientFundsError, InvalidOrderException,
OperationalException, TemporaryError)
from freqtrade.exchange import Exchange
@ -21,6 +22,8 @@ class Ftx(Exchange):
"ohlcv_candle_limit": 1500,
}
maintenance_margin_formula = MaintenanceMarginFormula.FTX
def market_is_tradable(self, market: Dict[str, Any]) -> bool:
"""
Check if the market symbol is tradable by Freqtrade.

View File

@ -4,6 +4,7 @@ from typing import Any, Dict
import ccxt
from freqtrade.enums import MaintenanceMarginFormula
from freqtrade.exceptions import (DDosProtection, InsufficientFundsError, InvalidOrderException,
OperationalException, TemporaryError)
from freqtrade.exchange import Exchange
@ -23,6 +24,8 @@ class Kraken(Exchange):
"trades_pagination_arg": "since",
}
maintenance_margin_formula = MaintenanceMarginFormula.KRAKEN
def market_is_tradable(self, market: Dict[str, Any]) -> bool:
"""
Check if the market symbol is tradable by Freqtrade.

View File

@ -20,6 +20,7 @@ from freqtrade.enums import RPCMessageType, SellType, State
from freqtrade.exceptions import (DependencyException, ExchangeError, InsufficientFundsError,
InvalidOrderException, PricingError)
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds
from freqtrade.maintenance_margin import MaintenanceMargin
from freqtrade.misc import safe_value_fallback, safe_value_fallback2
from freqtrade.mixins import LoggingMixin
from freqtrade.persistence import Order, PairLocks, Trade, cleanup_db, init_db
@ -102,6 +103,12 @@ class FreqtradeBot(LoggingMixin):
self._sell_lock = Lock()
LoggingMixin.__init__(self, logger, timeframe_to_seconds(self.strategy.timeframe))
# Start calculating maintenance margin if on cross margin
# TODO: Add margin_mode to freqtrade.configuration?
if self.config.get('margin_mode') == "cross":
self.maintenance_margin = MaintenanceMargin(self.exchange.maintenance_margin_formula)
self.maintenance_margin.run
def notify_status(self, msg: str) -> None:
"""
Public method for users of this class (worker, etc.) to send notifications

View File

@ -0,0 +1,38 @@
from freqtrade.enums import MaintenanceMarginFormula
from freqtrade.persistence import Trade
class MaintenanceMargin:
trades: list[Trade]
formula: MaintenanceMarginFormula
@property
def margin_level(self):
return self.formula() # TODO: Add args to formula
@property
def liq_level(self): # This may be a constant value and may not need a function
return
def __init__(self, formula: MaintenanceMarginFormula):
return
def add_new_trade(self, trade):
return
def remove_trade(self, trade):
return
# ? def update_trade_pric(self):
def sell_all(self):
return
def run(self):
# TODO-mg: implement a thread that constantly updates with every price change,
# TODO-mg: must update at least every second
# while true:
# if self.margin_level <= self.liq_level:
# self.sell_all()
return