Merge pull request #5381 from samgermain/interest-change

Changed interest implementation (Margin)
This commit is contained in:
Matthias 2021-08-09 11:58:08 +02:00 committed by GitHub
commit 98fe3e73de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 157 additions and 122 deletions

View File

@ -1,7 +1,6 @@
# flake8: noqa: F401
from freqtrade.enums.backteststate import BacktestState
from freqtrade.enums.collateral import Collateral
from freqtrade.enums.interestmode import InterestMode
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

@ -1,28 +0,0 @@
from decimal import Decimal
from enum import Enum
from math import ceil
from freqtrade.exceptions import OperationalException
one = Decimal(1.0)
four = Decimal(4.0)
twenty_four = Decimal(24.0)
class InterestMode(Enum):
"""Equations to calculate interest"""
HOURSPERDAY = "HOURSPERDAY"
HOURSPER4 = "HOURSPER4" # Hours per 4 hour segment
NONE = "NONE"
def __call__(self, borrowed: Decimal, rate: Decimal, hours: Decimal):
if self.name == "HOURSPERDAY":
return borrowed * rate * ceil(hours)/twenty_four
elif self.name == "HOURSPER4":
# Rounded based on https://kraken-fees-calculator.github.io/
return borrowed * rate * (1+ceil(hours/four))
else:
raise OperationalException("Leverage not available on this exchange with freqtrade")

View File

@ -1 +1,2 @@
# flake8: noqa: F401
from freqtrade.leverage.interest import interest

View File

@ -0,0 +1,42 @@
from decimal import Decimal
from math import ceil
from freqtrade.exceptions import OperationalException
one = Decimal(1.0)
four = Decimal(4.0)
twenty_four = Decimal(24.0)
def interest(
exchange_name: str,
borrowed: Decimal,
rate: Decimal,
hours: Decimal
) -> Decimal:
"""
Equation to calculate interest on margin trades
:param exchange_name: The exchanged being trading on
:param borrowed: The amount of currency being borrowed
:param rate: The rate of interest
:param hours: The time in hours that the currency has been borrowed for
Raises:
OperationalException: Raised if freqtrade does
not support margin trading for this exchange
Returns: The amount of interest owed (currency matches borrowed)
"""
exchange_name = exchange_name.lower()
if exchange_name == "binance":
return borrowed * rate * ceil(hours)/twenty_four
elif exchange_name == "kraken":
# Rounded based on https://kraken-fees-calculator.github.io/
return borrowed * rate * (one+ceil(hours/four))
elif exchange_name == "ftx":
# TODO-lev: Add FTX interest formula
raise OperationalException(f"Leverage not available on {exchange_name} with freqtrade")
else:
raise OperationalException(f"Leverage not available on {exchange_name} with freqtrade")

View File

@ -54,7 +54,6 @@ def migrate_trades_table(decl_base, inspector, engine, table_back_name: str, col
isolated_liq = get_column_def(cols, 'isolated_liq', 'null')
# sqlite does not support literals for booleans
is_short = get_column_def(cols, 'is_short', '0')
interest_mode = get_column_def(cols, 'interest_mode', 'null')
# If ticker-interval existed use that, else null.
if has_column(cols, 'ticker_interval'):
timeframe = get_column_def(cols, 'timeframe', 'ticker_interval')
@ -92,7 +91,7 @@ def migrate_trades_table(decl_base, inspector, engine, table_back_name: str, col
stoploss_order_id, stoploss_last_update,
max_rate, min_rate, sell_reason, sell_order_status, strategy, buy_tag,
timeframe, open_trade_value, close_profit_abs,
leverage, interest_rate, isolated_liq, is_short, interest_mode
leverage, interest_rate, isolated_liq, is_short
)
select id, lower(exchange), pair,
is_open, {fee_open} fee_open, {fee_open_cost} fee_open_cost,
@ -110,8 +109,7 @@ def migrate_trades_table(decl_base, inspector, engine, table_back_name: str, col
{strategy} strategy, {buy_tag} buy_tag, {timeframe} timeframe,
{open_trade_value} open_trade_value, {close_profit_abs} close_profit_abs,
{leverage} leverage, {interest_rate} interest_rate,
{isolated_liq} isolated_liq, {is_short} is_short,
{interest_mode} interest_mode
{isolated_liq} isolated_liq, {is_short} is_short
from {table_back_name}
"""))

View File

@ -6,7 +6,7 @@ from datetime import datetime, timezone
from decimal import Decimal
from typing import Any, Dict, List, Optional
from sqlalchemy import (Boolean, Column, DateTime, Enum, Float, ForeignKey, Integer, String,
from sqlalchemy import (Boolean, Column, DateTime, Float, ForeignKey, Integer, String,
create_engine, desc, func, inspect)
from sqlalchemy.exc import NoSuchModuleError
from sqlalchemy.orm import Query, declarative_base, relationship, scoped_session, sessionmaker
@ -14,8 +14,9 @@ from sqlalchemy.pool import StaticPool
from sqlalchemy.sql.schema import UniqueConstraint
from freqtrade.constants import DATETIME_PRINT_FORMAT
from freqtrade.enums import InterestMode, SellType
from freqtrade.enums import SellType
from freqtrade.exceptions import DependencyException, OperationalException
from freqtrade.leverage import interest
from freqtrade.misc import safe_value_fallback
from freqtrade.persistence.migrations import check_migrate
@ -236,7 +237,7 @@ class LocalTrade():
close_rate_requested: Optional[float] = None
close_profit: Optional[float] = None
close_profit_abs: Optional[float] = None
stake_amount: float = 0.0 # TODO: This should probably be computed
stake_amount: float = 0.0
amount: float = 0.0
amount_requested: Optional[float] = None
open_date: datetime
@ -271,7 +272,6 @@ class LocalTrade():
# Margin trading properties
interest_rate: float = 0.0
interest_mode: InterestMode = InterestMode.NONE
@property
def has_no_leverage(self) -> bool:
@ -654,7 +654,7 @@ class LocalTrade():
rate = Decimal(interest_rate or self.interest_rate)
borrowed = Decimal(self.borrowed)
return self.interest_mode(borrowed=borrowed, rate=rate, hours=hours)
return interest(exchange_name=self.exchange, borrowed=borrowed, rate=rate, hours=hours)
def calc_close_trade_value(self, rate: Optional[float] = None,
fee: Optional[float] = None,
@ -900,7 +900,6 @@ class Trade(_DECL_BASE, LocalTrade):
# Margin Trading Properties
interest_rate = Column(Float, nullable=False, default=0.0)
interest_mode = Column(Enum(InterestMode), nullable=True)
def __init__(self, **kwargs):
super().__init__(**kwargs)

View File

@ -1,6 +1,5 @@
from datetime import datetime, timedelta, timezone
from freqtrade.enums import InterestMode
from freqtrade.persistence.models import Order, Trade
@ -383,8 +382,7 @@ def short_trade(fee):
sell_reason='sell_signal', # TODO-lev: Update to exit/close reason
open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=20),
# close_date=datetime.now(tz=timezone.utc) - timedelta(minutes=2),
is_short=True,
interest_mode=InterestMode.HOURSPERDAY
is_short=True
)
o = Order.parse_from_ccxt_object(short_order(), 'ETC/BTC', 'sell')
trade.orders.append(o)
@ -473,8 +471,7 @@ def leverage_trade(fee):
sell_reason='sell_signal', # TODO-lev: Update to exit/close reason
open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=300),
close_date=datetime.now(tz=timezone.utc),
interest_rate=0.0005,
interest_mode=InterestMode.HOURSPER4
interest_rate=0.0005
)
o = Order.parse_from_ccxt_object(leverage_order(), 'DOGE/BTC', 'sell')
trade.orders.append(o)

View File

@ -0,0 +1,37 @@
from decimal import Decimal
from math import isclose
import pytest
from freqtrade.leverage import interest
ten_mins = Decimal(1/6)
five_hours = Decimal(5.0)
twentyfive_hours = Decimal(25.0)
@pytest.mark.parametrize('exchange,interest_rate,hours,expected', [
('binance', 0.0005, ten_mins, 0.00125),
('binance', 0.00025, ten_mins, 0.000625),
('binance', 0.00025, five_hours, 0.003125),
('binance', 0.00025, twentyfive_hours, 0.015625),
# Kraken
('kraken', 0.0005, ten_mins, 0.06),
('kraken', 0.00025, ten_mins, 0.03),
('kraken', 0.00025, five_hours, 0.045),
('kraken', 0.00025, twentyfive_hours, 0.12),
# FTX
# TODO-lev: - implement FTX tests
# ('ftx', Decimal(0.0005), ten_mins, 0.06),
# ('ftx', Decimal(0.0005), five_hours, 0.045),
])
def test_interest(exchange, interest_rate, hours, expected):
borrowed = Decimal(60.0)
assert isclose(interest(
exchange_name=exchange,
borrowed=borrowed,
rate=Decimal(interest_rate),
hours=hours
), expected)

View File

@ -11,7 +11,6 @@ import pytest
from sqlalchemy import create_engine, inspect, text
from freqtrade import constants
from freqtrade.enums import InterestMode
from freqtrade.exceptions import DependencyException, OperationalException
from freqtrade.persistence import LocalTrade, Order, Trade, clean_dry_run_db, init_db
from tests.conftest import create_mock_trades, create_mock_trades_with_leverage, log_has, log_has_re
@ -145,7 +144,7 @@ def test__set_stop_loss_isolated_liq(fee):
trade.stop_loss = None
trade.initial_stop_loss = None
trade.set_isolated_liq(0.09)
trade.set_isolated_liq(isolated_liq=0.09)
assert trade.isolated_liq == 0.09
assert trade.stop_loss == 0.09
assert trade.initial_stop_loss == 0.09
@ -155,12 +154,12 @@ def test__set_stop_loss_isolated_liq(fee):
assert trade.stop_loss == 0.08
assert trade.initial_stop_loss == 0.09
trade.set_isolated_liq(0.1)
trade.set_isolated_liq(isolated_liq=0.1)
assert trade.isolated_liq == 0.1
assert trade.stop_loss == 0.08
assert trade.initial_stop_loss == 0.09
trade.set_isolated_liq(0.07)
trade.set_isolated_liq(isolated_liq=0.07)
assert trade.isolated_liq == 0.07
assert trade.stop_loss == 0.07
assert trade.initial_stop_loss == 0.09
@ -234,26 +233,25 @@ def test_interest(market_buy_order_usdt, fee):
open_date=datetime.utcnow() - timedelta(hours=0, minutes=10),
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='kraken',
exchange='binance',
leverage=3.0,
interest_rate=0.0005,
interest_mode=InterestMode.HOURSPERDAY
)
# 10min, 3x leverage
# binance
assert round(float(trade.calculate_interest()), 8) == round(0.0008333333333333334, 8)
# kraken
trade.interest_mode = InterestMode.HOURSPER4
trade.exchange = "kraken"
assert float(trade.calculate_interest()) == 0.040
# Short
trade.is_short = True
trade.recalc_open_trade_value()
# binace
trade.interest_mode = InterestMode.HOURSPERDAY
trade.exchange = "binance"
assert float(trade.calculate_interest()) == 0.000625
# kraken
trade.interest_mode = InterestMode.HOURSPER4
trade.exchange = "kraken"
assert isclose(float(trade.calculate_interest()), 0.030)
# 5hr, long
@ -261,40 +259,40 @@ def test_interest(market_buy_order_usdt, fee):
trade.is_short = False
trade.recalc_open_trade_value()
# binance
trade.interest_mode = InterestMode.HOURSPERDAY
trade.exchange = "binance"
assert round(float(trade.calculate_interest()), 8) == round(0.004166666666666667, 8)
# kraken
trade.interest_mode = InterestMode.HOURSPER4
trade.exchange = "kraken"
assert float(trade.calculate_interest()) == 0.06
# short
trade.is_short = True
trade.recalc_open_trade_value()
# binace
trade.interest_mode = InterestMode.HOURSPERDAY
trade.exchange = "binance"
assert round(float(trade.calculate_interest()), 8) == round(0.0031249999999999997, 8)
# kraken
trade.interest_mode = InterestMode.HOURSPER4
trade.exchange = "kraken"
assert float(trade.calculate_interest()) == 0.045
# 0.00025 interest, 5hr, long
trade.is_short = False
trade.recalc_open_trade_value()
# binance
trade.interest_mode = InterestMode.HOURSPERDAY
trade.exchange = "binance"
assert round(float(trade.calculate_interest(interest_rate=0.00025)),
8) == round(0.0020833333333333333, 8)
# kraken
trade.interest_mode = InterestMode.HOURSPER4
trade.exchange = "kraken"
assert isclose(float(trade.calculate_interest(interest_rate=0.00025)), 0.03)
# short
trade.is_short = True
trade.recalc_open_trade_value()
# binace
trade.interest_mode = InterestMode.HOURSPERDAY
trade.exchange = "binance"
assert round(float(trade.calculate_interest(interest_rate=0.00025)),
8) == round(0.0015624999999999999, 8)
# kraken
trade.interest_mode = InterestMode.HOURSPER4
trade.exchange = "kraken"
assert float(trade.calculate_interest(interest_rate=0.00025)) == 0.0225
# 5x leverage, 0.0005 interest, 5hr, long
@ -302,19 +300,19 @@ def test_interest(market_buy_order_usdt, fee):
trade.recalc_open_trade_value()
trade.leverage = 5.0
# binance
trade.interest_mode = InterestMode.HOURSPERDAY
trade.exchange = "binance"
assert round(float(trade.calculate_interest()), 8) == 0.005
# kraken
trade.interest_mode = InterestMode.HOURSPER4
trade.exchange = "kraken"
assert float(trade.calculate_interest()) == round(0.07200000000000001, 8)
# short
trade.is_short = True
trade.recalc_open_trade_value()
# binace
trade.interest_mode = InterestMode.HOURSPERDAY
trade.exchange = "binance"
assert round(float(trade.calculate_interest()), 8) == round(0.0031249999999999997, 8)
# kraken
trade.interest_mode = InterestMode.HOURSPER4
trade.exchange = "kraken"
assert float(trade.calculate_interest()) == 0.045
# 1x leverage, 0.0005 interest, 5hr
@ -322,19 +320,19 @@ def test_interest(market_buy_order_usdt, fee):
trade.recalc_open_trade_value()
trade.leverage = 1.0
# binance
trade.interest_mode = InterestMode.HOURSPERDAY
trade.exchange = "binance"
assert float(trade.calculate_interest()) == 0.0
# kraken
trade.interest_mode = InterestMode.HOURSPER4
trade.exchange = "kraken"
assert float(trade.calculate_interest()) == 0.0
# short
trade.is_short = True
trade.recalc_open_trade_value()
# binace
trade.interest_mode = InterestMode.HOURSPERDAY
trade.exchange = "binance"
assert float(trade.calculate_interest()) == 0.003125
# kraken
trade.interest_mode = InterestMode.HOURSPER4
trade.exchange = "kraken"
assert float(trade.calculate_interest()) == 0.045
@ -506,7 +504,7 @@ def test_update_limit_order(limit_buy_order_usdt, limit_sell_order_usdt, fee, ca
open_date=arrow.utcnow().datetime,
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='binance',
exchange='binance'
)
assert trade.open_order_id is None
assert trade.close_profit is None
@ -550,7 +548,6 @@ def test_update_limit_order(limit_buy_order_usdt, limit_sell_order_usdt, fee, ca
is_short=True,
leverage=3.0,
interest_rate=0.0005,
interest_mode=InterestMode.HOURSPERDAY
)
trade.open_order_id = 'something'
trade.update(limit_sell_order_usdt)
@ -628,7 +625,6 @@ def test_calc_open_close_trade_price(limit_buy_order_usdt, limit_sell_order_usdt
amount=30.0,
open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=10),
interest_rate=0.0005,
interest_mode=InterestMode.HOURSPERDAY,
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='binance',
@ -644,12 +640,12 @@ def test_calc_open_close_trade_price(limit_buy_order_usdt, limit_sell_order_usdt
assert trade.calc_profit_ratio() == round(0.0945137157107232, 8)
# 3x leverage, binance
trade.leverage = 3
trade.interest_mode = InterestMode.HOURSPERDAY
trade.exchange = "binance"
assert trade._calc_open_trade_value() == 60.15
assert round(trade.calc_close_trade_value(), 8) == 65.83416667
assert trade.calc_profit() == round(5.684166670000003, 8)
assert trade.calc_profit_ratio() == round(0.2834995845386534, 8)
trade.interest_mode = InterestMode.HOURSPER4
trade.exchange = "kraken"
# 3x leverage, kraken
assert trade._calc_open_trade_value() == 60.15
assert trade.calc_close_trade_value() == 65.795
@ -662,7 +658,7 @@ def test_calc_open_close_trade_price(limit_buy_order_usdt, limit_sell_order_usdt
assert trade.calc_close_trade_value() == 66.231165
assert trade.calc_profit() == round(-6.381165000000003, 8)
assert trade.calc_profit_ratio() == round(-0.319857894736842, 8)
trade.interest_mode = InterestMode.HOURSPERDAY
trade.exchange = "binance"
# 3x leverage, short, binance
assert trade._calc_open_trade_value() == 59.85
assert trade.calc_close_trade_value() == 66.1663784375
@ -675,7 +671,7 @@ def test_calc_open_close_trade_price(limit_buy_order_usdt, limit_sell_order_usdt
assert trade.calc_profit() == round(-6.316378437500013, 8)
assert trade.calc_profit_ratio() == round(-0.1055368159983292, 8)
# 1x leverage, short, kraken
trade.interest_mode = InterestMode.HOURSPER4
trade.exchange = "kraken"
assert trade._calc_open_trade_value() == 59.850
assert trade.calc_close_trade_value() == 66.231165
assert trade.calc_profit() == -6.381165
@ -694,7 +690,6 @@ def test_trade_close(limit_buy_order_usdt, limit_sell_order_usdt, fee):
fee_close=fee.return_value,
open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=10),
interest_rate=0.0005,
interest_mode=InterestMode.HOURSPERDAY,
exchange='binance',
)
assert trade.close_profit is None
@ -805,7 +800,7 @@ def test_calc_open_trade_value(limit_buy_order_usdt, fee):
trade.recalc_open_trade_value()
assert trade._calc_open_trade_value() == 59.85
trade.leverage = 3
trade.interest_mode = InterestMode.HOURSPERDAY
trade.exchange = "binance"
assert trade._calc_open_trade_value() == 59.85
trade.is_short = False
trade.recalc_open_trade_value()
@ -832,7 +827,6 @@ def test_calc_close_trade_price(limit_buy_order_usdt, limit_sell_order_usdt, fee
fee_close=fee.return_value,
exchange='binance',
interest_rate=0.0005,
interest_mode=InterestMode.HOURSPERDAY
)
trade.open_order_id = 'close_trade'
trade.update(limit_buy_order_usdt)
@ -849,7 +843,7 @@ def test_calc_close_trade_price(limit_buy_order_usdt, limit_sell_order_usdt, fee
assert round(trade.calc_close_trade_value(rate=2.5, fee=0.003), 8) == 74.77416667
# 3x leverage kraken
trade.interest_mode = InterestMode.HOURSPER4
trade.exchange = "kraken"
assert trade.calc_close_trade_value(rate=2.5) == 74.7725
assert trade.calc_close_trade_value(rate=2.5, fee=0.003) == 74.735
@ -860,7 +854,7 @@ def test_calc_close_trade_price(limit_buy_order_usdt, limit_sell_order_usdt, fee
assert trade.calc_close_trade_value(rate=2.5, fee=0.003) == 75.300225
# 3x leverage binance, short
trade.interest_mode = InterestMode.HOURSPERDAY
trade.exchange = "binance"
assert round(trade.calc_close_trade_value(rate=2.5), 8) == 75.18906641
assert round(trade.calc_close_trade_value(rate=2.5, fee=0.003), 8) == 75.22656719
@ -870,7 +864,7 @@ def test_calc_close_trade_price(limit_buy_order_usdt, limit_sell_order_usdt, fee
assert round(trade.calc_close_trade_value(rate=2.5, fee=0.003), 8) == 75.22656719
# 1x leverage kraken, short
trade.interest_mode = InterestMode.HOURSPER4
trade.exchange = "kraken"
assert round(trade.calc_close_trade_value(rate=2.5), 8) == 75.2626875
assert trade.calc_close_trade_value(rate=2.5, fee=0.003) == 75.300225
@ -1013,7 +1007,6 @@ def test_calc_profit(limit_buy_order_usdt, limit_sell_order_usdt, fee):
open_rate=2.0,
open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=10),
interest_rate=0.0005,
interest_mode=InterestMode.HOURSPERDAY,
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='binance'
@ -1047,62 +1040,62 @@ def test_calc_profit(limit_buy_order_usdt, limit_sell_order_usdt, fee):
# 3x leverage, long ###################################################
trade.leverage = 3.0
# Higher than open rate - 2.1 quote
trade.interest_mode = InterestMode.HOURSPERDAY # binance
trade.exchange = "binance" # binance
assert trade.calc_profit(rate=2.1, fee=0.0025) == 2.69166667
trade.interest_mode = InterestMode.HOURSPER4 # kraken
trade.exchange = "kraken"
assert trade.calc_profit(rate=2.1, fee=0.0025) == 2.6525
# 1.9 quote
trade.interest_mode = InterestMode.HOURSPERDAY # binance
trade.exchange = "binance" # binance
assert trade.calc_profit(rate=1.9, fee=0.0025) == -3.29333333
trade.interest_mode = InterestMode.HOURSPER4 # kraken
trade.exchange = "kraken"
assert trade.calc_profit(rate=1.9, fee=0.0025) == -3.3325
# 2.2 quote
trade.interest_mode = InterestMode.HOURSPERDAY # binance
trade.exchange = "binance" # binance
assert trade.calc_profit(fee=0.0025) == 5.68416667
trade.interest_mode = InterestMode.HOURSPER4 # kraken
trade.exchange = "kraken"
assert trade.calc_profit(fee=0.0025) == 5.645
# 3x leverage, short ###################################################
trade.is_short = True
trade.recalc_open_trade_value()
# 2.1 quote - Higher than open rate
trade.interest_mode = InterestMode.HOURSPERDAY # binance
trade.exchange = "binance" # binance
assert trade.calc_profit(rate=2.1, fee=0.0025) == round(-3.308815781249997, 8)
trade.interest_mode = InterestMode.HOURSPER4 # kraken
trade.exchange = "kraken"
assert trade.calc_profit(rate=2.1, fee=0.0025) == -3.3706575
# 1.9 quote - Lower than open rate
trade.interest_mode = InterestMode.HOURSPERDAY # binance
trade.exchange = "binance" # binance
assert trade.calc_profit(rate=1.9, fee=0.0025) == round(2.7063095312499996, 8)
trade.interest_mode = InterestMode.HOURSPER4 # kraken
trade.exchange = "kraken"
assert trade.calc_profit(rate=1.9, fee=0.0025) == 2.6503575
# Test when we apply a Sell order. Uses sell order used above
trade.interest_mode = InterestMode.HOURSPERDAY # binance
trade.exchange = "binance" # binance
assert trade.calc_profit(fee=0.0025) == round(-6.316378437499999, 8)
trade.interest_mode = InterestMode.HOURSPER4 # kraken
trade.exchange = "kraken"
assert trade.calc_profit(fee=0.0025) == -6.381165
# 1x leverage, short ###################################################
trade.leverage = 1.0
# 2.1 quote - Higher than open rate
trade.interest_mode = InterestMode.HOURSPERDAY # binance
trade.exchange = "binance" # binance
assert trade.calc_profit(rate=2.1, fee=0.0025) == round(-3.308815781249997, 8)
trade.interest_mode = InterestMode.HOURSPER4 # kraken
trade.exchange = "kraken"
assert trade.calc_profit(rate=2.1, fee=0.0025) == -3.3706575
# 1.9 quote - Lower than open rate
trade.interest_mode = InterestMode.HOURSPERDAY # binance
trade.exchange = "binance" # binance
assert trade.calc_profit(rate=1.9, fee=0.0025) == round(2.7063095312499996, 8)
trade.interest_mode = InterestMode.HOURSPER4 # kraken
trade.exchange = "kraken"
assert trade.calc_profit(rate=1.9, fee=0.0025) == 2.6503575
# Test when we apply a Sell order. Uses sell order used above
trade.interest_mode = InterestMode.HOURSPERDAY # binance
trade.exchange = "binance" # binance
assert trade.calc_profit(fee=0.0025) == round(-6.316378437499999, 8)
trade.interest_mode = InterestMode.HOURSPER4 # kraken
trade.exchange = "kraken"
assert trade.calc_profit(fee=0.0025) == -6.381165
@ -1115,7 +1108,6 @@ def test_calc_profit_ratio(limit_buy_order_usdt, limit_sell_order_usdt, fee):
open_rate=2.0,
open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=10),
interest_rate=0.0005,
interest_mode=InterestMode.HOURSPERDAY,
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='binance'
@ -1150,62 +1142,62 @@ def test_calc_profit_ratio(limit_buy_order_usdt, limit_sell_order_usdt, fee):
# 3x leverage, long ###################################################
trade.leverage = 3.0
# 2.1 quote - Higher than open rate
trade.interest_mode = InterestMode.HOURSPERDAY # binance
trade.exchange = "binance" # binance
assert trade.calc_profit_ratio(rate=2.1) == round(0.13424771421446402, 8)
trade.interest_mode = InterestMode.HOURSPER4 # kraken
trade.exchange = "kraken"
assert trade.calc_profit_ratio(rate=2.1) == round(0.13229426433915248, 8)
# 1.9 quote - Lower than open rate
trade.interest_mode = InterestMode.HOURSPERDAY # binance
trade.exchange = "binance" # binance
assert trade.calc_profit_ratio(rate=1.9) == round(-0.16425602643391513, 8)
trade.interest_mode = InterestMode.HOURSPER4 # kraken
trade.exchange = "kraken"
assert trade.calc_profit_ratio(rate=1.9) == round(-0.16620947630922667, 8)
# Test when we apply a Sell order. Uses sell order used above
trade.interest_mode = InterestMode.HOURSPERDAY # binance
trade.exchange = "binance" # binance
assert trade.calc_profit_ratio() == round(0.2834995845386534, 8)
trade.interest_mode = InterestMode.HOURSPER4 # kraken
trade.exchange = "kraken"
assert trade.calc_profit_ratio() == round(0.2815461346633419, 8)
# 3x leverage, short ###################################################
trade.is_short = True
trade.recalc_open_trade_value()
# 2.1 quote - Higher than open rate
trade.interest_mode = InterestMode.HOURSPERDAY # binance
trade.exchange = "binance" # binance
assert trade.calc_profit_ratio(rate=2.1) == round(-0.1658554276315789, 8)
trade.interest_mode = InterestMode.HOURSPER4 # kraken
trade.exchange = "kraken"
assert trade.calc_profit_ratio(rate=2.1) == round(-0.16895526315789455, 8)
# 1.9 quote - Lower than open rate
trade.interest_mode = InterestMode.HOURSPERDAY # binance
trade.exchange = "binance" # binance
assert trade.calc_profit_ratio(rate=1.9) == round(0.13565461309523819, 8)
trade.interest_mode = InterestMode.HOURSPER4 # kraken
trade.exchange = "kraken"
assert trade.calc_profit_ratio(rate=1.9) == round(0.13285000000000002, 8)
# Test when we apply a Sell order. Uses sell order used above
trade.interest_mode = InterestMode.HOURSPERDAY # binance
trade.exchange = "binance" # binance
assert trade.calc_profit_ratio() == round(-0.3166104479949876, 8)
trade.interest_mode = InterestMode.HOURSPER4 # kraken
trade.exchange = "kraken"
assert trade.calc_profit_ratio() == round(-0.319857894736842, 8)
# 1x leverage, short ###################################################
trade.leverage = 1.0
# 2.1 quote - Higher than open rate
trade.interest_mode = InterestMode.HOURSPERDAY # binance
trade.exchange = "binance" # binance
assert trade.calc_profit_ratio(rate=2.1) == round(-0.05528514254385963, 8)
trade.interest_mode = InterestMode.HOURSPER4 # kraken
trade.exchange = "kraken"
assert trade.calc_profit_ratio(rate=2.1) == round(-0.05631842105263152, 8)
# 1.9 quote - Lower than open rate
trade.interest_mode = InterestMode.HOURSPERDAY # binance
trade.exchange = "binance"
assert trade.calc_profit_ratio(rate=1.9) == round(0.045218204365079395, 8)
trade.interest_mode = InterestMode.HOURSPER4 # kraken
trade.exchange = "kraken"
assert trade.calc_profit_ratio(rate=1.9) == round(0.04428333333333334, 8)
# Test when we apply a Sell order. Uses sell order used above
trade.interest_mode = InterestMode.HOURSPERDAY # binance
trade.exchange = "binance"
assert trade.calc_profit_ratio() == round(-0.1055368159983292, 8)
trade.interest_mode = InterestMode.HOURSPER4 # kraken
trade.exchange = "kraken"
assert trade.calc_profit_ratio() == round(-0.106619298245614, 8)
@ -1542,7 +1534,6 @@ def test_adjust_stop_loss_short(fee):
open_rate=1,
max_rate=1,
is_short=True,
interest_mode=InterestMode.HOURSPERDAY
)
trade.adjust_stop_loss(trade.open_rate, 0.05, True)
assert trade.stop_loss == 1.05
@ -1859,7 +1850,6 @@ def test_stoploss_reinitialization_short(default_conf, fee):
max_rate=1,
is_short=True,
leverage=3.0,
interest_mode=InterestMode.HOURSPERDAY
)
trade.adjust_stop_loss(trade.open_rate, -0.05, True)
assert trade.stop_loss == 1.05