Updated tests to new persistence
This commit is contained in:
parent
243173d2be
commit
6b20a315e3
@ -3,6 +3,7 @@ import logging
|
|||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
||||||
import ccxt
|
import ccxt
|
||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
from freqtrade.exceptions import (DDosProtection, InsufficientFundsError, InvalidOrderException,
|
from freqtrade.exceptions import (DDosProtection, InsufficientFundsError, InvalidOrderException,
|
||||||
OperationalException, TemporaryError)
|
OperationalException, TemporaryError)
|
||||||
@ -89,3 +90,12 @@ 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
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def calculate_interest(borrowed: Decimal, hours: Decimal, interest_rate: Decimal) -> Decimal:
|
||||||
|
# Rate is per day but accrued hourly or something
|
||||||
|
# binance: https://www.binance.com/en-AU/support/faq/360030157812
|
||||||
|
one = Decimal(1)
|
||||||
|
twenty_four = Decimal(24)
|
||||||
|
# TODO-mg: Is hours rounded?
|
||||||
|
return borrowed * interest_rate * max(hours, one)/twenty_four
|
||||||
|
@ -8,6 +8,7 @@ import inspect
|
|||||||
import logging
|
import logging
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
|
from decimal import Decimal
|
||||||
from math import ceil
|
from math import ceil
|
||||||
from typing import Any, Dict, List, Optional, Tuple
|
from typing import Any, Dict, List, Optional, Tuple
|
||||||
|
|
||||||
@ -1473,6 +1474,18 @@ 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))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def calculate_interest(borrowed: Decimal, hours: Decimal, interest_rate: Decimal) -> Decimal:
|
||||||
|
"""Generate the interest owed for borrowing an amount of currency for a certain amount of time
|
||||||
|
:param borrowed: The amount of currency borrowed
|
||||||
|
:param hours: The length of time in hours that the currency has been borrowed for
|
||||||
|
:param interest_rate: The rate of interest for this trade
|
||||||
|
#TODO: May update this just to the currency of the borrowed amount
|
||||||
|
:raises ValueError: Throws value error if not implemented for the exchange
|
||||||
|
:returns The amount of interest owed for the borrowed currency
|
||||||
|
"""
|
||||||
|
raise ValueError('Margin trading is not available on this exchange with freqtrade')
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
|
@ -3,6 +3,7 @@ import logging
|
|||||||
from typing import Any, Dict
|
from typing import Any, Dict
|
||||||
|
|
||||||
import ccxt
|
import ccxt
|
||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
from freqtrade.exceptions import (DDosProtection, InsufficientFundsError, InvalidOrderException,
|
from freqtrade.exceptions import (DDosProtection, InsufficientFundsError, InvalidOrderException,
|
||||||
OperationalException, TemporaryError)
|
OperationalException, TemporaryError)
|
||||||
@ -124,3 +125,11 @@ class Kraken(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
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def calculate_interest(borrowed: Decimal, hours: Decimal, interest_rate: Decimal) -> Decimal:
|
||||||
|
four = Decimal(4.0)
|
||||||
|
# https://support.kraken.com/hc/en-us/articles/206161568-What-are-the-fees-for-margin-trading-
|
||||||
|
opening_fee = borrowed * interest_rate
|
||||||
|
roll_over_fee = borrowed * interest_rate * max(0, (hours-four)/four)
|
||||||
|
return opening_fee + roll_over_fee
|
||||||
|
@ -49,9 +49,6 @@ def migrate_trades_table(decl_base, inspector, engine, table_back_name: str, col
|
|||||||
strategy = get_column_def(cols, 'strategy', 'null')
|
strategy = get_column_def(cols, 'strategy', 'null')
|
||||||
|
|
||||||
leverage = get_column_def(cols, 'leverage', 'null')
|
leverage = get_column_def(cols, 'leverage', 'null')
|
||||||
borrowed = get_column_def(cols, 'borrowed', '0.0')
|
|
||||||
borrowed_currency = get_column_def(cols, 'borrowed_currency', 'null')
|
|
||||||
collateral_currency = get_column_def(cols, 'collateral_currency', 'null')
|
|
||||||
interest_rate = get_column_def(cols, 'interest_rate', '0.0')
|
interest_rate = get_column_def(cols, 'interest_rate', '0.0')
|
||||||
liquidation_price = get_column_def(cols, 'liquidation_price', 'null')
|
liquidation_price = get_column_def(cols, 'liquidation_price', 'null')
|
||||||
is_short = get_column_def(cols, 'is_short', 'False')
|
is_short = get_column_def(cols, 'is_short', 'False')
|
||||||
@ -91,7 +88,7 @@ def migrate_trades_table(decl_base, inspector, engine, table_back_name: str, col
|
|||||||
stoploss_order_id, stoploss_last_update,
|
stoploss_order_id, stoploss_last_update,
|
||||||
max_rate, min_rate, sell_reason, sell_order_status, strategy,
|
max_rate, min_rate, sell_reason, sell_order_status, strategy,
|
||||||
timeframe, open_trade_value, close_profit_abs,
|
timeframe, open_trade_value, close_profit_abs,
|
||||||
leverage, borrowed, borrowed_currency, collateral_currency, interest_rate,
|
leverage, interest_rate,
|
||||||
liquidation_price, is_short
|
liquidation_price, is_short
|
||||||
)
|
)
|
||||||
select id, lower(exchange),
|
select id, lower(exchange),
|
||||||
@ -116,8 +113,7 @@ def migrate_trades_table(decl_base, inspector, engine, table_back_name: str, col
|
|||||||
{sell_order_status} sell_order_status,
|
{sell_order_status} sell_order_status,
|
||||||
{strategy} strategy, {timeframe} timeframe,
|
{strategy} strategy, {timeframe} timeframe,
|
||||||
{open_trade_value} open_trade_value, {close_profit_abs} close_profit_abs,
|
{open_trade_value} open_trade_value, {close_profit_abs} close_profit_abs,
|
||||||
{leverage} leverage, {borrowed} borrowed, {borrowed_currency} borrowed_currency,
|
{leverage} leverage, {interest_rate} interest_rate,
|
||||||
{collateral_currency} collateral_currency, {interest_rate} interest_rate,
|
|
||||||
{liquidation_price} liquidation_price, {is_short} is_short
|
{liquidation_price} liquidation_price, {is_short} is_short
|
||||||
from {table_back_name}
|
from {table_back_name}
|
||||||
"""))
|
"""))
|
||||||
|
@ -132,6 +132,9 @@ class Order(_DECL_BASE):
|
|||||||
order_filled_date = Column(DateTime, nullable=True)
|
order_filled_date = Column(DateTime, nullable=True)
|
||||||
order_update_date = Column(DateTime, nullable=True)
|
order_update_date = Column(DateTime, nullable=True)
|
||||||
|
|
||||||
|
leverage = Column(Float, nullable=True, default=None)
|
||||||
|
is_short = Column(Boolean, nullable=True, default=False)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return (f'Order(id={self.id}, order_id={self.order_id}, trade_id={self.ft_trade_id}, '
|
return (f'Order(id={self.id}, order_id={self.order_id}, trade_id={self.ft_trade_id}, '
|
||||||
f'side={self.side}, order_type={self.order_type}, status={self.status})')
|
f'side={self.side}, order_type={self.order_type}, status={self.status})')
|
||||||
@ -261,61 +264,17 @@ class LocalTrade():
|
|||||||
timeframe: Optional[int] = None
|
timeframe: Optional[int] = None
|
||||||
|
|
||||||
# Margin trading properties
|
# Margin trading properties
|
||||||
borrowed_currency: str = None
|
|
||||||
collateral_currency: str = None
|
|
||||||
interest_rate: float = 0.0
|
interest_rate: float = 0.0
|
||||||
liquidation_price: float = None
|
liquidation_price: float = None
|
||||||
is_short: bool = False
|
is_short: bool = False
|
||||||
borrowed: float = 0.0
|
|
||||||
leverage: float = None
|
leverage: float = None
|
||||||
|
|
||||||
# @property
|
@property
|
||||||
# def base_currency(self) -> str:
|
def borrowed(self):
|
||||||
# if not self.pair:
|
if not self.is_short:
|
||||||
# raise OperationalException('LocalTrade.pair must be assigned')
|
return self.amount * (self.leverage-1)/self.leverage
|
||||||
# return self.pair.split("/")[1]
|
else:
|
||||||
|
return self.amount
|
||||||
# TODO: @samgermain: Amount should be persisted "as is".
|
|
||||||
# I've partially reverted this (this killed most of your tests)
|
|
||||||
# but leave this here as i'm not sure where you intended to use this.
|
|
||||||
# @property
|
|
||||||
# def amount(self) -> float:
|
|
||||||
# if self._leverage is not None:
|
|
||||||
# return self._amount * self.leverage
|
|
||||||
# else:
|
|
||||||
# return self._amount
|
|
||||||
|
|
||||||
# @amount.setter
|
|
||||||
# def amount(self, value):
|
|
||||||
# self._amount = value
|
|
||||||
|
|
||||||
# @property
|
|
||||||
# def borrowed(self) -> float:
|
|
||||||
# if self._leverage is not None:
|
|
||||||
# if self.is_short:
|
|
||||||
# # If shorting the full amount must be borrowed
|
|
||||||
# return self._amount * self._leverage
|
|
||||||
# else:
|
|
||||||
# # If not shorting, then the trader already owns a bit
|
|
||||||
# return self._amount * (self._leverage-1)
|
|
||||||
# else:
|
|
||||||
# return self._borrowed
|
|
||||||
|
|
||||||
# @borrowed.setter
|
|
||||||
# def borrowed(self, value):
|
|
||||||
# self._borrowed = value
|
|
||||||
# self._leverage = None
|
|
||||||
|
|
||||||
# @property
|
|
||||||
# def leverage(self) -> float:
|
|
||||||
# return self._leverage
|
|
||||||
|
|
||||||
# @leverage.setter
|
|
||||||
# def leverage(self, value):
|
|
||||||
# self._leverage = value
|
|
||||||
# self._borrowed = None
|
|
||||||
|
|
||||||
# End of margin trading properties
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def open_date_utc(self):
|
def open_date_utc(self):
|
||||||
@ -326,13 +285,8 @@ class LocalTrade():
|
|||||||
return self.close_date.replace(tzinfo=timezone.utc)
|
return self.close_date.replace(tzinfo=timezone.utc)
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
if kwargs.get('leverage') and kwargs.get('borrowed'):
|
|
||||||
# TODO-mg: should I raise an error?
|
|
||||||
raise OperationalException('Cannot pass both borrowed and leverage to Trade')
|
|
||||||
for key in kwargs:
|
for key in kwargs:
|
||||||
setattr(self, key, kwargs[key])
|
setattr(self, key, kwargs[key])
|
||||||
if not self.is_short:
|
|
||||||
self.is_short = False
|
|
||||||
self.recalc_open_trade_value()
|
self.recalc_open_trade_value()
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
@ -404,9 +358,6 @@ class LocalTrade():
|
|||||||
'max_rate': self.max_rate,
|
'max_rate': self.max_rate,
|
||||||
|
|
||||||
'leverage': self.leverage,
|
'leverage': self.leverage,
|
||||||
'borrowed': self.borrowed,
|
|
||||||
'borrowed_currency': self.borrowed_currency,
|
|
||||||
'collateral_currency': self.collateral_currency,
|
|
||||||
'interest_rate': self.interest_rate,
|
'interest_rate': self.interest_rate,
|
||||||
'liquidation_price': self.liquidation_price,
|
'liquidation_price': self.liquidation_price,
|
||||||
'is_short': self.is_short,
|
'is_short': self.is_short,
|
||||||
@ -473,7 +424,7 @@ class LocalTrade():
|
|||||||
|
|
||||||
# evaluate if the stop loss needs to be updated
|
# evaluate if the stop loss needs to be updated
|
||||||
else:
|
else:
|
||||||
# stop losses only walk up, never down!, #TODO: But adding more to a margin account would create a lower liquidation price, decreasing the minimum stoploss
|
# stop losses only walk up, never down!, #But adding more to a margin account would create a lower liquidation price, decreasing the minimum stoploss
|
||||||
if (new_loss > self.stop_loss and not self.is_short) or (new_loss < self.stop_loss and self.is_short):
|
if (new_loss > self.stop_loss and not self.is_short) or (new_loss < self.stop_loss and self.is_short):
|
||||||
logger.debug(f"{self.pair} - Adjusting stoploss...")
|
logger.debug(f"{self.pair} - Adjusting stoploss...")
|
||||||
self._set_new_stoploss(new_loss, stoploss)
|
self._set_new_stoploss(new_loss, stoploss)
|
||||||
@ -510,15 +461,6 @@ class LocalTrade():
|
|||||||
"""
|
"""
|
||||||
order_type = order['type']
|
order_type = order['type']
|
||||||
|
|
||||||
if ('leverage' in order and 'borrowed' in order):
|
|
||||||
raise OperationalException(
|
|
||||||
'Pass only one of Leverage or Borrowed to the order in update trade')
|
|
||||||
|
|
||||||
if 'is_short' in order and order['side'] == 'sell':
|
|
||||||
# Only set's is_short on opening trades, ignores non-shorts
|
|
||||||
# TODO-mg: I don't like this, but it might be the only way
|
|
||||||
self.is_short = order['is_short']
|
|
||||||
|
|
||||||
# Ignore open and cancelled orders
|
# Ignore open and cancelled orders
|
||||||
if order['status'] == 'open' or safe_value_fallback(order, 'average', 'price') is None:
|
if order['status'] == 'open' or safe_value_fallback(order, 'average', 'price') is None:
|
||||||
return
|
return
|
||||||
@ -531,11 +473,6 @@ class LocalTrade():
|
|||||||
self.open_rate = float(safe_value_fallback(order, 'average', 'price'))
|
self.open_rate = float(safe_value_fallback(order, 'average', 'price'))
|
||||||
self.amount = float(safe_value_fallback(order, 'filled', 'amount'))
|
self.amount = float(safe_value_fallback(order, 'filled', 'amount'))
|
||||||
|
|
||||||
if 'borrowed' in order:
|
|
||||||
self.borrowed = order['borrowed']
|
|
||||||
elif 'leverage' in order:
|
|
||||||
self.leverage = order['leverage']
|
|
||||||
|
|
||||||
self.recalc_open_trade_value()
|
self.recalc_open_trade_value()
|
||||||
if self.is_open:
|
if self.is_open:
|
||||||
payment = "SELL" if self.is_short else "BUY"
|
payment = "SELL" if self.is_short else "BUY"
|
||||||
@ -632,17 +569,16 @@ class LocalTrade():
|
|||||||
: param interest_rate: interest_charge for borrowing this coin(optional).
|
: param interest_rate: interest_charge for borrowing this coin(optional).
|
||||||
If interest_rate is not set self.interest_rate will be used
|
If interest_rate is not set self.interest_rate will be used
|
||||||
"""
|
"""
|
||||||
# TODO-mg: Need to set other conditions because sometimes self.open_date is not defined, but why would it ever not be set
|
|
||||||
zero = Decimal(0.0)
|
zero = Decimal(0.0)
|
||||||
if not (self.borrowed):
|
# If nothing was borrowed
|
||||||
|
if (self.leverage == 1.0 and not self.is_short) or not self.leverage:
|
||||||
return zero
|
return zero
|
||||||
|
|
||||||
open_date = self.open_date.replace(tzinfo=None)
|
open_date = self.open_date.replace(tzinfo=None)
|
||||||
now = datetime.utcnow()
|
now = datetime.utcnow()
|
||||||
# sec_per_day = Decimal(86400)
|
|
||||||
sec_per_hour = Decimal(3600)
|
sec_per_hour = Decimal(3600)
|
||||||
total_seconds = Decimal((now - open_date).total_seconds())
|
total_seconds = Decimal((now - open_date).total_seconds())
|
||||||
# days = total_seconds/sec_per_day or zero
|
|
||||||
hours = total_seconds/sec_per_hour or zero
|
hours = total_seconds/sec_per_hour or zero
|
||||||
|
|
||||||
rate = Decimal(interest_rate or self.interest_rate)
|
rate = Decimal(interest_rate or self.interest_rate)
|
||||||
@ -746,7 +682,8 @@ class LocalTrade():
|
|||||||
if (self.is_short and close_trade_value == 0.0) or (not self.is_short and self.open_trade_value == 0.0):
|
if (self.is_short and close_trade_value == 0.0) or (not self.is_short and self.open_trade_value == 0.0):
|
||||||
return 0.0
|
return 0.0
|
||||||
else:
|
else:
|
||||||
if self.borrowed: # TODO: This is only needed so that previous tests that included dummy stake_amounts don't fail. Undate those tests and get rid of this else
|
# TODO: This is only needed so that previous tests that included dummy stake_amounts don't fail. Undate those tests and get rid of this else
|
||||||
|
if (self.leverage == 1.0 and not self.is_short) or not self.leverage:
|
||||||
if self.is_short:
|
if self.is_short:
|
||||||
profit_ratio = ((self.open_trade_value - close_trade_value) / self.stake_amount)
|
profit_ratio = ((self.open_trade_value - close_trade_value) / self.stake_amount)
|
||||||
else:
|
else:
|
||||||
@ -907,14 +844,10 @@ class Trade(_DECL_BASE, LocalTrade):
|
|||||||
timeframe = Column(Integer, nullable=True)
|
timeframe = Column(Integer, nullable=True)
|
||||||
|
|
||||||
# Margin trading properties
|
# Margin trading properties
|
||||||
leverage = Column(Float, nullable=True) # TODO: can this be nullable, or should it default to 1? (must also be changed in migrations eventually)
|
leverage = Column(Float, nullable=True)
|
||||||
borrowed = Column(Float, nullable=False, default=0.0)
|
|
||||||
interest_rate = Column(Float, nullable=False, default=0.0)
|
interest_rate = Column(Float, nullable=False, default=0.0)
|
||||||
liquidation_price = Column(Float, nullable=True)
|
liquidation_price = Column(Float, nullable=True)
|
||||||
is_short = Column(Boolean, nullable=False, default=False)
|
is_short = Column(Boolean, nullable=False, default=False)
|
||||||
# TODO: Bottom 2 might not be needed
|
|
||||||
borrowed_currency = Column(Float, nullable=True)
|
|
||||||
collateral_currency = Column(String(25), nullable=True)
|
|
||||||
# End of margin trading properties
|
# End of margin trading properties
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
|
@ -2132,8 +2132,8 @@ def market_short_order():
|
|||||||
'symbol': 'mocked',
|
'symbol': 'mocked',
|
||||||
'datetime': arrow.utcnow().isoformat(),
|
'datetime': arrow.utcnow().isoformat(),
|
||||||
'price': 0.00004173,
|
'price': 0.00004173,
|
||||||
'amount': 91.99181073,
|
'amount': 275.97543219,
|
||||||
'filled': 91.99181073,
|
'filled': 275.97543219,
|
||||||
'remaining': 0.0,
|
'remaining': 0.0,
|
||||||
'status': 'closed',
|
'status': 'closed',
|
||||||
'is_short': True,
|
'is_short': True,
|
||||||
@ -2151,8 +2151,8 @@ def market_exit_short_order():
|
|||||||
'symbol': 'mocked',
|
'symbol': 'mocked',
|
||||||
'datetime': arrow.utcnow().isoformat(),
|
'datetime': arrow.utcnow().isoformat(),
|
||||||
'price': 0.00004099,
|
'price': 0.00004099,
|
||||||
'amount': 91.99181073,
|
'amount': 275.97543219,
|
||||||
'filled': 91.99181073,
|
'filled': 275.97543219,
|
||||||
'remaining': 0.0,
|
'remaining': 0.0,
|
||||||
'status': 'closed',
|
'status': 'closed',
|
||||||
# 'leverage': 3.0,
|
# 'leverage': 3.0,
|
||||||
|
@ -433,8 +433,7 @@ def leverage_trade(fee):
|
|||||||
interest_rate: 0.05% per day
|
interest_rate: 0.05% per day
|
||||||
open_rate: 0.123 base
|
open_rate: 0.123 base
|
||||||
close_rate: 0.128 base
|
close_rate: 0.128 base
|
||||||
amount: 123.0 crypto
|
amount: 615 crypto
|
||||||
amount_with_leverage: 615.0
|
|
||||||
stake_amount: 15.129 base
|
stake_amount: 15.129 base
|
||||||
borrowed: 60.516 base
|
borrowed: 60.516 base
|
||||||
leverage: 5
|
leverage: 5
|
||||||
|
@ -54,14 +54,13 @@ def test_update_with_binance(limit_short_order, limit_exit_short_order, fee, ten
|
|||||||
open_date=ten_minutes_ago,
|
open_date=ten_minutes_ago,
|
||||||
fee_open=fee.return_value,
|
fee_open=fee.return_value,
|
||||||
fee_close=fee.return_value,
|
fee_close=fee.return_value,
|
||||||
# borrowed=90.99181073,
|
leverage=3.0,
|
||||||
interest_rate=0.0005,
|
interest_rate=0.0005,
|
||||||
exchange='binance'
|
exchange='binance'
|
||||||
)
|
)
|
||||||
# assert trade.open_order_id is None
|
# assert trade.open_order_id is None
|
||||||
assert trade.close_profit is None
|
assert trade.close_profit is None
|
||||||
assert trade.close_date is None
|
assert trade.close_date is None
|
||||||
assert trade.borrowed is None
|
|
||||||
assert trade.is_short is None
|
assert trade.is_short is None
|
||||||
# trade.open_order_id = 'something'
|
# trade.open_order_id = 'something'
|
||||||
trade.update(limit_short_order)
|
trade.update(limit_short_order)
|
||||||
@ -101,7 +100,7 @@ def test_update_market_order(
|
|||||||
interest_rate: 0.05% per 4 hrs
|
interest_rate: 0.05% per 4 hrs
|
||||||
open_rate: 0.00004173 base
|
open_rate: 0.00004173 base
|
||||||
close_rate: 0.00004099 base
|
close_rate: 0.00004099 base
|
||||||
amount: 91.99181073 * leverage(3) = 275.97543219 crypto
|
amount: = 275.97543219 crypto
|
||||||
stake_amount: 0.0038388182617629
|
stake_amount: 0.0038388182617629
|
||||||
borrowed: 275.97543219 crypto
|
borrowed: 275.97543219 crypto
|
||||||
time-periods: 10 minutes(rounds up to 1 time-period of 4hrs)
|
time-periods: 10 minutes(rounds up to 1 time-period of 4hrs)
|
||||||
@ -131,6 +130,7 @@ def test_update_market_order(
|
|||||||
fee_open=fee.return_value,
|
fee_open=fee.return_value,
|
||||||
fee_close=fee.return_value,
|
fee_close=fee.return_value,
|
||||||
open_date=ten_minutes_ago,
|
open_date=ten_minutes_ago,
|
||||||
|
leverage=3.0,
|
||||||
interest_rate=0.0005,
|
interest_rate=0.0005,
|
||||||
exchange='kraken'
|
exchange='kraken'
|
||||||
)
|
)
|
||||||
@ -228,7 +228,7 @@ def test_trade_close(fee, five_hours_ago):
|
|||||||
open_rate: 0.02 base
|
open_rate: 0.02 base
|
||||||
close_rate: 0.01 base
|
close_rate: 0.01 base
|
||||||
leverage: 3.0
|
leverage: 3.0
|
||||||
amount: 5 * 3 = 15 crypto
|
amount: 15 crypto
|
||||||
borrowed: 15 crypto
|
borrowed: 15 crypto
|
||||||
time-periods: 5 hours = 5/4
|
time-periods: 5 hours = 5/4
|
||||||
|
|
||||||
@ -286,13 +286,13 @@ def test_calc_close_trade_price_exception(limit_short_order, fee):
|
|||||||
pair='ETH/BTC',
|
pair='ETH/BTC',
|
||||||
stake_amount=0.001,
|
stake_amount=0.001,
|
||||||
open_rate=0.1,
|
open_rate=0.1,
|
||||||
amount=5,
|
amount=15.0,
|
||||||
fee_open=fee.return_value,
|
fee_open=fee.return_value,
|
||||||
fee_close=fee.return_value,
|
fee_close=fee.return_value,
|
||||||
exchange='binance',
|
exchange='binance',
|
||||||
interest_rate=0.0005,
|
interest_rate=0.0005,
|
||||||
is_short=True,
|
leverage=3.0,
|
||||||
borrowed=15
|
is_short=True
|
||||||
)
|
)
|
||||||
trade.open_order_id = 'something'
|
trade.open_order_id = 'something'
|
||||||
trade.update(limit_short_order)
|
trade.update(limit_short_order)
|
||||||
@ -306,6 +306,7 @@ def test_update_open_order(limit_short_order):
|
|||||||
stake_amount=1.00,
|
stake_amount=1.00,
|
||||||
open_rate=0.01,
|
open_rate=0.01,
|
||||||
amount=5,
|
amount=5,
|
||||||
|
leverage=3.0,
|
||||||
fee_open=0.1,
|
fee_open=0.1,
|
||||||
fee_close=0.1,
|
fee_close=0.1,
|
||||||
interest_rate=0.0005,
|
interest_rate=0.0005,
|
||||||
@ -355,7 +356,7 @@ def test_calc_close_trade_price(market_short_order, market_exit_short_order, ten
|
|||||||
interest_rate: 0.05% per 4 hrs
|
interest_rate: 0.05% per 4 hrs
|
||||||
open_rate: 0.00004173 base
|
open_rate: 0.00004173 base
|
||||||
close_rate: 0.00001234 base
|
close_rate: 0.00001234 base
|
||||||
amount: 91.99181073 * leverage(3) = 275.97543219 crypto
|
amount: = 275.97543219 crypto
|
||||||
borrowed: 275.97543219 crypto
|
borrowed: 275.97543219 crypto
|
||||||
time-periods: 10 minutes(rounds up to 1 time-period of 4hrs)
|
time-periods: 10 minutes(rounds up to 1 time-period of 4hrs)
|
||||||
interest: borrowed * interest_rate * time-periods
|
interest: borrowed * interest_rate * time-periods
|
||||||
@ -399,7 +400,7 @@ def test_calc_profit(market_short_order, market_exit_short_order, ten_minutes_ag
|
|||||||
open_rate: 0.00004173 base
|
open_rate: 0.00004173 base
|
||||||
close_rate: 0.00004099 base
|
close_rate: 0.00004099 base
|
||||||
stake_amount: 0.0038388182617629
|
stake_amount: 0.0038388182617629
|
||||||
amount: 91.99181073 * leverage(3) = 275.97543219 crypto
|
amount: = 275.97543219 crypto
|
||||||
borrowed: 275.97543219 crypto
|
borrowed: 275.97543219 crypto
|
||||||
time-periods: 10 minutes(rounds up to 1 time-period of 4hrs)
|
time-periods: 10 minutes(rounds up to 1 time-period of 4hrs)
|
||||||
5 hours = 5/4
|
5 hours = 5/4
|
||||||
@ -494,8 +495,8 @@ def test_interest_kraken(market_short_order, ten_minutes_ago, five_hours_ago, fe
|
|||||||
open_rate: 0.00004173 base
|
open_rate: 0.00004173 base
|
||||||
close_rate: 0.00004099 base
|
close_rate: 0.00004099 base
|
||||||
amount:
|
amount:
|
||||||
91.99181073 * leverage(3) = 275.97543219 crypto
|
275.97543219 crypto
|
||||||
91.99181073 * leverage(5) = 459.95905365 crypto
|
459.95905365 crypto
|
||||||
borrowed:
|
borrowed:
|
||||||
275.97543219 crypto
|
275.97543219 crypto
|
||||||
459.95905365 crypto
|
459.95905365 crypto
|
||||||
@ -512,7 +513,7 @@ def test_interest_kraken(market_short_order, ten_minutes_ago, five_hours_ago, fe
|
|||||||
trade = Trade(
|
trade = Trade(
|
||||||
pair='ETH/BTC',
|
pair='ETH/BTC',
|
||||||
stake_amount=0.001,
|
stake_amount=0.001,
|
||||||
amount=91.99181073,
|
amount=275.97543219,
|
||||||
open_rate=0.00001099,
|
open_rate=0.00001099,
|
||||||
open_date=ten_minutes_ago,
|
open_date=ten_minutes_ago,
|
||||||
fee_open=fee.return_value,
|
fee_open=fee.return_value,
|
||||||
@ -531,7 +532,7 @@ def test_interest_kraken(market_short_order, ten_minutes_ago, five_hours_ago, fe
|
|||||||
trade = Trade(
|
trade = Trade(
|
||||||
pair='ETH/BTC',
|
pair='ETH/BTC',
|
||||||
stake_amount=0.001,
|
stake_amount=0.001,
|
||||||
amount=91.99181073,
|
amount=459.95905365,
|
||||||
open_rate=0.00001099,
|
open_rate=0.00001099,
|
||||||
open_date=five_hours_ago,
|
open_date=five_hours_ago,
|
||||||
fee_open=fee.return_value,
|
fee_open=fee.return_value,
|
||||||
@ -581,7 +582,7 @@ def test_interest_binance(market_short_order, ten_minutes_ago, five_hours_ago, f
|
|||||||
fee_close=fee.return_value,
|
fee_close=fee.return_value,
|
||||||
exchange='binance',
|
exchange='binance',
|
||||||
is_short=True,
|
is_short=True,
|
||||||
borrowed=275.97543219,
|
leverage=3.0,
|
||||||
interest_rate=0.0005
|
interest_rate=0.0005
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -599,7 +600,7 @@ def test_interest_binance(market_short_order, ten_minutes_ago, five_hours_ago, f
|
|||||||
fee_close=fee.return_value,
|
fee_close=fee.return_value,
|
||||||
exchange='binance',
|
exchange='binance',
|
||||||
is_short=True,
|
is_short=True,
|
||||||
borrowed=459.95905365,
|
leverage=5.0,
|
||||||
interest_rate=0.0005
|
interest_rate=0.0005
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -679,7 +680,8 @@ def test_stoploss_reinitialization(default_conf, fee):
|
|||||||
exchange='binance',
|
exchange='binance',
|
||||||
open_rate=1,
|
open_rate=1,
|
||||||
max_rate=1,
|
max_rate=1,
|
||||||
is_short=True
|
is_short=True,
|
||||||
|
leverage=3.0,
|
||||||
)
|
)
|
||||||
trade.adjust_stop_loss(trade.open_rate, -0.05, True)
|
trade.adjust_stop_loss(trade.open_rate, -0.05, True)
|
||||||
assert trade.stop_loss == 1.05
|
assert trade.stop_loss == 1.05
|
||||||
|
Loading…
Reference in New Issue
Block a user