add fee to sqlalchemy model and respecting it in calc_profit

This commit is contained in:
gcarq 2017-11-01 02:20:55 +01:00
parent 41510fdb32
commit cd18629433
4 changed files with 14 additions and 13 deletions

View File

@ -182,11 +182,12 @@ def create_trade(stake_amount: float) -> Optional[Trade]:
else:
return None
# Calculate amount and subtract fee
fee = exchange.get_fee()
buy_limit = get_target_bid(exchange.get_ticker(pair))
# TODO: apply fee to amount and also consider it for profit calculations
amount = stake_amount / buy_limit
order_id = exchange.buy(pair, buy_limit, amount)
amount = (1 - fee) * stake_amount / buy_limit
order_id = exchange.buy(pair, buy_limit, amount)
# Create trade entity and return
message = '*{}:* Buying [{}]({}) with limit `{:f}`'.format(
exchange.get_name().upper(),
@ -196,9 +197,11 @@ def create_trade(stake_amount: float) -> Optional[Trade]:
)
logger.info(message)
telegram.send_msg(message)
# Fee is applied twice because we make a LIMIT_BUY and LIMIT_SELL
return Trade(pair=pair,
stake_amount=stake_amount,
amount=amount,
fee=fee * 2,
open_rate=buy_limit,
open_date=datetime.utcnow(),
exchange=exchange.get_name().upper(),

View File

@ -54,10 +54,11 @@ class Trade(Base):
exchange = Column(String, nullable=False)
pair = Column(String, nullable=False)
is_open = Column(Boolean, nullable=False, default=True)
fee = Column(Float, nullable=False, default=0.0)
open_rate = Column(Float)
close_rate = Column(Float)
close_profit = Column(Float)
stake_amount = Column(Float, name='btc_amount', nullable=False)
stake_amount = Column(Float, nullable=False)
amount = Column(Float)
open_date = Column(DateTime, nullable=False, default=datetime.utcnow)
close_date = Column(DateTime)
@ -95,14 +96,11 @@ class Trade(Base):
self.open_order_id = None
# Flush changes
Trade.session.flush()
def calc_profit(self, rate: float=None) -> float:
"""
Calculates the profit in percentage.
Calculates the profit in percentage (including fee).
:param rate: rate to compare with (optional).
If rate is not set self.close_rate will be used
:return: profit in percentage as float
"""
return (rate or self.close_rate - self.open_rate) / self.open_rate
return (rate or self.close_rate - self.open_rate) / self.open_rate - self.fee

View File

@ -128,7 +128,7 @@ def test_handle_trade(conf, mocker):
})
assert trade.close_rate == 0.17256061
assert trade.close_profit == 1.3748724900565639
assert trade.close_profit == 1.369872490056564
assert trade.close_date is not None

View File

@ -152,8 +152,8 @@ def test_profit_handle(conf, update, mocker):
_profit(bot=MagicBot(), update=update)
assert msg_mock.call_count == 2
assert '*ROI:* `1.582013 (10.55%)`' in msg_mock.call_args_list[-1][0][0]
assert 'Best Performing:* `BTC_ETH: 10.55%`' in msg_mock.call_args_list[-1][0][0]
assert '*ROI:* `1.507013 (10.05%)`' in msg_mock.call_args_list[-1][0][0]
assert 'Best Performing:* `BTC_ETH: 10.05%`' in msg_mock.call_args_list[-1][0][0]
def test_forcesell_handle(conf, update, mocker):
@ -249,7 +249,7 @@ def test_performance_handle(conf, update, mocker):
_performance(bot=MagicBot(), update=update)
assert msg_mock.call_count == 2
assert 'Performance' in msg_mock.call_args_list[-1][0][0]
assert '<code>BTC_ETH\t10.55%</code>' in msg_mock.call_args_list[-1][0][0]
assert '<code>BTC_ETH\t10.05%</code>' in msg_mock.call_args_list[-1][0][0]
def test_start_handle(conf, update, mocker):