Do not use ticker where it's not a ticker
This commit is contained in:
@@ -15,7 +15,7 @@ from telegram import Chat, Message, Update
|
||||
|
||||
from freqtrade import constants, persistence
|
||||
from freqtrade.commands import Arguments
|
||||
from freqtrade.data.converter import parse_ticker_dataframe
|
||||
from freqtrade.data.converter import ohlcv_to_dataframe
|
||||
from freqtrade.edge import Edge, PairInfo
|
||||
from freqtrade.exchange import Exchange
|
||||
from freqtrade.freqtradebot import FreqtradeBot
|
||||
@@ -849,15 +849,15 @@ def order_book_l2():
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def ticker_history_list():
|
||||
def ohlcv_history_list():
|
||||
return [
|
||||
[
|
||||
1511686200000, # unix timestamp ms
|
||||
8.794e-05, # open
|
||||
8.948e-05, # high
|
||||
8.794e-05, # low
|
||||
8.88e-05, # close
|
||||
0.0877869, # volume (in quote currency)
|
||||
8.794e-05, # open
|
||||
8.948e-05, # high
|
||||
8.794e-05, # low
|
||||
8.88e-05, # close
|
||||
0.0877869, # volume (in quote currency)
|
||||
],
|
||||
[
|
||||
1511686500000,
|
||||
@@ -879,8 +879,9 @@ def ticker_history_list():
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def ticker_history(ticker_history_list):
|
||||
return parse_ticker_dataframe(ticker_history_list, "5m", pair="UNITTEST/BTC", fill_missing=True)
|
||||
def ohlcv_history(ohlcv_history_list):
|
||||
return ohlcv_to_dataframe(ohlcv_history_list, "5m", pair="UNITTEST/BTC",
|
||||
fill_missing=True)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@@ -1195,8 +1196,8 @@ def tickers():
|
||||
@pytest.fixture
|
||||
def result(testdatadir):
|
||||
with (testdatadir / 'UNITTEST_BTC-1m.json').open('r') as data_file:
|
||||
return parse_ticker_dataframe(json.load(data_file), '1m', pair="UNITTEST/BTC",
|
||||
fill_missing=True)
|
||||
return ohlcv_to_dataframe(json.load(data_file), '1m', pair="UNITTEST/BTC",
|
||||
fill_missing=True)
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
|
@@ -8,7 +8,7 @@ from freqtrade.configuration import TimeRange
|
||||
from freqtrade.data.btanalysis import (BT_DATA_COLUMNS,
|
||||
analyze_trade_parallelism,
|
||||
calculate_max_drawdown,
|
||||
combine_tickers_with_mean,
|
||||
combine_dataframes_with_mean,
|
||||
create_cum_profit,
|
||||
extract_trades_of_period,
|
||||
load_backtest_data, load_trades,
|
||||
@@ -120,13 +120,10 @@ def test_load_trades(default_conf, mocker):
|
||||
assert bt_mock.call_count == 1
|
||||
|
||||
|
||||
def test_combine_tickers_with_mean(testdatadir):
|
||||
def test_combine_dataframes_with_mean(testdatadir):
|
||||
pairs = ["ETH/BTC", "ADA/BTC"]
|
||||
tickers = load_data(datadir=testdatadir,
|
||||
pairs=pairs,
|
||||
timeframe='5m'
|
||||
)
|
||||
df = combine_tickers_with_mean(tickers)
|
||||
data = load_data(datadir=testdatadir, pairs=pairs, timeframe='5m')
|
||||
df = combine_dataframes_with_mean(data)
|
||||
assert isinstance(df, DataFrame)
|
||||
assert "ETH/BTC" in df.columns
|
||||
assert "ADA/BTC" in df.columns
|
||||
|
@@ -5,9 +5,12 @@ from freqtrade.configuration.timerange import TimeRange
|
||||
from freqtrade.data.converter import (convert_ohlcv_format,
|
||||
convert_trades_format,
|
||||
ohlcv_fill_up_missing_data,
|
||||
parse_ticker_dataframe, trim_dataframe)
|
||||
from freqtrade.data.history import (get_timerange, load_data,
|
||||
load_pair_history, validate_backtest_data)
|
||||
ohlcv_to_dataframe,
|
||||
trim_dataframe)
|
||||
from freqtrade.data.history import (get_timerange,
|
||||
load_data,
|
||||
load_pair_history,
|
||||
validate_backtest_data)
|
||||
from tests.conftest import log_has
|
||||
from tests.data.test_history import _backup_file, _clean_test_file
|
||||
|
||||
@@ -16,15 +19,15 @@ def test_dataframe_correct_columns(result):
|
||||
assert result.columns.tolist() == ['date', 'open', 'high', 'low', 'close', 'volume']
|
||||
|
||||
|
||||
def test_parse_ticker_dataframe(ticker_history_list, caplog):
|
||||
def test_ohlcv_to_dataframe(ohlcv_history_list, caplog):
|
||||
columns = ['date', 'open', 'high', 'low', 'close', 'volume']
|
||||
|
||||
caplog.set_level(logging.DEBUG)
|
||||
# Test file with BV data
|
||||
dataframe = parse_ticker_dataframe(ticker_history_list, '5m',
|
||||
pair="UNITTEST/BTC", fill_missing=True)
|
||||
dataframe = ohlcv_to_dataframe(ohlcv_history_list, '5m', pair="UNITTEST/BTC",
|
||||
fill_missing=True)
|
||||
assert dataframe.columns.tolist() == columns
|
||||
assert log_has('Parsing tickerlist to dataframe', caplog)
|
||||
assert log_has('Converting candle (OHLCV) data to dataframe for pair UNITTEST/BTC.', caplog)
|
||||
|
||||
|
||||
def test_ohlcv_fill_up_missing_data(testdatadir, caplog):
|
||||
@@ -84,7 +87,8 @@ def test_ohlcv_fill_up_missing_data2(caplog):
|
||||
]
|
||||
|
||||
# Generate test-data without filling missing
|
||||
data = parse_ticker_dataframe(ticks, timeframe, pair="UNITTEST/BTC", fill_missing=False)
|
||||
data = ohlcv_to_dataframe(ticks, timeframe, pair="UNITTEST/BTC",
|
||||
fill_missing=False)
|
||||
assert len(data) == 3
|
||||
caplog.set_level(logging.DEBUG)
|
||||
data2 = ohlcv_fill_up_missing_data(data, timeframe, "UNITTEST/BTC")
|
||||
@@ -140,14 +144,14 @@ def test_ohlcv_drop_incomplete(caplog):
|
||||
]
|
||||
]
|
||||
caplog.set_level(logging.DEBUG)
|
||||
data = parse_ticker_dataframe(ticks, timeframe, pair="UNITTEST/BTC",
|
||||
fill_missing=False, drop_incomplete=False)
|
||||
data = ohlcv_to_dataframe(ticks, timeframe, pair="UNITTEST/BTC",
|
||||
fill_missing=False, drop_incomplete=False)
|
||||
assert len(data) == 4
|
||||
assert not log_has("Dropping last candle", caplog)
|
||||
|
||||
# Drop last candle
|
||||
data = parse_ticker_dataframe(ticks, timeframe, pair="UNITTEST/BTC",
|
||||
fill_missing=False, drop_incomplete=True)
|
||||
data = ohlcv_to_dataframe(ticks, timeframe, pair="UNITTEST/BTC",
|
||||
fill_missing=False, drop_incomplete=True)
|
||||
assert len(data) == 3
|
||||
|
||||
assert log_has("Dropping last candle", caplog)
|
||||
|
@@ -7,19 +7,19 @@ from freqtrade.state import RunMode
|
||||
from tests.conftest import get_patched_exchange
|
||||
|
||||
|
||||
def test_ohlcv(mocker, default_conf, ticker_history):
|
||||
def test_ohlcv(mocker, default_conf, ohlcv_history):
|
||||
default_conf["runmode"] = RunMode.DRY_RUN
|
||||
timeframe = default_conf["ticker_interval"]
|
||||
exchange = get_patched_exchange(mocker, default_conf)
|
||||
exchange._klines[("XRP/BTC", timeframe)] = ticker_history
|
||||
exchange._klines[("UNITTEST/BTC", timeframe)] = ticker_history
|
||||
exchange._klines[("XRP/BTC", timeframe)] = ohlcv_history
|
||||
exchange._klines[("UNITTEST/BTC", timeframe)] = ohlcv_history
|
||||
|
||||
dp = DataProvider(default_conf, exchange)
|
||||
assert dp.runmode == RunMode.DRY_RUN
|
||||
assert ticker_history.equals(dp.ohlcv("UNITTEST/BTC", timeframe))
|
||||
assert ohlcv_history.equals(dp.ohlcv("UNITTEST/BTC", timeframe))
|
||||
assert isinstance(dp.ohlcv("UNITTEST/BTC", timeframe), DataFrame)
|
||||
assert dp.ohlcv("UNITTEST/BTC", timeframe) is not ticker_history
|
||||
assert dp.ohlcv("UNITTEST/BTC", timeframe, copy=False) is ticker_history
|
||||
assert dp.ohlcv("UNITTEST/BTC", timeframe) is not ohlcv_history
|
||||
assert dp.ohlcv("UNITTEST/BTC", timeframe, copy=False) is ohlcv_history
|
||||
assert not dp.ohlcv("UNITTEST/BTC", timeframe).empty
|
||||
assert dp.ohlcv("NONESENSE/AAA", timeframe).empty
|
||||
|
||||
@@ -37,8 +37,8 @@ def test_ohlcv(mocker, default_conf, ticker_history):
|
||||
assert dp.ohlcv("UNITTEST/BTC", timeframe).empty
|
||||
|
||||
|
||||
def test_historic_ohlcv(mocker, default_conf, ticker_history):
|
||||
historymock = MagicMock(return_value=ticker_history)
|
||||
def test_historic_ohlcv(mocker, default_conf, ohlcv_history):
|
||||
historymock = MagicMock(return_value=ohlcv_history)
|
||||
mocker.patch("freqtrade.data.dataprovider.load_pair_history", historymock)
|
||||
|
||||
dp = DataProvider(default_conf, None)
|
||||
@@ -48,18 +48,18 @@ def test_historic_ohlcv(mocker, default_conf, ticker_history):
|
||||
assert historymock.call_args_list[0][1]["timeframe"] == "5m"
|
||||
|
||||
|
||||
def test_get_pair_dataframe(mocker, default_conf, ticker_history):
|
||||
def test_get_pair_dataframe(mocker, default_conf, ohlcv_history):
|
||||
default_conf["runmode"] = RunMode.DRY_RUN
|
||||
ticker_interval = default_conf["ticker_interval"]
|
||||
exchange = get_patched_exchange(mocker, default_conf)
|
||||
exchange._klines[("XRP/BTC", ticker_interval)] = ticker_history
|
||||
exchange._klines[("UNITTEST/BTC", ticker_interval)] = ticker_history
|
||||
exchange._klines[("XRP/BTC", ticker_interval)] = ohlcv_history
|
||||
exchange._klines[("UNITTEST/BTC", ticker_interval)] = ohlcv_history
|
||||
|
||||
dp = DataProvider(default_conf, exchange)
|
||||
assert dp.runmode == RunMode.DRY_RUN
|
||||
assert ticker_history.equals(dp.get_pair_dataframe("UNITTEST/BTC", ticker_interval))
|
||||
assert ohlcv_history.equals(dp.get_pair_dataframe("UNITTEST/BTC", ticker_interval))
|
||||
assert isinstance(dp.get_pair_dataframe("UNITTEST/BTC", ticker_interval), DataFrame)
|
||||
assert dp.get_pair_dataframe("UNITTEST/BTC", ticker_interval) is not ticker_history
|
||||
assert dp.get_pair_dataframe("UNITTEST/BTC", ticker_interval) is not ohlcv_history
|
||||
assert not dp.get_pair_dataframe("UNITTEST/BTC", ticker_interval).empty
|
||||
assert dp.get_pair_dataframe("NONESENSE/AAA", ticker_interval).empty
|
||||
|
||||
@@ -73,7 +73,7 @@ def test_get_pair_dataframe(mocker, default_conf, ticker_history):
|
||||
assert isinstance(dp.get_pair_dataframe("UNITTEST/BTC", ticker_interval), DataFrame)
|
||||
assert dp.get_pair_dataframe("NONESENSE/AAA", ticker_interval).empty
|
||||
|
||||
historymock = MagicMock(return_value=ticker_history)
|
||||
historymock = MagicMock(return_value=ohlcv_history)
|
||||
mocker.patch("freqtrade.data.dataprovider.load_pair_history", historymock)
|
||||
default_conf["runmode"] = RunMode.BACKTEST
|
||||
dp = DataProvider(default_conf, exchange)
|
||||
@@ -82,11 +82,11 @@ def test_get_pair_dataframe(mocker, default_conf, ticker_history):
|
||||
# assert dp.get_pair_dataframe("NONESENSE/AAA", ticker_interval).empty
|
||||
|
||||
|
||||
def test_available_pairs(mocker, default_conf, ticker_history):
|
||||
def test_available_pairs(mocker, default_conf, ohlcv_history):
|
||||
exchange = get_patched_exchange(mocker, default_conf)
|
||||
ticker_interval = default_conf["ticker_interval"]
|
||||
exchange._klines[("XRP/BTC", ticker_interval)] = ticker_history
|
||||
exchange._klines[("UNITTEST/BTC", ticker_interval)] = ticker_history
|
||||
exchange._klines[("XRP/BTC", ticker_interval)] = ohlcv_history
|
||||
exchange._klines[("UNITTEST/BTC", ticker_interval)] = ohlcv_history
|
||||
|
||||
dp = DataProvider(default_conf, exchange)
|
||||
assert len(dp.available_pairs) == 2
|
||||
@@ -96,7 +96,7 @@ def test_available_pairs(mocker, default_conf, ticker_history):
|
||||
]
|
||||
|
||||
|
||||
def test_refresh(mocker, default_conf, ticker_history):
|
||||
def test_refresh(mocker, default_conf, ohlcv_history):
|
||||
refresh_mock = MagicMock()
|
||||
mocker.patch("freqtrade.exchange.Exchange.refresh_latest_ohlcv", refresh_mock)
|
||||
|
||||
|
@@ -12,7 +12,7 @@ from pandas import DataFrame
|
||||
from pandas.testing import assert_frame_equal
|
||||
|
||||
from freqtrade.configuration import TimeRange
|
||||
from freqtrade.data.converter import parse_ticker_dataframe
|
||||
from freqtrade.data.converter import ohlcv_to_dataframe
|
||||
from freqtrade.data.history.history_utils import (
|
||||
_download_pair_history, _download_trades_history,
|
||||
_load_cached_data_for_updating, convert_trades_to_ohlcv, get_timerange,
|
||||
@@ -63,7 +63,7 @@ def _clean_test_file(file: Path) -> None:
|
||||
file_swp.rename(file)
|
||||
|
||||
|
||||
def test_load_data_30min_ticker(mocker, caplog, default_conf, testdatadir) -> None:
|
||||
def test_load_data_30min_timeframe(mocker, caplog, default_conf, testdatadir) -> None:
|
||||
ld = load_pair_history(pair='UNITTEST/BTC', timeframe='30m', datadir=testdatadir)
|
||||
assert isinstance(ld, DataFrame)
|
||||
assert not log_has(
|
||||
@@ -72,7 +72,7 @@ def test_load_data_30min_ticker(mocker, caplog, default_conf, testdatadir) -> No
|
||||
)
|
||||
|
||||
|
||||
def test_load_data_7min_ticker(mocker, caplog, default_conf, testdatadir) -> None:
|
||||
def test_load_data_7min_timeframe(mocker, caplog, default_conf, testdatadir) -> None:
|
||||
ld = load_pair_history(pair='UNITTEST/BTC', timeframe='7m', datadir=testdatadir)
|
||||
assert isinstance(ld, DataFrame)
|
||||
assert ld.empty
|
||||
@@ -82,8 +82,8 @@ def test_load_data_7min_ticker(mocker, caplog, default_conf, testdatadir) -> Non
|
||||
)
|
||||
|
||||
|
||||
def test_load_data_1min_ticker(ticker_history, mocker, caplog, testdatadir) -> None:
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv', return_value=ticker_history)
|
||||
def test_load_data_1min_timeframe(ohlcv_history, mocker, caplog, testdatadir) -> None:
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv', return_value=ohlcv_history)
|
||||
file = testdatadir / 'UNITTEST_BTC-1m.json'
|
||||
_backup_file(file, copy_file=True)
|
||||
load_data(datadir=testdatadir, timeframe='1m', pairs=['UNITTEST/BTC'])
|
||||
@@ -110,12 +110,12 @@ def test_load_data_startup_candles(mocker, caplog, default_conf, testdatadir) ->
|
||||
assert ltfmock.call_args_list[0][1]['timerange'].startts == timerange.startts - 20 * 60
|
||||
|
||||
|
||||
def test_load_data_with_new_pair_1min(ticker_history_list, mocker, caplog,
|
||||
def test_load_data_with_new_pair_1min(ohlcv_history_list, mocker, caplog,
|
||||
default_conf, testdatadir) -> None:
|
||||
"""
|
||||
Test load_pair_history() with 1 min ticker
|
||||
Test load_pair_history() with 1 min timeframe
|
||||
"""
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv', return_value=ticker_history_list)
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv', return_value=ohlcv_history_list)
|
||||
exchange = get_patched_exchange(mocker, default_conf)
|
||||
file = testdatadir / 'MEME_BTC-1m.json'
|
||||
|
||||
@@ -188,8 +188,8 @@ def test_load_cached_data_for_updating(mocker, testdatadir) -> None:
|
||||
with open(test_filename, "rt") as file:
|
||||
test_data = json.load(file)
|
||||
|
||||
test_data_df = parse_ticker_dataframe(test_data, '1m', 'UNITTEST/BTC',
|
||||
fill_missing=False, drop_incomplete=False)
|
||||
test_data_df = ohlcv_to_dataframe(test_data, '1m', 'UNITTEST/BTC',
|
||||
fill_missing=False, drop_incomplete=False)
|
||||
# now = last cached item + 1 hour
|
||||
now_ts = test_data[-1][0] / 1000 + 60 * 60
|
||||
mocker.patch('arrow.utcnow', return_value=arrow.get(now_ts))
|
||||
@@ -230,8 +230,8 @@ def test_load_cached_data_for_updating(mocker, testdatadir) -> None:
|
||||
assert start_ts is None
|
||||
|
||||
|
||||
def test_download_pair_history(ticker_history_list, mocker, default_conf, testdatadir) -> None:
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv', return_value=ticker_history_list)
|
||||
def test_download_pair_history(ohlcv_history_list, mocker, default_conf, testdatadir) -> None:
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv', return_value=ohlcv_history_list)
|
||||
exchange = get_patched_exchange(mocker, default_conf)
|
||||
file1_1 = testdatadir / 'MEME_BTC-1m.json'
|
||||
file1_5 = testdatadir / 'MEME_BTC-5m.json'
|
||||
@@ -293,7 +293,7 @@ def test_download_pair_history2(mocker, default_conf, testdatadir) -> None:
|
||||
assert json_dump_mock.call_count == 2
|
||||
|
||||
|
||||
def test_download_backtesting_data_exception(ticker_history, mocker, caplog,
|
||||
def test_download_backtesting_data_exception(ohlcv_history, mocker, caplog,
|
||||
default_conf, testdatadir) -> None:
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv',
|
||||
side_effect=Exception('File Error'))
|
||||
@@ -321,15 +321,15 @@ def test_load_partial_missing(testdatadir, caplog) -> None:
|
||||
# Make sure we start fresh - test missing data at start
|
||||
start = arrow.get('2018-01-01T00:00:00')
|
||||
end = arrow.get('2018-01-11T00:00:00')
|
||||
tickerdata = load_data(testdatadir, '5m', ['UNITTEST/BTC'], startup_candles=20,
|
||||
timerange=TimeRange('date', 'date', start.timestamp, end.timestamp))
|
||||
data = load_data(testdatadir, '5m', ['UNITTEST/BTC'], startup_candles=20,
|
||||
timerange=TimeRange('date', 'date', start.timestamp, end.timestamp))
|
||||
assert log_has(
|
||||
'Using indicator startup period: 20 ...', caplog
|
||||
)
|
||||
# timedifference in 5 minutes
|
||||
td = ((end - start).total_seconds() // 60 // 5) + 1
|
||||
assert td != len(tickerdata['UNITTEST/BTC'])
|
||||
start_real = tickerdata['UNITTEST/BTC'].iloc[0, 0]
|
||||
assert td != len(data['UNITTEST/BTC'])
|
||||
start_real = data['UNITTEST/BTC'].iloc[0, 0]
|
||||
assert log_has(f'Missing data at start for pair '
|
||||
f'UNITTEST/BTC, data starts at {start_real.strftime("%Y-%m-%d %H:%M:%S")}',
|
||||
caplog)
|
||||
@@ -337,14 +337,14 @@ def test_load_partial_missing(testdatadir, caplog) -> None:
|
||||
caplog.clear()
|
||||
start = arrow.get('2018-01-10T00:00:00')
|
||||
end = arrow.get('2018-02-20T00:00:00')
|
||||
tickerdata = load_data(datadir=testdatadir, timeframe='5m', pairs=['UNITTEST/BTC'],
|
||||
timerange=TimeRange('date', 'date', start.timestamp, end.timestamp))
|
||||
data = load_data(datadir=testdatadir, timeframe='5m', pairs=['UNITTEST/BTC'],
|
||||
timerange=TimeRange('date', 'date', start.timestamp, end.timestamp))
|
||||
# timedifference in 5 minutes
|
||||
td = ((end - start).total_seconds() // 60 // 5) + 1
|
||||
assert td != len(tickerdata['UNITTEST/BTC'])
|
||||
assert td != len(data['UNITTEST/BTC'])
|
||||
|
||||
# Shift endtime with +5 - as last candle is dropped (partial candle)
|
||||
end_real = arrow.get(tickerdata['UNITTEST/BTC'].iloc[-1, 0]).shift(minutes=5)
|
||||
end_real = arrow.get(data['UNITTEST/BTC'].iloc[-1, 0]).shift(minutes=5)
|
||||
assert log_has(f'Missing data at end for pair '
|
||||
f'UNITTEST/BTC, data ends at {end_real.strftime("%Y-%m-%d %H:%M:%S")}',
|
||||
caplog)
|
||||
@@ -403,7 +403,7 @@ def test_get_timerange(default_conf, mocker, testdatadir) -> None:
|
||||
default_conf.update({'strategy': 'DefaultStrategy'})
|
||||
strategy = StrategyResolver.load_strategy(default_conf)
|
||||
|
||||
data = strategy.tickerdata_to_dataframe(
|
||||
data = strategy.ohlcvdata_to_dataframe(
|
||||
load_data(
|
||||
datadir=testdatadir,
|
||||
timeframe='1m',
|
||||
@@ -421,7 +421,7 @@ def test_validate_backtest_data_warn(default_conf, mocker, caplog, testdatadir)
|
||||
default_conf.update({'strategy': 'DefaultStrategy'})
|
||||
strategy = StrategyResolver.load_strategy(default_conf)
|
||||
|
||||
data = strategy.tickerdata_to_dataframe(
|
||||
data = strategy.ohlcvdata_to_dataframe(
|
||||
load_data(
|
||||
datadir=testdatadir,
|
||||
timeframe='1m',
|
||||
@@ -446,7 +446,7 @@ def test_validate_backtest_data(default_conf, mocker, caplog, testdatadir) -> No
|
||||
strategy = StrategyResolver.load_strategy(default_conf)
|
||||
|
||||
timerange = TimeRange('index', 'index', 200, 250)
|
||||
data = strategy.tickerdata_to_dataframe(
|
||||
data = strategy.ohlcvdata_to_dataframe(
|
||||
load_data(
|
||||
datadir=testdatadir,
|
||||
timeframe='5m',
|
||||
|
@@ -11,7 +11,7 @@ import pytest
|
||||
from pandas import DataFrame, to_datetime
|
||||
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.data.converter import parse_ticker_dataframe
|
||||
from freqtrade.data.converter import ohlcv_to_dataframe
|
||||
from freqtrade.edge import Edge, PairInfo
|
||||
from freqtrade.strategy.interface import SellType
|
||||
from tests.conftest import get_patched_freqtradebot, log_has
|
||||
@@ -26,7 +26,7 @@ from tests.optimize import (BTContainer, BTrade, _build_backtest_dataframe,
|
||||
# 5) Stoploss and sell are hit. should sell on stoploss
|
||||
####################################################################
|
||||
|
||||
ticker_start_time = arrow.get(2018, 10, 3)
|
||||
tests_start_time = arrow.get(2018, 10, 3)
|
||||
ticker_interval_in_minute = 60
|
||||
_ohlc = {'date': 0, 'buy': 1, 'open': 2, 'high': 3, 'low': 4, 'close': 5, 'sell': 6, 'volume': 7}
|
||||
|
||||
@@ -43,10 +43,10 @@ def _validate_ohlc(buy_ohlc_sell_matrice):
|
||||
|
||||
def _build_dataframe(buy_ohlc_sell_matrice):
|
||||
_validate_ohlc(buy_ohlc_sell_matrice)
|
||||
tickers = []
|
||||
data = []
|
||||
for ohlc in buy_ohlc_sell_matrice:
|
||||
ticker = {
|
||||
'date': ticker_start_time.shift(
|
||||
d = {
|
||||
'date': tests_start_time.shift(
|
||||
minutes=(
|
||||
ohlc[0] *
|
||||
ticker_interval_in_minute)).timestamp *
|
||||
@@ -57,9 +57,9 @@ def _build_dataframe(buy_ohlc_sell_matrice):
|
||||
'low': ohlc[4],
|
||||
'close': ohlc[5],
|
||||
'sell': ohlc[6]}
|
||||
tickers.append(ticker)
|
||||
data.append(d)
|
||||
|
||||
frame = DataFrame(tickers)
|
||||
frame = DataFrame(data)
|
||||
frame['date'] = to_datetime(frame['date'],
|
||||
unit='ms',
|
||||
utc=True,
|
||||
@@ -69,7 +69,7 @@ def _build_dataframe(buy_ohlc_sell_matrice):
|
||||
|
||||
|
||||
def _time_on_candle(number):
|
||||
return np.datetime64(ticker_start_time.shift(
|
||||
return np.datetime64(tests_start_time.shift(
|
||||
minutes=(number * ticker_interval_in_minute)).timestamp * 1000, 'ms')
|
||||
|
||||
|
||||
@@ -262,7 +262,7 @@ def mocked_load_data(datadir, pairs=[], timeframe='0m',
|
||||
|
||||
NEOBTC = [
|
||||
[
|
||||
ticker_start_time.shift(minutes=(x * ticker_interval_in_minute)).timestamp * 1000,
|
||||
tests_start_time.shift(minutes=(x * ticker_interval_in_minute)).timestamp * 1000,
|
||||
math.sin(x * hz) / 1000 + base,
|
||||
math.sin(x * hz) / 1000 + base + 0.0001,
|
||||
math.sin(x * hz) / 1000 + base - 0.0001,
|
||||
@@ -274,7 +274,7 @@ def mocked_load_data(datadir, pairs=[], timeframe='0m',
|
||||
base = 0.002
|
||||
LTCBTC = [
|
||||
[
|
||||
ticker_start_time.shift(minutes=(x * ticker_interval_in_minute)).timestamp * 1000,
|
||||
tests_start_time.shift(minutes=(x * ticker_interval_in_minute)).timestamp * 1000,
|
||||
math.sin(x * hz) / 1000 + base,
|
||||
math.sin(x * hz) / 1000 + base + 0.0001,
|
||||
math.sin(x * hz) / 1000 + base - 0.0001,
|
||||
@@ -282,8 +282,10 @@ def mocked_load_data(datadir, pairs=[], timeframe='0m',
|
||||
123.45
|
||||
] for x in range(0, 500)]
|
||||
|
||||
pairdata = {'NEO/BTC': parse_ticker_dataframe(NEOBTC, '1h', pair="NEO/BTC", fill_missing=True),
|
||||
'LTC/BTC': parse_ticker_dataframe(LTCBTC, '1h', pair="LTC/BTC", fill_missing=True)}
|
||||
pairdata = {'NEO/BTC': ohlcv_to_dataframe(NEOBTC, '1h', pair="NEO/BTC",
|
||||
fill_missing=True),
|
||||
'LTC/BTC': ohlcv_to_dataframe(LTCBTC, '1h', pair="LTC/BTC",
|
||||
fill_missing=True)}
|
||||
return pairdata
|
||||
|
||||
|
||||
|
@@ -581,7 +581,7 @@ def test_validate_timeframes_failed(default_conf, mocker):
|
||||
mocker.patch('freqtrade.exchange.Exchange._load_markets', MagicMock(return_value={}))
|
||||
mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock())
|
||||
with pytest.raises(OperationalException,
|
||||
match=r"Invalid ticker interval '3m'. This exchange supports.*"):
|
||||
match=r"Invalid timeframe '3m'. This exchange supports.*"):
|
||||
Exchange(default_conf)
|
||||
default_conf["ticker_interval"] = "15s"
|
||||
|
||||
@@ -1211,7 +1211,7 @@ def test_fetch_ticker(default_conf, mocker, exchange_name):
|
||||
@pytest.mark.parametrize("exchange_name", EXCHANGES)
|
||||
def test_get_historic_ohlcv(default_conf, mocker, caplog, exchange_name):
|
||||
exchange = get_patched_exchange(mocker, default_conf, id=exchange_name)
|
||||
tick = [
|
||||
ohlcv = [
|
||||
[
|
||||
arrow.utcnow().timestamp * 1000, # unix timestamp ms
|
||||
1, # open
|
||||
@@ -1224,7 +1224,7 @@ def test_get_historic_ohlcv(default_conf, mocker, caplog, exchange_name):
|
||||
pair = 'ETH/BTC'
|
||||
|
||||
async def mock_candle_hist(pair, timeframe, since_ms):
|
||||
return pair, timeframe, tick
|
||||
return pair, timeframe, ohlcv
|
||||
|
||||
exchange._async_get_candle_history = Mock(wraps=mock_candle_hist)
|
||||
# one_call calculation * 1.8 should do 2 calls
|
||||
@@ -1232,12 +1232,12 @@ def test_get_historic_ohlcv(default_conf, mocker, caplog, exchange_name):
|
||||
ret = exchange.get_historic_ohlcv(pair, "5m", int((arrow.utcnow().timestamp - since) * 1000))
|
||||
|
||||
assert exchange._async_get_candle_history.call_count == 2
|
||||
# Returns twice the above tick
|
||||
# Returns twice the above OHLCV data
|
||||
assert len(ret) == 2
|
||||
|
||||
|
||||
def test_refresh_latest_ohlcv(mocker, default_conf, caplog) -> None:
|
||||
tick = [
|
||||
ohlcv = [
|
||||
[
|
||||
(arrow.utcnow().timestamp - 1) * 1000, # unix timestamp ms
|
||||
1, # open
|
||||
@@ -1258,14 +1258,14 @@ def test_refresh_latest_ohlcv(mocker, default_conf, caplog) -> None:
|
||||
|
||||
caplog.set_level(logging.DEBUG)
|
||||
exchange = get_patched_exchange(mocker, default_conf)
|
||||
exchange._api_async.fetch_ohlcv = get_mock_coro(tick)
|
||||
exchange._api_async.fetch_ohlcv = get_mock_coro(ohlcv)
|
||||
|
||||
pairs = [('IOTA/ETH', '5m'), ('XRP/ETH', '5m')]
|
||||
# empty dicts
|
||||
assert not exchange._klines
|
||||
exchange.refresh_latest_ohlcv(pairs)
|
||||
|
||||
assert log_has(f'Refreshing ohlcv data for {len(pairs)} pairs', caplog)
|
||||
assert log_has(f'Refreshing candle (OHLCV) data for {len(pairs)} pairs', caplog)
|
||||
assert exchange._klines
|
||||
assert exchange._api_async.fetch_ohlcv.call_count == 2
|
||||
for pair in pairs:
|
||||
@@ -1283,14 +1283,15 @@ def test_refresh_latest_ohlcv(mocker, default_conf, caplog) -> None:
|
||||
exchange.refresh_latest_ohlcv([('IOTA/ETH', '5m'), ('XRP/ETH', '5m')])
|
||||
|
||||
assert exchange._api_async.fetch_ohlcv.call_count == 2
|
||||
assert log_has(f"Using cached ohlcv data for pair {pairs[0][0]}, timeframe {pairs[0][1]} ...",
|
||||
assert log_has(f"Using cached candle (OHLCV) data for pair {pairs[0][0]}, "
|
||||
f"timeframe {pairs[0][1]} ...",
|
||||
caplog)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize("exchange_name", EXCHANGES)
|
||||
async def test__async_get_candle_history(default_conf, mocker, caplog, exchange_name):
|
||||
tick = [
|
||||
ohlcv = [
|
||||
[
|
||||
arrow.utcnow().timestamp * 1000, # unix timestamp ms
|
||||
1, # open
|
||||
@@ -1304,7 +1305,7 @@ async def test__async_get_candle_history(default_conf, mocker, caplog, exchange_
|
||||
caplog.set_level(logging.DEBUG)
|
||||
exchange = get_patched_exchange(mocker, default_conf, id=exchange_name)
|
||||
# Monkey-patch async function
|
||||
exchange._api_async.fetch_ohlcv = get_mock_coro(tick)
|
||||
exchange._api_async.fetch_ohlcv = get_mock_coro(ohlcv)
|
||||
|
||||
pair = 'ETH/BTC'
|
||||
res = await exchange._async_get_candle_history(pair, "5m")
|
||||
@@ -1312,9 +1313,9 @@ async def test__async_get_candle_history(default_conf, mocker, caplog, exchange_
|
||||
assert len(res) == 3
|
||||
assert res[0] == pair
|
||||
assert res[1] == "5m"
|
||||
assert res[2] == tick
|
||||
assert res[2] == ohlcv
|
||||
assert exchange._api_async.fetch_ohlcv.call_count == 1
|
||||
assert not log_has(f"Using cached ohlcv data for {pair} ...", caplog)
|
||||
assert not log_has(f"Using cached candle (OHLCV) data for {pair} ...", caplog)
|
||||
|
||||
# exchange = Exchange(default_conf)
|
||||
await async_ccxt_exception(mocker, default_conf, MagicMock(),
|
||||
@@ -1322,14 +1323,15 @@ async def test__async_get_candle_history(default_conf, mocker, caplog, exchange_
|
||||
pair='ABCD/BTC', timeframe=default_conf['ticker_interval'])
|
||||
|
||||
api_mock = MagicMock()
|
||||
with pytest.raises(OperationalException, match=r'Could not fetch ticker data*'):
|
||||
with pytest.raises(OperationalException,
|
||||
match=r'Could not fetch historical candle \(OHLCV\) data.*'):
|
||||
api_mock.fetch_ohlcv = MagicMock(side_effect=ccxt.BaseError("Unknown error"))
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name)
|
||||
await exchange._async_get_candle_history(pair, "5m",
|
||||
(arrow.utcnow().timestamp - 2000) * 1000)
|
||||
|
||||
with pytest.raises(OperationalException, match=r'Exchange.* does not support fetching '
|
||||
r'historical candlestick data\..*'):
|
||||
r'historical candle \(OHLCV\) data\..*'):
|
||||
api_mock.fetch_ohlcv = MagicMock(side_effect=ccxt.NotSupported("Not supported"))
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name)
|
||||
await exchange._async_get_candle_history(pair, "5m",
|
||||
@@ -1339,7 +1341,7 @@ async def test__async_get_candle_history(default_conf, mocker, caplog, exchange_
|
||||
@pytest.mark.asyncio
|
||||
async def test__async_get_candle_history_empty(default_conf, mocker, caplog):
|
||||
""" Test empty exchange result """
|
||||
tick = []
|
||||
ohlcv = []
|
||||
|
||||
caplog.set_level(logging.DEBUG)
|
||||
exchange = get_patched_exchange(mocker, default_conf)
|
||||
@@ -1353,7 +1355,7 @@ async def test__async_get_candle_history_empty(default_conf, mocker, caplog):
|
||||
assert len(res) == 3
|
||||
assert res[0] == pair
|
||||
assert res[1] == "5m"
|
||||
assert res[2] == tick
|
||||
assert res[2] == ohlcv
|
||||
assert exchange._api_async.fetch_ohlcv.call_count == 1
|
||||
|
||||
|
||||
@@ -1431,8 +1433,8 @@ async def test___async_get_candle_history_sort(default_conf, mocker, exchange_na
|
||||
return sorted(data, key=key)
|
||||
|
||||
# GDAX use-case (real data from GDAX)
|
||||
# This ticker history is ordered DESC (newest first, oldest last)
|
||||
tick = [
|
||||
# This OHLCV data is ordered DESC (newest first, oldest last)
|
||||
ohlcv = [
|
||||
[1527833100000, 0.07666, 0.07671, 0.07666, 0.07668, 16.65244264],
|
||||
[1527832800000, 0.07662, 0.07666, 0.07662, 0.07666, 1.30051526],
|
||||
[1527832500000, 0.07656, 0.07661, 0.07656, 0.07661, 12.034778840000001],
|
||||
@@ -1445,31 +1447,31 @@ async def test___async_get_candle_history_sort(default_conf, mocker, exchange_na
|
||||
[1527830400000, 0.07649, 0.07651, 0.07649, 0.07651, 2.5734867]
|
||||
]
|
||||
exchange = get_patched_exchange(mocker, default_conf, id=exchange_name)
|
||||
exchange._api_async.fetch_ohlcv = get_mock_coro(tick)
|
||||
exchange._api_async.fetch_ohlcv = get_mock_coro(ohlcv)
|
||||
sort_mock = mocker.patch('freqtrade.exchange.exchange.sorted', MagicMock(side_effect=sort_data))
|
||||
# Test the ticker history sort
|
||||
# Test the OHLCV data sort
|
||||
res = await exchange._async_get_candle_history('ETH/BTC', default_conf['ticker_interval'])
|
||||
assert res[0] == 'ETH/BTC'
|
||||
ticks = res[2]
|
||||
res_ohlcv = res[2]
|
||||
|
||||
assert sort_mock.call_count == 1
|
||||
assert ticks[0][0] == 1527830400000
|
||||
assert ticks[0][1] == 0.07649
|
||||
assert ticks[0][2] == 0.07651
|
||||
assert ticks[0][3] == 0.07649
|
||||
assert ticks[0][4] == 0.07651
|
||||
assert ticks[0][5] == 2.5734867
|
||||
assert res_ohlcv[0][0] == 1527830400000
|
||||
assert res_ohlcv[0][1] == 0.07649
|
||||
assert res_ohlcv[0][2] == 0.07651
|
||||
assert res_ohlcv[0][3] == 0.07649
|
||||
assert res_ohlcv[0][4] == 0.07651
|
||||
assert res_ohlcv[0][5] == 2.5734867
|
||||
|
||||
assert ticks[9][0] == 1527833100000
|
||||
assert ticks[9][1] == 0.07666
|
||||
assert ticks[9][2] == 0.07671
|
||||
assert ticks[9][3] == 0.07666
|
||||
assert ticks[9][4] == 0.07668
|
||||
assert ticks[9][5] == 16.65244264
|
||||
assert res_ohlcv[9][0] == 1527833100000
|
||||
assert res_ohlcv[9][1] == 0.07666
|
||||
assert res_ohlcv[9][2] == 0.07671
|
||||
assert res_ohlcv[9][3] == 0.07666
|
||||
assert res_ohlcv[9][4] == 0.07668
|
||||
assert res_ohlcv[9][5] == 16.65244264
|
||||
|
||||
# Bittrex use-case (real data from Bittrex)
|
||||
# This ticker history is ordered ASC (oldest first, newest last)
|
||||
tick = [
|
||||
# This OHLCV data is ordered ASC (oldest first, newest last)
|
||||
ohlcv = [
|
||||
[1527827700000, 0.07659999, 0.0766, 0.07627, 0.07657998, 1.85216924],
|
||||
[1527828000000, 0.07657995, 0.07657995, 0.0763, 0.0763, 26.04051037],
|
||||
[1527828300000, 0.0763, 0.07659998, 0.0763, 0.0764, 10.36434124],
|
||||
@@ -1481,29 +1483,29 @@ async def test___async_get_candle_history_sort(default_conf, mocker, exchange_na
|
||||
[1527830100000, 0.076695, 0.07671, 0.07624171, 0.07671, 1.80689244],
|
||||
[1527830400000, 0.07671, 0.07674399, 0.07629216, 0.07655213, 2.31452783]
|
||||
]
|
||||
exchange._api_async.fetch_ohlcv = get_mock_coro(tick)
|
||||
exchange._api_async.fetch_ohlcv = get_mock_coro(ohlcv)
|
||||
# Reset sort mock
|
||||
sort_mock = mocker.patch('freqtrade.exchange.sorted', MagicMock(side_effect=sort_data))
|
||||
# Test the ticker history sort
|
||||
# Test the OHLCV data sort
|
||||
res = await exchange._async_get_candle_history('ETH/BTC', default_conf['ticker_interval'])
|
||||
assert res[0] == 'ETH/BTC'
|
||||
assert res[1] == default_conf['ticker_interval']
|
||||
ticks = res[2]
|
||||
res_ohlcv = res[2]
|
||||
# Sorted not called again - data is already in order
|
||||
assert sort_mock.call_count == 0
|
||||
assert ticks[0][0] == 1527827700000
|
||||
assert ticks[0][1] == 0.07659999
|
||||
assert ticks[0][2] == 0.0766
|
||||
assert ticks[0][3] == 0.07627
|
||||
assert ticks[0][4] == 0.07657998
|
||||
assert ticks[0][5] == 1.85216924
|
||||
assert res_ohlcv[0][0] == 1527827700000
|
||||
assert res_ohlcv[0][1] == 0.07659999
|
||||
assert res_ohlcv[0][2] == 0.0766
|
||||
assert res_ohlcv[0][3] == 0.07627
|
||||
assert res_ohlcv[0][4] == 0.07657998
|
||||
assert res_ohlcv[0][5] == 1.85216924
|
||||
|
||||
assert ticks[9][0] == 1527830400000
|
||||
assert ticks[9][1] == 0.07671
|
||||
assert ticks[9][2] == 0.07674399
|
||||
assert ticks[9][3] == 0.07629216
|
||||
assert ticks[9][4] == 0.07655213
|
||||
assert ticks[9][5] == 2.31452783
|
||||
assert res_ohlcv[9][0] == 1527830400000
|
||||
assert res_ohlcv[9][1] == 0.07671
|
||||
assert res_ohlcv[9][2] == 0.07674399
|
||||
assert res_ohlcv[9][3] == 0.07629216
|
||||
assert res_ohlcv[9][4] == 0.07655213
|
||||
assert res_ohlcv[9][5] == 2.31452783
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
@@ -6,7 +6,7 @@ from pandas import DataFrame
|
||||
from freqtrade.exchange import timeframe_to_minutes
|
||||
from freqtrade.strategy.interface import SellType
|
||||
|
||||
ticker_start_time = arrow.get(2018, 10, 3)
|
||||
tests_start_time = arrow.get(2018, 10, 3)
|
||||
tests_timeframe = '1h'
|
||||
|
||||
|
||||
@@ -36,14 +36,14 @@ class BTContainer(NamedTuple):
|
||||
|
||||
|
||||
def _get_frame_time_from_offset(offset):
|
||||
return ticker_start_time.shift(minutes=(offset * timeframe_to_minutes(tests_timeframe))
|
||||
).datetime
|
||||
minutes = offset * timeframe_to_minutes(tests_timeframe)
|
||||
return tests_start_time.shift(minutes=minutes).datetime
|
||||
|
||||
|
||||
def _build_backtest_dataframe(ticker_with_signals):
|
||||
def _build_backtest_dataframe(data):
|
||||
columns = ['date', 'open', 'high', 'low', 'close', 'volume', 'buy', 'sell']
|
||||
|
||||
frame = DataFrame.from_records(ticker_with_signals, columns=columns)
|
||||
frame = DataFrame.from_records(data, columns=columns)
|
||||
frame['date'] = frame['date'].apply(_get_frame_time_from_offset)
|
||||
# Ensure floats are in place
|
||||
for column in ['open', 'high', 'low', 'close', 'volume']:
|
||||
|
@@ -84,7 +84,7 @@ def simple_backtest(config, contour, num_results, mocker, testdatadir) -> None:
|
||||
backtesting = Backtesting(config)
|
||||
|
||||
data = load_data_test(contour, testdatadir)
|
||||
processed = backtesting.strategy.tickerdata_to_dataframe(data)
|
||||
processed = backtesting.strategy.ohlcvdata_to_dataframe(data)
|
||||
min_date, max_date = get_timerange(processed)
|
||||
assert isinstance(processed, dict)
|
||||
results = backtesting.backtest(
|
||||
@@ -105,7 +105,7 @@ def _make_backtest_conf(mocker, datadir, conf=None, pair='UNITTEST/BTC'):
|
||||
data = trim_dictlist(data, -201)
|
||||
patch_exchange(mocker)
|
||||
backtesting = Backtesting(conf)
|
||||
processed = backtesting.strategy.tickerdata_to_dataframe(data)
|
||||
processed = backtesting.strategy.ohlcvdata_to_dataframe(data)
|
||||
min_date, max_date = get_timerange(processed)
|
||||
return {
|
||||
'processed': processed,
|
||||
@@ -275,7 +275,7 @@ def test_backtesting_init(mocker, default_conf, order_types) -> None:
|
||||
backtesting = Backtesting(default_conf)
|
||||
assert backtesting.config == default_conf
|
||||
assert backtesting.timeframe == '5m'
|
||||
assert callable(backtesting.strategy.tickerdata_to_dataframe)
|
||||
assert callable(backtesting.strategy.ohlcvdata_to_dataframe)
|
||||
assert callable(backtesting.strategy.advise_buy)
|
||||
assert callable(backtesting.strategy.advise_sell)
|
||||
assert isinstance(backtesting.strategy.dp, DataProvider)
|
||||
@@ -297,7 +297,7 @@ def test_backtesting_init_no_ticker_interval(mocker, default_conf, caplog) -> No
|
||||
"or as cli argument `--ticker-interval 5m`", caplog)
|
||||
|
||||
|
||||
def test_tickerdata_with_fee(default_conf, mocker, testdatadir) -> None:
|
||||
def test_data_with_fee(default_conf, mocker, testdatadir) -> None:
|
||||
patch_exchange(mocker)
|
||||
default_conf['fee'] = 0.1234
|
||||
|
||||
@@ -307,21 +307,21 @@ def test_tickerdata_with_fee(default_conf, mocker, testdatadir) -> None:
|
||||
assert fee_mock.call_count == 0
|
||||
|
||||
|
||||
def test_tickerdata_to_dataframe_bt(default_conf, mocker, testdatadir) -> None:
|
||||
def test_data_to_dataframe_bt(default_conf, mocker, testdatadir) -> None:
|
||||
patch_exchange(mocker)
|
||||
timerange = TimeRange.parse_timerange('1510694220-1510700340')
|
||||
tickerlist = history.load_data(testdatadir, '1m', ['UNITTEST/BTC'], timerange=timerange,
|
||||
fill_up_missing=True)
|
||||
data = history.load_data(testdatadir, '1m', ['UNITTEST/BTC'], timerange=timerange,
|
||||
fill_up_missing=True)
|
||||
backtesting = Backtesting(default_conf)
|
||||
data = backtesting.strategy.tickerdata_to_dataframe(tickerlist)
|
||||
assert len(data['UNITTEST/BTC']) == 102
|
||||
processed = backtesting.strategy.ohlcvdata_to_dataframe(data)
|
||||
assert len(processed['UNITTEST/BTC']) == 102
|
||||
|
||||
# Load strategy to compare the result between Backtesting function and strategy are the same
|
||||
default_conf.update({'strategy': 'DefaultStrategy'})
|
||||
strategy = StrategyResolver.load_strategy(default_conf)
|
||||
|
||||
data2 = strategy.tickerdata_to_dataframe(tickerlist)
|
||||
assert data['UNITTEST/BTC'].equals(data2['UNITTEST/BTC'])
|
||||
processed2 = strategy.ohlcvdata_to_dataframe(data)
|
||||
assert processed['UNITTEST/BTC'].equals(processed2['UNITTEST/BTC'])
|
||||
|
||||
|
||||
def test_backtesting_start(default_conf, mocker, testdatadir, caplog) -> None:
|
||||
@@ -329,7 +329,6 @@ def test_backtesting_start(default_conf, mocker, testdatadir, caplog) -> None:
|
||||
return Arrow(2017, 11, 14, 21, 17), Arrow(2017, 11, 14, 22, 59)
|
||||
|
||||
mocker.patch('freqtrade.data.history.get_timerange', get_timerange)
|
||||
mocker.patch('freqtrade.exchange.Exchange.refresh_latest_ohlcv', MagicMock())
|
||||
patch_exchange(mocker)
|
||||
mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', MagicMock())
|
||||
mocker.patch('freqtrade.optimize.backtesting.generate_text_table', MagicMock(return_value=1))
|
||||
@@ -360,7 +359,6 @@ def test_backtesting_start_no_data(default_conf, mocker, caplog, testdatadir) ->
|
||||
mocker.patch('freqtrade.data.history.history_utils.load_pair_history',
|
||||
MagicMock(return_value=pd.DataFrame()))
|
||||
mocker.patch('freqtrade.data.history.get_timerange', get_timerange)
|
||||
mocker.patch('freqtrade.exchange.Exchange.refresh_latest_ohlcv', MagicMock())
|
||||
patch_exchange(mocker)
|
||||
mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', MagicMock())
|
||||
mocker.patch('freqtrade.optimize.backtesting.generate_text_table', MagicMock(return_value=1))
|
||||
@@ -385,10 +383,10 @@ def test_backtest(default_conf, fee, mocker, testdatadir) -> None:
|
||||
timerange = TimeRange('date', None, 1517227800, 0)
|
||||
data = history.load_data(datadir=testdatadir, timeframe='5m', pairs=['UNITTEST/BTC'],
|
||||
timerange=timerange)
|
||||
data_processed = backtesting.strategy.tickerdata_to_dataframe(data)
|
||||
min_date, max_date = get_timerange(data_processed)
|
||||
processed = backtesting.strategy.ohlcvdata_to_dataframe(data)
|
||||
min_date, max_date = get_timerange(processed)
|
||||
results = backtesting.backtest(
|
||||
processed=data_processed,
|
||||
processed=processed,
|
||||
stake_amount=default_conf['stake_amount'],
|
||||
start_date=min_date,
|
||||
end_date=max_date,
|
||||
@@ -416,7 +414,7 @@ def test_backtest(default_conf, fee, mocker, testdatadir) -> None:
|
||||
'sell_reason': [SellType.ROI, SellType.ROI]
|
||||
})
|
||||
pd.testing.assert_frame_equal(results, expected)
|
||||
data_pair = data_processed[pair]
|
||||
data_pair = processed[pair]
|
||||
for _, t in results.iterrows():
|
||||
ln = data_pair.loc[data_pair["date"] == t["open_time"]]
|
||||
# Check open trade rate alignes to open rate
|
||||
@@ -439,7 +437,7 @@ def test_backtest_1min_ticker_interval(default_conf, fee, mocker, testdatadir) -
|
||||
timerange = TimeRange.parse_timerange('1510688220-1510700340')
|
||||
data = history.load_data(datadir=testdatadir, timeframe='1m', pairs=['UNITTEST/BTC'],
|
||||
timerange=timerange)
|
||||
processed = backtesting.strategy.tickerdata_to_dataframe(data)
|
||||
processed = backtesting.strategy.ohlcvdata_to_dataframe(data)
|
||||
min_date, max_date = get_timerange(processed)
|
||||
results = backtesting.backtest(
|
||||
processed=processed,
|
||||
@@ -458,7 +456,7 @@ def test_processed(default_conf, mocker, testdatadir) -> None:
|
||||
backtesting = Backtesting(default_conf)
|
||||
|
||||
dict_of_tickerrows = load_data_test('raise', testdatadir)
|
||||
dataframes = backtesting.strategy.tickerdata_to_dataframe(dict_of_tickerrows)
|
||||
dataframes = backtesting.strategy.ohlcvdata_to_dataframe(dict_of_tickerrows)
|
||||
dataframe = dataframes['UNITTEST/BTC']
|
||||
cols = dataframe.columns
|
||||
# assert the dataframe got some of the indicator columns
|
||||
@@ -557,10 +555,10 @@ def test_backtest_multi_pair(default_conf, fee, mocker, tres, pair, testdatadir)
|
||||
backtesting.strategy.advise_buy = _trend_alternate_hold # Override
|
||||
backtesting.strategy.advise_sell = _trend_alternate_hold # Override
|
||||
|
||||
data_processed = backtesting.strategy.tickerdata_to_dataframe(data)
|
||||
min_date, max_date = get_timerange(data_processed)
|
||||
processed = backtesting.strategy.ohlcvdata_to_dataframe(data)
|
||||
min_date, max_date = get_timerange(processed)
|
||||
backtest_conf = {
|
||||
'processed': data_processed,
|
||||
'processed': processed,
|
||||
'stake_amount': default_conf['stake_amount'],
|
||||
'start_date': min_date,
|
||||
'end_date': max_date,
|
||||
@@ -576,7 +574,7 @@ def test_backtest_multi_pair(default_conf, fee, mocker, tres, pair, testdatadir)
|
||||
assert len(evaluate_result_multi(results, '5m', 3)) == 0
|
||||
|
||||
backtest_conf = {
|
||||
'processed': data_processed,
|
||||
'processed': processed,
|
||||
'stake_amount': default_conf['stake_amount'],
|
||||
'start_date': min_date,
|
||||
'end_date': max_date,
|
||||
|
@@ -524,7 +524,7 @@ def test_start_calls_optimizer(mocker, default_conf, caplog, capsys) -> None:
|
||||
}])
|
||||
)
|
||||
patch_exchange(mocker)
|
||||
# Co-test loading ticker-interval from strategy
|
||||
# Co-test loading timeframe from strategy
|
||||
del default_conf['ticker_interval']
|
||||
default_conf.update({'config': 'config.json.example',
|
||||
'hyperopt': 'DefaultHyperOpt',
|
||||
@@ -534,7 +534,7 @@ def test_start_calls_optimizer(mocker, default_conf, caplog, capsys) -> None:
|
||||
'hyperopt_jobs': 1, })
|
||||
|
||||
hyperopt = Hyperopt(default_conf)
|
||||
hyperopt.backtesting.strategy.tickerdata_to_dataframe = MagicMock()
|
||||
hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock()
|
||||
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
||||
|
||||
hyperopt.start()
|
||||
@@ -544,7 +544,7 @@ def test_start_calls_optimizer(mocker, default_conf, caplog, capsys) -> None:
|
||||
out, err = capsys.readouterr()
|
||||
assert 'Best result:\n\n* 1/1: foo result Objective: 1.00000\n' in out
|
||||
assert dumper.called
|
||||
# Should be called twice, once for tickerdata, once to save evaluations
|
||||
# Should be called twice, once for historical candle data, once to save evaluations
|
||||
assert dumper.call_count == 2
|
||||
assert hasattr(hyperopt.backtesting.strategy, "advise_sell")
|
||||
assert hasattr(hyperopt.backtesting.strategy, "advise_buy")
|
||||
@@ -630,8 +630,8 @@ def test_has_space(hyperopt, spaces, expected_results):
|
||||
|
||||
|
||||
def test_populate_indicators(hyperopt, testdatadir) -> None:
|
||||
tickerlist = load_data(testdatadir, '1m', ['UNITTEST/BTC'], fill_up_missing=True)
|
||||
dataframes = hyperopt.backtesting.strategy.tickerdata_to_dataframe(tickerlist)
|
||||
data = load_data(testdatadir, '1m', ['UNITTEST/BTC'], fill_up_missing=True)
|
||||
dataframes = hyperopt.backtesting.strategy.ohlcvdata_to_dataframe(data)
|
||||
dataframe = hyperopt.custom_hyperopt.populate_indicators(dataframes['UNITTEST/BTC'],
|
||||
{'pair': 'UNITTEST/BTC'})
|
||||
|
||||
@@ -642,8 +642,8 @@ def test_populate_indicators(hyperopt, testdatadir) -> None:
|
||||
|
||||
|
||||
def test_buy_strategy_generator(hyperopt, testdatadir) -> None:
|
||||
tickerlist = load_data(testdatadir, '1m', ['UNITTEST/BTC'], fill_up_missing=True)
|
||||
dataframes = hyperopt.backtesting.strategy.tickerdata_to_dataframe(tickerlist)
|
||||
data = load_data(testdatadir, '1m', ['UNITTEST/BTC'], fill_up_missing=True)
|
||||
dataframes = hyperopt.backtesting.strategy.ohlcvdata_to_dataframe(data)
|
||||
dataframe = hyperopt.custom_hyperopt.populate_indicators(dataframes['UNITTEST/BTC'],
|
||||
{'pair': 'UNITTEST/BTC'})
|
||||
|
||||
@@ -783,7 +783,7 @@ def test_clean_hyperopt(mocker, default_conf, caplog):
|
||||
h = Hyperopt(default_conf)
|
||||
|
||||
assert unlinkmock.call_count == 2
|
||||
assert log_has(f"Removing `{h.tickerdata_pickle}`.", caplog)
|
||||
assert log_has(f"Removing `{h.data_pickle_file}`.", caplog)
|
||||
|
||||
|
||||
def test_continue_hyperopt(mocker, default_conf, caplog):
|
||||
@@ -845,7 +845,7 @@ def test_print_json_spaces_all(mocker, default_conf, caplog, capsys) -> None:
|
||||
})
|
||||
|
||||
hyperopt = Hyperopt(default_conf)
|
||||
hyperopt.backtesting.strategy.tickerdata_to_dataframe = MagicMock()
|
||||
hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock()
|
||||
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
||||
|
||||
hyperopt.start()
|
||||
@@ -859,7 +859,7 @@ def test_print_json_spaces_all(mocker, default_conf, caplog, capsys) -> None:
|
||||
)
|
||||
assert result_str in out # noqa: E501
|
||||
assert dumper.called
|
||||
# Should be called twice, once for tickerdata, once to save evaluations
|
||||
# Should be called twice, once for historical candle data, once to save evaluations
|
||||
assert dumper.call_count == 2
|
||||
|
||||
|
||||
@@ -903,7 +903,7 @@ def test_print_json_spaces_default(mocker, default_conf, caplog, capsys) -> None
|
||||
})
|
||||
|
||||
hyperopt = Hyperopt(default_conf)
|
||||
hyperopt.backtesting.strategy.tickerdata_to_dataframe = MagicMock()
|
||||
hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock()
|
||||
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
||||
|
||||
hyperopt.start()
|
||||
@@ -913,7 +913,7 @@ def test_print_json_spaces_default(mocker, default_conf, caplog, capsys) -> None
|
||||
out, err = capsys.readouterr()
|
||||
assert '{"params":{"mfi-value":null,"sell-mfi-value":null},"minimal_roi":{},"stoploss":null}' in out # noqa: E501
|
||||
assert dumper.called
|
||||
# Should be called twice, once for tickerdata, once to save evaluations
|
||||
# Should be called twice, once for historical candle data, once to save evaluations
|
||||
assert dumper.call_count == 2
|
||||
|
||||
|
||||
@@ -953,7 +953,7 @@ def test_print_json_spaces_roi_stoploss(mocker, default_conf, caplog, capsys) ->
|
||||
})
|
||||
|
||||
hyperopt = Hyperopt(default_conf)
|
||||
hyperopt.backtesting.strategy.tickerdata_to_dataframe = MagicMock()
|
||||
hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock()
|
||||
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
||||
|
||||
hyperopt.start()
|
||||
@@ -963,7 +963,7 @@ def test_print_json_spaces_roi_stoploss(mocker, default_conf, caplog, capsys) ->
|
||||
out, err = capsys.readouterr()
|
||||
assert '{"minimal_roi":{},"stoploss":null}' in out
|
||||
assert dumper.called
|
||||
# Should be called twice, once for tickerdata, once to save evaluations
|
||||
# Should be called twice, once for historical candle data, once to save evaluations
|
||||
assert dumper.call_count == 2
|
||||
|
||||
|
||||
@@ -1000,7 +1000,7 @@ def test_simplified_interface_roi_stoploss(mocker, default_conf, caplog, capsys)
|
||||
'hyperopt_jobs': 1, })
|
||||
|
||||
hyperopt = Hyperopt(default_conf)
|
||||
hyperopt.backtesting.strategy.tickerdata_to_dataframe = MagicMock()
|
||||
hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock()
|
||||
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
||||
|
||||
del hyperopt.custom_hyperopt.__class__.buy_strategy_generator
|
||||
@@ -1015,7 +1015,7 @@ def test_simplified_interface_roi_stoploss(mocker, default_conf, caplog, capsys)
|
||||
out, err = capsys.readouterr()
|
||||
assert 'Best result:\n\n* 1/1: foo result Objective: 1.00000\n' in out
|
||||
assert dumper.called
|
||||
# Should be called twice, once for tickerdata, once to save evaluations
|
||||
# Should be called twice, once for historical candle data, once to save evaluations
|
||||
assert dumper.call_count == 2
|
||||
assert hasattr(hyperopt.backtesting.strategy, "advise_sell")
|
||||
assert hasattr(hyperopt.backtesting.strategy, "advise_buy")
|
||||
@@ -1043,7 +1043,7 @@ def test_simplified_interface_all_failed(mocker, default_conf, caplog, capsys) -
|
||||
'hyperopt_jobs': 1, })
|
||||
|
||||
hyperopt = Hyperopt(default_conf)
|
||||
hyperopt.backtesting.strategy.tickerdata_to_dataframe = MagicMock()
|
||||
hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock()
|
||||
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
||||
|
||||
del hyperopt.custom_hyperopt.__class__.buy_strategy_generator
|
||||
@@ -1088,7 +1088,7 @@ def test_simplified_interface_buy(mocker, default_conf, caplog, capsys) -> None:
|
||||
'hyperopt_jobs': 1, })
|
||||
|
||||
hyperopt = Hyperopt(default_conf)
|
||||
hyperopt.backtesting.strategy.tickerdata_to_dataframe = MagicMock()
|
||||
hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock()
|
||||
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
||||
|
||||
# TODO: sell_strategy_generator() is actually not called because
|
||||
@@ -1103,7 +1103,7 @@ def test_simplified_interface_buy(mocker, default_conf, caplog, capsys) -> None:
|
||||
out, err = capsys.readouterr()
|
||||
assert 'Best result:\n\n* 1/1: foo result Objective: 1.00000\n' in out
|
||||
assert dumper.called
|
||||
# Should be called twice, once for tickerdata, once to save evaluations
|
||||
# Should be called twice, once for historical candle data, once to save evaluations
|
||||
assert dumper.call_count == 2
|
||||
assert hasattr(hyperopt.backtesting.strategy, "advise_sell")
|
||||
assert hasattr(hyperopt.backtesting.strategy, "advise_buy")
|
||||
@@ -1145,7 +1145,7 @@ def test_simplified_interface_sell(mocker, default_conf, caplog, capsys) -> None
|
||||
'hyperopt_jobs': 1, })
|
||||
|
||||
hyperopt = Hyperopt(default_conf)
|
||||
hyperopt.backtesting.strategy.tickerdata_to_dataframe = MagicMock()
|
||||
hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock()
|
||||
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
||||
|
||||
# TODO: buy_strategy_generator() is actually not called because
|
||||
@@ -1160,7 +1160,7 @@ def test_simplified_interface_sell(mocker, default_conf, caplog, capsys) -> None
|
||||
out, err = capsys.readouterr()
|
||||
assert 'Best result:\n\n* 1/1: foo result Objective: 1.00000\n' in out
|
||||
assert dumper.called
|
||||
# Should be called twice, once for tickerdata, once to save evaluations
|
||||
# Should be called twice, once for historical candle data, once to save evaluations
|
||||
assert dumper.call_count == 2
|
||||
assert hasattr(hyperopt.backtesting.strategy, "advise_sell")
|
||||
assert hasattr(hyperopt.backtesting.strategy, "advise_buy")
|
||||
@@ -1194,7 +1194,7 @@ def test_simplified_interface_failed(mocker, default_conf, caplog, capsys, metho
|
||||
'hyperopt_jobs': 1, })
|
||||
|
||||
hyperopt = Hyperopt(default_conf)
|
||||
hyperopt.backtesting.strategy.tickerdata_to_dataframe = MagicMock()
|
||||
hyperopt.backtesting.strategy.ohlcvdata_to_dataframe = MagicMock()
|
||||
hyperopt.custom_hyperopt.generate_roi_table = MagicMock(return_value={})
|
||||
|
||||
delattr(hyperopt.custom_hyperopt.__class__, method)
|
||||
|
@@ -68,7 +68,7 @@ class DefaultStrategy(IStrategy):
|
||||
Performance Note: For the best performance be frugal on the number of indicators
|
||||
you are using. Let uncomment only the indicator you are using in your strategies
|
||||
or your hyperopt configuration, otherwise you will waste your memory and CPU usage.
|
||||
:param dataframe: Raw data from the exchange and parsed by parse_ticker_dataframe()
|
||||
:param dataframe: Dataframe with data from the exchange
|
||||
:param metadata: Additional information, like the currently traded pair
|
||||
:return: a Dataframe with all mandatory indicators for the strategies
|
||||
"""
|
||||
|
@@ -17,69 +17,69 @@ from tests.conftest import get_patched_exchange, log_has
|
||||
_STRATEGY = DefaultStrategy(config={})
|
||||
|
||||
|
||||
def test_returns_latest_buy_signal(mocker, default_conf, ticker_history):
|
||||
def test_returns_latest_buy_signal(mocker, default_conf, ohlcv_history):
|
||||
mocker.patch.object(
|
||||
_STRATEGY, '_analyze_ticker_internal',
|
||||
return_value=DataFrame([{'buy': 1, 'sell': 0, 'date': arrow.utcnow()}])
|
||||
)
|
||||
assert _STRATEGY.get_signal('ETH/BTC', '5m', ticker_history) == (True, False)
|
||||
assert _STRATEGY.get_signal('ETH/BTC', '5m', ohlcv_history) == (True, False)
|
||||
|
||||
mocker.patch.object(
|
||||
_STRATEGY, '_analyze_ticker_internal',
|
||||
return_value=DataFrame([{'buy': 0, 'sell': 1, 'date': arrow.utcnow()}])
|
||||
)
|
||||
assert _STRATEGY.get_signal('ETH/BTC', '5m', ticker_history) == (False, True)
|
||||
assert _STRATEGY.get_signal('ETH/BTC', '5m', ohlcv_history) == (False, True)
|
||||
|
||||
|
||||
def test_returns_latest_sell_signal(mocker, default_conf, ticker_history):
|
||||
def test_returns_latest_sell_signal(mocker, default_conf, ohlcv_history):
|
||||
mocker.patch.object(
|
||||
_STRATEGY, '_analyze_ticker_internal',
|
||||
return_value=DataFrame([{'sell': 1, 'buy': 0, 'date': arrow.utcnow()}])
|
||||
)
|
||||
|
||||
assert _STRATEGY.get_signal('ETH/BTC', '5m', ticker_history) == (False, True)
|
||||
assert _STRATEGY.get_signal('ETH/BTC', '5m', ohlcv_history) == (False, True)
|
||||
|
||||
mocker.patch.object(
|
||||
_STRATEGY, '_analyze_ticker_internal',
|
||||
return_value=DataFrame([{'sell': 0, 'buy': 1, 'date': arrow.utcnow()}])
|
||||
)
|
||||
assert _STRATEGY.get_signal('ETH/BTC', '5m', ticker_history) == (True, False)
|
||||
assert _STRATEGY.get_signal('ETH/BTC', '5m', ohlcv_history) == (True, False)
|
||||
|
||||
|
||||
def test_get_signal_empty(default_conf, mocker, caplog):
|
||||
assert (False, False) == _STRATEGY.get_signal('foo', default_conf['ticker_interval'],
|
||||
DataFrame())
|
||||
assert log_has('Empty ticker history for pair foo', caplog)
|
||||
assert log_has('Empty candle (OHLCV) data for pair foo', caplog)
|
||||
caplog.clear()
|
||||
|
||||
assert (False, False) == _STRATEGY.get_signal('bar', default_conf['ticker_interval'],
|
||||
[])
|
||||
assert log_has('Empty ticker history for pair bar', caplog)
|
||||
assert log_has('Empty candle (OHLCV) data for pair bar', caplog)
|
||||
|
||||
|
||||
def test_get_signal_exception_valueerror(default_conf, mocker, caplog, ticker_history):
|
||||
def test_get_signal_exception_valueerror(default_conf, mocker, caplog, ohlcv_history):
|
||||
caplog.set_level(logging.INFO)
|
||||
mocker.patch.object(
|
||||
_STRATEGY, '_analyze_ticker_internal',
|
||||
side_effect=ValueError('xyz')
|
||||
)
|
||||
assert (False, False) == _STRATEGY.get_signal('foo', default_conf['ticker_interval'],
|
||||
ticker_history)
|
||||
assert log_has('Unable to analyze ticker for pair foo: xyz', caplog)
|
||||
ohlcv_history)
|
||||
assert log_has('Unable to analyze candle (OHLCV) data for pair foo: xyz', caplog)
|
||||
|
||||
|
||||
def test_get_signal_empty_dataframe(default_conf, mocker, caplog, ticker_history):
|
||||
def test_get_signal_empty_dataframe(default_conf, mocker, caplog, ohlcv_history):
|
||||
caplog.set_level(logging.INFO)
|
||||
mocker.patch.object(
|
||||
_STRATEGY, '_analyze_ticker_internal',
|
||||
return_value=DataFrame([])
|
||||
)
|
||||
assert (False, False) == _STRATEGY.get_signal('xyz', default_conf['ticker_interval'],
|
||||
ticker_history)
|
||||
ohlcv_history)
|
||||
assert log_has('Empty dataframe for pair xyz', caplog)
|
||||
|
||||
|
||||
def test_get_signal_old_dataframe(default_conf, mocker, caplog, ticker_history):
|
||||
def test_get_signal_old_dataframe(default_conf, mocker, caplog, ohlcv_history):
|
||||
caplog.set_level(logging.INFO)
|
||||
# default_conf defines a 5m interval. we check interval * 2 + 5m
|
||||
# this is necessary as the last candle is removed (partial candles) by default
|
||||
@@ -90,7 +90,7 @@ def test_get_signal_old_dataframe(default_conf, mocker, caplog, ticker_history):
|
||||
return_value=DataFrame(ticks)
|
||||
)
|
||||
assert (False, False) == _STRATEGY.get_signal('xyz', default_conf['ticker_interval'],
|
||||
ticker_history)
|
||||
ohlcv_history)
|
||||
assert log_has('Outdated history for pair xyz. Last tick is 16 minutes old', caplog)
|
||||
|
||||
|
||||
@@ -103,15 +103,15 @@ def test_get_signal_handles_exceptions(mocker, default_conf):
|
||||
assert _STRATEGY.get_signal(exchange, 'ETH/BTC', '5m') == (False, False)
|
||||
|
||||
|
||||
def test_tickerdata_to_dataframe(default_conf, testdatadir) -> None:
|
||||
def test_ohlcvdata_to_dataframe(default_conf, testdatadir) -> None:
|
||||
default_conf.update({'strategy': 'DefaultStrategy'})
|
||||
strategy = StrategyResolver.load_strategy(default_conf)
|
||||
|
||||
timerange = TimeRange.parse_timerange('1510694220-1510700340')
|
||||
tickerlist = load_data(testdatadir, '1m', ['UNITTEST/BTC'], timerange=timerange,
|
||||
fill_up_missing=True)
|
||||
data = strategy.tickerdata_to_dataframe(tickerlist)
|
||||
assert len(data['UNITTEST/BTC']) == 102 # partial candle was removed
|
||||
data = load_data(testdatadir, '1m', ['UNITTEST/BTC'], timerange=timerange,
|
||||
fill_up_missing=True)
|
||||
processed = strategy.ohlcvdata_to_dataframe(data)
|
||||
assert len(processed['UNITTEST/BTC']) == 102 # partial candle was removed
|
||||
|
||||
|
||||
def test_min_roi_reached(default_conf, fee) -> None:
|
||||
@@ -222,7 +222,7 @@ def test_min_roi_reached3(default_conf, fee) -> None:
|
||||
assert strategy.min_roi_reached(trade, 0.31, arrow.utcnow().shift(minutes=-2).datetime)
|
||||
|
||||
|
||||
def test_analyze_ticker_default(ticker_history, mocker, caplog) -> None:
|
||||
def test_analyze_ticker_default(ohlcv_history, mocker, caplog) -> None:
|
||||
caplog.set_level(logging.DEBUG)
|
||||
ind_mock = MagicMock(side_effect=lambda x, meta: x)
|
||||
buy_mock = MagicMock(side_effect=lambda x, meta: x)
|
||||
@@ -235,7 +235,7 @@ def test_analyze_ticker_default(ticker_history, mocker, caplog) -> None:
|
||||
|
||||
)
|
||||
strategy = DefaultStrategy({})
|
||||
strategy.analyze_ticker(ticker_history, {'pair': 'ETH/BTC'})
|
||||
strategy.analyze_ticker(ohlcv_history, {'pair': 'ETH/BTC'})
|
||||
assert ind_mock.call_count == 1
|
||||
assert buy_mock.call_count == 1
|
||||
assert buy_mock.call_count == 1
|
||||
@@ -244,7 +244,7 @@ def test_analyze_ticker_default(ticker_history, mocker, caplog) -> None:
|
||||
assert not log_has('Skipping TA Analysis for already analyzed candle', caplog)
|
||||
caplog.clear()
|
||||
|
||||
strategy.analyze_ticker(ticker_history, {'pair': 'ETH/BTC'})
|
||||
strategy.analyze_ticker(ohlcv_history, {'pair': 'ETH/BTC'})
|
||||
# No analysis happens as process_only_new_candles is true
|
||||
assert ind_mock.call_count == 2
|
||||
assert buy_mock.call_count == 2
|
||||
@@ -253,7 +253,7 @@ def test_analyze_ticker_default(ticker_history, mocker, caplog) -> None:
|
||||
assert not log_has('Skipping TA Analysis for already analyzed candle', caplog)
|
||||
|
||||
|
||||
def test__analyze_ticker_internal_skip_analyze(ticker_history, mocker, caplog) -> None:
|
||||
def test__analyze_ticker_internal_skip_analyze(ohlcv_history, mocker, caplog) -> None:
|
||||
caplog.set_level(logging.DEBUG)
|
||||
ind_mock = MagicMock(side_effect=lambda x, meta: x)
|
||||
buy_mock = MagicMock(side_effect=lambda x, meta: x)
|
||||
@@ -268,7 +268,7 @@ def test__analyze_ticker_internal_skip_analyze(ticker_history, mocker, caplog) -
|
||||
strategy = DefaultStrategy({})
|
||||
strategy.process_only_new_candles = True
|
||||
|
||||
ret = strategy._analyze_ticker_internal(ticker_history, {'pair': 'ETH/BTC'})
|
||||
ret = strategy._analyze_ticker_internal(ohlcv_history, {'pair': 'ETH/BTC'})
|
||||
assert 'high' in ret.columns
|
||||
assert 'low' in ret.columns
|
||||
assert 'close' in ret.columns
|
||||
@@ -280,7 +280,7 @@ def test__analyze_ticker_internal_skip_analyze(ticker_history, mocker, caplog) -
|
||||
assert not log_has('Skipping TA Analysis for already analyzed candle', caplog)
|
||||
caplog.clear()
|
||||
|
||||
ret = strategy._analyze_ticker_internal(ticker_history, {'pair': 'ETH/BTC'})
|
||||
ret = strategy._analyze_ticker_internal(ohlcv_history, {'pair': 'ETH/BTC'})
|
||||
# No analysis happens as process_only_new_candles is true
|
||||
assert ind_mock.call_count == 1
|
||||
assert buy_mock.call_count == 1
|
||||
|
@@ -6,7 +6,7 @@ from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
from freqtrade.data.converter import parse_ticker_dataframe
|
||||
from freqtrade.data.converter import ohlcv_to_dataframe
|
||||
from freqtrade.misc import (datesarray_to_datetimearray, file_dump_json,
|
||||
file_load_json, format_ms_time, pair_to_filename,
|
||||
plural, shorten_date)
|
||||
@@ -18,9 +18,9 @@ def test_shorten_date() -> None:
|
||||
assert shorten_date(str_data) == str_shorten_data
|
||||
|
||||
|
||||
def test_datesarray_to_datetimearray(ticker_history_list):
|
||||
dataframes = parse_ticker_dataframe(ticker_history_list, "5m", pair="UNITTEST/BTC",
|
||||
fill_missing=True)
|
||||
def test_datesarray_to_datetimearray(ohlcv_history_list):
|
||||
dataframes = ohlcv_to_dataframe(ohlcv_history_list, "5m", pair="UNITTEST/BTC",
|
||||
fill_missing=True)
|
||||
dates = datesarray_to_datetimearray(dataframes['date'])
|
||||
|
||||
assert isinstance(dates[0], datetime.datetime)
|
||||
|
@@ -51,15 +51,15 @@ def test_init_plotscript(default_conf, mocker, testdatadir):
|
||||
default_conf["datadir"] = testdatadir
|
||||
default_conf['exportfilename'] = str(testdatadir / "backtest-result_test.json")
|
||||
ret = init_plotscript(default_conf)
|
||||
assert "tickers" in ret
|
||||
assert "ohlcv" in ret
|
||||
assert "trades" in ret
|
||||
assert "pairs" in ret
|
||||
|
||||
default_conf['pairs'] = ["TRX/BTC", "ADA/BTC"]
|
||||
ret = init_plotscript(default_conf)
|
||||
assert "tickers" in ret
|
||||
assert "TRX/BTC" in ret["tickers"]
|
||||
assert "ADA/BTC" in ret["tickers"]
|
||||
assert "ohlcv" in ret
|
||||
assert "TRX/BTC" in ret["ohlcv"]
|
||||
assert "ADA/BTC" in ret["ohlcv"]
|
||||
|
||||
|
||||
def test_add_indicators(default_conf, testdatadir, caplog):
|
||||
@@ -269,14 +269,14 @@ def test_generate_profit_graph(testdatadir):
|
||||
pairs = ["TRX/BTC", "ADA/BTC"]
|
||||
trades = trades[trades['close_time'] < pd.Timestamp('2018-01-12', tz='UTC')]
|
||||
|
||||
tickers = history.load_data(datadir=testdatadir,
|
||||
pairs=pairs,
|
||||
timeframe='5m',
|
||||
timerange=timerange
|
||||
)
|
||||
data = history.load_data(datadir=testdatadir,
|
||||
pairs=pairs,
|
||||
timeframe='5m',
|
||||
timerange=timerange)
|
||||
|
||||
trades = trades[trades['pair'].isin(pairs)]
|
||||
|
||||
fig = generate_profit_graph(pairs, tickers, trades, timeframe="5m")
|
||||
fig = generate_profit_graph(pairs, data, trades, timeframe="5m")
|
||||
assert isinstance(fig, go.Figure)
|
||||
|
||||
assert fig.layout.title.text == "Freqtrade Profit plot"
|
||||
|
Reference in New Issue
Block a user