remove Test classes and use pytest fixtures

This commit is contained in:
Janne Sinivirta 2017-10-01 11:02:47 +03:00
parent 53b4c3722e
commit 06ad311aa3
5 changed files with 288 additions and 302 deletions

View File

@ -1,7 +1,7 @@
# pragma pylint: disable=missing-docstring # pragma pylint: disable=missing-docstring
import unittest
from unittest.mock import patch from unittest.mock import patch
import pytest
import arrow import arrow
from pandas import DataFrame from pandas import DataFrame
@ -19,34 +19,30 @@ RESULT_BITTREX = {
] ]
} }
class TestAnalyze(unittest.TestCase): @pytest.fixture
def setUp(self): def result():
self.result = parse_ticker_dataframe(RESULT_BITTREX['result'], arrow.get('2017-08-30T10:00:00')) return parse_ticker_dataframe(RESULT_BITTREX['result'], arrow.get('2017-08-30T10:00:00'))
def test_1_dataframe_has_correct_columns(self): def test_1_dataframe_has_correct_columns(result):
assert self.result.columns.tolist() == \ assert result.columns.tolist() == \
['close', 'high', 'low', 'open', 'date', 'volume'] ['close', 'high', 'low', 'open', 'date', 'volume']
def test_2_orders_by_date(self): def test_2_orders_by_date(result):
assert self.result['date'].tolist() == \ assert result['date'].tolist() == \
['2017-08-30T10:34:00', ['2017-08-30T10:34:00',
'2017-08-30T10:37:00', '2017-08-30T10:37:00',
'2017-08-30T10:40:00', '2017-08-30T10:40:00',
'2017-08-30T10:42:00'] '2017-08-30T10:42:00']
def test_3_populates_buy_trend(self): def test_3_populates_buy_trend(result):
dataframe = populate_buy_trend(populate_indicators(self.result)) dataframe = populate_buy_trend(populate_indicators(result))
assert 'buy' in dataframe.columns assert 'buy' in dataframe.columns
assert 'buy_price' in dataframe.columns assert 'buy_price' in dataframe.columns
def test_4_returns_latest_buy_signal(self): def test_4_returns_latest_buy_signal():
buydf = DataFrame([{'buy': 1, 'date': arrow.utcnow()}]) buydf = DataFrame([{'buy': 1, 'date': arrow.utcnow()}])
with patch('freqtrade.analyze.analyze_ticker', return_value=buydf): with patch('freqtrade.analyze.analyze_ticker', return_value=buydf):
assert get_buy_signal('BTC-ETH') == True assert get_buy_signal('BTC-ETH') == True
buydf = DataFrame([{'buy': 0, 'date': arrow.utcnow()}]) buydf = DataFrame([{'buy': 0, 'date': arrow.utcnow()}])
with patch('freqtrade.analyze.analyze_ticker', return_value=buydf): with patch('freqtrade.analyze.analyze_ticker', return_value=buydf):
assert get_buy_signal('BTC-ETH') == False assert get_buy_signal('BTC-ETH') == False
if __name__ == '__main__':
unittest.main()

View File

@ -2,9 +2,9 @@
import json import json
import logging import logging
import os import os
import unittest
from unittest.mock import patch from unittest.mock import patch
import pytest
import arrow import arrow
from pandas import DataFrame from pandas import DataFrame
@ -12,6 +12,7 @@ from freqtrade.analyze import analyze_ticker
from freqtrade.main import should_sell from freqtrade.main import should_sell
from freqtrade.persistence import Trade from freqtrade.persistence import Trade
logging.disable(logging.DEBUG) # disable debug logs that slow backtesting a lot
def print_results(results): def print_results(results):
print('Made {} buys. Average profit {:.2f}%. Total profit was {:.3f}. Average duration {:.1f} mins.'.format( print('Made {} buys. Average profit {:.2f}%. Total profit was {:.3f}. Average duration {:.1f} mins.'.format(
@ -21,9 +22,14 @@ def print_results(results):
results.duration.mean()*5 results.duration.mean()*5
)) ))
class TestMain(unittest.TestCase): @pytest.fixture
pairs = ['btc-neo', 'btc-eth', 'btc-omg', 'btc-edg', 'btc-pay', 'btc-pivx', 'btc-qtum', 'btc-mtl', 'btc-etc', 'btc-ltc'] def pairs():
conf = { return ['btc-neo', 'btc-eth', 'btc-omg', 'btc-edg', 'btc-pay',
'btc-pivx', 'btc-qtum', 'btc-mtl', 'btc-etc', 'btc-ltc']
@pytest.fixture
def conf():
return {
"minimal_roi": { "minimal_roi": {
"60": 0.0, "60": 0.0,
"40": 0.01, "40": 0.01,
@ -33,43 +39,40 @@ class TestMain(unittest.TestCase):
"stoploss": -0.40 "stoploss": -0.40
} }
@classmethod
def setUpClass(cls):
logging.disable(logging.DEBUG) # disable debug logs that slow backtesting a lot
@unittest.skipIf(not os.environ.get('BACKTEST', False), "slow, should be run manually") @pytest.mark.skipif(not os.environ.get('BACKTEST', False), reason="BACKTEST not set")
def test_backtest(self): def test_backtest(conf, pairs):
trades = [] trades = []
with patch.dict('freqtrade.main._CONF', self.conf): with patch.dict('freqtrade.main._CONF', conf):
for pair in self.pairs: for pair in pairs:
with open('testdata/'+pair+'.json') as data_file: with open('tests/testdata/'+pair+'.json') as data_file:
data = json.load(data_file) data = json.load(data_file)
with patch('freqtrade.analyze.get_ticker', return_value=data): with patch('freqtrade.analyze.get_ticker', return_value=data):
with patch('arrow.utcnow', return_value=arrow.get('2017-08-20T14:50:00')): with patch('arrow.utcnow', return_value=arrow.get('2017-08-20T14:50:00')):
ticker = analyze_ticker(pair) ticker = analyze_ticker(pair)
# for each buy point # for each buy point
for index, row in ticker[ticker.buy == 1].iterrows(): for index, row in ticker[ticker.buy == 1].iterrows():
trade = Trade( trade = Trade(
open_rate=row['close'], open_rate=row['close'],
open_date=arrow.get(row['date']).datetime, open_date=arrow.get(row['date']).datetime,
amount=1, amount=1,
) )
# calculate win/lose forwards from buy point # calculate win/lose forwards from buy point
for index2, row2 in ticker[index:].iterrows(): for index2, row2 in ticker[index:].iterrows():
if should_sell(trade, row2['close'], arrow.get(row2['date']).datetime): if should_sell(trade, row2['close'], arrow.get(row2['date']).datetime):
current_profit = (row2['close'] - trade.open_rate) / trade.open_rate current_profit = (row2['close'] - trade.open_rate) / trade.open_rate
trades.append((pair, current_profit, index2 - index)) trades.append((pair, current_profit, index2 - index))
break break
labels = ['currency', 'profit', 'duration'] labels = ['currency', 'profit', 'duration']
results = DataFrame.from_records(trades, columns=labels) results = DataFrame.from_records(trades, columns=labels)
print('====================== BACKTESTING REPORT ================================') print('====================== BACKTESTING REPORT ================================')
for pair in self.pairs: for pair in pairs:
print('For currency {}:'.format(pair)) print('For currency {}:'.format(pair))
print_results(results[results.currency == pair]) print_results(results[results.currency == pair])
print('TOTAL OVER ALL TRADES:') print('TOTAL OVER ALL TRADES:')
print_results(results) print_results(results)

View File

@ -1,7 +1,7 @@
import unittest import copy
from unittest.mock import patch, MagicMock, call from unittest.mock import patch, MagicMock, call
import copy import pytest
from jsonschema import validate from jsonschema import validate
from freqtrade import exchange from freqtrade import exchange
@ -11,8 +11,9 @@ from freqtrade.misc import CONF_SCHEMA
from freqtrade.persistence import Trade from freqtrade.persistence import Trade
class TestMain(unittest.TestCase): @pytest.fixture
conf = { def conf():
configuration = {
"max_open_trades": 3, "max_open_trades": 3,
"stake_currency": "BTC", "stake_currency": "BTC",
"stake_amount": 0.05, "stake_amount": 0.05,
@ -42,86 +43,80 @@ class TestMain(unittest.TestCase):
"chat_id": "chat_id" "chat_id": "chat_id"
} }
} }
validate(configuration, CONF_SCHEMA)
return configuration
def test_1_create_trade(self): def test_1_create_trade(conf):
with patch.dict('freqtrade.main._CONF', self.conf): with patch.dict('freqtrade.main._CONF', conf):
with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True) as buy_signal: with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True) as buy_signal:
with patch.multiple('freqtrade.main.telegram', init=MagicMock(), send_msg=MagicMock()):
with patch.multiple('freqtrade.main.exchange',
get_ticker=MagicMock(return_value={
'bid': 0.07256061,
'ask': 0.072661,
'last': 0.07256061
}),
buy=MagicMock(return_value='mocked_order_id')):
# Save state of current whitelist
whitelist = copy.deepcopy(self.conf['bittrex']['pair_whitelist'])
init(self.conf, 'sqlite://')
for pair in ['BTC_ETH', 'BTC_TKN', 'BTC_TRST', 'BTC_SWT']:
trade = create_trade(15.0, exchange.Exchange.BITTREX)
Trade.session.add(trade)
Trade.session.flush()
assert trade is not None
assert trade.open_rate == 0.072661
assert trade.pair == pair
assert trade.exchange == exchange.Exchange.BITTREX
assert trade.amount == 206.43811673387373
assert trade.stake_amount == 15.0
assert trade.is_open == True
assert trade.open_date is not None
assert whitelist == self.conf['bittrex']['pair_whitelist']
buy_signal.assert_has_calls(
[call('BTC_ETH'), call('BTC_TKN'), call('BTC_TRST'), call('BTC_SWT')]
)
def test_2_handle_trade(self):
with patch.dict('freqtrade.main._CONF', self.conf):
with patch.multiple('freqtrade.main.telegram', init=MagicMock(), send_msg=MagicMock()): with patch.multiple('freqtrade.main.telegram', init=MagicMock(), send_msg=MagicMock()):
with patch.multiple('freqtrade.main.exchange', with patch.multiple('freqtrade.main.exchange',
get_ticker=MagicMock(return_value={ get_ticker=MagicMock(return_value={
'bid': 0.17256061, 'bid': 0.07256061,
'ask': 0.172661, 'ask': 0.072661,
'last': 0.17256061 'last': 0.07256061
}), }),
buy=MagicMock(return_value='mocked_order_id')): buy=MagicMock(return_value='mocked_order_id')):
trade = Trade.query.filter(Trade.is_open.is_(True)).first() # Save state of current whitelist
assert trade whitelist = copy.deepcopy(conf['bittrex']['pair_whitelist'])
handle_trade(trade)
assert trade.close_rate == 0.17256061
assert trade.close_profit == 137.4872490056564
assert trade.close_date is not None
assert trade.open_order_id == 'dry_run'
def test_3_close_trade(self): init(conf, 'sqlite://')
with patch.dict('freqtrade.main._CONF', self.conf): for pair in ['BTC_ETH', 'BTC_TKN', 'BTC_TRST', 'BTC_SWT']:
trade = Trade.query.filter(Trade.is_open.is_(True)).first() trade = create_trade(15.0, exchange.Exchange.BITTREX)
assert trade Trade.session.add(trade)
Trade.session.flush()
assert trade is not None
assert trade.open_rate == 0.072661
assert trade.pair == pair
assert trade.exchange == exchange.Exchange.BITTREX
assert trade.amount == 206.43811673387373
assert trade.stake_amount == 15.0
assert trade.is_open == True
assert trade.open_date is not None
assert whitelist == conf['bittrex']['pair_whitelist']
# Simulate that there is no open order buy_signal.assert_has_calls(
trade.open_order_id = None [call('BTC_ETH'), call('BTC_TKN'), call('BTC_TRST'), call('BTC_SWT')]
)
closed = close_trade_if_fulfilled(trade) def test_2_handle_trade(conf):
assert closed with patch.dict('freqtrade.main._CONF', conf):
assert trade.is_open == False with patch.multiple('freqtrade.main.telegram', init=MagicMock(), send_msg=MagicMock()):
with patch.multiple('freqtrade.main.exchange',
get_ticker=MagicMock(return_value={
'bid': 0.17256061,
'ask': 0.172661,
'last': 0.17256061
}),
buy=MagicMock(return_value='mocked_order_id')):
trade = Trade.query.filter(Trade.is_open.is_(True)).first()
assert trade
handle_trade(trade)
assert trade.close_rate == 0.17256061
assert trade.close_profit == 137.4872490056564
assert trade.close_date is not None
assert trade.open_order_id == 'dry_run'
def test_balance_fully_ask_side(self): def test_3_close_trade(conf):
with patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 0.0}}): with patch.dict('freqtrade.main._CONF', conf):
assert get_target_bid({'ask': 20, 'last': 10}) == 20 trade = Trade.query.filter(Trade.is_open.is_(True)).first()
assert trade
def test_balance_fully_last_side(self): # Simulate that there is no open order
with patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 1.0}}): trade.open_order_id = None
assert get_target_bid({'ask': 20, 'last': 10}) == 10
def test_balance_when_last_bigger_than_ask(self): closed = close_trade_if_fulfilled(trade)
with patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 1.0}}): assert closed
assert get_target_bid({'ask': 5, 'last': 10}) == 5 assert trade.is_open == False
@classmethod def test_balance_fully_ask_side():
def setUpClass(cls): with patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 0.0}}):
validate(cls.conf, CONF_SCHEMA) assert get_target_bid({'ask': 20, 'last': 10}) == 20
def test_balance_fully_last_side():
with patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 1.0}}):
assert get_target_bid({'ask': 20, 'last': 10}) == 10
if __name__ == '__main__': def test_balance_when_last_bigger_than_ask():
unittest.main() with patch.dict('freqtrade.main._CONF', {'bid_strategy': {'ask_last_balance': 1.0}}):
assert get_target_bid({'ask': 5, 'last': 10}) == 5

View File

@ -1,28 +1,22 @@
import unittest
from unittest.mock import patch from unittest.mock import patch
from freqtrade.exchange import Exchange from freqtrade.exchange import Exchange
from freqtrade.persistence import Trade from freqtrade.persistence import Trade
class TestTrade(unittest.TestCase): def test_1_exec_sell_order():
def test_1_exec_sell_order(self): with patch('freqtrade.main.exchange.sell', side_effect='mocked_order_id') as api_mock:
with patch('freqtrade.main.exchange.sell', side_effect='mocked_order_id') as api_mock: trade = Trade(
trade = Trade( pair='BTC_ETH',
pair='BTC_ETH', stake_amount=1.00,
stake_amount=1.00, open_rate=0.50,
open_rate=0.50, amount=10.00,
amount=10.00, exchange=Exchange.BITTREX,
exchange=Exchange.BITTREX, open_order_id='mocked'
open_order_id='mocked' )
) profit = trade.exec_sell_order(1.00, 10.00)
profit = trade.exec_sell_order(1.00, 10.00) api_mock.assert_called_once_with('BTC_ETH', 1.0, 10.0)
api_mock.assert_called_once_with('BTC_ETH', 1.0, 10.0) assert profit == 100.0
assert profit == 100.0 assert trade.close_rate == 1.0
assert trade.close_rate == 1.0 assert trade.close_profit == profit
assert trade.close_profit == profit assert trade.close_date is not None
assert trade.close_date is not None
if __name__ == '__main__':
unittest.main()

View File

@ -1,7 +1,7 @@
import unittest
from datetime import datetime from datetime import datetime
from unittest.mock import patch, MagicMock from unittest.mock import patch, MagicMock
import pytest
from jsonschema import validate from jsonschema import validate
from telegram import Bot, Update, Message, Chat from telegram import Bot, Update, Message, Chat
@ -12,13 +12,9 @@ from freqtrade.persistence import Trade
from freqtrade.rpc.telegram import _status, _profit, _forcesell, _performance, _start, _stop from freqtrade.rpc.telegram import _status, _profit, _forcesell, _performance, _start, _stop
class MagicBot(MagicMock, Bot): @pytest.fixture
pass def conf():
configuration = {
class TestTelegram(unittest.TestCase):
conf = {
"max_open_trades": 3, "max_open_trades": 3,
"stake_currency": "BTC", "stake_currency": "BTC",
"stake_amount": 0.05, "stake_amount": 0.05,
@ -46,150 +42,152 @@ class TestTelegram(unittest.TestCase):
}, },
"initial_state": "running" "initial_state": "running"
} }
validate(configuration, CONF_SCHEMA)
return configuration
def test_1_status_handle(self): @pytest.fixture
with patch.dict('freqtrade.main._CONF', self.conf): def update():
with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True): _update = Update(0)
msg_mock = MagicMock() _update.message = Message(0, 0, datetime.utcnow(), Chat(0, 0))
with patch.multiple('freqtrade.main.telegram', _CONF=self.conf, init=MagicMock(), send_msg=msg_mock): return _update
with patch.multiple('freqtrade.main.exchange',
get_ticker=MagicMock(return_value={
'bid': 0.07256061,
'ask': 0.072661,
'last': 0.07256061
}),
buy=MagicMock(return_value='mocked_order_id')):
init(self.conf, 'sqlite://')
# Create some test data
trade = create_trade(15.0, exchange.Exchange.BITTREX)
assert trade
Trade.session.add(trade)
Trade.session.flush()
_status(bot=MagicBot(), update=self.update) class MagicBot(MagicMock, Bot):
assert msg_mock.call_count == 2 pass
assert '[BTC_ETH]' in msg_mock.call_args_list[-1][0][0]
def test_2_profit_handle(self):
with patch.dict('freqtrade.main._CONF', self.conf):
with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True):
msg_mock = MagicMock()
with patch.multiple('freqtrade.main.telegram', _CONF=self.conf, init=MagicMock(), send_msg=msg_mock):
with patch.multiple('freqtrade.main.exchange',
get_ticker=MagicMock(return_value={
'bid': 0.07256061,
'ask': 0.072661,
'last': 0.07256061
}),
buy=MagicMock(return_value='mocked_order_id')):
init(self.conf, 'sqlite://')
# Create some test data def test_1_status_handle(conf, update):
trade = create_trade(15.0, exchange.Exchange.BITTREX) with patch.dict('freqtrade.main._CONF', conf):
assert trade with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True):
trade.close_rate = 0.07256061
trade.close_profit = 100.00
trade.close_date = datetime.utcnow()
trade.open_order_id = None
trade.is_open = False
Trade.session.add(trade)
Trade.session.flush()
_profit(bot=MagicBot(), update=self.update)
assert msg_mock.call_count == 2
assert '(100.00%)' in msg_mock.call_args_list[-1][0][0]
def test_3_forcesell_handle(self):
with patch.dict('freqtrade.main._CONF', self.conf):
with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True):
msg_mock = MagicMock()
with patch.multiple('freqtrade.main.telegram', _CONF=self.conf, init=MagicMock(), send_msg=msg_mock):
with patch.multiple('freqtrade.main.exchange',
get_ticker=MagicMock(return_value={
'bid': 0.07256061,
'ask': 0.072661,
'last': 0.07256061
}),
buy=MagicMock(return_value='mocked_order_id')):
init(self.conf, 'sqlite://')
# Create some test data
trade = create_trade(15.0, exchange.Exchange.BITTREX)
assert trade
Trade.session.add(trade)
Trade.session.flush()
self.update.message.text = '/forcesell 1'
_forcesell(bot=MagicBot(), update=self.update)
assert msg_mock.call_count == 2
assert 'Selling [BTC/ETH]' in msg_mock.call_args_list[-1][0][0]
assert '0.072561' in msg_mock.call_args_list[-1][0][0]
def test_4_performance_handle(self):
with patch.dict('freqtrade.main._CONF', self.conf):
with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True):
msg_mock = MagicMock()
with patch.multiple('freqtrade.main.telegram', _CONF=self.conf, init=MagicMock(), send_msg=msg_mock):
with patch.multiple('freqtrade.main.exchange',
get_ticker=MagicMock(return_value={
'bid': 0.07256061,
'ask': 0.072661,
'last': 0.07256061
}),
buy=MagicMock(return_value='mocked_order_id')):
init(self.conf, 'sqlite://')
# Create some test data
trade = create_trade(15.0, exchange.Exchange.BITTREX)
assert trade
trade.close_rate = 0.07256061
trade.close_profit = 100.00
trade.close_date = datetime.utcnow()
trade.open_order_id = None
trade.is_open = False
Trade.session.add(trade)
Trade.session.flush()
_performance(bot=MagicBot(), update=self.update)
assert msg_mock.call_count == 2
assert 'Performance' in msg_mock.call_args_list[-1][0][0]
assert 'BTC_ETH 100.00%' in msg_mock.call_args_list[-1][0][0]
def test_5_start_handle(self):
with patch.dict('freqtrade.main._CONF', self.conf):
msg_mock = MagicMock() msg_mock = MagicMock()
with patch.multiple('freqtrade.main.telegram', _CONF=self.conf, init=MagicMock(), send_msg=msg_mock): with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock):
init(self.conf, 'sqlite://') with patch.multiple('freqtrade.main.exchange',
get_ticker=MagicMock(return_value={
'bid': 0.07256061,
'ask': 0.072661,
'last': 0.07256061
}),
buy=MagicMock(return_value='mocked_order_id')):
init(conf, 'sqlite://')
update_state(State.STOPPED) # Create some test data
assert get_state() == State.STOPPED trade = create_trade(15.0, exchange.Exchange.BITTREX)
_start(bot=MagicBot(), update=self.update) assert trade
assert get_state() == State.RUNNING Trade.session.add(trade)
assert msg_mock.call_count == 0 Trade.session.flush()
def test_6_stop_handle(self): _status(bot=MagicBot(), update=update)
with patch.dict('freqtrade.main._CONF', self.conf): assert msg_mock.call_count == 2
assert '[BTC_ETH]' in msg_mock.call_args_list[-1][0][0]
def test_2_profit_handle(conf, update):
with patch.dict('freqtrade.main._CONF', conf):
with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True):
msg_mock = MagicMock() msg_mock = MagicMock()
with patch.multiple('freqtrade.main.telegram', _CONF=self.conf, init=MagicMock(), send_msg=msg_mock): with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock):
init(self.conf, 'sqlite://') with patch.multiple('freqtrade.main.exchange',
get_ticker=MagicMock(return_value={
'bid': 0.07256061,
'ask': 0.072661,
'last': 0.07256061
}),
buy=MagicMock(return_value='mocked_order_id')):
init(conf, 'sqlite://')
update_state(State.RUNNING) # Create some test data
assert get_state() == State.RUNNING trade = create_trade(15.0, exchange.Exchange.BITTREX)
_stop(bot=MagicBot(), update=self.update) assert trade
assert get_state() == State.STOPPED trade.close_rate = 0.07256061
assert msg_mock.call_count == 1 trade.close_profit = 100.00
assert 'Stopping trader' in msg_mock.call_args_list[0][0][0] trade.close_date = datetime.utcnow()
trade.open_order_id = None
trade.is_open = False
Trade.session.add(trade)
Trade.session.flush()
def setUp(self): _profit(bot=MagicBot(), update=update)
self.update = Update(0) assert msg_mock.call_count == 2
self.update.message = Message(0, 0, datetime.utcnow(), Chat(0, 0)) assert '(100.00%)' in msg_mock.call_args_list[-1][0][0]
@classmethod def test_3_forcesell_handle(conf, update):
def setUpClass(cls): with patch.dict('freqtrade.main._CONF', conf):
validate(cls.conf, CONF_SCHEMA) with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True):
msg_mock = MagicMock()
with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock):
with patch.multiple('freqtrade.main.exchange',
get_ticker=MagicMock(return_value={
'bid': 0.07256061,
'ask': 0.072661,
'last': 0.07256061
}),
buy=MagicMock(return_value='mocked_order_id')):
init(conf, 'sqlite://')
# Create some test data
trade = create_trade(15.0, exchange.Exchange.BITTREX)
assert trade
Trade.session.add(trade)
Trade.session.flush()
update.message.text = '/forcesell 1'
_forcesell(bot=MagicBot(), update=update)
assert msg_mock.call_count == 2
assert 'Selling [BTC/ETH]' in msg_mock.call_args_list[-1][0][0]
assert '0.072561' in msg_mock.call_args_list[-1][0][0]
def test_4_performance_handle(conf, update):
with patch.dict('freqtrade.main._CONF', conf):
with patch('freqtrade.main.get_buy_signal', side_effect=lambda _: True):
msg_mock = MagicMock()
with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock):
with patch.multiple('freqtrade.main.exchange',
get_ticker=MagicMock(return_value={
'bid': 0.07256061,
'ask': 0.072661,
'last': 0.07256061
}),
buy=MagicMock(return_value='mocked_order_id')):
init(conf, 'sqlite://')
# Create some test data
trade = create_trade(15.0, exchange.Exchange.BITTREX)
assert trade
trade.close_rate = 0.07256061
trade.close_profit = 100.00
trade.close_date = datetime.utcnow()
trade.open_order_id = None
trade.is_open = False
Trade.session.add(trade)
Trade.session.flush()
_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 100.00%' in msg_mock.call_args_list[-1][0][0]
def test_5_start_handle(conf, update):
with patch.dict('freqtrade.main._CONF', conf):
msg_mock = MagicMock()
with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock):
init(conf, 'sqlite://')
update_state(State.STOPPED)
assert get_state() == State.STOPPED
_start(bot=MagicBot(), update=update)
assert get_state() == State.RUNNING
assert msg_mock.call_count == 0
def test_6_stop_handle(conf, update):
with patch.dict('freqtrade.main._CONF', conf):
msg_mock = MagicMock()
with patch.multiple('freqtrade.main.telegram', _CONF=conf, init=MagicMock(), send_msg=msg_mock):
init(conf, 'sqlite://')
update_state(State.RUNNING)
assert get_state() == State.RUNNING
_stop(bot=MagicBot(), update=update)
assert get_state() == State.STOPPED
assert msg_mock.call_count == 1
assert 'Stopping trader' in msg_mock.call_args_list[0][0][0]
if __name__ == '__main__':
unittest.main()