Updated Trade class

This commit is contained in:
Sam Germain 2021-06-19 22:19:09 -06:00
parent c7e8439c76
commit 7823a33cbb
2 changed files with 25 additions and 11 deletions

View File

@ -268,7 +268,7 @@ class FreqtradeBot(LoggingMixin):
# Updating open orders in dry-run does not make sense and will fail. # Updating open orders in dry-run does not make sense and will fail.
return return
trades: List[Trade] = Trade.get_sold_trades_without_assigned_fees() trades: List[Trade] = Trade.get_closed_trades_without_assigned_fees()
for trade in trades: for trade in trades:
if not trade.is_open and not trade.fee_updated('sell'): if not trade.is_open and not trade.fee_updated('sell'):

View File

@ -263,7 +263,7 @@ class LocalTrade():
timeframe: Optional[int] = None timeframe: Optional[int] = None
#Margin trading properties #Margin trading properties
leverage: float = 1.0 leverage: Optional[float] = None
borrowed: float = 0 borrowed: float = 0
borrowed_currency: float = None borrowed_currency: float = None
interest_rate: float = 0 interest_rate: float = 0
@ -555,8 +555,6 @@ class LocalTrade():
If rate is not set self.fee will be used If rate is not set self.fee will be used
:param rate: rate to compare with (optional). :param rate: rate to compare with (optional).
If rate is not set self.close_rate will be used If rate is not set self.close_rate will be used
:param borrowed: amount borrowed to make this trade
If borrowed is not set self.borrowed will be used
:return: Price in BTC of the open trade :return: Price in BTC of the open trade
""" """
if rate is None and not self.close_rate: if rate is None and not self.close_rate:
@ -564,11 +562,11 @@ class LocalTrade():
close_trade = Decimal(self.amount) * Decimal(rate or self.close_rate) # type: ignore close_trade = Decimal(self.amount) * Decimal(rate or self.close_rate) # type: ignore
fees = close_trade * Decimal(fee or self.fee_close) fees = close_trade * Decimal(fee or self.fee_close)
interest = ((self.interest_rate * Decimal(borrowed or self.borrowed)) * (datetime.utcnow() - self.open_date).days) or 0 #Interest/day * num of days
if (self.isShort): if (self.isShort):
interest = (self.interest_rate * Decimal(borrowed or self.borrowed)) * (datetime.utcnow() - self.open_date).days #Interest/day * num of days, 0 if not margin
return float(close_trade + fees + interest) return float(close_trade + fees + interest)
else: else:
return float(close_trade - fees) return float(close_trade - fees - interest)
def calc_profit(self, rate: Optional[float] = None, def calc_profit(self, rate: Optional[float] = None,
fee: Optional[float] = None) -> float: fee: Optional[float] = None) -> float:
@ -578,8 +576,6 @@ class LocalTrade():
If fee is not set self.fee will be used If fee is not set self.fee will be used
:param rate: close rate to compare with (optional). :param rate: close rate to compare with (optional).
If rate is not set self.close_rate will be used If rate is not set self.close_rate will be used
:param borrowed: amount borrowed to make this trade
If borrowed is not set self.borrowed will be used
:return: profit in stake currency as float :return: profit in stake currency as float
""" """
close_trade_value = self.calc_close_trade_value( close_trade_value = self.calc_close_trade_value(
@ -594,8 +590,7 @@ class LocalTrade():
return float(f"{profit:.8f}") return float(f"{profit:.8f}")
def calc_profit_ratio(self, rate: Optional[float] = None, def calc_profit_ratio(self, rate: Optional[float] = None,
fee: Optional[float] = None, fee: Optional[float] = None) -> float:
borrowed: Optional[float] = None) -> float:
""" """
Calculates the profit as ratio (including fee). Calculates the profit as ratio (including fee).
:param rate: rate to compare with (optional). :param rate: rate to compare with (optional).
@ -763,7 +758,26 @@ class Trade(_DECL_BASE, LocalTrade):
strategy = Column(String(100), nullable=True) strategy = Column(String(100), nullable=True)
timeframe = Column(Integer, nullable=True) timeframe = Column(Integer, nullable=True)
#Margin trading properties
leverage = Column(Float, nullable=True)
borrowed = Column(Float, nullable=False, default=0.0)
borrowed_currency = Column(Float, nullable=True)
interest_rate = Column(Float, nullable=False, default=0.0)
min_stoploss = Column(Float, nullable=True)
isShort = Column(Boolean, nullable=False, default=False)
#End of margin trading properties
def __init__(self, **kwargs): def __init__(self, **kwargs):
lev = kwargs.get('leverage')
bor = kwargs.get('borrowed')
amount = kwargs.get('amount')
if lev and bor:
raise OperationalException('Cannot pass both borrowed and leverage to Trade') #TODO: should I raise an error?
elif lev:
self.amount = amount * lev
self.borrowed = amount * (lev-1)
elif bor:
self.lev = (bor + amount)/amount
super().__init__(**kwargs) super().__init__(**kwargs)
self.recalc_open_trade_value() self.recalc_open_trade_value()
@ -849,7 +863,7 @@ class Trade(_DECL_BASE, LocalTrade):
]).all() ]).all()
@staticmethod @staticmethod
def get_sold_trades_without_assigned_fees(): def get_closed_trades_without_assigned_fees():
""" """
Returns all closed trades which don't have fees set correctly Returns all closed trades which don't have fees set correctly
NOTE: Not supported in Backtesting. NOTE: Not supported in Backtesting.