Most of the short tests work again

This commit is contained in:
Sam Germain 2021-07-04 03:13:11 -06:00
parent 6b20a315e3
commit 356ec4e44a
8 changed files with 801 additions and 854 deletions

View File

@ -88,8 +88,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,
timeframe, open_trade_value, close_profit_abs,
leverage, interest_rate,
liquidation_price, is_short
leverage, interest_rate, liquidation_price, is_short
)
select id, lower(exchange),
case
@ -118,8 +117,6 @@ def migrate_trades_table(decl_base, inspector, engine, table_back_name: str, col
from {table_back_name}
"""))
# TODO: Does leverage go in here?
def migrate_open_orders_to_trades(engine):
with engine.begin() as connection:

View File

@ -136,6 +136,7 @@ class Order(_DECL_BASE):
is_short = Column(Boolean, nullable=True, default=False)
def __repr__(self):
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})')
@ -229,7 +230,6 @@ class LocalTrade():
fee_close_currency: str = ''
open_rate: float = 0.0
open_rate_requested: Optional[float] = None
# open_trade_value - calculated via _calc_open_trade_value
open_trade_value: float = 0.0
close_rate: Optional[float] = None
@ -270,9 +270,15 @@ class LocalTrade():
leverage: float = None
@property
def borrowed(self):
if not self.is_short:
return self.amount * (self.leverage-1)/self.leverage
def has_no_leverage(self) -> bool:
return (self.leverage == 1.0 and not self.is_short) or self.leverage is None
@property
def borrowed(self) -> float:
if self.has_no_leverage:
return 0.0
elif not self.is_short:
return self.stake_amount * (self.leverage-1)
else:
return self.amount
@ -461,6 +467,10 @@ class LocalTrade():
"""
order_type = order['type']
if 'is_short' in order and order['side'] == 'sell':
# Only set's is_short on opening trades, ignores non-shorts
self.is_short = order['is_short']
# Ignore open and cancelled orders
if order['status'] == 'open' or safe_value_fallback(order, 'average', 'price') is None:
return
@ -469,10 +479,10 @@ class LocalTrade():
if order_type in ('market', 'limit') and self.is_opening_trade(order['side']):
# Update open rate and actual amount
self.open_rate = float(safe_value_fallback(order, 'average', 'price'))
self.amount = float(safe_value_fallback(order, 'filled', 'amount'))
if 'leverage' in order:
self.leverage = order['leverage']
self.recalc_open_trade_value()
if self.is_open:
payment = "SELL" if self.is_short else "BUY"
@ -481,7 +491,8 @@ class LocalTrade():
elif order_type in ('market', 'limit') and self.is_closing_trade(order['side']):
if self.is_open:
payment = "BUY" if self.is_short else "SELL"
# TODO: On Shorts technically your buying a little bit more than the amount because it's the ammount plus the interest
# TODO-mg: On Shorts technically your buying a little bit more than the amount because it's the ammount plus the interest
# But this wll only print the original
logger.info(f'{order_type.upper()}_{payment} has been fulfilled for {self}.')
self.close(safe_value_fallback(order, 'average', 'price')) # TODO: Double check this
elif order_type in ('stop_loss_limit', 'stop-loss', 'stop-loss-limit', 'stop'):
@ -576,7 +587,7 @@ class LocalTrade():
return zero
open_date = self.open_date.replace(tzinfo=None)
now = datetime.utcnow()
now = datetime.utcnow() # TODO-mg: Update to self.close_date
sec_per_hour = Decimal(3600)
total_seconds = Decimal((now - open_date).total_seconds())
hours = total_seconds/sec_per_hour or zero
@ -682,17 +693,15 @@ class LocalTrade():
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
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.has_no_leverage:
# 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
profit_ratio = (close_trade_value/self.open_trade_value) - 1
else:
if self.is_short:
profit_ratio = ((self.open_trade_value - close_trade_value) / self.stake_amount)
else:
profit_ratio = ((close_trade_value - self.open_trade_value) / self.stake_amount)
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.is_short:
profit_ratio = 1 - (close_trade_value/self.open_trade_value)
else:
profit_ratio = (close_trade_value/self.open_trade_value) - 1
return float(f"{profit_ratio:.8f}")
def select_order(self, order_side: str, is_open: Optional[bool]) -> Optional[Order]:

View File

@ -7,10 +7,12 @@ from datetime import datetime, timedelta
from functools import reduce
from pathlib import Path
from unittest.mock import MagicMock, Mock, PropertyMock
import arrow
import numpy as np
import pytest
from telegram import Chat, Message, Update
from freqtrade import constants
from freqtrade.commands import Arguments
from freqtrade.data.converter import ohlcv_to_dataframe
@ -23,7 +25,11 @@ from freqtrade.resolvers import ExchangeResolver
from freqtrade.worker import Worker
from tests.conftest_trades import (mock_trade_1, mock_trade_2, mock_trade_3, mock_trade_4,
mock_trade_5, mock_trade_6, short_trade, leverage_trade)
logging.getLogger('').setLevel(logging.INFO)
# Do not mask numpy errors as warnings that no one read, raise the exсeption
np.seterr(all='raise')
@ -63,6 +69,7 @@ def get_args(args):
def get_mock_coro(return_value):
async def mock_coro(*args, **kwargs):
return return_value
return Mock(wraps=mock_coro)
@ -85,6 +92,7 @@ def patch_exchange(mocker, api_mock=None, id='binance', mock_markets=True) -> No
if mock_markets:
mocker.patch('freqtrade.exchange.Exchange.markets',
PropertyMock(return_value=get_markets()))
if api_mock:
mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
else:
@ -118,6 +126,7 @@ def patch_edge(mocker) -> None:
# "LTC/BTC",
# "XRP/BTC",
# "NEO/BTC"
mocker.patch('freqtrade.edge.Edge._cached_pairs', mocker.PropertyMock(
return_value={
'NEO/BTC': PairInfo(-0.20, 0.66, 3.71, 0.50, 1.71, 10, 25),
@ -131,6 +140,7 @@ def get_patched_edge(mocker, config) -> Edge:
patch_edge(mocker)
edge = Edge(config)
return edge
# Functions for recurrent object patching
@ -191,6 +201,7 @@ def create_mock_trades(fee, use_db: bool = True):
Trade.query.session.add(trade)
else:
LocalTrade.add_bt_trade(trade)
# Simulate dry_run entries
trade = mock_trade_1(fee)
add_trade(trade)
@ -220,14 +231,19 @@ def create_mock_trades_with_leverage(fee, use_db: bool = True):
add_trade(trade)
trade = mock_trade_2(fee)
add_trade(trade)
trade = mock_trade_3(fee)
add_trade(trade)
trade = mock_trade_4(fee)
add_trade(trade)
trade = mock_trade_5(fee)
add_trade(trade)
trade = mock_trade_6(fee)
add_trade(trade)
trade = short_trade(fee)
add_trade(trade)
trade = leverage_trade(fee)
@ -243,6 +259,7 @@ def patch_coingekko(mocker) -> None:
:param mocker: mocker to patch coingekko class
:return: None
"""
tickermock = MagicMock(return_value={'bitcoin': {'usd': 12345.0}, 'ethereum': {'usd': 12345.0}})
listmock = MagicMock(return_value=[{'id': 'bitcoin', 'name': 'Bitcoin', 'symbol': 'btc',
'website_slug': 'bitcoin'},
@ -253,13 +270,13 @@ def patch_coingekko(mocker) -> None:
'freqtrade.rpc.fiat_convert.CoinGeckoAPI',
get_price=tickermock,
get_coins_list=listmock,
)
@pytest.fixture(scope='function')
def init_persistence(default_conf):
init_db(default_conf['db_url'], default_conf['dry_run'])
# TODO-mg: trade with leverage and/or borrowed?
@pytest.fixture(scope="function")
@ -924,17 +941,18 @@ def limit_sell_order_old():
@pytest.fixture
def limit_buy_order_old_partial():
return {'id': 'mocked_limit_buy_old_partial',
'type': 'limit',
'side': 'buy',
'symbol': 'ETH/BTC',
'datetime': arrow.utcnow().shift(minutes=-601).isoformat(),
'price': 0.00001099,
'amount': 90.99181073,
'filled': 23.0,
'remaining': 67.99181073,
'status': 'open'
}
return {
'id': 'mocked_limit_buy_old_partial',
'type': 'limit',
'side': 'buy',
'symbol': 'ETH/BTC',
'datetime': arrow.utcnow().shift(minutes=-601).isoformat(),
'price': 0.00001099,
'amount': 90.99181073,
'filled': 23.0,
'remaining': 67.99181073,
'status': 'open'
}
@pytest.fixture
@ -950,6 +968,7 @@ def limit_buy_order_canceled_empty(request):
# Indirect fixture
# Documentation:
# https://docs.pytest.org/en/latest/example/parametrize.html#apply-indirect-on-particular-arguments
exchange_name = request.param
if exchange_name == 'ftx':
return {
@ -1705,6 +1724,7 @@ def edge_conf(default_conf):
"max_trade_duration_minute": 1440,
"remove_pumps": False
}
return conf
@ -1742,7 +1762,6 @@ def rpc_balance():
'used': 0.0
},
}
# TODO-mg: Add shorts and leverage?
@pytest.fixture
@ -1762,9 +1781,12 @@ def import_fails() -> None:
if name in ["filelock", 'systemd.journal', 'uvloop']:
raise ImportError(f"No module named '{name}'")
return realimport(name, *args, **kwargs)
builtins.__import__ = mockedimport
# Run test - then cleanup
yield
# restore previous importfunction
builtins.__import__ = realimport
@ -2048,23 +2070,13 @@ def saved_hyperopt_results():
'is_best': False
}
]
for res in hyperopt_res:
res['results_metrics']['holding_avg_s'] = res['results_metrics']['holding_avg'
].total_seconds()
return hyperopt_res
# * Margin Tests
# TODO-mg: fill in these tests with something useful
@pytest.fixture
def ten_minutes_ago():
return datetime.utcnow() - timedelta(hours=0, minutes=10)
@pytest.fixture
def five_hours_ago():
return datetime.utcnow() - timedelta(hours=5, minutes=0)
@pytest.fixture(scope='function')
@ -2078,12 +2090,12 @@ def limit_short_order_open():
'timestamp': arrow.utcnow().int_timestamp,
'price': 0.00001173,
'amount': 90.99181073,
'borrowed': 90.99181073,
'leverage': 1.0,
'filled': 0.0,
'cost': 0.00106733393,
'remaining': 90.99181073,
'status': 'open',
'exchange': 'binance'
'is_short': True
}
@ -2097,11 +2109,10 @@ def limit_exit_short_order_open():
'datetime': arrow.utcnow().isoformat(),
'timestamp': arrow.utcnow().int_timestamp,
'price': 0.00001099,
'amount': 90.99181073,
'amount': 90.99370639272354,
'filled': 0.0,
'remaining': 90.99181073,
'status': 'open',
'exchange': 'binance'
'remaining': 90.99370639272354,
'status': 'open'
}
@ -2137,8 +2148,7 @@ def market_short_order():
'remaining': 0.0,
'status': 'closed',
'is_short': True,
# 'leverage': 3.0,
'exchange': 'kraken'
'leverage': 3.0
}
@ -2151,12 +2161,11 @@ def market_exit_short_order():
'symbol': 'mocked',
'datetime': arrow.utcnow().isoformat(),
'price': 0.00004099,
'amount': 275.97543219,
'filled': 275.97543219,
'amount': 276.113419906095,
'filled': 276.113419906095,
'remaining': 0.0,
'status': 'closed',
# 'leverage': 3.0,
'exchange': 'kraken'
'leverage': 3.0
}

View File

@ -3,7 +3,7 @@ from datetime import datetime, timedelta, timezone
from freqtrade.persistence.models import Order, Trade
MOCK_TRADE_COUNT = 6 # TODO-mg: Increase for short and leverage
MOCK_TRADE_COUNT = 6
def mock_order_1():

View File

@ -109,9 +109,6 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
'exchange': 'binance',
'leverage': None,
'borrowed': 0.0,
'borrowed_currency': None,
'collateral_currency': None,
'interest_rate': 0.0,
'liquidation_price': None,
'is_short': False,
@ -183,9 +180,6 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
'exchange': 'binance',
'leverage': None,
'borrowed': 0.0,
'borrowed_currency': None,
'collateral_currency': None,
'interest_rate': 0.0,
'liquidation_price': None,
'is_short': False,

View File

@ -105,27 +105,6 @@ def test_is_opening_closing_trade(fee):
assert trade.is_closing_trade('sell') == False
@pytest.mark.usefixtures("init_persistence")
def test_amount(limit_buy_order, limit_sell_order, fee, caplog):
trade = Trade(
id=2,
pair='ETH/BTC',
stake_amount=0.001,
open_rate=0.01,
amount=5,
is_open=True,
open_date=arrow.utcnow().datetime,
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='binance',
is_short=False
)
assert trade.amount == 5
trade.leverage = 3
assert trade.amount == 15
assert trade._amount == 5
@pytest.mark.usefixtures("init_persistence")
def test_update_with_binance(limit_buy_order, limit_sell_order, fee, caplog):
"""
@ -728,6 +707,7 @@ def test_migrate_new(mocker, default_conf, fee, caplog):
FOREIGN KEY(ft_trade_id) REFERENCES trades (id)
)
"""))
connection.execute(text("""
insert into orders ( id, ft_trade_id, ft_order_side, ft_pair, ft_is_open, order_id, status,
symbol, order_type, side, price, amount, filled, remaining, cost, order_date,
@ -978,9 +958,6 @@ def test_to_json(default_conf, fee):
'exchange': 'binance',
'leverage': None,
'borrowed': None,
'borrowed_currency': None,
'collateral_currency': None,
'interest_rate': None,
'liquidation_price': None,
'is_short': None,
@ -1051,9 +1028,6 @@ def test_to_json(default_conf, fee):
'exchange': 'binance',
'leverage': None,
'borrowed': None,
'borrowed_currency': None,
'collateral_currency': None,
'interest_rate': None,
'liquidation_price': None,
'is_short': None,
@ -1189,42 +1163,6 @@ def test_fee_updated(fee):
assert not trade.fee_updated('asfd')
@pytest.mark.usefixtures("init_persistence")
def test_update_leverage(fee, ten_minutes_ago):
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
amount=5,
open_rate=0.00001099,
open_date=ten_minutes_ago,
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='binance',
is_short=True,
interest_rate=0.0005
)
trade.leverage = 3.0
assert trade.borrowed == 15.0
assert trade.amount == 15.0
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
amount=5,
open_rate=0.00001099,
open_date=ten_minutes_ago,
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='binance',
is_short=False,
interest_rate=0.0005
)
trade.leverage = 5.0
assert trade.borrowed == 20.0
assert trade.amount == 25.0
@pytest.mark.usefixtures("init_persistence")
@pytest.mark.parametrize('use_db', [True, False])
def test_total_open_trades_stakes(fee, use_db):

View File

@ -14,7 +14,355 @@ from tests.conftest import create_mock_trades_with_leverage, log_has, log_has_re
@pytest.mark.usefixtures("init_persistence")
def test_update_with_binance(limit_leveraged_buy_order, limit_leveraged_sell_order, fee, ten_minutes_ago, caplog):
def test_interest_kraken(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
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
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
)
assert float(trade.calculate_interest()) == 3.7707443218227e-06
trade.open_date = datetime.utcnow() - timedelta(hours=5, minutes=0)
assert float(round(trade.calculate_interest(interest_rate=0.00025), 8)
) == round(2.3567152011391876e-06, 8)
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(), 8)
) == round(9.42686080455675e-06, 8)
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 8x 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:
91.99181073 * leverage(3) = 275.97543219 crypto
91.99181073 * leverage(5) = 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/24
interest: borrowed * interest_rate * time-periods
= 0.0075414886436454 * 0.0005 * 1/24 = 1.571143467426125e-07 base
= 0.0075414886436454 * 0.00025 * 5/24 = 3.9278586685653125e-07 base
= 0.0150829772872908 * 0.0005 * 5/24 = 1.571143467426125e-06 base
= 0.0150829772872908 * 0.00025 * 1/24 = 1.571143467426125e-07 base
"""
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
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='binance',
leverage=3.0,
interest_rate=0.0005
)
assert float(trade.calculate_interest()) == 1.571143467426125e-07
trade.open_date = datetime.utcnow() - timedelta(hours=5, minutes=0)
assert float(round(trade.calculate_interest(interest_rate=0.00025), 8)
) == 3.9278586685653125e-07
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
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=3.0,
interest_rate=0.0005
)
assert float(round(trade.calculate_interest(), 8)) == 1.571143467426125e-06
trade.open_date = datetime.utcnow() - timedelta(hours=0, minutes=10)
assert float(trade.calculate_interest(interest_rate=0.00025)) == 1.571143467426125e-07
@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,
interest_rate=0.0005,
leverage=3.0,
exchange='binance',
)
assert trade.open_order_id is None
assert trade.close_profit is None
assert trade.close_date is None
limit_leveraged_buy_order['status'] = 'open'
trade.update(limit_leveraged_buy_order)
assert trade.open_order_id is None
assert trade.close_profit is None
assert trade.close_date is None
@pytest.mark.usefixtures("init_persistence")
def test_calc_open_trade_value(market_leveraged_buy_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
"""
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
amount=5,
open_rate=0.00004099,
open_date=datetime.utcnow() - timedelta(hours=0, minutes=10),
fee_open=fee.return_value,
fee_close=fee.return_value,
interest_rate=0.0005,
exchange='kraken',
leverage=3
)
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
@pytest.mark.usefixtures("init_persistence")
def test_calc_open_close_trade_price(limit_leveraged_buy_order, limit_leveraged_sell_order, fee):
"""
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
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 - 2.0833333331722917e-07
= 0.00018628848193889054
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,
open_date=datetime.utcnow() - timedelta(hours=5, minutes=0),
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)
assert trade._calc_open_trade_value() == 0.0030074999997675204
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
assert round(trade.calc_close_trade_value(), 11) == round(0.003193996815039728, 11)
# Profit in BTC
assert round(trade.calc_profit(), 8) == round(0.18628848195329067, 8)
# Profit in percent
# assert round(trade.calc_profit_ratio(), 11) == round(0.05822425142973869, 11)
@pytest.mark.usefixtures("init_persistence")
def test_trade_close(fee):
"""
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
close_value: (amount_closed * close_rate) + (amount_closed * close_rate * fee)
= (15 * 0.2) - (15 * 0.2 * 0.0025)
= 2.9925
total_profit = close_value - open_value - interest
= 2.9925 - 1.50375 - 0.000625
= 1.4881250000000001
total_profit_percentage = total_profit / stake_amount
= 1.4881250000000001 / 0.5
= 2.9762500000000003
"""
trade = Trade(
pair='ETH/BTC',
stake_amount=0.1,
open_rate=0.01,
amount=5,
is_open=True,
fee_open=fee.return_value,
fee_close=fee.return_value,
open_date=datetime.utcnow() - timedelta(hours=5, minutes=0),
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
trade.close(0.02)
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")
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)
= (275.97543219 * 0.00001234) - (275.97543219 * 0.00001234 * 0.0025) = 0.0033970229911415386
= (275.97543219 * 0.00001234) - (275.97543219 * 0.00001234 * 0.003) = 0.0033953202227249265
= (275.97543219 * 0.00004173) - (275.97543219 * 0.00004173 * 0.005) = 0.011458872511362258
"""
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
amount=5,
open_rate=0.00001099,
fee_open=fee.return_value,
fee_close=fee.return_value,
open_date=datetime.utcnow() - timedelta(hours=0, minutes=10),
interest_rate=0.0005,
leverage=3.0,
exchange='kraken',
)
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.0033970229911415386)
# 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.0033953202227249265)
# 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.011458872511362258)
@pytest.mark.usefixtures("init_persistence")
def test_update_with_binance(limit_leveraged_buy_order, limit_leveraged_sell_order, fee, caplog):
"""
10 minute leveraged limit trade on binance at 3x leverage
@ -50,10 +398,10 @@ def test_update_with_binance(limit_leveraged_buy_order, limit_leveraged_sell_ord
open_rate=0.01,
amount=5,
is_open=True,
open_date=ten_minutes_ago,
open_date=datetime.utcnow() - timedelta(hours=0, minutes=10),
fee_open=fee.return_value,
fee_close=fee.return_value,
# borrowed=90.99181073,
leveage=3.0,
interest_rate=0.0005,
exchange='binance'
)
@ -61,7 +409,7 @@ def test_update_with_binance(limit_leveraged_buy_order, limit_leveraged_sell_ord
assert trade.close_profit is None
assert trade.close_date is None
assert trade.borrowed is None
assert trade.is_short is None
# trade.open_order_id = 'something'
trade.update(limit_leveraged_buy_order)
# assert trade.open_order_id is None
@ -69,7 +417,6 @@ def test_update_with_binance(limit_leveraged_buy_order, limit_leveraged_sell_ord
assert trade.close_profit is None
assert trade.close_date is None
assert trade.borrowed == 0.0019999999998453998
assert trade.is_short is True
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)
@ -86,7 +433,7 @@ def test_update_with_binance(limit_leveraged_buy_order, limit_leveraged_sell_ord
@pytest.mark.usefixtures("init_persistence")
def test_update_market_order(limit_leveraged_buy_order, limit_leveraged_sell_order, fee, ten_minutes_ago, caplog):
def test_update_market_order(limit_leveraged_buy_order, limit_leveraged_sell_order, fee, caplog):
"""
10 minute leveraged market trade on Kraken at 3x leverage
Short trade
@ -94,7 +441,7 @@ def test_update_market_order(limit_leveraged_buy_order, limit_leveraged_sell_ord
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
amount: = 275.97543219 crypto
stake_amount: 0.0037707443218227
borrowed: 0.0075414886436454 base
time-periods: 10 minutes(rounds up to 1 time-period of 4hrs)
@ -123,14 +470,13 @@ def test_update_market_order(limit_leveraged_buy_order, limit_leveraged_sell_ord
leverage=3,
fee_open=fee.return_value,
fee_close=fee.return_value,
open_date=ten_minutes_ago,
open_date=datetime.utcnow() - timedelta(hours=0, minutes=10),
interest_rate=0.0005,
exchange='kraken'
)
trade.open_order_id = 'something'
trade.update(limit_leveraged_buy_order)
assert trade.leverage == 3.0
assert trade.is_short == True
assert trade.open_order_id is None
assert trade.open_rate == 0.00004099
assert trade.close_profit is None
@ -157,116 +503,6 @@ def test_update_market_order(limit_leveraged_buy_order, limit_leveraged_sell_ord
caplog)
@pytest.mark.usefixtures("init_persistence")
def test_calc_open_close_trade_price(limit_leveraged_buy_order, limit_leveraged_sell_order, five_hours_ago, fee):
"""
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
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 - 2.0833333331722917e-07
= 0.00018628848193889054
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,
open_date=five_hours_ago,
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)
assert trade._calc_open_trade_value() == 0.0030074999997675204
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
assert round(trade.calc_close_trade_value(), 11) == round(0.003193996815039728, 11)
# Profit in BTC
assert round(trade.calc_profit(), 8) == round(0.18628848195329067, 8)
# Profit in percent
# assert round(trade.calc_profit_ratio(), 11) == round(0.05822425142973869, 11)
@pytest.mark.usefixtures("init_persistence")
def test_trade_close(fee, five_hours_ago):
"""
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
close_value: (amount_closed * close_rate) + (amount_closed * close_rate * fee)
= (15 * 0.2) - (15 * 0.2 * 0.0025)
= 2.9925
total_profit = close_value - open_value - interest
= 2.9925 - 1.50375 - 0.000625
= 1.4881250000000001
total_profit_percentage = total_profit / stake_amount
= 1.4881250000000001 / 0.5
= 2.9762500000000003
"""
trade = Trade(
pair='ETH/BTC',
stake_amount=0.1,
open_rate=0.01,
amount=5,
is_open=True,
fee_open=fee.return_value,
fee_close=fee.return_value,
open_date=five_hours_ago,
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
trade.close(0.02)
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")
def test_calc_close_trade_price_exception(limit_leveraged_buy_order, fee):
trade = Trade(
@ -278,7 +514,7 @@ def test_calc_close_trade_price_exception(limit_leveraged_buy_order, fee):
fee_close=fee.return_value,
exchange='binance',
interest_rate=0.0005,
borrowed=0.002
leverage=3.0
)
trade.open_order_id = 'something'
trade.update(limit_leveraged_buy_order)
@ -286,118 +522,7 @@ def test_calc_close_trade_price_exception(limit_leveraged_buy_order, fee):
@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,
interest_rate=0.0005,
borrowed=2.00,
exchange='binance',
)
assert trade.open_order_id is None
assert trade.close_profit is None
assert trade.close_date is None
limit_leveraged_buy_order['status'] = 'open'
trade.update(limit_leveraged_buy_order)
assert trade.open_order_id is None
assert trade.close_profit is None
assert trade.close_date is None
@pytest.mark.usefixtures("init_persistence")
def test_calc_open_trade_value(market_leveraged_buy_order, ten_minutes_ago, 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
"""
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
amount=5,
open_rate=0.00004099,
open_date=ten_minutes_ago,
fee_open=fee.return_value,
fee_close=fee.return_value,
interest_rate=0.0005,
exchange='kraken',
leverage=3
)
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
@pytest.mark.usefixtures("init_persistence")
def test_calc_close_trade_price(market_leveraged_buy_order, market_leveraged_sell_order, ten_minutes_ago, 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)
= (275.97543219 * 0.00001234) - (275.97543219 * 0.00001234 * 0.0025) = 0.0033970229911415386
= (275.97543219 * 0.00001234) - (275.97543219 * 0.00001234 * 0.003) = 0.0033953202227249265
= (275.97543219 * 0.00004173) - (275.97543219 * 0.00004173 * 0.005) = 0.011458872511362258
"""
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
amount=5,
open_rate=0.00001099,
fee_open=fee.return_value,
fee_close=fee.return_value,
open_date=ten_minutes_ago,
interest_rate=0.0005,
is_short=True,
leverage=3.0,
exchange='kraken',
)
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.0033970229911415386)
# 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.0033953202227249265)
# 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.011458872511362258)
@pytest.mark.usefixtures("init_persistence")
def test_calc_profit(market_leveraged_buy_order, market_leveraged_sell_order, ten_minutes_ago, five_hours_ago, fee):
def test_calc_profit(market_leveraged_buy_order, market_leveraged_sell_order, fee):
"""
# TODO: Update this one
Leveraged trade on Kraken at 3x leverage
@ -440,7 +565,7 @@ def test_calc_profit(market_leveraged_buy_order, market_leveraged_sell_order, te
stake_amount=0.0038388182617629,
amount=5,
open_rate=0.00004099,
open_date=ten_minutes_ago,
open_date=datetime.utcnow() - timedelta(hours=0, minutes=10),
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='kraken',
@ -458,7 +583,7 @@ def test_calc_profit(market_leveraged_buy_order, market_leveraged_sell_order, te
rate=0.00004374, interest_rate=0.0005) == round(0.9158215418394733, 8)
# Lower than open rate
trade.open_date = five_hours_ago
trade.open_date = datetime.utcnow() - timedelta(hours=5, minutes=0)
assert trade.calc_profit(
rate=0.00000437, interest_rate=0.00025) == round(-0.010137515940808145, 8)
assert trade.calc_profit_ratio(
@ -472,7 +597,7 @@ def test_calc_profit(market_leveraged_buy_order, market_leveraged_sell_order, te
interest_rate=0.0005) == round(0.9138549646255183, 8)
# Lower than open rate
trade.open_date = ten_minutes_ago
trade.open_date = datetime.utcnow() - timedelta(hours=0, minutes=10)
assert trade.calc_profit(rate=0.00000437, fee=0.003,
interest_rate=0.00025) == round(-0.01013811894712748, 8)
assert trade.calc_profit_ratio(rate=0.00000437, fee=0.003,
@ -486,131 +611,3 @@ def test_calc_profit(market_leveraged_buy_order, market_leveraged_sell_order, te
# 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
@pytest.mark.usefixtures("init_persistence")
def test_interest_kraken(market_leveraged_buy_order, ten_minutes_ago, five_hours_ago, fee):
"""
Market trade on Kraken at 3x and 8x 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:
91.99181073 * leverage(3) = 275.97543219 crypto
91.99181073 * leverage(5) = 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
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=91.99181073,
open_rate=0.00001099,
open_date=ten_minutes_ago,
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='kraken',
leverage=3.0,
interest_rate=0.0005
)
assert float(round(trade.calculate_interest(), 8)) == 3.7707443218227e-06
trade.open_date = five_hours_ago
assert float(round(trade.calculate_interest(interest_rate=0.00025), 8)
) == 2.3567152011391876e-06 # TODO: Fails with 0.08624233
trade = Trade(
pair='ETH/BTC',
stake_amount=0.0037707443218227,
amount=91.99181073,
open_rate=0.00001099,
open_date=five_hours_ago,
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='kraken',
is_short=True,
leverage=5.0,
interest_rate=0.0005
)
assert float(round(trade.calculate_interest(), 8)
) == 9.42686080455675e-06 # TODO: Fails with 0.28747445
trade.open_date = ten_minutes_ago
assert float(round(trade.calculate_interest(interest_rate=0.00025), 8)) == 3.7707443218227e-06
@pytest.mark.usefixtures("init_persistence")
def test_interest_binance(market_leveraged_buy_order, ten_minutes_ago, five_hours_ago, fee):
"""
Market trade on Kraken at 3x and 8x 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:
91.99181073 * leverage(3) = 275.97543219 crypto
91.99181073 * leverage(5) = 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/24
interest: borrowed * interest_rate * time-periods
= 0.0075414886436454 * 0.0005 * 1/24 = 1.571143467426125e-07 base
= 0.0075414886436454 * 0.00025 * 5/24 = 3.9278586685653125e-07 base
= 0.0150829772872908 * 0.0005 * 5/24 = 1.571143467426125e-06 base
= 0.0150829772872908 * 0.00025 * 1/24 = 1.571143467426125e-07 base
"""
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
amount=275.97543219,
open_rate=0.00001099,
open_date=ten_minutes_ago,
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='binance',
is_short=True,
borrowed=275.97543219,
interest_rate=0.0005
)
assert float(round(trade.calculate_interest(), 8)) == 1.571143467426125e-07
trade.open_date = five_hours_ago
assert float(round(trade.calculate_interest(interest_rate=0.00025), 8)
) == 3.9278586685653125e-07
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
amount=459.95905365,
open_rate=0.00001099,
open_date=five_hours_ago,
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='binance',
is_short=True,
borrowed=459.95905365,
interest_rate=0.0005
)
assert float(round(trade.calculate_interest(), 8)) == 1.571143467426125e-06
trade.open_date = ten_minutes_ago
assert float(round(trade.calculate_interest(interest_rate=0.00025), 8)) == 1.571143467426125e-07

View File

@ -14,7 +14,357 @@ from tests.conftest import create_mock_trades_with_leverage, log_has, log_has_re
@pytest.mark.usefixtures("init_persistence")
def test_update_with_binance(limit_short_order, limit_exit_short_order, fee, ten_minutes_ago, caplog):
def test_interest_kraken(market_short_order, fee):
"""
Market trade on Kraken at 3x and 8x leverage
Short trade
interest_rate: 0.05%, 0.25% per 4 hrs
open_rate: 0.00004173 base
close_rate: 0.00004099 base
amount:
275.97543219 crypto
459.95905365 crypto
borrowed:
275.97543219 crypto
459.95905365 crypto
time-periods: 10 minutes(rounds up to 1 time-period of 4hrs)
5 hours = 5/4
interest: borrowed * interest_rate * time-periods
= 275.97543219 * 0.0005 * 1 = 0.137987716095 crypto
= 275.97543219 * 0.00025 * 5/4 = 0.086242322559375 crypto
= 459.95905365 * 0.0005 * 5/4 = 0.28747440853125 crypto
= 459.95905365 * 0.00025 * 1 = 0.1149897634125 crypto
"""
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
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',
is_short=True,
leverage=3.0,
interest_rate=0.0005
)
assert float(round(trade.calculate_interest(), 8)) == round(0.137987716095, 8)
trade.open_date = datetime.utcnow() - timedelta(hours=5, minutes=0)
assert float(round(trade.calculate_interest(interest_rate=0.00025), 8)
) == round(0.086242322559375, 8)
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
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',
is_short=True,
leverage=5.0,
interest_rate=0.0005
)
assert float(round(trade.calculate_interest(), 8)) == round(0.28747440853125, 8)
trade.open_date = datetime.utcnow() - timedelta(hours=0, minutes=10)
assert float(round(trade.calculate_interest(interest_rate=0.00025), 8)
) == round(0.1149897634125, 8)
@ pytest.mark.usefixtures("init_persistence")
def test_interest_binance(market_short_order, fee):
"""
Market trade on Binance at 3x and 5x leverage
Short trade
interest_rate: 0.05%, 0.25% per 1 day
open_rate: 0.00004173 base
close_rate: 0.00004099 base
amount:
91.99181073 * leverage(3) = 275.97543219 crypto
91.99181073 * leverage(5) = 459.95905365 crypto
borrowed:
275.97543219 crypto
459.95905365 crypto
time-periods: 10 minutes(rounds up to 1/24 time-period of 1 day)
5 hours = 5/24
interest: borrowed * interest_rate * time-periods
= 275.97543219 * 0.0005 * 1/24 = 0.005749488170625 crypto
= 275.97543219 * 0.00025 * 5/24 = 0.0143737204265625 crypto
= 459.95905365 * 0.0005 * 5/24 = 0.047912401421875 crypto
= 459.95905365 * 0.00025 * 1/24 = 0.0047912401421875 crypto
"""
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
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='binance',
is_short=True,
leverage=3.0,
interest_rate=0.0005
)
assert float(round(trade.calculate_interest(), 8)) == 0.00574949
trade.open_date = datetime.utcnow() - timedelta(hours=5, minutes=0)
assert float(round(trade.calculate_interest(interest_rate=0.00025), 8)) == 0.01437372
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
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',
is_short=True,
leverage=5.0,
interest_rate=0.0005
)
assert float(round(trade.calculate_interest(), 8)) == 0.04791240
trade.open_date = datetime.utcnow() - timedelta(hours=0, minutes=10)
assert float(round(trade.calculate_interest(interest_rate=0.00025), 8)) == 0.00479124
@ pytest.mark.usefixtures("init_persistence")
def test_calc_open_trade_value(market_short_order, fee):
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
amount=5,
open_rate=0.00004173,
open_date=datetime.utcnow() - timedelta(hours=0, minutes=10),
fee_open=fee.return_value,
fee_close=fee.return_value,
interest_rate=0.0005,
is_short=True,
leverage=3.0,
exchange='kraken',
)
trade.open_order_id = 'open_trade'
trade.update(market_short_order) # Buy @ 0.00001099
# Get the open rate price with the standard fee rate
assert trade._calc_open_trade_value() == 0.011487663648325479
trade.fee_open = 0.003
# Get the open rate price with a custom fee rate
assert trade._calc_open_trade_value() == 0.011481905420932834
@ pytest.mark.usefixtures("init_persistence")
def test_update_open_order(limit_short_order):
trade = Trade(
pair='ETH/BTC',
stake_amount=1.00,
open_rate=0.01,
amount=5,
leverage=3.0,
fee_open=0.1,
fee_close=0.1,
interest_rate=0.0005,
is_short=True,
exchange='binance',
)
assert trade.open_order_id is None
assert trade.close_profit is None
assert trade.close_date is None
limit_short_order['status'] = 'open'
trade.update(limit_short_order)
assert trade.open_order_id is None
assert trade.close_profit is None
assert trade.close_date is None
@ pytest.mark.usefixtures("init_persistence")
def test_calc_close_trade_price_exception(limit_short_order, fee):
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
open_rate=0.1,
amount=15.0,
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='binance',
interest_rate=0.0005,
leverage=3.0,
is_short=True
)
trade.open_order_id = 'something'
trade.update(limit_short_order)
assert trade.calc_close_trade_value() == 0.0
@ pytest.mark.usefixtures("init_persistence")
def test_calc_close_trade_price(market_short_order, market_exit_short_order, fee):
"""
10 minute short market trade on Kraken at 3x leverage
Short trade
fee: 0.25% base
interest_rate: 0.05% per 4 hrs
open_rate: 0.00004173 base
close_rate: 0.00001234 base
amount: = 275.97543219 crypto
borrowed: 275.97543219 crypto
time-periods: 10 minutes(rounds up to 1 time-period of 4hrs)
interest: borrowed * interest_rate * time-periods
= 275.97543219 * 0.0005 * 1 = 0.137987716095 crypto
amount_closed: amount + interest = 275.97543219 + 0.137987716095 = 276.113419906095
close_value: (amount_closed * close_rate) + (amount_closed * close_rate * fee)
= (276.113419906095 * 0.00001234) + (276.113419906095 * 0.00001234 * 0.0025)
= 0.01134618380465571
"""
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
amount=5,
open_rate=0.00001099,
fee_open=fee.return_value,
fee_close=fee.return_value,
open_date=datetime.utcnow() - timedelta(hours=0, minutes=10),
interest_rate=0.0005,
is_short=True,
leverage=3.0,
exchange='kraken',
)
trade.open_order_id = 'close_trade'
trade.update(market_short_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.003415757700645315)
# 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.0034174613204461354)
# Test when we apply a Sell order, and ask price with a custom fee rate
trade.update(market_exit_short_order)
assert isclose(trade.calc_close_trade_value(fee=0.005), 0.011374478527360586)
@ pytest.mark.usefixtures("init_persistence")
def test_calc_open_close_trade_price(limit_short_order, limit_exit_short_order, fee):
"""
5 hour short trade on Binance
Short trade
fee: 0.25% base
interest_rate: 0.05% per day
open_rate: 0.00001173 base
close_rate: 0.00001099 base
amount: 90.99181073 crypto
borrowed: 90.99181073 crypto
stake_amount: 0.0010673339398629
time-periods: 5 hours = 5/24
interest: borrowed * interest_rate * time-periods
= 90.99181073 * 0.0005 * 5/24 = 0.009478313617708333 crypto
open_value: (amount * open_rate) - (amount * open_rate * fee)
= (90.99181073 * 0.00001173) - (90.99181073 * 0.00001173 * 0.0025)
= 0.0010646656050132426
amount_closed: amount + interest = 90.99181073 + 0.009478313617708333 = 91.0012890436177
close_value: (amount_closed * close_rate) + (amount_closed * close_rate * fee)
= (91.0012890436177 * 0.00001099) + (91.0012890436177 * 0.00001099 * 0.0025)
= 0.001002604427005832
total_profit = open_value - close_value
= 0.0010646656050132426 - 0.001002604427005832
= 0.00006206117800741065
total_profit_percentage = (close_value - open_value) / stake_amount
= (0.0010646656050132426 - 0.0010025208853391716)/0.0010673339398629
= 0.05822425142973869
"""
trade = Trade(
pair='ETH/BTC',
stake_amount=0.0010673339398629,
open_rate=0.01,
amount=5,
open_date=datetime.utcnow() - timedelta(hours=5, minutes=0),
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='binance',
interest_rate=0.0005
)
trade.open_order_id = 'something'
trade.update(limit_short_order)
assert trade._calc_open_trade_value() == 0.0010646656050132426
trade.update(limit_exit_short_order)
# Will be slightly different due to slight changes in compilation time, and the fact that interest depends on time
assert round(trade.calc_close_trade_value(), 11) == round(0.001002604427005832, 11)
# Profit in BTC
assert round(trade.calc_profit(), 8) == round(0.00006206117800741065, 8)
# Profit in percent
# assert round(trade.calc_profit_ratio(), 11) == round(0.05822425142973869, 11)
@ pytest.mark.usefixtures("init_persistence")
def test_trade_close(fee):
"""
Five hour short trade on Kraken at 3x leverage
Short trade
Exchange: Kraken
fee: 0.25% base
interest_rate: 0.05% per 4 hours
open_rate: 0.02 base
close_rate: 0.01 base
leverage: 3.0
amount: 15 crypto
borrowed: 15 crypto
time-periods: 5 hours = 5/4
interest: borrowed * interest_rate * time-periods
= 15 * 0.0005 * 5/4 = 0.009375 crypto
open_value: (amount * open_rate) - (amount * open_rate * fee)
= (15 * 0.02) - (15 * 0.02 * 0.0025)
= 0.29925
amount_closed: amount + interest = 15 + 0.009375 = 15.009375
close_value: (amount_closed * close_rate) + (amount_closed * close_rate * fee)
= (15.009375 * 0.01) + (15.009375 * 0.01 * 0.0025)
= 0.150468984375
total_profit = open_value - close_value
= 0.29925 - 0.150468984375
= 0.148781015625
total_profit_percentage = total_profit / stake_amount
= 0.148781015625 / 0.1
= 1.4878101562500001
"""
trade = Trade(
pair='ETH/BTC',
stake_amount=0.1,
open_rate=0.02,
amount=15,
is_open=True,
fee_open=fee.return_value,
fee_close=fee.return_value,
open_date=datetime.utcnow() - timedelta(hours=5, minutes=0),
exchange='kraken',
is_short=True,
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
trade.close(0.01)
assert trade.is_open is False
assert trade.close_profit == round(1.4878101562500001, 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")
def test_update_with_binance(limit_short_order, limit_exit_short_order, fee, caplog):
"""
10 minute short limit trade on binance
@ -40,7 +390,7 @@ def test_update_with_binance(limit_short_order, limit_exit_short_order, fee, ten
= 0.0010646656050132426 - 0.0010025208853391716
= 0.00006214471967407108
total_profit_percentage = (close_value - open_value) / stake_amount
= (0.0010646656050132426 - 0.0010025208853391716) / 0.0010673339398629
= 0.00006214471967407108 / 0.0010673339398629
= 0.05822425142973869
"""
@ -51,16 +401,17 @@ def test_update_with_binance(limit_short_order, limit_exit_short_order, fee, ten
open_rate=0.01,
amount=5,
is_open=True,
open_date=ten_minutes_ago,
open_date=datetime.utcnow() - timedelta(hours=0, minutes=10),
fee_open=fee.return_value,
fee_close=fee.return_value,
leverage=3.0,
# borrowed=90.99181073,
interest_rate=0.0005,
exchange='binance'
)
# assert trade.open_order_id is None
assert trade.close_profit is None
assert trade.close_date is None
assert trade.borrowed == 0.0
assert trade.is_short is None
# trade.open_order_id = 'something'
trade.update(limit_short_order)
@ -85,12 +436,11 @@ def test_update_with_binance(limit_short_order, limit_exit_short_order, fee, ten
caplog)
@pytest.mark.usefixtures("init_persistence")
@ pytest.mark.usefixtures("init_persistence")
def test_update_market_order(
market_short_order,
market_exit_short_order,
fee,
ten_minutes_ago,
caplog
):
"""
@ -129,7 +479,7 @@ def test_update_market_order(
is_open=True,
fee_open=fee.return_value,
fee_close=fee.return_value,
open_date=ten_minutes_ago,
open_date=datetime.utcnow() - timedelta(hours=0, minutes=10),
leverage=3.0,
interest_rate=0.0005,
exchange='kraken'
@ -164,234 +514,8 @@ def test_update_market_order(
# caplog)
@pytest.mark.usefixtures("init_persistence")
def test_calc_open_close_trade_price(limit_short_order, limit_exit_short_order, five_hours_ago, fee):
"""
5 hour short trade on Binance
Short trade
fee: 0.25% base
interest_rate: 0.05% per day
open_rate: 0.00001173 base
close_rate: 0.00001099 base
amount: 90.99181073 crypto
borrowed: 90.99181073 crypto
stake_amount: 0.0010673339398629
time-periods: 5 hours = 5/24
interest: borrowed * interest_rate * time-periods
= 90.99181073 * 0.0005 * 5/24 = 0.009478313617708333 crypto
open_value: (amount * open_rate) - (amount * open_rate * fee)
= (90.99181073 * 0.00001173) - (90.99181073 * 0.00001173 * 0.0025)
= 0.0010646656050132426
amount_closed: amount + interest = 90.99181073 + 0.009478313617708333 = 91.0012890436177
close_value: (amount_closed * close_rate) + (amount_closed * close_rate * fee)
= (91.0012890436177 * 0.00001099) + (91.0012890436177 * 0.00001099 * 0.0025)
= 0.001002604427005832
total_profit = open_value - close_value
= 0.0010646656050132426 - 0.001002604427005832
= 0.00006206117800741065
total_profit_percentage = (close_value - open_value) / stake_amount
= (0.0010646656050132426 - 0.0010025208853391716)/0.0010673339398629
= 0.05822425142973869
"""
trade = Trade(
pair='ETH/BTC',
stake_amount=0.0010673339398629,
open_rate=0.01,
amount=5,
open_date=five_hours_ago,
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='binance',
interest_rate=0.0005
)
trade.open_order_id = 'something'
trade.update(limit_short_order)
assert trade._calc_open_trade_value() == 0.0010646656050132426
trade.update(limit_exit_short_order)
# Will be slightly different due to slight changes in compilation time, and the fact that interest depends on time
assert round(trade.calc_close_trade_value(), 11) == round(0.001002604427005832, 11)
# Profit in BTC
assert round(trade.calc_profit(), 8) == round(0.00006206117800741065, 8)
# Profit in percent
# assert round(trade.calc_profit_ratio(), 11) == round(0.05822425142973869, 11)
@pytest.mark.usefixtures("init_persistence")
def test_trade_close(fee, five_hours_ago):
"""
Five hour short trade on Kraken at 3x leverage
Short trade
Exchange: Kraken
fee: 0.25% base
interest_rate: 0.05% per 4 hours
open_rate: 0.02 base
close_rate: 0.01 base
leverage: 3.0
amount: 15 crypto
borrowed: 15 crypto
time-periods: 5 hours = 5/4
interest: borrowed * interest_rate * time-periods
= 15 * 0.0005 * 5/4 = 0.009375 crypto
open_value: (amount * open_rate) - (amount * open_rate * fee)
= (15 * 0.02) - (15 * 0.02 * 0.0025)
= 0.29925
amount_closed: amount + interest = 15 + 0.009375 = 15.009375
close_value: (amount_closed * close_rate) + (amount_closed * close_rate * fee)
= (15.009375 * 0.01) + (15.009375 * 0.01 * 0.0025)
= 0.150468984375
total_profit = open_value - close_value
= 0.29925 - 0.150468984375
= 0.148781015625
total_profit_percentage = total_profit / stake_amount
= 0.148781015625 / 0.1
= 1.4878101562500001
"""
trade = Trade(
pair='ETH/BTC',
stake_amount=0.1,
open_rate=0.02,
amount=5,
is_open=True,
fee_open=fee.return_value,
fee_close=fee.return_value,
open_date=five_hours_ago,
exchange='kraken',
is_short=True,
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
trade.close(0.01)
assert trade.is_open is False
assert trade.close_profit == round(1.4878101562500001, 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")
def test_calc_close_trade_price_exception(limit_short_order, fee):
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
open_rate=0.1,
amount=15.0,
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='binance',
interest_rate=0.0005,
leverage=3.0,
is_short=True
)
trade.open_order_id = 'something'
trade.update(limit_short_order)
assert trade.calc_close_trade_value() == 0.0
@pytest.mark.usefixtures("init_persistence")
def test_update_open_order(limit_short_order):
trade = Trade(
pair='ETH/BTC',
stake_amount=1.00,
open_rate=0.01,
amount=5,
leverage=3.0,
fee_open=0.1,
fee_close=0.1,
interest_rate=0.0005,
is_short=True,
exchange='binance',
)
assert trade.open_order_id is None
assert trade.close_profit is None
assert trade.close_date is None
limit_short_order['status'] = 'open'
trade.update(limit_short_order)
assert trade.open_order_id is None
assert trade.close_profit is None
assert trade.close_date is None
@pytest.mark.usefixtures("init_persistence")
def test_calc_open_trade_value(market_short_order, ten_minutes_ago, fee):
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
amount=5,
open_rate=0.00004173,
open_date=ten_minutes_ago,
fee_open=fee.return_value,
fee_close=fee.return_value,
interest_rate=0.0005,
is_short=True,
leverage=3.0,
exchange='kraken',
)
trade.open_order_id = 'open_trade'
trade.update(market_short_order) # Buy @ 0.00001099
# Get the open rate price with the standard fee rate
assert trade._calc_open_trade_value() == 0.011487663648325479
trade.fee_open = 0.003
# Get the open rate price with a custom fee rate
assert trade._calc_open_trade_value() == 0.011481905420932834
@pytest.mark.usefixtures("init_persistence")
def test_calc_close_trade_price(market_short_order, market_exit_short_order, ten_minutes_ago, fee):
"""
10 minute short market trade on Kraken at 3x leverage
Short trade
fee: 0.25% base
interest_rate: 0.05% per 4 hrs
open_rate: 0.00004173 base
close_rate: 0.00001234 base
amount: = 275.97543219 crypto
borrowed: 275.97543219 crypto
time-periods: 10 minutes(rounds up to 1 time-period of 4hrs)
interest: borrowed * interest_rate * time-periods
= 275.97543219 * 0.0005 * 1 = 0.137987716095 crypto
amount_closed: amount + interest = 275.97543219 + 0.137987716095 = 276.113419906095
close_value: (amount_closed * close_rate) + (amount_closed * close_rate * fee)
= (276.113419906095 * 0.00001234) + (276.113419906095 * 0.00001234 * 0.0025)
= 0.01134618380465571
"""
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
amount=5,
open_rate=0.00001099,
fee_open=fee.return_value,
fee_close=fee.return_value,
open_date=ten_minutes_ago,
interest_rate=0.0005,
is_short=True,
leverage=3.0,
exchange='kraken',
)
trade.open_order_id = 'close_trade'
trade.update(market_short_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.003415757700645315)
# 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.0034174613204461354)
# Test when we apply a Sell order, and ask price with a custom fee rate
trade.update(market_exit_short_order)
assert isclose(trade.calc_close_trade_value(fee=0.005), 0.011374478527360586)
@pytest.mark.usefixtures("init_persistence")
def test_calc_profit(market_short_order, market_exit_short_order, ten_minutes_ago, five_hours_ago, fee):
@ pytest.mark.usefixtures("init_persistence")
def test_calc_profit(market_short_order, market_exit_short_order, fee):
"""
Market trade on Kraken at 3x leverage
Short trade
@ -439,7 +563,7 @@ def test_calc_profit(market_short_order, market_exit_short_order, ten_minutes_ag
stake_amount=0.0038388182617629,
amount=5,
open_rate=0.00001099,
open_date=ten_minutes_ago,
open_date=datetime.utcnow() - timedelta(hours=0, minutes=10),
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='kraken',
@ -457,7 +581,7 @@ def test_calc_profit(market_short_order, market_exit_short_order, ten_minutes_ag
rate=0.00004374, interest_rate=0.0005) == round(-0.16143779115744006, 8)
# Lower than open rate
trade.open_date = five_hours_ago
trade.open_date = datetime.utcnow() - timedelta(hours=5, minutes=0)
assert trade.calc_profit(rate=0.00000437, interest_rate=0.00025) == round(0.01027826, 8)
assert trade.calc_profit_ratio(
rate=0.00000437, interest_rate=0.00025) == round(2.677453699564163, 8)
@ -470,7 +594,7 @@ def test_calc_profit(market_short_order, market_exit_short_order, ten_minutes_ag
interest_rate=0.0005) == round(-0.16340506919482353, 8)
# Lower than open rate
trade.open_date = ten_minutes_ago
trade.open_date = datetime.utcnow() - timedelta(hours=0, minutes=10)
assert trade.calc_profit(rate=0.00000437, fee=0.003,
interest_rate=0.00025) == round(0.01027773, 8)
assert trade.calc_profit_ratio(rate=0.00000437, fee=0.003,
@ -486,129 +610,6 @@ def test_calc_profit(market_short_order, market_exit_short_order, ten_minutes_ag
# assert trade.calc_profit_ratio(fee=0.003) == 0.06147824
@pytest.mark.usefixtures("init_persistence")
def test_interest_kraken(market_short_order, ten_minutes_ago, five_hours_ago, fee):
"""
Market trade on Kraken at 3x and 8x leverage
Short trade
interest_rate: 0.05%, 0.25% per 4 hrs
open_rate: 0.00004173 base
close_rate: 0.00004099 base
amount:
275.97543219 crypto
459.95905365 crypto
borrowed:
275.97543219 crypto
459.95905365 crypto
time-periods: 10 minutes(rounds up to 1 time-period of 4hrs)
5 hours = 5/4
interest: borrowed * interest_rate * time-periods
= 275.97543219 * 0.0005 * 1 = 0.137987716095 crypto
= 275.97543219 * 0.00025 * 5/4 = 0.086242322559375 crypto
= 459.95905365 * 0.0005 * 5/4 = 0.28747440853125 crypto
= 459.95905365 * 0.00025 * 1 = 0.1149897634125 crypto
"""
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
amount=275.97543219,
open_rate=0.00001099,
open_date=ten_minutes_ago,
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='kraken',
is_short=True,
leverage=3.0,
interest_rate=0.0005
)
assert float(round(trade.calculate_interest(), 8)) == 0.13798772
trade.open_date = five_hours_ago
assert float(round(trade.calculate_interest(interest_rate=0.00025), 8)
) == 0.08624232 # TODO: Fails with 0.08624233
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
amount=459.95905365,
open_rate=0.00001099,
open_date=five_hours_ago,
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='kraken',
is_short=True,
leverage=5.0,
interest_rate=0.0005
)
assert float(round(trade.calculate_interest(), 8)) == 0.28747441 # TODO: Fails with 0.28747445
trade.open_date = ten_minutes_ago
assert float(round(trade.calculate_interest(interest_rate=0.00025), 8)) == 0.11498976
@pytest.mark.usefixtures("init_persistence")
def test_interest_binance(market_short_order, ten_minutes_ago, five_hours_ago, fee):
"""
Market trade on Binance at 3x and 5x leverage
Short trade
interest_rate: 0.05%, 0.25% per 1 day
open_rate: 0.00004173 base
close_rate: 0.00004099 base
amount:
91.99181073 * leverage(3) = 275.97543219 crypto
91.99181073 * leverage(5) = 459.95905365 crypto
borrowed:
275.97543219 crypto
459.95905365 crypto
time-periods: 10 minutes(rounds up to 1/24 time-period of 1 day)
5 hours = 5/24
interest: borrowed * interest_rate * time-periods
= 275.97543219 * 0.0005 * 1/24 = 0.005749488170625 crypto
= 275.97543219 * 0.00025 * 5/24 = 0.0143737204265625 crypto
= 459.95905365 * 0.0005 * 5/24 = 0.047912401421875 crypto
= 459.95905365 * 0.00025 * 1/24 = 0.0047912401421875 crypto
"""
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
amount=275.97543219,
open_rate=0.00001099,
open_date=ten_minutes_ago,
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='binance',
is_short=True,
leverage=3.0,
interest_rate=0.0005
)
assert float(round(trade.calculate_interest(), 8)) == 0.00574949
trade.open_date = five_hours_ago
assert float(round(trade.calculate_interest(interest_rate=0.00025), 8)) == 0.01437372
trade = Trade(
pair='ETH/BTC',
stake_amount=0.001,
amount=459.95905365,
open_rate=0.00001099,
open_date=five_hours_ago,
fee_open=fee.return_value,
fee_close=fee.return_value,
exchange='binance',
is_short=True,
leverage=5.0,
interest_rate=0.0005
)
assert float(round(trade.calculate_interest(), 8)) == 0.04791240
trade.open_date = ten_minutes_ago
assert float(round(trade.calculate_interest(interest_rate=0.00025), 8)) == 0.00479124
def test_adjust_stop_loss(fee):
trade = Trade(
pair='ETH/BTC',
@ -654,11 +655,13 @@ def test_adjust_stop_loss(fee):
assert trade.initial_stop_loss == 1.05
assert trade.initial_stop_loss_pct == 0.05
assert trade.stop_loss_pct == 0.1
trade.liquidation_price == 1.03
# TODO-mg: Do a test with a trade that has a liquidation price
@pytest.mark.usefixtures("init_persistence")
@pytest.mark.parametrize('use_db', [True, False])
@ pytest.mark.usefixtures("init_persistence")
@ pytest.mark.parametrize('use_db', [True, False])
def test_get_open(fee, use_db):
Trade.use_db = use_db
Trade.reset_trades()
@ -722,8 +725,8 @@ def test_stoploss_reinitialization(default_conf, fee):
assert trade_adj.initial_stop_loss_pct == 0.04
@pytest.mark.usefixtures("init_persistence")
@pytest.mark.parametrize('use_db', [True, False])
@ pytest.mark.usefixtures("init_persistence")
@ pytest.mark.parametrize('use_db', [True, False])
def test_total_open_trades_stakes(fee, use_db):
Trade.use_db = use_db
Trade.reset_trades()
@ -735,7 +738,7 @@ def test_total_open_trades_stakes(fee, use_db):
Trade.use_db = True
@pytest.mark.usefixtures("init_persistence")
@ pytest.mark.usefixtures("init_persistence")
def test_get_best_pair(fee):
res = Trade.get_best_pair()
assert res is None