stable/tests/test_persistence_leverage.py

616 lines
26 KiB
Python
Raw Normal View History

2021-07-02 08:48:30 +00:00
import logging
from datetime import datetime, timedelta, timezone
from pathlib import Path
from types import FunctionType
from unittest.mock import MagicMock
import arrow
import pytest
from math import isclose
from sqlalchemy import create_engine, inspect, text
from freqtrade import constants
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_with_leverage, log_has, log_has_re
@pytest.mark.usefixtures("init_persistence")
2021-07-04 06:11:59 +00:00
def test_interest_kraken(market_leveraged_buy_order, fee):
2021-07-02 08:48:30 +00:00
"""
2021-07-04 06:11:59 +00:00
Market trade on Kraken at 3x and 5x leverage
Short trade
interest_rate: 0.05%, 0.25% per 4 hrs
open_rate: 0.00004099 base
close_rate: 0.00004173 base
stake_amount: 0.0037707443218227
borrowed: 0.0075414886436454
amount:
275.97543219 crypto
459.95905365 crypto
borrowed:
0.0075414886436454 base
0.0150829772872908 base
time-periods: 10 minutes(rounds up to 1 time-period of 4hrs)
5 hours = 5/4
2021-07-02 08:48:30 +00:00
2021-07-04 06:11:59 +00:00
interest: borrowed * interest_rate * time-periods
= 0.0075414886436454 * 0.0005 * 1 = 3.7707443218227e-06 base
= 0.0075414886436454 * 0.00025 * 5/4 = 2.3567152011391876e-06 base
= 0.0150829772872908 * 0.0005 * 5/4 = 9.42686080455675e-06 base
= 0.0150829772872908 * 0.00025 * 1 = 3.7707443218227e-06 base
"""
trade = Trade(
pair='ETH/BTC',
stake_amount=0.0037707443218227,
amount=275.97543219,
open_rate=0.00001099,
open_date=datetime.utcnow() - timedelta(hours=0, minutes=10),
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='kraken',
leverage=3.0,
interest_rate=0.0005
)
# The trades that last 10 minutes do not need to be rounded because they round up to 4 hours on kraken so we can predict the correct value
assert float(trade.calculate_interest()) == 3.7707443218227e-06
trade.open_date = datetime.utcnow() - timedelta(hours=5, minutes=0)
# The trades that last for 5 hours have to be rounded because the length of time that the test takes will vary every time it runs, so we can't predict the exact value
assert float(round(trade.calculate_interest(interest_rate=0.00025), 11)
) == round(2.3567152011391876e-06, 11)
trade = Trade(
pair='ETH/BTC',
stake_amount=0.0037707443218227,
amount=459.95905365,
open_rate=0.00001099,
open_date=datetime.utcnow() - timedelta(hours=5, minutes=0),
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='kraken',
leverage=5.0,
interest_rate=0.0005
)
assert float(round(trade.calculate_interest(), 11)
) == round(9.42686080455675e-06, 11)
trade.open_date = datetime.utcnow() - timedelta(hours=0, minutes=10)
assert float(trade.calculate_interest(interest_rate=0.00025)) == 3.7707443218227e-06
@pytest.mark.usefixtures("init_persistence")
def test_interest_binance(market_leveraged_buy_order, fee):
"""
Market trade on Kraken at 3x and 5x leverage
Short trade
interest_rate: 0.05%, 0.25% per 4 hrs
2021-07-02 08:48:30 +00:00
open_rate: 0.00001099 base
close_rate: 0.00001173 base
2021-07-04 06:11:59 +00:00
stake_amount: 0.0009999999999226999
borrowed: 0.0019999999998453998
amount:
90.99181073 * leverage(3) = 272.97543219 crypto
90.99181073 * leverage(5) = 454.95905365 crypto
borrowed:
0.0019999999998453998 base
0.0039999999996907995 base
time-periods: 10 minutes(rounds up to 1/24 time-period of 24hrs)
5 hours = 5/24
2021-07-02 08:48:30 +00:00
2021-07-04 06:11:59 +00:00
interest: borrowed * interest_rate * time-periods
= 0.0019999999998453998 * 0.00050 * 1/24 = 4.166666666344583e-08 base
= 0.0019999999998453998 * 0.00025 * 5/24 = 1.0416666665861459e-07 base
= 0.0039999999996907995 * 0.00050 * 5/24 = 4.1666666663445834e-07 base
= 0.0039999999996907995 * 0.00025 * 1/24 = 4.166666666344583e-08 base
2021-07-02 08:48:30 +00:00
"""
2021-07-04 06:11:59 +00:00
2021-07-02 08:48:30 +00:00
trade = Trade(
pair='ETH/BTC',
stake_amount=0.0009999999999226999,
2021-07-04 06:11:59 +00:00
amount=272.97543219,
open_rate=0.00001099,
open_date=datetime.utcnow() - timedelta(hours=0, minutes=10),
2021-07-02 08:48:30 +00:00
fee_open=fee.return_value,
fee_close=fee.return_value,
2021-07-04 06:11:59 +00:00
exchange='binance',
leverage=3.0,
interest_rate=0.0005
)
# The trades that last 10 minutes do not always need to be rounded because they round up to 4 hours on kraken so we can predict the correct value
assert round(float(trade.calculate_interest()), 22) == round(4.166666666344583e-08, 22)
trade.open_date = datetime.utcnow() - timedelta(hours=5, minutes=0)
# The trades that last for 5 hours have to be rounded because the length of time that the test takes will vary every time it runs, so we can't predict the exact value
assert float(round(trade.calculate_interest(interest_rate=0.00025), 14)
) == round(1.0416666665861459e-07, 14)
trade = Trade(
pair='ETH/BTC',
stake_amount=0.0009999999999226999,
amount=459.95905365,
open_rate=0.00001099,
open_date=datetime.utcnow() - timedelta(hours=5, minutes=0),
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='binance',
leverage=5.0,
interest_rate=0.0005
)
assert float(round(trade.calculate_interest(), 14)) == round(4.1666666663445834e-07, 14)
trade.open_date = datetime.utcnow() - timedelta(hours=0, minutes=10)
assert float(round(trade.calculate_interest(interest_rate=0.00025), 22)
) == round(4.166666666344583e-08, 22)
@pytest.mark.usefixtures("init_persistence")
def test_update_open_order(limit_leveraged_buy_order):
trade = Trade(
pair='ETH/BTC',
stake_amount=1.00,
open_rate=0.01,
amount=5,
fee_open=0.1,
fee_close=0.1,
2021-07-02 08:48:30 +00:00
interest_rate=0.0005,
2021-07-04 06:11:59 +00:00
leverage=3.0,
exchange='binance',
2021-07-02 08:48:30 +00:00
)
2021-07-04 06:11:59 +00:00
assert trade.open_order_id is None
2021-07-02 08:48:30 +00:00
assert trade.close_profit is None
assert trade.close_date is None
2021-07-04 06:11:59 +00:00
limit_leveraged_buy_order['status'] = 'open'
2021-07-02 08:48:30 +00:00
trade.update(limit_leveraged_buy_order)
2021-07-04 06:11:59 +00:00
assert trade.open_order_id is None
2021-07-02 08:48:30 +00:00
assert trade.close_profit is None
assert trade.close_date is None
@pytest.mark.usefixtures("init_persistence")
2021-07-04 06:11:59 +00:00
def test_calc_open_trade_value(market_leveraged_buy_order, fee):
2021-07-02 08:48:30 +00:00
"""
10 minute leveraged market trade on Kraken at 3x leverage
Short trade
fee: 0.25% base
interest_rate: 0.05% per 4 hrs
open_rate: 0.00004099 base
close_rate: 0.00004173 base
amount: 91.99181073 * leverage(3) = 275.97543219 crypto
stake_amount: 0.0037707443218227
borrowed: 0.0075414886436454 base
time-periods: 10 minutes(rounds up to 1 time-period of 4hrs)
interest: borrowed * interest_rate * time-periods
2021-07-04 06:11:59 +00:00
= 0.0075414886436454 * 0.0005 * 1 = 3.7707443218227e-06 crypto
2021-07-02 08:48:30 +00:00
open_value: (amount * open_rate) + (amount * open_rate * fee)
= (275.97543219 * 0.00004099) + (275.97543219 * 0.00004099 * 0.0025)
= 0.01134051354788177
"""
trade = Trade(
pair='ETH/BTC',
2021-07-04 06:11:59 +00:00
stake_amount=0.001,
2021-07-02 08:48:30 +00:00
amount=5,
2021-07-04 06:11:59 +00:00
open_rate=0.00004099,
open_date=datetime.utcnow() - timedelta(hours=0, minutes=10),
2021-07-02 08:48:30 +00:00
fee_open=fee.return_value,
fee_close=fee.return_value,
interest_rate=0.0005,
2021-07-04 06:11:59 +00:00
exchange='kraken',
leverage=3
2021-07-02 08:48:30 +00:00
)
2021-07-04 06:11:59 +00:00
trade.open_order_id = 'open_trade'
trade.update(market_leveraged_buy_order) # Buy @ 0.00001099
# Get the open rate price with the standard fee rate
assert trade._calc_open_trade_value() == 0.01134051354788177
trade.fee_open = 0.003
# Get the open rate price with a custom fee rate
assert trade._calc_open_trade_value() == 0.011346169664364504
2021-07-02 08:48:30 +00:00
@pytest.mark.usefixtures("init_persistence")
2021-07-04 06:11:59 +00:00
def test_calc_open_close_trade_price(limit_leveraged_buy_order, limit_leveraged_sell_order, fee):
2021-07-02 08:48:30 +00:00
"""
5 hour leveraged trade on Binance
fee: 0.25% base
interest_rate: 0.05% per day
open_rate: 0.00001099 base
close_rate: 0.00001173 base
amount: 272.97543219 crypto
stake_amount: 0.0009999999999226999 base
borrowed: 0.0019999999998453998 base
time-periods: 5 hours(rounds up to 5/24 time-period of 1 day)
interest: borrowed * interest_rate * time-periods
= 0.0019999999998453998 * 0.0005 * 5/24 = 2.0833333331722917e-07 base
open_value: (amount * open_rate) + (amount * open_rate * fee)
= (272.97543219 * 0.00001099) + (272.97543219 * 0.00001099 * 0.0025)
= 0.0030074999997675204
2021-07-04 06:11:59 +00:00
close_value: ((amount_closed * close_rate) - (amount_closed * close_rate * fee)) - interest
= (272.97543219 * 0.00001173) - (272.97543219 * 0.00001173 * 0.0025) - 2.0833333331722917e-07
= 0.003193788481706411
total_profit = close_value - open_value
= 0.003193788481706411 - 0.0030074999997675204
= 0.00018628848193889044
2021-07-02 08:48:30 +00:00
total_profit_percentage = total_profit / stake_amount
= 0.00018628848193889054 / 0.0009999999999226999
= 0.18628848195329067
"""
trade = Trade(
pair='ETH/BTC',
stake_amount=0.0009999999999226999,
open_rate=0.01,
amount=5,
2021-07-04 06:11:59 +00:00
open_date=datetime.utcnow() - timedelta(hours=5, minutes=0),
2021-07-02 08:48:30 +00:00
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='binance',
interest_rate=0.0005
)
trade.open_order_id = 'something'
trade.update(limit_leveraged_buy_order)
2021-07-04 06:11:59 +00:00
assert trade._calc_open_trade_value() == 0.00300749999976752
2021-07-02 08:48:30 +00:00
trade.update(limit_leveraged_sell_order)
# Will be slightly different due to slight changes in compilation time, and the fact that interest depends on time
2021-07-04 06:11:59 +00:00
assert round(trade.calc_close_trade_value(), 11) == round(0.003193788481706411, 11)
2021-07-02 08:48:30 +00:00
# Profit in BTC
2021-07-04 06:11:59 +00:00
assert round(trade.calc_profit(), 8) == round(0.00018628848193889054, 8)
2021-07-02 08:48:30 +00:00
# Profit in percent
2021-07-04 06:11:59 +00:00
assert round(trade.calc_profit_ratio(), 8) == round(0.18628848195329067, 8)
2021-07-02 08:48:30 +00:00
@pytest.mark.usefixtures("init_persistence")
2021-07-04 06:11:59 +00:00
def test_trade_close(fee):
2021-07-02 08:48:30 +00:00
"""
5 hour leveraged market trade on Kraken at 3x leverage
fee: 0.25% base
interest_rate: 0.05% per 4 hrs
open_rate: 0.1 base
close_rate: 0.2 base
amount: 5 * leverage(3) = 15 crypto
stake_amount: 0.5
borrowed: 1 base
time-periods: 5/4 periods of 4hrs
interest: borrowed * interest_rate * time-periods
= 1 * 0.0005 * 5/4 = 0.000625 crypto
open_value: (amount * open_rate) + (amount * open_rate * fee)
= (15 * 0.1) + (15 * 0.1 * 0.0025)
= 1.50375
2021-07-04 06:11:59 +00:00
close_value: (amount_closed * close_rate) + (amount_closed * close_rate * fee) - interest
= (15 * 0.2) - (15 * 0.2 * 0.0025) - 0.000625
= 2.9918750000000003
total_profit = close_value - open_value
= 2.9918750000000003 - 1.50375
2021-07-02 08:48:30 +00:00
= 1.4881250000000001
total_profit_percentage = total_profit / stake_amount
= 1.4881250000000001 / 0.5
= 2.9762500000000003
"""
trade = Trade(
pair='ETH/BTC',
2021-07-04 06:11:59 +00:00
stake_amount=0.5,
open_rate=0.1,
amount=15,
2021-07-02 08:48:30 +00:00
is_open=True,
fee_open=fee.return_value,
fee_close=fee.return_value,
2021-07-04 06:11:59 +00:00
open_date=datetime.utcnow() - timedelta(hours=5, minutes=0),
2021-07-02 08:48:30 +00:00
exchange='kraken',
leverage=3.0,
interest_rate=0.0005
)
assert trade.close_profit is None
assert trade.close_date is None
assert trade.is_open is True
2021-07-04 06:11:59 +00:00
trade.close(0.2)
2021-07-02 08:48:30 +00:00
assert trade.is_open is False
assert trade.close_profit == round(2.9762500000000003, 8)
assert trade.close_date is not None
# TODO-mg: Remove these comments probably
# new_date = arrow.Arrow(2020, 2, 2, 15, 6, 1).datetime,
# assert trade.close_date != new_date
# # Close should NOT update close_date if the trade has been closed already
# assert trade.is_open is False
# trade.close_date = new_date
# trade.close(0.02)
# assert trade.close_date == new_date
@pytest.mark.usefixtures("init_persistence")
2021-07-04 06:11:59 +00:00
def test_calc_close_trade_price(market_leveraged_buy_order, market_leveraged_sell_order, fee):
"""
10 minute leveraged market trade on Kraken at 3x leverage
Short trade
fee: 0.25% base
interest_rate: 0.05% per 4 hrs
open_rate: 0.00004099 base
close_rate: 0.00004173 base
amount: 91.99181073 * leverage(3) = 275.97543219 crypto
stake_amount: 0.0037707443218227
borrowed: 0.0075414886436454 base
time-periods: 10 minutes(rounds up to 1 time-period of 4hrs)
interest: borrowed * interest_rate * time-periods
= 0.0075414886436454 * 0.0005 * 1 = 3.7707443218227e-06 crypto
open_value: (amount * open_rate) + (amount * open_rate * fee)
= (275.97543219 * 0.00004099) + (275.97543219 * 0.00004099 * 0.0025)
= 0.01134051354788177
close_value: (amount_closed * close_rate) - (amount_closed * close_rate * fee) - interest
= (275.97543219 * 0.00001234) - (275.97543219 * 0.00001234 * 0.0025) - 3.7707443218227e-06 = 0.003393252246819716
= (275.97543219 * 0.00001234) - (275.97543219 * 0.00001234 * 0.003) - 3.7707443218227e-06 = 0.003391549478403104
= (275.97543219 * 0.00004173) - (275.97543219 * 0.00004173 * 0.005) - 3.7707443218227e-06 = 0.011455101767040435
"""
2021-07-02 08:48:30 +00:00
trade = Trade(
pair='ETH/BTC',
2021-07-04 06:11:59 +00:00
stake_amount=0.0037707443218227,
2021-07-02 08:48:30 +00:00
amount=5,
2021-07-04 06:11:59 +00:00
open_rate=0.00004099,
2021-07-02 08:48:30 +00:00
fee_open=fee.return_value,
fee_close=fee.return_value,
2021-07-04 06:11:59 +00:00
open_date=datetime.utcnow() - timedelta(hours=0, minutes=10),
2021-07-02 08:48:30 +00:00
interest_rate=0.0005,
2021-07-04 06:11:59 +00:00
leverage=3.0,
exchange='kraken',
2021-07-02 08:48:30 +00:00
)
2021-07-04 06:11:59 +00:00
trade.open_order_id = 'close_trade'
trade.update(market_leveraged_buy_order) # Buy @ 0.00001099
# Get the close rate price with a custom close rate and a regular fee rate
assert isclose(trade.calc_close_trade_value(rate=0.00001234), 0.003393252246819716)
# Get the close rate price with a custom close rate and a custom fee rate
assert isclose(trade.calc_close_trade_value(rate=0.00001234, fee=0.003), 0.003391549478403104)
# Test when we apply a Sell order, and ask price with a custom fee rate
trade.update(market_leveraged_sell_order)
assert isclose(trade.calc_close_trade_value(fee=0.005), 0.011455101767040435)
2021-07-02 08:48:30 +00:00
@pytest.mark.usefixtures("init_persistence")
2021-07-04 06:11:59 +00:00
def test_update_limit_order(limit_leveraged_buy_order, limit_leveraged_sell_order, fee, caplog):
"""
10 minute leveraged limit trade on binance at 3x leverage
Leveraged trade
fee: 0.25% base
interest_rate: 0.05% per day
open_rate: 0.00001099 base
close_rate: 0.00001173 base
amount: 272.97543219 crypto
stake_amount: 0.0009999999999226999 base
borrowed: 0.0019999999998453998 base
time-periods: 10 minutes(rounds up to 1/24 time-period of 1 day)
interest: borrowed * interest_rate * time-periods
= 0.0019999999998453998 * 0.0005 * 1/24 = 4.166666666344583e-08 base
open_value: (amount * open_rate) + (amount * open_rate * fee)
= (272.97543219 * 0.00001099) + (272.97543219 * 0.00001099 * 0.0025)
= 0.0030074999997675204
close_value: (amount_closed * close_rate) - (amount_closed * close_rate * fee)
= (272.97543219 * 0.00001173) - (272.97543219 * 0.00001173 * 0.0025)
= 0.003193996815039728
total_profit = close_value - open_value - interest
= 0.003193996815039728 - 0.0030074999997675204 - 4.166666666344583e-08
= 0.00018645514860554435
total_profit_percentage = total_profit / stake_amount
= 0.00018645514860554435 / 0.0009999999999226999
= 0.18645514861995735
"""
2021-07-02 08:48:30 +00:00
trade = Trade(
2021-07-04 06:11:59 +00:00
id=2,
2021-07-02 08:48:30 +00:00
pair='ETH/BTC',
2021-07-04 06:11:59 +00:00
stake_amount=0.0009999999999226999,
2021-07-02 08:48:30 +00:00
open_rate=0.01,
amount=5,
2021-07-04 06:11:59 +00:00
is_open=True,
open_date=datetime.utcnow() - timedelta(hours=0, minutes=10),
fee_open=fee.return_value,
fee_close=fee.return_value,
leverage=3.0,
2021-07-02 08:48:30 +00:00
interest_rate=0.0005,
2021-07-04 06:11:59 +00:00
exchange='binance'
2021-07-02 08:48:30 +00:00
)
2021-07-04 06:11:59 +00:00
# assert trade.open_order_id is None
2021-07-02 08:48:30 +00:00
assert trade.close_profit is None
assert trade.close_date is None
2021-07-04 06:11:59 +00:00
# trade.open_order_id = 'something'
2021-07-02 08:48:30 +00:00
trade.update(limit_leveraged_buy_order)
2021-07-04 06:11:59 +00:00
# assert trade.open_order_id is None
assert trade.open_rate == 0.00001099
2021-07-02 08:48:30 +00:00
assert trade.close_profit is None
assert trade.close_date is None
2021-07-04 06:11:59 +00:00
assert trade.borrowed == 0.0019999999998453998
assert log_has_re(r"LIMIT_BUY has been fulfilled for Trade\(id=2, "
r"pair=ETH/BTC, amount=272.97543219, open_rate=0.00001099, open_since=.*\).",
caplog)
caplog.clear()
# trade.open_order_id = 'something'
trade.update(limit_leveraged_sell_order)
# assert trade.open_order_id is None
assert trade.close_rate == 0.00001173
assert trade.close_profit == round(0.18645514861995735, 8)
assert trade.close_date is not None
assert log_has_re(r"LIMIT_SELL has been fulfilled for Trade\(id=2, "
r"pair=ETH/BTC, amount=272.97543219, open_rate=0.00001099, open_since=.*\).",
caplog)
2021-07-02 08:48:30 +00:00
@pytest.mark.usefixtures("init_persistence")
2021-07-04 06:11:59 +00:00
def test_update_market_order(market_leveraged_buy_order, market_leveraged_sell_order, fee, caplog):
2021-07-02 08:48:30 +00:00
"""
10 minute leveraged market trade on Kraken at 3x leverage
Short trade
fee: 0.25% base
interest_rate: 0.05% per 4 hrs
open_rate: 0.00004099 base
close_rate: 0.00004173 base
2021-07-04 06:11:59 +00:00
amount: = 275.97543219 crypto
2021-07-02 08:48:30 +00:00
stake_amount: 0.0037707443218227
borrowed: 0.0075414886436454 base
time-periods: 10 minutes(rounds up to 1 time-period of 4hrs)
interest: borrowed * interest_rate * time-periods
2021-07-04 06:11:59 +00:00
= 0.0075414886436454 * 0.0005 * 1 = 3.7707443218227e-06 crypto
2021-07-02 08:48:30 +00:00
open_value: (amount * open_rate) + (amount * open_rate * fee)
= (275.97543219 * 0.00004099) + (275.97543219 * 0.00004099 * 0.0025)
= 0.01134051354788177
2021-07-04 06:11:59 +00:00
close_value: (amount_closed * close_rate) - (amount_closed * close_rate * fee)
= (275.97543219 * 0.00004173) - (275.97543219 * 0.00004173 * 0.0025)
= 0.011487663648325479
total_profit = close_value - open_value - interest
= 0.011487663648325479 - 0.01134051354788177 - 3.7707443218227e-06
= 0.0001433793561218866
total_profit_percentage = total_profit / stake_amount
= 0.0001433793561218866 / 0.0037707443218227
= 0.03802415223225211
2021-07-02 08:48:30 +00:00
"""
trade = Trade(
2021-07-04 06:11:59 +00:00
id=1,
2021-07-02 08:48:30 +00:00
pair='ETH/BTC',
2021-07-04 06:11:59 +00:00
stake_amount=0.0037707443218227,
2021-07-02 08:48:30 +00:00
amount=5,
open_rate=0.00004099,
2021-07-04 06:11:59 +00:00
is_open=True,
leverage=3,
2021-07-02 08:48:30 +00:00
fee_open=fee.return_value,
fee_close=fee.return_value,
2021-07-04 06:11:59 +00:00
open_date=datetime.utcnow() - timedelta(hours=0, minutes=10),
2021-07-02 08:48:30 +00:00
interest_rate=0.0005,
2021-07-04 06:11:59 +00:00
exchange='kraken'
2021-07-02 08:48:30 +00:00
)
2021-07-04 06:11:59 +00:00
trade.open_order_id = 'something'
trade.update(market_leveraged_buy_order)
assert trade.leverage == 3.0
assert trade.open_order_id is None
assert trade.open_rate == 0.00004099
assert trade.close_profit is None
assert trade.close_date is None
assert trade.interest_rate == 0.0005
# TODO: Uncomment the next assert and make it work.
# The logger also has the exact same but there's some spacing in there
assert log_has_re(r"MARKET_BUY has been fulfilled for Trade\(id=1, "
r"pair=ETH/BTC, amount=275.97543219, open_rate=0.00004099, open_since=.*\).",
caplog)
caplog.clear()
trade.is_open = True
trade.open_order_id = 'something'
trade.update(market_leveraged_sell_order)
assert trade.open_order_id is None
assert trade.close_rate == 0.00004173
assert trade.close_profit == round(0.03802415223225211, 8)
assert trade.close_date is not None
# TODO: The amount should maybe be the opening amount + the interest
# TODO: Uncomment the next assert and make it work.
# The logger also has the exact same but there's some spacing in there
assert log_has_re(r"MARKET_SELL has been fulfilled for Trade\(id=1, "
r"pair=ETH/BTC, amount=275.97543219, open_rate=0.00004099, open_since=.*\).",
caplog)
2021-07-02 08:48:30 +00:00
@pytest.mark.usefixtures("init_persistence")
2021-07-04 06:11:59 +00:00
def test_calc_close_trade_price_exception(limit_leveraged_buy_order, fee):
2021-07-02 08:48:30 +00:00
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
2021-07-04 06:11:59 +00:00
open_rate=0.1,
2021-07-02 08:48:30 +00:00
amount=5,
fee_open=fee.return_value,
fee_close=fee.return_value,
2021-07-04 06:11:59 +00:00
exchange='binance',
2021-07-02 08:48:30 +00:00
interest_rate=0.0005,
2021-07-04 06:11:59 +00:00
leverage=3.0
2021-07-02 08:48:30 +00:00
)
2021-07-04 06:11:59 +00:00
trade.open_order_id = 'something'
trade.update(limit_leveraged_buy_order)
assert trade.calc_close_trade_value() == 0.0
2021-07-02 08:48:30 +00:00
@pytest.mark.usefixtures("init_persistence")
2021-07-04 06:11:59 +00:00
def test_calc_profit(market_leveraged_buy_order, market_leveraged_sell_order, fee):
2021-07-02 08:48:30 +00:00
"""
# TODO: Update this one
Leveraged trade on Kraken at 3x leverage
fee: 0.25% base or 0.3%
interest_rate: 0.05%, 0.25% per 4 hrs
open_rate: 0.00004099 base
close_rate: 0.00004173 base
stake_amount: 0.0037707443218227
amount: 91.99181073 * leverage(3) = 275.97543219 crypto
borrowed: 0.0075414886436454 base
time-periods: 10 minutes(rounds up to 1 time-period of 4hrs)
5 hours = 5/4
interest: borrowed * interest_rate * time-periods
2021-07-04 06:11:59 +00:00
= 0.0075414886436454 * 0.0005 * 1 = 3.7707443218227e-06 crypto
2021-07-02 08:48:30 +00:00
= 0.0075414886436454 * 0.00025 * 5/4 = 2.3567152011391876e-06 crypto
2021-07-04 06:11:59 +00:00
= 0.0075414886436454 * 0.0005 * 5/4 = 4.713430402278375e-06 crypto
= 0.0075414886436454 * 0.00025 * 1 = 1.88537216091135e-06 crypto
2021-07-02 08:48:30 +00:00
open_value: (amount * open_rate) + (amount * open_rate * fee)
= (275.97543219 * 0.00004099) + (275.97543219 * 0.00004099 * 0.0025) = 0.01134051354788177
2021-07-04 06:11:59 +00:00
close_value: (amount_closed * close_rate) - (amount_closed * close_rate * fee) - interest
(275.97543219 * 0.00005374) - (275.97543219 * 0.00005374 * 0.0025) - 3.7707443218227e-06 = 0.01479007168225405
(275.97543219 * 0.00000437) - (275.97543219 * 0.00000437 * 0.0025) - 2.3567152011391876e-06 = 0.001200640891872485
(275.97543219 * 0.00005374) - (275.97543219 * 0.00005374 * 0.003) - 4.713430402278375e-06 = 0.014781713536310649
(275.97543219 * 0.00000437) - (275.97543219 * 0.00000437 * 0.003) - 1.88537216091135e-06 = 0.0012005092285933775
2021-07-02 08:48:30 +00:00
total_profit = close_value - open_value
2021-07-04 06:11:59 +00:00
= 0.01479007168225405 - 0.01134051354788177 = 0.003449558134372281
= 0.001200640891872485 - 0.01134051354788177 = -0.010139872656009285
= 0.014781713536310649 - 0.01134051354788177 = 0.0034411999884288794
= 0.0012005092285933775 - 0.01134051354788177 = -0.010140004319288392
2021-07-02 08:48:30 +00:00
total_profit_percentage = total_profit / stake_amount
2021-07-04 06:11:59 +00:00
0.003449558134372281/0.0037707443218227 = 0.9148215418394732
-0.010139872656009285/0.0037707443218227 = -2.6890904793852157
0.0034411999884288794/0.0037707443218227 = 0.9126049646255184
-0.010140004319288392/0.0037707443218227 = -2.6891253964381554
2021-07-02 08:48:30 +00:00
"""
trade = Trade(
pair='ETH/BTC',
2021-07-04 06:11:59 +00:00
stake_amount=0.0037707443218227,
2021-07-02 08:48:30 +00:00
amount=5,
open_rate=0.00004099,
2021-07-04 06:11:59 +00:00
open_date=datetime.utcnow() - timedelta(hours=0, minutes=10),
2021-07-02 08:48:30 +00:00
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='kraken',
leverage=3.0,
interest_rate=0.0005
)
trade.open_order_id = 'something'
trade.update(market_leveraged_buy_order) # Buy @ 0.00001099
# Custom closing rate and regular fee rate
# Higher than open rate
2021-07-04 06:11:59 +00:00
assert trade.calc_profit(rate=0.00005374, interest_rate=0.0005) == round(
0.003449558134372281, 8)
2021-07-02 08:48:30 +00:00
assert trade.calc_profit_ratio(
2021-07-04 06:11:59 +00:00
rate=0.00005374, interest_rate=0.0005) == round(0.9148215418394732, 8)
2021-07-02 08:48:30 +00:00
# Lower than open rate
2021-07-04 06:11:59 +00:00
trade.open_date = datetime.utcnow() - timedelta(hours=5, minutes=0)
2021-07-02 08:48:30 +00:00
assert trade.calc_profit(
2021-07-04 06:11:59 +00:00
rate=0.00000437, interest_rate=0.00025) == round(-0.010139872656009285, 8)
2021-07-02 08:48:30 +00:00
assert trade.calc_profit_ratio(
2021-07-04 06:11:59 +00:00
rate=0.00000437, interest_rate=0.00025) == round(-2.6890904793852157, 8)
2021-07-02 08:48:30 +00:00
# Custom closing rate and custom fee rate
# Higher than open rate
2021-07-04 06:11:59 +00:00
assert trade.calc_profit(rate=0.00005374, fee=0.003,
interest_rate=0.0005) == round(0.0034411999884288794, 8)
assert trade.calc_profit_ratio(rate=0.00005374, fee=0.003,
interest_rate=0.0005) == round(0.9126049646255184, 8)
2021-07-02 08:48:30 +00:00
# Lower than open rate
2021-07-04 06:11:59 +00:00
trade.open_date = datetime.utcnow() - timedelta(hours=0, minutes=10)
2021-07-02 08:48:30 +00:00
assert trade.calc_profit(rate=0.00000437, fee=0.003,
2021-07-04 06:11:59 +00:00
interest_rate=0.00025) == round(-0.010140004319288392, 8)
2021-07-02 08:48:30 +00:00
assert trade.calc_profit_ratio(rate=0.00000437, fee=0.003,
2021-07-04 06:11:59 +00:00
interest_rate=0.00025) == round(-2.6891253964381554, 8)
2021-07-02 08:48:30 +00:00
# Test when we apply a Sell order. Sell higher than open rate @ 0.00001173
trade.update(market_leveraged_sell_order)
assert trade.calc_profit() == round(0.0001433793561218866, 8)
assert trade.calc_profit_ratio() == round(0.03802415223225211, 8)
# Test with a custom fee rate on the close trade
# assert trade.calc_profit(fee=0.003) == 0.00006163
# assert trade.calc_profit_ratio(fee=0.003) == 0.06147824