Refactor tests, implement @creslinux's data

This commit is contained in:
Matthias 2018-07-10 21:08:44 +02:00
parent e0fda7a5dd
commit b8f78cb187

View File

@ -1,55 +1,177 @@
# pragma pylint: disable=missing-docstring, W0212, line-too-long, C0103, unused-argument
import logging
from unittest.mock import MagicMock
from typing import NamedTuple
import pandas as pd
from pandas import DataFrame
import pytest
from arrow import get as getdate
from freqtrade.optimize.backtesting import Backtesting
from freqtrade.tests.conftest import patch_exchange, log_has
class BTContainer(NamedTuple):
"""
NamedTuple Defining BacktestResults inputs.
"""
data: DataFrame
stop_loss: float
roi: float
trades: int
profit_perc: float
sl: float
columns = ['date', 'open', 'high', 'low', 'close', 'volume', 'buy', 'sell']
data_profit = pd.DataFrame([[getdate('2018-07-08 18:00:00').datetime,
0.0009910, 0.001011, 0.00098618, 0.001000, 47027.0, 1, 0],
[getdate('2018-07-08 19:00:00').datetime,
0.001000, 0.001010, 0.0009900, 0.0009900, 87116.0, 0, 0],
[getdate('2018-07-08 20:00:00').datetime,
0.0009900, 0.001011, 0.00091618, 0.0009900, 58539.0, 0, 0],
[getdate('2018-07-08 21:00:00').datetime,
0.001000, 0.001011, 0.00098618, 0.001100, 37498.0, 0, 1],
[getdate('2018-07-08 22:00:00').datetime,
0.001000, 0.001011, 0.00098618, 0.0009900, 59792.0, 0, 0]],
columns=columns)
data_profit = DataFrame([
[getdate('2018-07-08 18:00:00').datetime, 0.0009910,
0.001011, 0.00098618, 0.001000, 12345, 1, 0],
[getdate('2018-07-08 19:00:00').datetime, 0.001000,
0.001010, 0.0009900, 0.0009900, 12345, 0, 0],
[getdate('2018-07-08 20:00:00').datetime, 0.0009900,
0.001011, 0.00091618, 0.0009900, 12345, 0, 0],
[getdate('2018-07-08 21:00:00').datetime, 0.001000,
0.001011, 0.00098618, 0.001100, 12345, 0, 1],
[getdate('2018-07-08 22:00:00').datetime, 0.001000,
0.001011, 0.00098618, 0.0009900, 12345, 0, 0]
], columns=columns)
data_loss = pd.DataFrame([[getdate('2018-07-08 18:00:00').datetime,
0.0009910, 0.001011, 0.00098618, 0.001000, 47027.0, 1, 0],
[getdate('2018-07-08 19:00:00').datetime,
0.001000, 0.001010, 0.0009900, 0.001000, 87116.0, 0, 0],
[getdate('2018-07-08 20:00:00').datetime,
0.001000, 0.001011, 0.0010618, 0.00091618, 58539.0, 0, 0],
[getdate('2018-07-08 21:00:00').datetime,
0.001000, 0.001011, 0.00098618, 0.00091618, 37498.0, 0, 0],
[getdate('2018-07-08 22:00:00').datetime,
0.001000, 0.001011, 0.00098618, 0.00091618, 59792.0, 0, 0]],
columns=columns)
tc_profit1 = BTContainer(data=data_profit, stop_loss=-0.01, roi=1, trades=1,
profit_perc=0.10557, sl=False) # should be stoploss - drops 8%
tc_profit2 = BTContainer(data=data_profit, stop_loss=-0.10, roi=1,
trades=1, profit_perc=0.10557, sl=True)
@pytest.mark.parametrize("data, stoploss, tradecount, profit_perc, sl", [
(data_profit, -0.01, 1, 0.10557, False), # should be stoploss - drops 8%
# (data_profit, -0.10, 1, 0.10557, True), # win
(data_loss, -0.05, 1, -0.08839, True), # Stoploss ...
])
def test_backtest_results(default_conf, fee, mocker, caplog,
data, stoploss, tradecount, profit_perc, sl) -> None:
tc_loss0 = BTContainer(data=DataFrame([
[getdate('2018-07-08 18:00:00').datetime, 0.0009910,
0.001011, 0.00098618, 0.001000, 12345, 1, 0],
[getdate('2018-07-08 19:00:00').datetime, 0.001000,
0.001010, 0.0009900, 0.001000, 12345, 0, 0],
[getdate('2018-07-08 20:00:00').datetime, 0.001000,
0.001011, 0.0010618, 0.00091618, 12345, 0, 0],
[getdate('2018-07-08 21:00:00').datetime, 0.001000,
0.001011, 0.00098618, 0.00091618, 12345, 0, 0],
[getdate('2018-07-08 22:00:00').datetime, 0.001000,
0.001011, 0.00098618, 0.00091618, 12345, 0, 0]
], columns=columns),
stop_loss=-0.05, roi=1, trades=1, profit_perc=-0.08839, sl=True)
# Test 1 Minus 8% Close
# Candle Data for test 1 close at -8% (9200)
# Test with Stop-loss at 1%
tc1 = BTContainer(data=DataFrame([
[getdate('2018-06-10 08:00:00').datetime, 10000, 10050, 9950, 9975, 12345, 1, 0],
[getdate('2018-06-10 09:00:00').datetime, 9975, 10025, 9925, 9950, 12345, 0, 0],
[getdate('2018-06-10 10:00:00').datetime, 9950, 10000, 9960, 9955, 12345, 0, 0],
[getdate('2018-06-10 11:00:00').datetime, 9955, 9975, 9955, 9990, 12345, 0, 0],
[getdate('2018-06-10 12:00:00').datetime, 9990, 9990, 9200, 9200, 12345, 0, 0]
], columns=columns),
stop_loss=-0.01, roi=1, trades=1, profit_perc=-0.07999, sl=True)
# Test 2 Minus 4% Low, minus 1% close
# Candle Data for test 2
# Test with Stop-Loss at 3%
tc2 = BTContainer(data=DataFrame([
[getdate('2018-06-10 08:00:00').datetime, 10000, 10050, 9950, 9975, 12345, 1, 0],
[getdate('2018-06-10 09:00:00').datetime, 9975, 10025, 9925, 9950, 12345, 0, 0],
[getdate('2018-06-10 10:00:00').datetime, 9950, 10000, 9600, 9925, 12345, 0, 0],
[getdate('2018-06-10 11:00:00').datetime, 9925, 9975, 9875, 9900, 12345, 0, 0],
[getdate('2018-06-10 12:00:00').datetime, 9900, 9950, 9850, 9900, 12345, 0, 0]
], columns=columns), stop_loss=-0.03, roi=1, trades=1, profit_perc=-0.00999, sl=False) #
# Test 3 Candle drops 4%, Recovers 1%.
# Entry Criteria Met
# Candle drops 20%
# Candle Data for test 3
# Test with Stop-Loss at 2%
tc3 = BTContainer(data=DataFrame([
[getdate('2018-06-10 08:00:00').datetime, 10000, 10050, 9950, 9975, 12345, 1, 0],
[getdate('2018-06-10 09:00:00').datetime, 9975, 10025, 9600, 9950, 12345, 0, 0],
[getdate('2018-06-10 10:00:00').datetime, 9950, 10000, 9900, 9925, 12345, 1, 0],
[getdate('2018-06-10 11:00:00').datetime, 9925, 9975, 8000, 8000, 12345, 0, 0],
[getdate('2018-06-10 12:00:00').datetime, 9900, 9950, 9950, 9900, 12345, 0, 0]
], columns=columns), stop_loss=-0.02, roi=1, trades=1, profit_perc=-0.19999, sl=True) #
# Test 4 Minus 3% / recovery +15%
# Candle Data for test 4 Candle drops 3% Closed 15% up
# Test with Stop-loss at 2% ROI 6%
tc4 = BTContainer(data=DataFrame([
[getdate('2018-06-10 08:00:00').datetime, 10000, 10050, 9950, 9975, 12345, 1, 0],
[getdate('2018-06-10 09:00:00').datetime, 9975, 11500, 9700, 11500, 12345, 0, 0],
[getdate('2018-06-10 10:00:00').datetime, 9950, 10000, 9900, 9925, 12345, 0, 0],
[getdate('2018-06-10 11:00:00').datetime, 9925, 9975, 9875, 9900, 12345, 0, 0],
[getdate('2018-06-10 12:00:00').datetime, 9900, 9950, 9850, 9900, 12345, 0, 0]
], columns=columns),
stop_loss=-0.02, roi=0.06, trades=1, profit_perc=-0.141, sl=True)
# Test 5 / Drops 0.5% Closes +20%
# Candle Data for test 5
# Set stop-loss at 1% ROI 3%
tc5 = BTContainer(data=DataFrame([
[getdate('2018-06-10 08:00:00').datetime, 10000, 10050, 9950, 9975, 12345, 1, 0],
[getdate('2018-06-10 09:00:00').datetime, 9975, 12000, 9950, 12000, 12345, 0, 0],
[getdate('2018-06-10 10:00:00').datetime, 9950, 10000, 9900, 9925, 12345, 0, 0],
[getdate('2018-06-10 11:00:00').datetime, 9925, 9975, 9945, 9900, 12345, 0, 0],
[getdate('2018-06-10 12:00:00').datetime, 9900, 9950, 9850, 9900, 12345, 0, 0]
], columns=columns),
stop_loss=-0.01, roi=0.03, trades=1, profit_perc=-0.177, sl=True)
# Test 6 / Drops 3% / Recovers 6% Positive / Closes 1% positve
# Candle Data for test 6
# Set stop-loss at 2% ROI at 5%
tc6 = BTContainer(data=DataFrame([
[getdate('2018-06-10 08:00:00').datetime, 10000, 10050, 9950, 9975, 12345, 1, 0],
[getdate('2018-06-10 09:00:00').datetime, 9975, 10600, 9700, 10100, 12345, 0, 0],
[getdate('2018-06-10 10:00:00').datetime, 9950, 10000, 9900, 9925, 12345, 0, 0],
[getdate('2018-06-10 11:00:00').datetime, 9925, 9975, 9945, 9900, 12345, 0, 0],
[getdate('2018-06-10 12:00:00').datetime, 9900, 9950, 9850, 9900, 12345, 0, 0]
], columns=columns), stop_loss=-0.02, roi=0.05,
trades=1, profit_perc=-0.025, sl=False)
# Test 7 - 6% Positive / 1% Negative / Close 1% Positve
# Candle Data for test 7
# Set stop-loss at 2% ROI at 3%
tc7 = BTContainer(data=DataFrame([
[getdate('2018-06-10 08:00:00').datetime, 10000, 10050, 9950, 9975, 12345, 1, 0],
[getdate('2018-06-10 09:00:00').datetime, 9975, 10600, 9900, 10100, 12345, 0, 0],
[getdate('2018-06-10 10:00:00').datetime, 9950, 10000, 9900, 9925, 12345, 0, 0],
[getdate('2018-06-10 11:00:00').datetime, 9925, 9975, 9945, 9900, 12345, 0, 0],
[getdate('2018-06-10 12:00:00').datetime, 9900, 9950, 9850, 9900, 12345, 0, 0]
], columns=columns), stop_loss=-0.02, roi=0.03,
trades=1, profit_perc=-0.025, sl=False)
TESTS = [
# tc_profit1,
# tc_profit2,
tc_loss0,
tc1,
tc2,
tc3,
tc4,
tc5,
tc6,
tc7,
]
@pytest.mark.parametrize("data", TESTS)
def test_backtest_results(default_conf, fee, mocker, caplog, data) -> None:
"""
run functional tests
"""
default_conf["stoploss"] = stoploss
default_conf["stoploss"] = data.stop_loss
default_conf["minimal_roi"] = {"0": data.roi}
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
mocker.patch('freqtrade.analyze.Analyze.populate_sell_trend', MagicMock(return_value=data))
mocker.patch('freqtrade.analyze.Analyze.populate_buy_trend', MagicMock(return_value=data))
mocker.patch.multiple('freqtrade.analyze.Analyze',
populate_sell_trend=MagicMock(return_value=data.data),
populate_buy_trend=MagicMock(return_value=data.data))
patch_exchange(mocker)
backtesting = Backtesting(default_conf)
@ -57,7 +179,7 @@ def test_backtest_results(default_conf, fee, mocker, caplog,
pair = 'UNITTEST/BTC'
# Dummy data as we mock the analyze functions
data_processed = {pair: pd.DataFrame()}
data_processed = {pair: DataFrame()}
results = backtesting.backtest(
{
'stake_amount': default_conf['stake_amount'],
@ -68,9 +190,9 @@ def test_backtest_results(default_conf, fee, mocker, caplog,
)
print(results.T)
assert len(results) == tradecount
assert round(results["profit_percent"].sum(), 5) == profit_perc
if sl:
assert len(results) == data.trades
assert round(results["profit_percent"].sum(), 3) == round(data.profit_perc, 3)
if data.sl:
assert log_has("Stop loss hit.", caplog.record_tuples)
else: