Merge pull request #200 from glonlas/fix_fees_calculation
Fix the fee calculation
This commit is contained in:
@@ -15,7 +15,7 @@ def default_conf():
|
||||
configuration = {
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "BTC",
|
||||
"stake_amount": 0.05,
|
||||
"stake_amount": 0.001,
|
||||
"dry_run": True,
|
||||
"minimal_roi": {
|
||||
"40": 0.0,
|
||||
@@ -61,9 +61,27 @@ def update():
|
||||
@pytest.fixture
|
||||
def ticker():
|
||||
return MagicMock(return_value={
|
||||
'bid': 0.07256061,
|
||||
'ask': 0.072661,
|
||||
'last': 0.07256061,
|
||||
'bid': 0.00001098,
|
||||
'ask': 0.00001099,
|
||||
'last': 0.00001098,
|
||||
})
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def ticker_sell_up():
|
||||
return MagicMock(return_value={
|
||||
'bid': 0.00001172,
|
||||
'ask': 0.00001173,
|
||||
'last': 0.00001172,
|
||||
})
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def ticker_sell_down():
|
||||
return MagicMock(return_value={
|
||||
'bid': 0.00001044,
|
||||
'ask': 0.00001043,
|
||||
'last': 0.00001044,
|
||||
})
|
||||
|
||||
|
||||
@@ -104,8 +122,8 @@ def limit_buy_order():
|
||||
'type': 'LIMIT_BUY',
|
||||
'pair': 'mocked',
|
||||
'opened': datetime.utcnow(),
|
||||
'rate': 0.07256061,
|
||||
'amount': 206.43811673387373,
|
||||
'rate': 0.00001099,
|
||||
'amount': 90.99181073,
|
||||
'remaining': 0.0,
|
||||
'closed': datetime.utcnow(),
|
||||
}
|
||||
@@ -118,8 +136,8 @@ def limit_sell_order():
|
||||
'type': 'LIMIT_SELL',
|
||||
'pair': 'mocked',
|
||||
'opened': datetime.utcnow(),
|
||||
'rate': 0.0802134,
|
||||
'amount': 206.43811673387373,
|
||||
'rate': 0.00001173,
|
||||
'amount': 90.99181073,
|
||||
'remaining': 0.0,
|
||||
'closed': datetime.utcnow(),
|
||||
}
|
||||
|
@@ -40,8 +40,8 @@ def test_process_trade_creation(default_conf, ticker, health, mocker):
|
||||
assert trade.is_open
|
||||
assert trade.open_date is not None
|
||||
assert trade.exchange == Exchanges.BITTREX.name
|
||||
assert trade.open_rate == 0.072661
|
||||
assert trade.amount == 0.6881270557795791
|
||||
assert trade.open_rate == 0.00001099
|
||||
assert trade.amount == 90.99181073703367
|
||||
|
||||
|
||||
def test_process_exchange_failures(default_conf, ticker, health, mocker):
|
||||
@@ -115,11 +115,11 @@ def test_create_trade(default_conf, ticker, limit_buy_order, mocker):
|
||||
whitelist = copy.deepcopy(default_conf['exchange']['pair_whitelist'])
|
||||
|
||||
init(default_conf, create_engine('sqlite://'))
|
||||
create_trade(15.0)
|
||||
create_trade(0.001)
|
||||
|
||||
trade = Trade.query.first()
|
||||
assert trade is not None
|
||||
assert trade.stake_amount == 15.0
|
||||
assert trade.stake_amount == 0.001
|
||||
assert trade.is_open
|
||||
assert trade.open_date is not None
|
||||
assert trade.exchange == Exchanges.BITTREX.name
|
||||
@@ -127,8 +127,8 @@ def test_create_trade(default_conf, ticker, limit_buy_order, mocker):
|
||||
# Simulate fulfilled LIMIT_BUY order for trade
|
||||
trade.update(limit_buy_order)
|
||||
|
||||
assert trade.open_rate == 0.07256061
|
||||
assert trade.amount == 206.43811673387373
|
||||
assert trade.open_rate == 0.00001099
|
||||
assert trade.amount == 90.99181073
|
||||
|
||||
assert whitelist == default_conf['exchange']['pair_whitelist']
|
||||
|
||||
@@ -186,14 +186,14 @@ def test_handle_trade(default_conf, limit_buy_order, limit_sell_order, mocker):
|
||||
mocker.patch.multiple('freqtrade.main.exchange',
|
||||
validate_pairs=MagicMock(),
|
||||
get_ticker=MagicMock(return_value={
|
||||
'bid': 0.17256061,
|
||||
'ask': 0.172661,
|
||||
'last': 0.17256061
|
||||
'bid': 0.00001172,
|
||||
'ask': 0.00001173,
|
||||
'last': 0.00001172
|
||||
}),
|
||||
buy=MagicMock(return_value='mocked_limit_buy'),
|
||||
sell=MagicMock(return_value='mocked_limit_sell'))
|
||||
init(default_conf, create_engine('sqlite://'))
|
||||
create_trade(15.0)
|
||||
create_trade(0.001)
|
||||
|
||||
trade = Trade.query.first()
|
||||
assert trade
|
||||
@@ -207,8 +207,9 @@ def test_handle_trade(default_conf, limit_buy_order, limit_sell_order, mocker):
|
||||
# Simulate fulfilled LIMIT_SELL order for trade
|
||||
trade.update(limit_sell_order)
|
||||
|
||||
assert trade.close_rate == 0.0802134
|
||||
assert trade.close_profit == 0.10046755
|
||||
assert trade.close_rate == 0.00001173
|
||||
assert trade.close_profit == 0.06201057
|
||||
assert trade.calc_profit() == 0.00006217
|
||||
assert trade.close_date is not None
|
||||
|
||||
|
||||
@@ -223,7 +224,7 @@ def test_close_trade(default_conf, ticker, limit_buy_order, limit_sell_order, mo
|
||||
|
||||
# Create trade and sell it
|
||||
init(default_conf, create_engine('sqlite://'))
|
||||
create_trade(15.0)
|
||||
create_trade(0.001)
|
||||
|
||||
trade = Trade.query.first()
|
||||
assert trade
|
||||
|
@@ -5,11 +5,38 @@ from freqtrade.exchange import Exchanges
|
||||
from freqtrade.persistence import Trade
|
||||
|
||||
|
||||
def test_update(limit_buy_order, limit_sell_order):
|
||||
def test_update_with_bittrex(limit_buy_order, limit_sell_order):
|
||||
"""
|
||||
On this test we will buy and sell a crypto currency.
|
||||
|
||||
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(
|
||||
pair='BTC_ETH',
|
||||
stake_amount=1.00,
|
||||
fee=0.1,
|
||||
stake_amount=0.001,
|
||||
fee=0.0025,
|
||||
exchange=Exchanges.BITTREX,
|
||||
)
|
||||
assert trade.open_order_id is None
|
||||
@@ -20,18 +47,40 @@ def test_update(limit_buy_order, limit_sell_order):
|
||||
trade.open_order_id = 'something'
|
||||
trade.update(limit_buy_order)
|
||||
assert trade.open_order_id is None
|
||||
assert trade.open_rate == 0.07256061
|
||||
assert trade.open_rate == 0.00001099
|
||||
assert trade.close_profit is None
|
||||
assert trade.close_date is None
|
||||
|
||||
trade.open_order_id = 'something'
|
||||
trade.update(limit_sell_order)
|
||||
assert trade.open_order_id is None
|
||||
assert trade.open_rate == 0.07256061
|
||||
assert trade.close_profit == 0.00546755
|
||||
assert trade.close_rate == 0.00001173
|
||||
assert trade.close_profit == 0.06201057
|
||||
assert trade.close_date is not None
|
||||
|
||||
|
||||
def test_calc_open_close_trade_price(limit_buy_order, limit_sell_order):
|
||||
trade = Trade(
|
||||
pair='BTC_ETH',
|
||||
stake_amount=0.001,
|
||||
fee=0.0025,
|
||||
exchange=Exchanges.BITTREX,
|
||||
)
|
||||
|
||||
trade.open_order_id = 'something'
|
||||
trade.update(limit_buy_order)
|
||||
assert trade.calc_open_trade_price() == 0.001002500
|
||||
|
||||
trade.update(limit_sell_order)
|
||||
assert trade.calc_close_trade_price() == 0.0010646656
|
||||
|
||||
# Profit in BTC
|
||||
assert trade.calc_profit() == 0.00006217
|
||||
|
||||
# Profit in percent
|
||||
assert trade.calc_profit_percent() == 0.06201057
|
||||
|
||||
|
||||
def test_update_open_order(limit_buy_order):
|
||||
trade = Trade(
|
||||
pair='BTC_ETH',
|
||||
@@ -64,3 +113,103 @@ def test_update_invalid_order(limit_buy_order):
|
||||
limit_buy_order['type'] = 'invalid'
|
||||
with pytest.raises(ValueError, match=r'Unknown order type'):
|
||||
trade.update(limit_buy_order)
|
||||
|
||||
|
||||
def test_calc_open_trade_price(limit_buy_order):
|
||||
trade = Trade(
|
||||
pair='BTC_ETH',
|
||||
stake_amount=0.001,
|
||||
fee=0.0025,
|
||||
exchange=Exchanges.BITTREX,
|
||||
)
|
||||
trade.open_order_id = 'open_trade'
|
||||
trade.update(limit_buy_order) # Buy @ 0.00001099
|
||||
|
||||
# Get the open rate price with the standard fee rate
|
||||
assert trade.calc_open_trade_price() == 0.001002500
|
||||
|
||||
# Get the open rate price with a custom fee rate
|
||||
assert trade.calc_open_trade_price(fee=0.003) == 0.001003000
|
||||
|
||||
|
||||
def test_calc_close_trade_price(limit_buy_order, limit_sell_order):
|
||||
trade = Trade(
|
||||
pair='BTC_ETH',
|
||||
stake_amount=0.001,
|
||||
fee=0.0025,
|
||||
exchange=Exchanges.BITTREX,
|
||||
)
|
||||
trade.open_order_id = 'close_trade'
|
||||
trade.update(limit_buy_order) # Buy @ 0.00001099
|
||||
|
||||
# Get the close rate price with a custom close rate and a regular fee rate
|
||||
assert trade.calc_close_trade_price(rate=0.00001234) == 0.0011200318
|
||||
|
||||
# Get the close rate price with a custom close rate and a custom fee rate
|
||||
assert trade.calc_close_trade_price(rate=0.00001234, fee=0.003) == 0.0011194704
|
||||
|
||||
# Test when we apply a Sell order, and ask price with a custom fee rate
|
||||
trade.update(limit_sell_order)
|
||||
assert trade.calc_close_trade_price(fee=0.005) == 0.0010619972
|
||||
|
||||
|
||||
def test_calc_profit(limit_buy_order, limit_sell_order):
|
||||
trade = Trade(
|
||||
pair='BTC_ETH',
|
||||
stake_amount=0.001,
|
||||
fee=0.0025,
|
||||
exchange=Exchanges.BITTREX,
|
||||
)
|
||||
trade.open_order_id = 'profit_percent'
|
||||
trade.update(limit_buy_order) # Buy @ 0.00001099
|
||||
|
||||
# Custom closing rate and regular fee rate
|
||||
# Higher than open rate
|
||||
assert trade.calc_profit(rate=0.00001234) == 0.00011753
|
||||
# Lower than open rate
|
||||
assert trade.calc_profit(rate=0.00000123) == -0.00089086
|
||||
|
||||
# Custom closing rate and custom fee rate
|
||||
# Higher than open rate
|
||||
assert trade.calc_profit(rate=0.00001234, fee=0.003) == 0.00011697
|
||||
# Lower than open rate
|
||||
assert trade.calc_profit(rate=0.00000123, fee=0.003) == -0.00089092
|
||||
|
||||
# Only custom fee without sell order applied
|
||||
with pytest.raises(TypeError):
|
||||
trade.calc_profit(fee=0.003)
|
||||
|
||||
# Test when we apply a Sell order. Sell higher than open rate @ 0.00001173
|
||||
trade.update(limit_sell_order)
|
||||
assert trade.calc_profit() == 0.00006217
|
||||
|
||||
# Test with a custom fee rate on the close trade
|
||||
assert trade.calc_profit(fee=0.003) == 0.00006163
|
||||
|
||||
|
||||
def test_calc_profit_percent(limit_buy_order, limit_sell_order):
|
||||
trade = Trade(
|
||||
pair='BTC_ETH',
|
||||
stake_amount=0.001,
|
||||
fee=0.0025,
|
||||
exchange=Exchanges.BITTREX,
|
||||
)
|
||||
trade.open_order_id = 'profit_percent'
|
||||
trade.update(limit_buy_order) # Buy @ 0.00001099
|
||||
|
||||
# Get percent of profit with a custom rate (Higher than open rate)
|
||||
assert trade.calc_profit_percent(rate=0.00001234) == 0.1172387
|
||||
|
||||
# Get percent of profit with a custom rate (Lower than open rate)
|
||||
assert trade.calc_profit_percent(rate=0.00000123) == -0.88863827
|
||||
|
||||
# Only custom fee without sell order applied
|
||||
with pytest.raises(TypeError):
|
||||
trade.calc_profit_percent(fee=0.003)
|
||||
|
||||
# Test when we apply a Sell order. Sell higher than open rate @ 0.00001173
|
||||
trade.update(limit_sell_order)
|
||||
assert trade.calc_profit_percent() == 0.06201057
|
||||
|
||||
# Test with a custom fee rate on the close trade
|
||||
assert trade.calc_profit_percent(fee=0.003) == 0.0614782
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# pragma pylint: disable=missing-docstring, too-many-arguments, too-many-ancestors, C0103
|
||||
import re
|
||||
from datetime import datetime, date
|
||||
from datetime import datetime
|
||||
from random import randint
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
@@ -102,7 +102,7 @@ def test_status_handle(default_conf, update, ticker, mocker):
|
||||
msg_mock.reset_mock()
|
||||
|
||||
# Create some test data
|
||||
create_trade(15.0)
|
||||
create_trade(0.001)
|
||||
# Trigger status while we have a fulfilled order for the open trade
|
||||
_status(bot=MagicMock(), update=update)
|
||||
|
||||
@@ -151,7 +151,8 @@ def test_status_table_handle(default_conf, update, ticker, mocker):
|
||||
assert msg_mock.call_count == 1
|
||||
|
||||
|
||||
def test_profit_handle(default_conf, update, ticker, limit_buy_order, limit_sell_order, mocker):
|
||||
def test_profit_handle(
|
||||
default_conf, update, ticker, ticker_sell_up, limit_buy_order, limit_sell_order, mocker):
|
||||
mocker.patch.dict('freqtrade.main._CONF', default_conf)
|
||||
mocker.patch('freqtrade.main.get_signal', side_effect=lambda s, t: True)
|
||||
msg_mock = MagicMock()
|
||||
@@ -171,7 +172,7 @@ def test_profit_handle(default_conf, update, ticker, limit_buy_order, limit_sell
|
||||
msg_mock.reset_mock()
|
||||
|
||||
# Create some test data
|
||||
create_trade(15.0)
|
||||
create_trade(0.001)
|
||||
trade = Trade.query.first()
|
||||
|
||||
# Simulate fulfilled LIMIT_BUY order for trade
|
||||
@@ -182,7 +183,10 @@ def test_profit_handle(default_conf, update, ticker, limit_buy_order, limit_sell
|
||||
assert 'no closed trade' in msg_mock.call_args_list[-1][0][0]
|
||||
msg_mock.reset_mock()
|
||||
|
||||
# Simulate fulfilled LIMIT_SELL order for trade
|
||||
# Update the ticker with a market going up
|
||||
mocker.patch.multiple('freqtrade.main.exchange',
|
||||
validate_pairs=MagicMock(),
|
||||
get_ticker=ticker_sell_up)
|
||||
trade.update(limit_sell_order)
|
||||
|
||||
trade.close_date = datetime.utcnow()
|
||||
@@ -190,11 +194,12 @@ def test_profit_handle(default_conf, update, ticker, limit_buy_order, limit_sell
|
||||
|
||||
_profit(bot=MagicMock(), update=update)
|
||||
assert msg_mock.call_count == 1
|
||||
assert '*ROI All trades:* `0.00765279 BTC (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]
|
||||
assert '*ROI Trade closed:* `0.00006217 BTC (6.20%)`' in msg_mock.call_args_list[-1][0][0]
|
||||
assert '*ROI All trades:* `0.00006217 BTC (6.20%)`' in msg_mock.call_args_list[-1][0][0]
|
||||
assert 'Best Performing:* `BTC_ETH: 6.20%`' in msg_mock.call_args_list[-1][0][0]
|
||||
|
||||
|
||||
def test_forcesell_handle(default_conf, update, ticker, mocker):
|
||||
def test_forcesell_handle(default_conf, update, ticker, ticker_sell_up, mocker):
|
||||
mocker.patch.dict('freqtrade.main._CONF', default_conf)
|
||||
mocker.patch('freqtrade.main.get_signal', side_effect=lambda s, t: True)
|
||||
rpc_mock = mocker.patch('freqtrade.main.rpc.send_msg', MagicMock())
|
||||
@@ -208,7 +213,44 @@ def test_forcesell_handle(default_conf, update, ticker, mocker):
|
||||
init(default_conf, create_engine('sqlite://'))
|
||||
|
||||
# Create some test data
|
||||
create_trade(15.0)
|
||||
create_trade(0.001)
|
||||
|
||||
trade = Trade.query.first()
|
||||
assert trade
|
||||
|
||||
# Increase the price and sell it
|
||||
mocker.patch.multiple('freqtrade.main.exchange',
|
||||
validate_pairs=MagicMock(),
|
||||
get_ticker=ticker_sell_up)
|
||||
|
||||
update.message.text = '/forcesell 1'
|
||||
_forcesell(bot=MagicMock(), update=update)
|
||||
|
||||
assert rpc_mock.call_count == 2
|
||||
assert 'Selling [BTC/ETH]' in rpc_mock.call_args_list[-1][0][0]
|
||||
assert '0.00001172 (profit: ~6.11%, 0.00006126)' in rpc_mock.call_args_list[-1][0][0]
|
||||
|
||||
|
||||
def test_forcesell_down_handle(default_conf, update, ticker, ticker_sell_down, mocker):
|
||||
mocker.patch.dict('freqtrade.main._CONF', default_conf)
|
||||
mocker.patch('freqtrade.main.get_signal', side_effect=lambda s, t: True)
|
||||
rpc_mock = mocker.patch('freqtrade.main.rpc.send_msg', MagicMock())
|
||||
mocker.patch.multiple('freqtrade.rpc.telegram',
|
||||
_CONF=default_conf,
|
||||
init=MagicMock(),
|
||||
send_msg=MagicMock())
|
||||
mocker.patch.multiple('freqtrade.main.exchange',
|
||||
validate_pairs=MagicMock(),
|
||||
get_ticker=ticker)
|
||||
init(default_conf, create_engine('sqlite://'))
|
||||
|
||||
# Create some test data
|
||||
create_trade(0.001)
|
||||
|
||||
# Decrease the price and sell it
|
||||
mocker.patch.multiple('freqtrade.main.exchange',
|
||||
validate_pairs=MagicMock(),
|
||||
get_ticker=ticker_sell_down)
|
||||
|
||||
trade = Trade.query.first()
|
||||
assert trade
|
||||
@@ -218,7 +260,7 @@ def test_forcesell_handle(default_conf, update, ticker, mocker):
|
||||
|
||||
assert rpc_mock.call_count == 2
|
||||
assert 'Selling [BTC/ETH]' in rpc_mock.call_args_list[-1][0][0]
|
||||
assert '0.07256061 (profit: ~-0.64%)' in rpc_mock.call_args_list[-1][0][0]
|
||||
assert '0.00001044 (profit: ~-5.48%, -0.00005492)' in rpc_mock.call_args_list[-1][0][0]
|
||||
|
||||
|
||||
def test_exec_forcesell_open_orders(default_conf, ticker, mocker):
|
||||
@@ -260,7 +302,7 @@ def test_forcesell_all_handle(default_conf, update, ticker, mocker):
|
||||
|
||||
# Create some test data
|
||||
for _ in range(4):
|
||||
create_trade(15.0)
|
||||
create_trade(0.001)
|
||||
rpc_mock.reset_mock()
|
||||
|
||||
update.message.text = '/forcesell all'
|
||||
@@ -268,7 +310,7 @@ def test_forcesell_all_handle(default_conf, update, ticker, mocker):
|
||||
|
||||
assert rpc_mock.call_count == 4
|
||||
for args in rpc_mock.call_args_list:
|
||||
assert '0.07256061 (profit: ~-0.64%)' in args[0][0]
|
||||
assert '0.00001098 (profit: ~-0.59%, -0.00000591)' in args[0][0]
|
||||
|
||||
|
||||
def test_forcesell_handle_invalid(default_conf, update, mocker):
|
||||
@@ -323,7 +365,7 @@ def test_performance_handle(
|
||||
init(default_conf, create_engine('sqlite://'))
|
||||
|
||||
# Create some test data
|
||||
create_trade(15.0)
|
||||
create_trade(0.001)
|
||||
trade = Trade.query.first()
|
||||
assert trade
|
||||
|
||||
@@ -339,7 +381,7 @@ def test_performance_handle(
|
||||
_performance(bot=MagicMock(), update=update)
|
||||
assert msg_mock.call_count == 1
|
||||
assert 'Performance' in msg_mock.call_args_list[0][0][0]
|
||||
assert '<code>BTC_ETH\t10.05%</code>' in msg_mock.call_args_list[0][0][0]
|
||||
assert '<code>BTC_ETH\t6.20%</code>' in msg_mock.call_args_list[0][0][0]
|
||||
|
||||
|
||||
def test_daily_handle(
|
||||
@@ -358,7 +400,7 @@ def test_daily_handle(
|
||||
init(default_conf, create_engine('sqlite://'))
|
||||
|
||||
# Create some test data
|
||||
create_trade(15.0)
|
||||
create_trade(0.001)
|
||||
trade = Trade.query.first()
|
||||
assert trade
|
||||
|
||||
@@ -371,14 +413,14 @@ def test_daily_handle(
|
||||
trade.close_date = datetime.utcnow()
|
||||
trade.is_open = False
|
||||
|
||||
# try valid data
|
||||
update.message.text = '/daily 7'
|
||||
# Try valid data
|
||||
update.message.text = '/daily 2'
|
||||
_daily(bot=MagicMock(), update=update)
|
||||
assert msg_mock.call_count == 1
|
||||
assert 'Daily' in msg_mock.call_args_list[0][0][0]
|
||||
assert str(date.today()) + ' 1.50701325 BTC' in msg_mock.call_args_list[0][0][0]
|
||||
assert str(datetime.utcnow().date()) + ' 0.00006217 BTC' in msg_mock.call_args_list[0][0][0]
|
||||
|
||||
# try invalid data
|
||||
# Try invalid data
|
||||
msg_mock.reset_mock()
|
||||
update_state(State.RUNNING)
|
||||
update.message.text = '/daily -2'
|
||||
@@ -409,7 +451,7 @@ def test_count_handle(default_conf, update, ticker, mocker):
|
||||
update_state(State.RUNNING)
|
||||
|
||||
# Create some test data
|
||||
create_trade(15.0)
|
||||
create_trade(0.001)
|
||||
msg_mock.reset_mock()
|
||||
_count(bot=MagicMock(), update=update)
|
||||
|
||||
|
Reference in New Issue
Block a user