Changed tests in tests/test_persistence.py to use usdt prices

This commit is contained in:
Sam Germain 2021-07-31 19:52:55 -06:00
parent c5e3348b89
commit 90a61b1765
2 changed files with 388 additions and 160 deletions

View File

@ -812,7 +812,7 @@ def shitcoinmarkets(markets):
"future": False, "future": False,
"active": True "active": True
}, },
}) })
return shitmarkets return shitmarkets
@ -1115,7 +1115,7 @@ def order_book_l2_usd():
[25.576, 262.016], [25.576, 262.016],
[25.577, 178.557], [25.577, 178.557],
[25.578, 78.614] [25.578, 78.614]
], ],
'timestamp': None, 'timestamp': None,
'datetime': None, 'datetime': None,
'nonce': 2372149736 'nonce': 2372149736
@ -2084,3 +2084,88 @@ def saved_hyperopt_results():
].total_seconds() ].total_seconds()
return hyperopt_res return hyperopt_res
@pytest.fixture(scope='function')
def limit_buy_order_usdt_open():
return {
'id': 'mocked_limit_buy',
'type': 'limit',
'side': 'buy',
'symbol': 'mocked',
'datetime': arrow.utcnow().isoformat(),
'timestamp': arrow.utcnow().int_timestamp,
'price': 2.00,
'amount': 30.0,
'filled': 0.0,
'cost': 60.0,
'remaining': 30.0,
'status': 'open'
}
@pytest.fixture(scope='function')
def limit_buy_order_usdt(limit_buy_order_usdt_open):
order = deepcopy(limit_buy_order_usdt_open)
order['status'] = 'closed'
order['filled'] = order['amount']
order['remaining'] = 0.0
return order
@pytest.fixture
def limit_sell_order_usdt_open():
return {
'id': 'mocked_limit_sell',
'type': 'limit',
'side': 'sell',
'pair': 'mocked',
'datetime': arrow.utcnow().isoformat(),
'timestamp': arrow.utcnow().int_timestamp,
'price': 2.20,
'amount': 30.0,
'filled': 0.0,
'remaining': 30.0,
'status': 'open'
}
@pytest.fixture
def limit_sell_order_usdt(limit_sell_order_usdt_open):
order = deepcopy(limit_sell_order_usdt_open)
order['remaining'] = 0.0
order['filled'] = order['amount']
order['status'] = 'closed'
return order
@pytest.fixture(scope='function')
def market_buy_order_usdt():
return {
'id': 'mocked_market_buy',
'type': 'market',
'side': 'buy',
'symbol': 'mocked',
'datetime': arrow.utcnow().isoformat(),
'price': 2.00,
'amount': 30.0,
'filled': 30.0,
'remaining': 0.0,
'status': 'closed'
}
@pytest.fixture
def market_sell_order_usdt():
return {
'id': 'mocked_limit_sell',
'type': 'market',
'side': 'sell',
'symbol': 'mocked',
'datetime': arrow.utcnow().isoformat(),
'price': 2.20,
'amount': 30.0,
'filled': 30.0,
'remaining': 0.0,
'status': 'closed'
}

View File

@ -1,6 +1,7 @@
# pragma pylint: disable=missing-docstring, C0103 # pragma pylint: disable=missing-docstring, C0103
import logging import logging
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
from math import isclose
from pathlib import Path from pathlib import Path
from types import FunctionType from types import FunctionType
from unittest.mock import MagicMock from unittest.mock import MagicMock
@ -64,40 +65,39 @@ def test_init_dryrun_db(default_conf, tmpdir):
@pytest.mark.usefixtures("init_persistence") @pytest.mark.usefixtures("init_persistence")
def test_update_with_binance(limit_buy_order, limit_sell_order, fee, caplog): def test_update_limit_order(limit_buy_order_usdt, limit_sell_order_usdt, fee, caplog):
""" """
On this test we will buy and sell a crypto currency. On this test we will buy and sell a crypto currency.
fee: 0.25% quote
open_rate: 2.00 quote
close_rate: 2.20 quote
amount: = 30.0 crypto
stake_amount
1x,-1x: 60.0 quote
borrowed
1x: 0 quote
open_value: (amount * open_rate) ± (amount * open_rate * fee)
1x, 3x: 30 * 2 + 30 * 2 * 0.0025 = 60.15 quote
amount_closed:
1x, 3x : amount
close_value:
1x, 3x: (amount_closed * close_rate) - (amount_closed * close_rate * fee) - interest
binance,kraken 1x: (30.00 * 2.20) - (30.00 * 2.20 * 0.0025) = 65.835
total_profit:
1x, 3x : close_value - open_value
binance,kraken 1x: 65.835 - 60.15 = 5.685
total_profit_ratio:
1x, 3x : ((close_value/open_value) - 1) * leverage
binance 1x: ((65.835 / 60.15) - 1) * 1 = 0.0945137157107232
Buy
- Buy: 90.99181073 Crypto at 0.00001099 BTC
(90.99181073*0.00001099 = 0.0009999 BTC)
- Buying fee: 0.25%
- Total cost of buy trade: 0.001002500 BTC
((90.99181073*0.00001099) + ((90.99181073*0.00001099)*0.0025))
Sell
- Sell: 90.99181073 Crypto at 0.00001173 BTC
(90.99181073*0.00001173 = 0,00106733394 BTC)
- Selling fee: 0.25%
- Total cost of sell trade: 0.001064666 BTC
((90.99181073*0.00001173) - ((90.99181073*0.00001173)*0.0025))
Profit/Loss: +0.000062166 BTC
(Sell:0.001064666 - Buy:0.001002500)
Profit/Loss percentage: 0.0620
((0.001064666/0.001002500)-1 = 6.20%)
:param limit_buy_order:
:param limit_sell_order:
:return:
""" """
trade = Trade( trade = Trade(
id=2, id=2,
pair='ETH/BTC', pair='ADA/USDT',
stake_amount=0.001, stake_amount=60.0,
open_rate=0.01, open_rate=2.0,
amount=5, amount=30.0,
is_open=True, is_open=True,
open_date=arrow.utcnow().datetime, open_date=arrow.utcnow().datetime,
fee_open=fee.return_value, fee_open=fee.return_value,
@ -109,35 +109,36 @@ def test_update_with_binance(limit_buy_order, limit_sell_order, fee, caplog):
assert trade.close_date is None assert trade.close_date is None
trade.open_order_id = 'something' trade.open_order_id = 'something'
trade.update(limit_buy_order) trade.update(limit_buy_order_usdt)
assert trade.open_order_id is None assert trade.open_order_id is None
assert trade.open_rate == 0.00001099 assert trade.open_rate == 2.00
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 log_has_re(r"LIMIT_BUY has been fulfilled for Trade\(id=2, " assert log_has_re(r"LIMIT_BUY has been fulfilled for Trade\(id=2, "
r"pair=ETH/BTC, amount=90.99181073, open_rate=0.00001099, open_since=.*\).", r"pair=ADA/USDT, amount=30.00000000, open_rate=2.00000000, open_since=.*\).",
caplog) caplog)
caplog.clear() caplog.clear()
trade.open_order_id = 'something' trade.open_order_id = 'something'
trade.update(limit_sell_order) trade.update(limit_sell_order_usdt)
assert trade.open_order_id is None assert trade.open_order_id is None
assert trade.close_rate == 0.00001173 assert trade.close_rate == 2.20
assert trade.close_profit == 0.06201058 assert trade.close_profit == round(0.0945137157107232, 8)
assert trade.close_date is not None assert trade.close_date is not None
assert log_has_re(r"LIMIT_SELL has been fulfilled for Trade\(id=2, " assert log_has_re(r"LIMIT_SELL has been fulfilled for Trade\(id=2, "
r"pair=ETH/BTC, amount=90.99181073, open_rate=0.00001099, open_since=.*\).", r"pair=ADA/USDT, amount=30.00000000, open_rate=2.00000000, open_since=.*\).",
caplog) caplog)
caplog.clear()
@pytest.mark.usefixtures("init_persistence") @pytest.mark.usefixtures("init_persistence")
def test_update_market_order(market_buy_order, market_sell_order, fee, caplog): def test_update_market_order(market_buy_order_usdt, market_sell_order_usdt, fee, caplog):
trade = Trade( trade = Trade(
id=1, id=1,
pair='ETH/BTC', pair='ADA/USDT',
stake_amount=0.001, stake_amount=60.0,
amount=5, open_rate=2.0,
open_rate=0.01, amount=30.0,
is_open=True, is_open=True,
fee_open=fee.return_value, fee_open=fee.return_value,
fee_close=fee.return_value, fee_close=fee.return_value,
@ -146,61 +147,60 @@ def test_update_market_order(market_buy_order, market_sell_order, fee, caplog):
) )
trade.open_order_id = 'something' trade.open_order_id = 'something'
trade.update(market_buy_order) trade.update(market_buy_order_usdt)
assert trade.open_order_id is None assert trade.open_order_id is None
assert trade.open_rate == 0.00004099 assert trade.open_rate == 2.0
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 log_has_re(r"MARKET_BUY has been fulfilled for Trade\(id=1, " assert log_has_re(r"MARKET_BUY has been fulfilled for Trade\(id=1, "
r"pair=ETH/BTC, amount=91.99181073, open_rate=0.00004099, open_since=.*\).", r"pair=ADA/USDT, amount=30.00000000, open_rate=2.00000000, open_since=.*\).",
caplog) caplog)
caplog.clear() caplog.clear()
trade.is_open = True trade.is_open = True
trade.open_order_id = 'something' trade.open_order_id = 'something'
trade.update(market_sell_order) trade.update(market_sell_order_usdt)
assert trade.open_order_id is None assert trade.open_order_id is None
assert trade.close_rate == 0.00004173 assert trade.close_rate == 2.2
assert trade.close_profit == 0.01297561 assert trade.close_profit == round(0.0945137157107232, 8)
assert trade.close_date is not None assert trade.close_date is not None
assert log_has_re(r"MARKET_SELL has been fulfilled for Trade\(id=1, " assert log_has_re(r"MARKET_SELL has been fulfilled for Trade\(id=1, "
r"pair=ETH/BTC, amount=91.99181073, open_rate=0.00004099, open_since=.*\).", r"pair=ADA/USDT, amount=30.00000000, open_rate=2.00000000, open_since=.*\).",
caplog) caplog)
@pytest.mark.usefixtures("init_persistence") @pytest.mark.usefixtures("init_persistence")
def test_calc_open_close_trade_price(limit_buy_order, limit_sell_order, fee): def test_calc_open_close_trade_price(limit_buy_order_usdt, limit_sell_order_usdt, fee):
trade = Trade( trade = Trade(
pair='ETH/BTC', pair='ADA/USDT',
stake_amount=0.001, stake_amount=60.0,
open_rate=0.01, open_rate=2.0,
amount=5, amount=30.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',
) )
trade.open_order_id = 'something' trade.open_order_id = 'something'
trade.update(limit_buy_order) trade.update(limit_buy_order_usdt)
assert trade._calc_open_trade_value() == 0.0010024999999225068 assert trade._calc_open_trade_value() == 60.15
trade.update(limit_sell_order_usdt)
assert isclose(trade.calc_close_trade_value(), 65.835)
trade.update(limit_sell_order) # Profit in USDT
assert trade.calc_close_trade_value() == 0.0010646656050132426 assert trade.calc_profit() == 5.685
# Profit in BTC
assert trade.calc_profit() == 0.00006217
# Profit in percent # Profit in percent
assert trade.calc_profit_ratio() == 0.06201058 assert trade.calc_profit_ratio() == round(0.0945137157107232, 8)
@pytest.mark.usefixtures("init_persistence") @pytest.mark.usefixtures("init_persistence")
def test_trade_close(limit_buy_order, limit_sell_order, fee): def test_trade_close(limit_buy_order_usdt, limit_sell_order_usdt, fee):
trade = Trade( trade = Trade(
pair='ETH/BTC', pair='ADA/USDT',
stake_amount=0.001, stake_amount=60.0,
open_rate=0.01, open_rate=2.0,
amount=5, amount=30.0,
is_open=True, is_open=True,
fee_open=fee.return_value, fee_open=fee.return_value,
fee_close=fee.return_value, fee_close=fee.return_value,
@ -210,9 +210,9 @@ def test_trade_close(limit_buy_order, limit_sell_order, fee):
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.is_open is True assert trade.is_open is True
trade.close(0.02) trade.close(2.2)
assert trade.is_open is False assert trade.is_open is False
assert trade.close_profit == 0.99002494 assert trade.close_profit == round(0.0945137157107232, 8)
assert trade.close_date is not None assert trade.close_date is not None
new_date = arrow.Arrow(2020, 2, 2, 15, 6, 1).datetime, new_date = arrow.Arrow(2020, 2, 2, 15, 6, 1).datetime,
@ -220,34 +220,34 @@ def test_trade_close(limit_buy_order, limit_sell_order, fee):
# Close should NOT update close_date if the trade has been closed already # Close should NOT update close_date if the trade has been closed already
assert trade.is_open is False assert trade.is_open is False
trade.close_date = new_date trade.close_date = new_date
trade.close(0.02) trade.close(2.2)
assert trade.close_date == new_date assert trade.close_date == new_date
@pytest.mark.usefixtures("init_persistence") @pytest.mark.usefixtures("init_persistence")
def test_calc_close_trade_price_exception(limit_buy_order, fee): def test_calc_close_trade_price_exception(limit_buy_order_usdt, fee):
trade = Trade( trade = Trade(
pair='ETH/BTC', pair='ADA/USDT',
stake_amount=0.001, stake_amount=60.0,
open_rate=0.1, open_rate=2.0,
amount=5, amount=30.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',
) )
trade.open_order_id = 'something' trade.open_order_id = 'something'
trade.update(limit_buy_order) trade.update(limit_buy_order_usdt)
assert trade.calc_close_trade_value() == 0.0 assert trade.calc_close_trade_value() == 0.0
@pytest.mark.usefixtures("init_persistence") @pytest.mark.usefixtures("init_persistence")
def test_update_open_order(limit_buy_order): def test_update_open_order(limit_buy_order_usdt):
trade = Trade( trade = Trade(
pair='ETH/BTC', pair='ADA/USDT',
stake_amount=1.00, stake_amount=60.0,
open_rate=0.01, open_rate=2.0,
amount=5, amount=30.0,
fee_open=0.1, fee_open=0.1,
fee_close=0.1, fee_close=0.1,
exchange='binance', exchange='binance',
@ -257,8 +257,8 @@ def test_update_open_order(limit_buy_order):
assert trade.close_profit is None assert trade.close_profit is None
assert trade.close_date is None assert trade.close_date is None
limit_buy_order['status'] = 'open' limit_buy_order_usdt['status'] = 'open'
trade.update(limit_buy_order) trade.update(limit_buy_order_usdt)
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
@ -266,127 +266,270 @@ def test_update_open_order(limit_buy_order):
@pytest.mark.usefixtures("init_persistence") @pytest.mark.usefixtures("init_persistence")
def test_update_invalid_order(limit_buy_order): def test_update_invalid_order(limit_buy_order_usdt):
trade = Trade( trade = Trade(
pair='ETH/BTC', pair='ADA/USDT',
stake_amount=1.00, stake_amount=60.0,
amount=5, amount=30.0,
open_rate=0.001, open_rate=2.0,
fee_open=0.1, fee_open=0.1,
fee_close=0.1, fee_close=0.1,
exchange='binance', exchange='binance',
) )
limit_buy_order['type'] = 'invalid' limit_buy_order_usdt['type'] = 'invalid'
with pytest.raises(ValueError, match=r'Unknown order type'): with pytest.raises(ValueError, match=r'Unknown order type'):
trade.update(limit_buy_order) trade.update(limit_buy_order_usdt)
@pytest.mark.usefixtures("init_persistence") @pytest.mark.usefixtures("init_persistence")
def test_calc_open_trade_value(limit_buy_order, fee): def test_calc_open_trade_value(limit_buy_order_usdt, fee):
# 10 minute limit trade on Binance/Kraken
# fee: 0.25 %, 0.3% quote
# open_rate: 2.00 quote
# amount: = 30.0 crypto
# stake_amount
# 1x, -1x: 60.0 quote
# open_value: (amount * open_rate) ± (amount * open_rate * fee)
# 0.25% fee
# 1x, 3x: 30 * 2 + 30 * 2 * 0.0025 = 60.15 quote
# 0.3% fee
# 1x, 3x: 30 * 2 + 30 * 2 * 0.003 = 60.18 quote
trade = Trade( trade = Trade(
pair='ETH/BTC', pair='ADA/USDT',
stake_amount=0.001, stake_amount=60.0,
amount=5, amount=30.0,
open_rate=0.00001099, open_rate=2.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',
) )
trade.open_order_id = 'open_trade' trade.open_order_id = 'open_trade'
trade.update(limit_buy_order) # Buy @ 0.00001099 trade.update(limit_buy_order_usdt) # Buy @ 2.0
# Get the open rate price with the standard fee rate # Get the open rate price with the standard fee rate
assert trade._calc_open_trade_value() == 0.0010024999999225068 assert trade._calc_open_trade_value() == 60.15
trade.fee_open = 0.003 trade.fee_open = 0.003
# Get the open rate price with a custom fee rate # Get the open rate price with a custom fee rate
assert trade._calc_open_trade_value() == 0.001002999999922468 assert trade._calc_open_trade_value() == 60.18
@pytest.mark.usefixtures("init_persistence") @pytest.mark.usefixtures("init_persistence")
def test_calc_close_trade_price(limit_buy_order, limit_sell_order, fee): def test_calc_close_trade_price(limit_buy_order_usdt, limit_sell_order_usdt, fee):
trade = Trade( trade = Trade(
pair='ETH/BTC', pair='ADA/USDT',
stake_amount=0.001, stake_amount=60.0,
amount=5, amount=30.0,
open_rate=0.00001099, open_rate=2.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',
) )
trade.open_order_id = 'close_trade' trade.open_order_id = 'close_trade'
trade.update(limit_buy_order) # Buy @ 0.00001099 trade.update(limit_buy_order_usdt) # Buy @ 2.0
# Get the close rate price with a custom close rate and a regular fee rate # Get the close rate price with a custom close rate and a regular fee rate
assert trade.calc_close_trade_value(rate=0.00001234) == 0.0011200318470471794 assert trade.calc_close_trade_value(rate=2.5) == 74.8125
# Get the close rate price with a custom close rate and a custom fee rate # Get the close rate price with a custom close rate and a custom fee rate
assert trade.calc_close_trade_value(rate=0.00001234, fee=0.003) == 0.0011194704275749754 assert trade.calc_close_trade_value(rate=2.5, fee=0.003) == 74.775
# Test when we apply a Sell order, and ask price with a custom fee rate # Test when we apply a Sell order, and ask price with a custom fee rate
trade.update(limit_sell_order) trade.update(limit_sell_order_usdt)
assert trade.calc_close_trade_value(fee=0.005) == 0.0010619972701635854 assert trade.calc_close_trade_value(fee=0.005) == 65.67
@pytest.mark.usefixtures("init_persistence") @pytest.mark.usefixtures("init_persistence")
def test_calc_profit(limit_buy_order, limit_sell_order, fee): def test_calc_profit(limit_buy_order_usdt, limit_sell_order_usdt, fee):
"""
10 minute limit trade on Binance/Kraken at 1x, 3x leverage
arguments:
fee:
0.25% quote
0.30% quote
interest_rate: 0.05% per 4 hrs
open_rate: 2.0 quote
close_rate:
1.9 quote
2.1 quote
2.2 quote
amount: = 30.0 crypto
stake_amount
1x,-1x: 60.0 quote
3x,-3x: 20.0 quote
hours: 1/6 (10 minutes)
borrowed
1x: 0 quote
3x: 40 quote
-1x: 30 crypto
-3x: 30 crypto
time-periods:
kraken: (1 + 1) 4hr_periods = 2 4hr_periods
binance: 1/24 24hr_periods
interest: borrowed * interest_rate * time-periods
1x : /
binance 3x: 40 * 0.0005 * 1/24 = 0.0008333333333333334 quote
kraken 3x: 40 * 0.0005 * 2 = 0.040 quote
binace -1x,-3x: 30 * 0.0005 * 1/24 = 0.000625 crypto
kraken -1x,-3x: 30 * 0.0005 * 2 = 0.030 crypto
open_value: (amount * open_rate) ± (amount * open_rate * fee)
0.0025 fee
1x, 3x: 30 * 2 + 30 * 2 * 0.0025 = 60.15 quote
-1x,-3x: 30 * 2 - 30 * 2 * 0.0025 = 59.85 quote
0.003 fee: Is only applied to close rate in this test
amount_closed:
1x, 3x = amount
-1x, -3x = amount + interest
binance -1x,-3x: 30 + 0.000625 = 30.000625 crypto
kraken -1x,-3x: 30 + 0.03 = 30.03 crypto
close_value:
equations:
1x, 3x: (amount_closed * close_rate) - (amount_closed * close_rate * fee) - interest
-1x,-3x: (amount_closed * close_rate) + (amount_closed * close_rate * fee)
2.1 quote
bin,krak 1x: (30.00 * 2.1) - (30.00 * 2.1 * 0.0025) = 62.8425
bin 3x: (30.00 * 2.1) - (30.00 * 2.1 * 0.0025) - 0.0008333333 = 62.8416666667
krak 3x: (30.00 * 2.1) - (30.00 * 2.1 * 0.0025) - 0.040 = 62.8025
bin -1x,-3x: (30.000625 * 2.1) + (30.000625 * 2.1 * 0.0025) = 63.15881578125
krak -1x,-3x: (30.03 * 2.1) + (30.03 * 2.1 * 0.0025) = 63.2206575
1.9 quote
bin,krak 1x: (30.00 * 1.9) - (30.00 * 1.9 * 0.0025) = 56.8575
bin 3x: (30.00 * 1.9) - (30.00 * 1.9 * 0.0025) - 0.0008333333 = 56.85666667
krak 3x: (30.00 * 1.9) - (30.00 * 1.9 * 0.0025) - 0.040 = 56.8175
bin -1x,-3x: (30.000625 * 1.9) + (30.000625 * 1.9 * 0.0025) = 57.14369046875
krak -1x,-3x: (30.03 * 1.9) + (30.03 * 1.9 * 0.0025) = 57.1996425
2.2 quote
bin,krak 1x: (30.00 * 2.20) - (30.00 * 2.20 * 0.0025) = 65.835
bin 3x: (30.00 * 2.20) - (30.00 * 2.20 * 0.0025) - 0.00083333 = 65.83416667
krak 3x: (30.00 * 2.20) - (30.00 * 2.20 * 0.0025) - 0.040 = 65.795
bin -1x,-3x: (30.000625 * 2.20) + (30.000625 * 2.20 * 0.0025) = 66.1663784375
krak -1x,-3x: (30.03 * 2.20) + (30.03 * 2.20 * 0.0025) = 66.231165
total_profit:
equations:
1x, 3x : close_value - open_value
-1x,-3x: open_value - close_value
2.1 quote
binance,kraken 1x: 62.8425 - 60.15 = 2.6925
binance 3x: 62.84166667 - 60.15 = 2.69166667
kraken 3x: 62.8025 - 60.15 = 2.6525
binance -1x,-3x: 59.850 - 63.15881578125 = -3.308815781249997
kraken -1x,-3x: 59.850 - 63.2206575 = -3.3706575
1.9 quote
binance,kraken 1x: 56.8575 - 60.15 = -3.2925
binance 3x: 56.85666667 - 60.15 = -3.29333333
kraken 3x: 56.8175 - 60.15 = -3.3325
binance -1x,-3x: 59.850 - 57.14369046875 = 2.7063095312499996
kraken -1x,-3x: 59.850 - 57.1996425 = 2.6503575
2.2 quote
binance,kraken 1x: 65.835 - 60.15 = 5.685
binance 3x: 65.83416667 - 60.15 = 5.68416667
kraken 3x: 65.795 - 60.15 = 5.645
binance -1x,-3x: 59.850 - 66.1663784375 = -6.316378437499999
kraken -1x,-3x: 59.850 - 66.231165 = -6.381165
total_profit_ratio:
equations:
1x, 3x : ((close_value/open_value) - 1) * leverage
-1x,-3x: (1 - (close_value/open_value)) * leverage
2.1 quote
binance,kraken 1x: (62.8425 / 60.15) - 1 = 0.04476309226932673
binance 3x: ((62.84166667 / 60.15) - 1)*3 = 0.13424771421446402
kraken 3x: ((62.8025 / 60.15) - 1)*3 = 0.13229426433915248
binance -1x: 1 - (63.15881578125 / 59.850) = -0.05528514254385963
binance -3x: (1 - (63.15881578125 / 59.850))*3 = -0.1658554276315789
kraken -1x: 1 - (63.2206575 / 59.850) = -0.05631842105263152
kraken -3x: (1 - (63.2206575 / 59.850))*3 = -0.16895526315789455
1.9 quote
binance,kraken 1x: (56.8575 / 60.15) - 1 = -0.05473815461346632
binance 3x: ((56.85666667 / 60.15) - 1)*3 = -0.16425602643391513
kraken 3x: ((56.8175 / 60.15) - 1)*3 = -0.16620947630922667
binance -1x: 1 - (57.14369046875 / 59.850) = 0.045218204365079395
binance -3x: (1 - (57.14369046875 / 59.850))*3 = 0.13565461309523819
kraken -1x: 1 - (57.1996425 / 59.850) = 0.04428333333333334
kraken -3x: (1 - (57.1996425 / 59.850))*3 = 0.13285000000000002
2.2 quote
binance,kraken 1x: (65.835 / 60.15) - 1 = 0.0945137157107232
binance 3x: ((65.83416667 / 60.15) - 1)*3 = 0.2834995845386534
kraken 3x: ((65.795 / 60.15) - 1)*3 = 0.2815461346633419
binance -1x: 1 - (66.1663784375 / 59.850) = -0.1055368159983292
binance -3x: (1 - (66.1663784375 / 59.850))*3 = -0.3166104479949876
kraken -1x: 1 - (66.231165 / 59.850) = -0.106619298245614
kraken -3x: (1 - (66.231165 / 59.850))*3 = -0.319857894736842
fee: 0.003, 1x
close_value:
2.1 quote: (30.00 * 2.1) - (30.00 * 2.1 * 0.003) = 62.811
1.9 quote: (30.00 * 1.9) - (30.00 * 1.9 * 0.003) = 56.829
2.2 quote: (30.00 * 2.2) - (30.00 * 2.2 * 0.003) = 65.802
total_profit
fee: 0.003, 1x
2.1 quote: 62.811 - 60.15 = 2.6610000000000014
1.9 quote: 56.829 - 60.15 = -3.320999999999998
2.2 quote: 65.802 - 60.15 = 5.652000000000008
total_profit_ratio
fee: 0.003, 1x
2.1 quote: (62.811 / 60.15) - 1 = 0.04423940149625927
1.9 quote: (56.829 / 60.15) - 1 = -0.05521197007481293
2.2 quote: (65.802 / 60.15) - 1 = 0.09396508728179565
"""
trade = Trade( trade = Trade(
pair='ETH/BTC', pair='ADA/USDT',
stake_amount=0.001, stake_amount=60.0,
amount=5, amount=30.0,
open_rate=0.00001099, open_rate=2.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',
) )
trade.open_order_id = 'something' trade.open_order_id = 'something'
trade.update(limit_buy_order) # Buy @ 0.00001099 trade.update(limit_buy_order_usdt) # Buy @ 2.0
# Custom closing rate and regular fee rate # Custom closing rate and regular fee rate
# Higher than open rate # Higher than open rate - 2.1 quote
assert trade.calc_profit(rate=0.00001234) == 0.00011753 assert trade.calc_profit(rate=2.1) == 2.6925
# Lower than open rate # Lower than open rate - 1.9 quote
assert trade.calc_profit(rate=0.00000123) == -0.00089086 assert trade.calc_profit(rate=1.9) == round(-3.292499999999997, 8)
# Custom closing rate and custom fee rate # fee 0.003
# Higher than open rate # Higher than open rate - 2.1 quote
assert trade.calc_profit(rate=0.00001234, fee=0.003) == 0.00011697 assert trade.calc_profit(rate=2.1, fee=0.003) == 2.661
# Lower than open rate # Lower than open rate - 1.9 quote
assert trade.calc_profit(rate=0.00000123, fee=0.003) == -0.00089092 assert trade.calc_profit(rate=1.9, fee=0.003) == round(-3.320999999999998, 8)
# Test when we apply a Sell order. Sell higher than open rate @ 0.00001173 # Test when we apply a Sell order. Sell higher than open rate @ 2.2
trade.update(limit_sell_order) trade.update(limit_sell_order_usdt)
assert trade.calc_profit() == 0.00006217 assert trade.calc_profit() == round(5.684999999999995, 8)
# Test with a custom fee rate on the close trade # Test with a custom fee rate on the close trade
assert trade.calc_profit(fee=0.003) == 0.00006163 assert trade.calc_profit(fee=0.003) == round(5.652000000000008, 8)
@pytest.mark.usefixtures("init_persistence") @pytest.mark.usefixtures("init_persistence")
def test_calc_profit_ratio(limit_buy_order, limit_sell_order, fee): def test_calc_profit_ratio(limit_buy_order_usdt, limit_sell_order_usdt, fee):
trade = Trade( trade = Trade(
pair='ETH/BTC', pair='ADA/USDT',
stake_amount=0.001, stake_amount=60.0,
amount=5, amount=30.0,
open_rate=0.00001099, open_rate=2.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'
) )
trade.open_order_id = 'something' trade.open_order_id = 'something'
trade.update(limit_buy_order) # Buy @ 0.00001099 trade.update(limit_buy_order_usdt) # Buy @ 2.0
# Get percent of profit with a custom rate (Higher than open rate) # Higher than open rate - 2.1 quote
assert trade.calc_profit_ratio(rate=0.00001234) == 0.11723875 assert trade.calc_profit_ratio(rate=2.1) == round(0.04476309226932673, 8)
# Lower than open rate - 1.9 quote
assert trade.calc_profit_ratio(rate=1.9) == round(-0.05473815461346632, 8)
# Get percent of profit with a custom rate (Lower than open rate) # fee 0.003
assert trade.calc_profit_ratio(rate=0.00000123) == -0.88863828 # Higher than open rate - 2.1 quote
assert trade.calc_profit_ratio(rate=2.1, fee=0.003) == round(0.04423940149625927, 8)
# Lower than open rate - 1.9 quote
assert trade.calc_profit_ratio(rate=1.9, fee=0.003) == round(-0.05521197007481293, 8)
# Test when we apply a Sell order. Sell higher than open rate @ 0.00001173 # Test when we apply a Sell order. Sell higher than open rate @ 2.2
trade.update(limit_sell_order) trade.update(limit_sell_order_usdt)
assert trade.calc_profit_ratio() == 0.06201058 assert trade.calc_profit_ratio() == round(0.0945137157107232, 8)
# Test with a custom fee rate on the close trade # Test with a custom fee rate on the close trade
assert trade.calc_profit_ratio(fee=0.003) == 0.06147824 assert trade.calc_profit_ratio(fee=0.003) == round(0.09396508728179565, 8)
trade.open_trade_value = 0.0 trade.open_trade_value = 0.0
assert trade.calc_profit_ratio(fee=0.003) == 0.0 assert trade.calc_profit_ratio(fee=0.003) == 0.0
@ -397,7 +540,7 @@ def test_clean_dry_run_db(default_conf, fee):
# Simulate dry_run entries # Simulate dry_run entries
trade = Trade( trade = Trade(
pair='ETH/BTC', pair='ADA/USDT',
stake_amount=0.001, stake_amount=0.001,
amount=123.0, amount=123.0,
fee_open=fee.return_value, fee_open=fee.return_value,
@ -664,9 +807,9 @@ def test_migrate_mid_state(mocker, default_conf, fee, caplog):
def test_adjust_stop_loss(fee): def test_adjust_stop_loss(fee):
trade = Trade( trade = Trade(
pair='ETH/BTC', pair='ADA/USDT',
stake_amount=0.001, stake_amount=30.0,
amount=5, amount=30,
fee_open=fee.return_value, fee_open=fee.return_value,
fee_close=fee.return_value, fee_close=fee.return_value,
exchange='binance', exchange='binance',
@ -716,9 +859,9 @@ def test_adjust_stop_loss(fee):
def test_adjust_min_max_rates(fee): def test_adjust_min_max_rates(fee):
trade = Trade( trade = Trade(
pair='ETH/BTC', pair='ADA/USDT',
stake_amount=0.001, stake_amount=30.0,
amount=5, amount=30.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',
@ -897,11 +1040,11 @@ def test_to_json(default_conf, fee):
def test_stoploss_reinitialization(default_conf, fee): def test_stoploss_reinitialization(default_conf, fee):
init_db(default_conf['db_url']) init_db(default_conf['db_url'])
trade = Trade( trade = Trade(
pair='ETH/BTC', pair='ADA/USDT',
stake_amount=0.001, stake_amount=30.0,
fee_open=fee.return_value, fee_open=fee.return_value,
open_date=arrow.utcnow().shift(hours=-2).datetime, open_date=arrow.utcnow().shift(hours=-2).datetime,
amount=10, amount=30.0,
fee_close=fee.return_value, fee_close=fee.return_value,
exchange='binance', exchange='binance',
open_rate=1, open_rate=1,
@ -956,11 +1099,11 @@ def test_stoploss_reinitialization(default_conf, fee):
def test_update_fee(fee): def test_update_fee(fee):
trade = Trade( trade = Trade(
pair='ETH/BTC', pair='ADA/USDT',
stake_amount=0.001, stake_amount=30.0,
fee_open=fee.return_value, fee_open=fee.return_value,
open_date=arrow.utcnow().shift(hours=-2).datetime, open_date=arrow.utcnow().shift(hours=-2).datetime,
amount=10, amount=30.0,
fee_close=fee.return_value, fee_close=fee.return_value,
exchange='binance', exchange='binance',
open_rate=1, open_rate=1,
@ -995,11 +1138,11 @@ def test_update_fee(fee):
def test_fee_updated(fee): def test_fee_updated(fee):
trade = Trade( trade = Trade(
pair='ETH/BTC', pair='ADA/USDT',
stake_amount=0.001, stake_amount=30.0,
fee_open=fee.return_value, fee_open=fee.return_value,
open_date=arrow.utcnow().shift(hours=-2).datetime, open_date=arrow.utcnow().shift(hours=-2).datetime,
amount=10, amount=30.0,
fee_close=fee.return_value, fee_close=fee.return_value,
exchange='binance', exchange='binance',
open_rate=1, open_rate=1,