diff --git a/freqtrade/main.py b/freqtrade/main.py
index f96718c6b..ae8561c96 100755
--- a/freqtrade/main.py
+++ b/freqtrade/main.py
@@ -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(),
diff --git a/freqtrade/persistence.py b/freqtrade/persistence.py
index d33f494e9..a30bf9bcf 100644
--- a/freqtrade/persistence.py
+++ b/freqtrade/persistence.py
@@ -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
diff --git a/freqtrade/tests/test_main.py b/freqtrade/tests/test_main.py
index c098c3dc0..cddf61f52 100644
--- a/freqtrade/tests/test_main.py
+++ b/freqtrade/tests/test_main.py
@@ -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
diff --git a/freqtrade/tests/test_telegram.py b/freqtrade/tests/test_telegram.py
index 109374321..7024aa282 100644
--- a/freqtrade/tests/test_telegram.py
+++ b/freqtrade/tests/test_telegram.py
@@ -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 'BTC_ETH\t10.55%
' in msg_mock.call_args_list[-1][0][0]
+ assert 'BTC_ETH\t10.05%
' in msg_mock.call_args_list[-1][0][0]
def test_start_handle(conf, update, mocker):