Compare commits
1 Commits
develop
...
feat/cross
Author | SHA1 | Date | |
---|---|---|---|
|
2b9775ae22 |
@ -17,12 +17,13 @@ from freqtrade.constants import BuySell, LongShort
|
||||
from freqtrade.data.converter import order_book_to_dataframe
|
||||
from freqtrade.data.dataprovider import DataProvider
|
||||
from freqtrade.edge import Edge
|
||||
from freqtrade.enums import (ExitCheckTuple, ExitType, RPCMessageType, RunMode, SignalDirection,
|
||||
State, TradingMode)
|
||||
from freqtrade.enums import (ExitCheckTuple, ExitType, MarginMode, RPCMessageType, RunMode,
|
||||
SignalDirection, State, TradingMode)
|
||||
from freqtrade.exceptions import (DependencyException, ExchangeError, InsufficientFundsError,
|
||||
InvalidOrderException, PricingError)
|
||||
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds
|
||||
from freqtrade.exchange.exchange import timeframe_to_next_date
|
||||
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
|
||||
@ -104,7 +105,11 @@ class FreqtradeBot(LoggingMixin):
|
||||
LoggingMixin.__init__(self, logger, timeframe_to_seconds(self.strategy.timeframe))
|
||||
|
||||
self.trading_mode: TradingMode = self.config.get('trading_mode', TradingMode.SPOT)
|
||||
|
||||
self.margin_mode: MarginMode = (
|
||||
MarginMode(config.get('margin_mode'))
|
||||
if config.get('margin_mode')
|
||||
else MarginMode.NONE
|
||||
)
|
||||
self._schedule = Scheduler()
|
||||
|
||||
if self.trading_mode == TradingMode.FUTURES:
|
||||
@ -125,6 +130,16 @@ class FreqtradeBot(LoggingMixin):
|
||||
# Initialize protections AFTER bot start - otherwise parameters are not loaded.
|
||||
self.protections = ProtectionManager(self.config, self.strategy.protections)
|
||||
|
||||
# Start calculating maintenance margin if on cross margin
|
||||
# TODO-lev: finish the below...
|
||||
if self.margin_mode == MarginMode.CROSS:
|
||||
|
||||
self.maintenance_margin = MaintenanceMargin(
|
||||
exchange_name=self.exchange.name,
|
||||
trading_mode=self.trading_mode)
|
||||
|
||||
self.maintenance_margin.run()
|
||||
|
||||
def notify_status(self, msg: str) -> None:
|
||||
"""
|
||||
Public method for users of this class (worker, etc.) to send notifications
|
||||
@ -721,6 +736,10 @@ class FreqtradeBot(LoggingMixin):
|
||||
|
||||
trade.orders.append(order_obj)
|
||||
trade.recalc_trade_from_orders()
|
||||
|
||||
if self.margin_mode == MarginMode.CROSS:
|
||||
self.maintenance_margin.add_new_trade(trade)
|
||||
|
||||
Trade.query.session.add(trade)
|
||||
Trade.commit()
|
||||
|
||||
@ -1501,10 +1520,21 @@ class FreqtradeBot(LoggingMixin):
|
||||
# In case of market sell orders the order can be closed immediately
|
||||
if order.get('status', 'unknown') in ('closed', 'expired'):
|
||||
self.update_trade_state(trade, trade.open_order_id, order)
|
||||
|
||||
Trade.commit()
|
||||
|
||||
self._remove_maintenance_trade(trade)
|
||||
|
||||
return True
|
||||
|
||||
def _remove_maintenance_trade(self, trade: Trade):
|
||||
"""
|
||||
Removes a trade from the maintenance margin object
|
||||
:param trade: The trade to remove from the maintenance margin
|
||||
"""
|
||||
if self.margin_mode == MarginMode.CROSS:
|
||||
self.maintenance_margin.remove_trade(trade)
|
||||
|
||||
def _notify_exit(self, trade: Trade, order_type: str, fill: bool = False) -> None:
|
||||
"""
|
||||
Sends rpc notification when a sell occurred.
|
||||
|
52
freqtrade/maintenance_margin.py
Normal file
52
freqtrade/maintenance_margin.py
Normal file
@ -0,0 +1,52 @@
|
||||
from typing import List
|
||||
|
||||
from freqtrade.enums import TradingMode
|
||||
from freqtrade.leverage import liquidation_price
|
||||
from freqtrade.persistence import Trade
|
||||
|
||||
|
||||
class MaintenanceMargin:
|
||||
|
||||
trades: List[Trade]
|
||||
exchange_name: str
|
||||
trading_mode: TradingMode
|
||||
|
||||
@property
|
||||
def margin_level(self):
|
||||
# This is the current value of all assets,
|
||||
# and if you pass below liq_level, you are liquidated
|
||||
# TODO-lev: Add args to formula
|
||||
return liquidation_price(
|
||||
trading_mode=self.trading_mode,
|
||||
exchange_name=self.exchange_name
|
||||
)
|
||||
|
||||
@property
|
||||
def liq_level(self): # This may be a constant value and may not need a function
|
||||
# TODO-lev: The is the value that you are liquidated at
|
||||
return # If constant, would need to be recalculated after each new trade
|
||||
|
||||
def __init__(self, exchange_name: str, trading_mode: TradingMode):
|
||||
self.exchange_name = exchange_name
|
||||
self.trading_mode = trading_mode
|
||||
return
|
||||
|
||||
def add_new_trade(self, trade):
|
||||
self.trades.append(trade)
|
||||
|
||||
def remove_trade(self, trade):
|
||||
self.trades.remove(trade)
|
||||
|
||||
# ? def update_trade_pric(self):
|
||||
|
||||
def sell_all(self):
|
||||
# TODO-lev
|
||||
return
|
||||
|
||||
def run(self):
|
||||
# TODO-lev: implement a thread that constantly updates with every price change,
|
||||
# TODO-lev: must update at least every few seconds or so
|
||||
# while true:
|
||||
# if self.margin_level <= self.liq_level:
|
||||
# self.sell_all()
|
||||
return
|
Loading…
Reference in New Issue
Block a user