commit
14d16f2574
@ -51,6 +51,29 @@ python3 ./freqtrade/main.py backtesting --realistic-simulation --live
|
|||||||
python3 ./freqtrade/main.py backtesting --datadir freqtrade/tests/testdata-20180101
|
python3 ./freqtrade/main.py backtesting --datadir freqtrade/tests/testdata-20180101
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Running backtest with smaller testset**
|
||||||
|
Use the --timerange argument to change how much of the testset
|
||||||
|
you want to use. The last N ticks/timeframes will be used.
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 ./freqtrade/main.py backtesting --timerange=-200
|
||||||
|
```
|
||||||
|
|
||||||
|
***Advanced use of timerange***
|
||||||
|
Doing --timerange=-200 will get the last 200 timeframes
|
||||||
|
from your inputdata. You can also specify specific dates,
|
||||||
|
or a range span indexed by start and stop.
|
||||||
|
The full timerange specification:
|
||||||
|
Not implemented yet! --timerange=-20180131
|
||||||
|
Not implemented yet! --timerange=20180101-
|
||||||
|
Not implemented yet! --timerange=20180101-20181231
|
||||||
|
Last 123 tickframes of data: --timerange=-123
|
||||||
|
First 123 tickframes of data: --timerange=123-
|
||||||
|
Tickframes from line 123 through 456: --timerange=123-456
|
||||||
|
|
||||||
|
|
||||||
|
**Update testdata directory
|
||||||
To update your testdata directory, or download into another testdata directory:
|
To update your testdata directory, or download into another testdata directory:
|
||||||
```bash
|
```bash
|
||||||
mkdir freqtrade/tests/testdata-20180113
|
mkdir freqtrade/tests/testdata-20180113
|
||||||
|
@ -168,6 +168,16 @@ If you would like to learn parameters using an alternate ticke-data that
|
|||||||
you have on-disk, use the --datadir PATH option. Default hyperopt will
|
you have on-disk, use the --datadir PATH option. Default hyperopt will
|
||||||
use data from directory freqtrade/tests/testdata.
|
use data from directory freqtrade/tests/testdata.
|
||||||
|
|
||||||
|
### Running hyperopt with smaller testset
|
||||||
|
|
||||||
|
Use the --timeperiod argument to change how much of the testset
|
||||||
|
you want to use. The last N ticks/timeframes will be used.
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 ./freqtrade/main.py hyperopt --timeperiod -200
|
||||||
|
```
|
||||||
|
|
||||||
### Hyperopt with MongoDB
|
### Hyperopt with MongoDB
|
||||||
Hyperopt with MongoDB, is like Hyperopt under steroids. As you saw by
|
Hyperopt with MongoDB, is like Hyperopt under steroids. As you saw by
|
||||||
executing the previous command is the execution takes a long time.
|
executing the previous command is the execution takes a long time.
|
||||||
|
@ -4,6 +4,7 @@ import json
|
|||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
from typing import Any, Callable, Dict, List
|
from typing import Any, Callable, Dict, List
|
||||||
|
|
||||||
from jsonschema import Draft4Validator, validate
|
from jsonschema import Draft4Validator, validate
|
||||||
@ -132,7 +133,7 @@ def parse_args(args: List[str], description: str):
|
|||||||
dest='dry_run_db',
|
dest='dry_run_db',
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-dd', '--datadir',
|
'--datadir',
|
||||||
help='path to backtest data (default freqdata/tests/testdata',
|
help='path to backtest data (default freqdata/tests/testdata',
|
||||||
dest='datadir',
|
dest='datadir',
|
||||||
default=os.path.join('freqtrade', 'tests', 'testdata'),
|
default=os.path.join('freqtrade', 'tests', 'testdata'),
|
||||||
@ -190,6 +191,13 @@ def build_subcommands(parser: argparse.ArgumentParser) -> None:
|
|||||||
action='store_true',
|
action='store_true',
|
||||||
dest='refresh_pairs',
|
dest='refresh_pairs',
|
||||||
)
|
)
|
||||||
|
backtesting_cmd.add_argument(
|
||||||
|
'--timerange',
|
||||||
|
help='Specify what timerange of data to use.',
|
||||||
|
default=None,
|
||||||
|
type=str,
|
||||||
|
dest='timerange',
|
||||||
|
)
|
||||||
|
|
||||||
# Add hyperopt subcommand
|
# Add hyperopt subcommand
|
||||||
hyperopt_cmd = subparsers.add_parser('hyperopt', help='hyperopt module')
|
hyperopt_cmd = subparsers.add_parser('hyperopt', help='hyperopt module')
|
||||||
@ -216,6 +224,43 @@ def build_subcommands(parser: argparse.ArgumentParser) -> None:
|
|||||||
type=int,
|
type=int,
|
||||||
metavar='INT',
|
metavar='INT',
|
||||||
)
|
)
|
||||||
|
hyperopt_cmd.add_argument(
|
||||||
|
'--timerange',
|
||||||
|
help='Specify what timerange of data to use.',
|
||||||
|
default=None,
|
||||||
|
type=str,
|
||||||
|
dest='timerange',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_timerange(text):
|
||||||
|
if text is None:
|
||||||
|
return None
|
||||||
|
syntax = [('^-(\d{8})$', (None, 'date')),
|
||||||
|
('^(\d{8})-$', ('date', None)),
|
||||||
|
('^(\d{8})-(\d{8})$', ('date', 'date')),
|
||||||
|
('^(-\d+)$', (None, 'line')),
|
||||||
|
('^(\d+)-$', ('line', None)),
|
||||||
|
('^(\d+)-(\d+)$', ('index', 'index'))]
|
||||||
|
for rex, stype in syntax:
|
||||||
|
# Apply the regular expression to text
|
||||||
|
m = re.match(rex, text)
|
||||||
|
if m: # Regex has matched
|
||||||
|
rvals = m.groups()
|
||||||
|
n = 0
|
||||||
|
start = None
|
||||||
|
stop = None
|
||||||
|
if stype[0]:
|
||||||
|
start = rvals[n]
|
||||||
|
if stype[0] != 'date':
|
||||||
|
start = int(start)
|
||||||
|
n += 1
|
||||||
|
if stype[1]:
|
||||||
|
stop = rvals[n]
|
||||||
|
if stype[1] != 'date':
|
||||||
|
stop = int(stop)
|
||||||
|
return (stype, start, stop)
|
||||||
|
raise Exception('Incorrect syntax for timerange "%s"' % text)
|
||||||
|
|
||||||
|
|
||||||
# Required json-schema for user specified config
|
# Required json-schema for user specified config
|
||||||
|
@ -12,7 +12,20 @@ from freqtrade.analyze import populate_indicators, parse_ticker_dataframe
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def load_tickerdata_file(datadir, pair, ticker_interval):
|
def trim_tickerlist(tickerlist, timerange):
|
||||||
|
(stype, start, stop) = timerange
|
||||||
|
if stype == (None, 'line'):
|
||||||
|
return tickerlist[stop:]
|
||||||
|
elif stype == ('line', None):
|
||||||
|
return tickerlist[0:start]
|
||||||
|
elif stype == ('index', 'index'):
|
||||||
|
return tickerlist[start:stop]
|
||||||
|
else:
|
||||||
|
return tickerlist
|
||||||
|
|
||||||
|
|
||||||
|
def load_tickerdata_file(datadir, pair, ticker_interval,
|
||||||
|
timerange=None):
|
||||||
"""
|
"""
|
||||||
Load a pair from file,
|
Load a pair from file,
|
||||||
:return dict OR empty if unsuccesful
|
:return dict OR empty if unsuccesful
|
||||||
@ -30,11 +43,15 @@ def load_tickerdata_file(datadir, pair, ticker_interval):
|
|||||||
# Read the file, load the json
|
# Read the file, load the json
|
||||||
with open(file) as tickerdata:
|
with open(file) as tickerdata:
|
||||||
pairdata = json.load(tickerdata)
|
pairdata = json.load(tickerdata)
|
||||||
|
if timerange:
|
||||||
|
pairdata = trim_tickerlist(pairdata, timerange)
|
||||||
return pairdata
|
return pairdata
|
||||||
|
|
||||||
|
|
||||||
def load_data(datadir: str, ticker_interval: int = 5, pairs: Optional[List[str]] = None,
|
def load_data(datadir: str, ticker_interval: int = 5,
|
||||||
refresh_pairs: Optional[bool] = False) -> Dict[str, List]:
|
pairs: Optional[List[str]] = None,
|
||||||
|
refresh_pairs: Optional[bool] = False,
|
||||||
|
timerange=None) -> Dict[str, List]:
|
||||||
"""
|
"""
|
||||||
Loads ticker history data for the given parameters
|
Loads ticker history data for the given parameters
|
||||||
:param ticker_interval: ticker interval in minutes
|
:param ticker_interval: ticker interval in minutes
|
||||||
@ -51,16 +68,21 @@ def load_data(datadir: str, ticker_interval: int = 5, pairs: Optional[List[str]]
|
|||||||
download_pairs(datadir, _pairs)
|
download_pairs(datadir, _pairs)
|
||||||
|
|
||||||
for pair in _pairs:
|
for pair in _pairs:
|
||||||
pairdata = load_tickerdata_file(datadir, pair, ticker_interval)
|
pairdata = load_tickerdata_file(datadir, pair, ticker_interval, timerange=timerange)
|
||||||
if not pairdata:
|
if not pairdata:
|
||||||
# download the tickerdata from exchange
|
# download the tickerdata from exchange
|
||||||
download_backtesting_testdata(datadir, pair=pair, interval=ticker_interval)
|
download_backtesting_testdata(datadir, pair=pair, interval=ticker_interval)
|
||||||
# and retry reading the pair
|
# and retry reading the pair
|
||||||
pairdata = load_tickerdata_file(datadir, pair, ticker_interval)
|
pairdata = load_tickerdata_file(datadir, pair, ticker_interval, timerange=timerange)
|
||||||
result[pair] = pairdata
|
result[pair] = pairdata
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def tickerdata_to_dataframe(data):
|
||||||
|
preprocessed = preprocess(data)
|
||||||
|
return preprocessed
|
||||||
|
|
||||||
|
|
||||||
def preprocess(tickerdata: Dict[str, List]) -> Dict[str, DataFrame]:
|
def preprocess(tickerdata: Dict[str, List]) -> Dict[str, DataFrame]:
|
||||||
"""Creates a dataframe and populates indicators for given ticker data"""
|
"""Creates a dataframe and populates indicators for given ticker data"""
|
||||||
return {pair: populate_indicators(parse_ticker_dataframe(pair_data))
|
return {pair: populate_indicators(parse_ticker_dataframe(pair_data))
|
||||||
|
@ -13,7 +13,6 @@ from freqtrade import exchange
|
|||||||
from freqtrade.analyze import populate_buy_trend, populate_sell_trend
|
from freqtrade.analyze import populate_buy_trend, populate_sell_trend
|
||||||
from freqtrade.exchange import Bittrex
|
from freqtrade.exchange import Bittrex
|
||||||
from freqtrade.main import min_roi_reached
|
from freqtrade.main import min_roi_reached
|
||||||
from freqtrade.optimize import preprocess
|
|
||||||
from freqtrade.persistence import Trade
|
from freqtrade.persistence import Trade
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -161,12 +160,13 @@ def start(args):
|
|||||||
data[pair] = exchange.get_ticker_history(pair, args.ticker_interval)
|
data[pair] = exchange.get_ticker_history(pair, args.ticker_interval)
|
||||||
else:
|
else:
|
||||||
logger.info('Using local backtesting data (using whitelist in given config) ...')
|
logger.info('Using local backtesting data (using whitelist in given config) ...')
|
||||||
data = optimize.load_data(args.datadir, pairs=pairs, ticker_interval=args.ticker_interval,
|
|
||||||
refresh_pairs=args.refresh_pairs)
|
|
||||||
|
|
||||||
logger.info('Using stake_currency: %s ...', config['stake_currency'])
|
logger.info('Using stake_currency: %s ...', config['stake_currency'])
|
||||||
logger.info('Using stake_amount: %s ...', config['stake_amount'])
|
logger.info('Using stake_amount: %s ...', config['stake_amount'])
|
||||||
|
|
||||||
|
timerange = misc.parse_timerange(args.timerange)
|
||||||
|
data = optimize.load_data(args.datadir, pairs=pairs, ticker_interval=args.ticker_interval,
|
||||||
|
refresh_pairs=args.refresh_pairs,
|
||||||
|
timerange=timerange)
|
||||||
max_open_trades = 0
|
max_open_trades = 0
|
||||||
if args.realistic_simulation:
|
if args.realistic_simulation:
|
||||||
logger.info('Using max_open_trades: %s ...', config['max_open_trades'])
|
logger.info('Using max_open_trades: %s ...', config['max_open_trades'])
|
||||||
@ -176,7 +176,7 @@ def start(args):
|
|||||||
from freqtrade import main
|
from freqtrade import main
|
||||||
main._CONF = config
|
main._CONF = config
|
||||||
|
|
||||||
preprocessed = preprocess(data)
|
preprocessed = optimize.tickerdata_to_dataframe(data)
|
||||||
# Print timeframe
|
# Print timeframe
|
||||||
min_date, max_date = get_timeframe(preprocessed)
|
min_date, max_date = get_timeframe(preprocessed)
|
||||||
logger.info('Measuring data from %s up to %s ...', min_date.isoformat(), max_date.isoformat())
|
logger.info('Measuring data from %s up to %s ...', min_date.isoformat(), max_date.isoformat())
|
||||||
|
@ -15,7 +15,7 @@ from hyperopt import STATUS_FAIL, STATUS_OK, Trials, fmin, hp, space_eval, tpe
|
|||||||
from hyperopt.mongoexp import MongoTrials
|
from hyperopt.mongoexp import MongoTrials
|
||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
|
|
||||||
from freqtrade import main # noqa
|
from freqtrade import main, misc # noqa
|
||||||
from freqtrade import exchange, optimize
|
from freqtrade import exchange, optimize
|
||||||
from freqtrade.exchange import Bittrex
|
from freqtrade.exchange import Bittrex
|
||||||
from freqtrade.misc import load_config
|
from freqtrade.misc import load_config
|
||||||
@ -273,8 +273,11 @@ def start(args):
|
|||||||
logger.info('Using config: %s ...', args.config)
|
logger.info('Using config: %s ...', args.config)
|
||||||
config = load_config(args.config)
|
config = load_config(args.config)
|
||||||
pairs = config['exchange']['pair_whitelist']
|
pairs = config['exchange']['pair_whitelist']
|
||||||
PROCESSED = optimize.preprocess(optimize.load_data(
|
timerange = misc.parse_timerange(args.timerange)
|
||||||
args.datadir, pairs=pairs, ticker_interval=args.ticker_interval))
|
data = optimize.load_data(args.datadir, pairs=pairs,
|
||||||
|
ticker_interval=args.ticker_interval,
|
||||||
|
timerange=timerange)
|
||||||
|
PROCESSED = optimize.tickerdata_to_dataframe(data)
|
||||||
|
|
||||||
if args.mongodb:
|
if args.mongodb:
|
||||||
logger.info('Using mongodb ...')
|
logger.info('Using mongodb ...')
|
||||||
|
@ -69,8 +69,8 @@ def test_backtest_1min_ticker_interval(default_conf, mocker):
|
|||||||
|
|
||||||
|
|
||||||
def load_data_test(what):
|
def load_data_test(what):
|
||||||
data = optimize.load_data(None, ticker_interval=1, pairs=['BTC_UNITEST'])
|
timerange = ((None, 'line'), None, -100)
|
||||||
data = trim_dictlist(data, -100)
|
data = optimize.load_data(None, ticker_interval=1, pairs=['BTC_UNITEST'], timerange=timerange)
|
||||||
pair = data['BTC_UNITEST']
|
pair = data['BTC_UNITEST']
|
||||||
datalen = len(pair)
|
datalen = len(pair)
|
||||||
# Depending on the what parameter we now adjust the
|
# Depending on the what parameter we now adjust the
|
||||||
@ -152,10 +152,10 @@ def test_backtest_pricecontours(default_conf, mocker):
|
|||||||
simple_backtest(default_conf, contour, numres)
|
simple_backtest(default_conf, contour, numres)
|
||||||
|
|
||||||
|
|
||||||
def mocked_load_data(datadir, pairs=[], ticker_interval=0, refresh_pairs=False):
|
def mocked_load_data(datadir, pairs=[], ticker_interval=0, refresh_pairs=False, timerange=None):
|
||||||
tickerdata = optimize.load_tickerdata_file(datadir, 'BTC_UNITEST', 1)
|
tickerdata = optimize.load_tickerdata_file(datadir, 'BTC_UNITEST', 1, timerange=timerange)
|
||||||
pairdata = {'BTC_UNITEST': tickerdata}
|
pairdata = {'BTC_UNITEST': tickerdata}
|
||||||
return trim_dictlist(pairdata, -100)
|
return pairdata
|
||||||
|
|
||||||
|
|
||||||
def test_backtest_start(default_conf, mocker, caplog):
|
def test_backtest_start(default_conf, mocker, caplog):
|
||||||
@ -169,6 +169,7 @@ def test_backtest_start(default_conf, mocker, caplog):
|
|||||||
args.level = 10
|
args.level = 10
|
||||||
args.live = False
|
args.live = False
|
||||||
args.datadir = None
|
args.datadir = None
|
||||||
|
args.timerange = '-100' # needed due to MagicMock malleability
|
||||||
backtesting.start(args)
|
backtesting.start(args)
|
||||||
# check the logs, that will contain the backtest result
|
# check the logs, that will contain the backtest result
|
||||||
exists = ['Using max_open_trades: 1 ...',
|
exists = ['Using max_open_trades: 1 ...',
|
||||||
|
@ -54,6 +54,7 @@ def create_trials(mocker):
|
|||||||
|
|
||||||
def test_start_calls_fmin(mocker):
|
def test_start_calls_fmin(mocker):
|
||||||
trials = create_trials(mocker)
|
trials = create_trials(mocker)
|
||||||
|
mocker.patch('freqtrade.optimize.tickerdata_to_dataframe')
|
||||||
mocker.patch('freqtrade.optimize.hyperopt.TRIALS', return_value=trials)
|
mocker.patch('freqtrade.optimize.hyperopt.TRIALS', return_value=trials)
|
||||||
mocker.patch('freqtrade.optimize.hyperopt.sorted',
|
mocker.patch('freqtrade.optimize.hyperopt.sorted',
|
||||||
return_value=trials.results)
|
return_value=trials.results)
|
||||||
@ -61,7 +62,8 @@ def test_start_calls_fmin(mocker):
|
|||||||
mocker.patch('freqtrade.optimize.load_data')
|
mocker.patch('freqtrade.optimize.load_data')
|
||||||
mock_fmin = mocker.patch('freqtrade.optimize.hyperopt.fmin', return_value={})
|
mock_fmin = mocker.patch('freqtrade.optimize.hyperopt.fmin', return_value={})
|
||||||
|
|
||||||
args = mocker.Mock(epochs=1, config='config.json.example', mongodb=False)
|
args = mocker.Mock(epochs=1, config='config.json.example', mongodb=False,
|
||||||
|
timerange=None)
|
||||||
start(args)
|
start(args)
|
||||||
|
|
||||||
mock_fmin.assert_called_once()
|
mock_fmin.assert_called_once()
|
||||||
@ -70,11 +72,12 @@ def test_start_calls_fmin(mocker):
|
|||||||
def test_start_uses_mongotrials(mocker):
|
def test_start_uses_mongotrials(mocker):
|
||||||
mock_mongotrials = mocker.patch('freqtrade.optimize.hyperopt.MongoTrials',
|
mock_mongotrials = mocker.patch('freqtrade.optimize.hyperopt.MongoTrials',
|
||||||
return_value=create_trials(mocker))
|
return_value=create_trials(mocker))
|
||||||
mocker.patch('freqtrade.optimize.preprocess')
|
mocker.patch('freqtrade.optimize.tickerdata_to_dataframe')
|
||||||
mocker.patch('freqtrade.optimize.load_data')
|
mocker.patch('freqtrade.optimize.load_data')
|
||||||
mocker.patch('freqtrade.optimize.hyperopt.fmin', return_value={})
|
mocker.patch('freqtrade.optimize.hyperopt.fmin', return_value={})
|
||||||
|
|
||||||
args = mocker.Mock(epochs=1, config='config.json.example', mongodb=True)
|
args = mocker.Mock(epochs=1, config='config.json.example', mongodb=True,
|
||||||
|
timerange=None)
|
||||||
start(args)
|
start(args)
|
||||||
|
|
||||||
mock_mongotrials.assert_called_once()
|
mock_mongotrials.assert_called_once()
|
||||||
@ -125,11 +128,12 @@ def test_fmin_best_results(mocker, caplog):
|
|||||||
}
|
}
|
||||||
|
|
||||||
mocker.patch('freqtrade.optimize.hyperopt.MongoTrials', return_value=create_trials(mocker))
|
mocker.patch('freqtrade.optimize.hyperopt.MongoTrials', return_value=create_trials(mocker))
|
||||||
mocker.patch('freqtrade.optimize.preprocess')
|
mocker.patch('freqtrade.optimize.tickerdata_to_dataframe')
|
||||||
mocker.patch('freqtrade.optimize.load_data')
|
mocker.patch('freqtrade.optimize.load_data')
|
||||||
mocker.patch('freqtrade.optimize.hyperopt.fmin', return_value=fmin_result)
|
mocker.patch('freqtrade.optimize.hyperopt.fmin', return_value=fmin_result)
|
||||||
|
|
||||||
args = mocker.Mock(epochs=1, config='config.json.example')
|
args = mocker.Mock(epochs=1, config='config.json.example',
|
||||||
|
timerange=None)
|
||||||
start(args)
|
start(args)
|
||||||
|
|
||||||
exists = [
|
exists = [
|
||||||
@ -147,11 +151,12 @@ def test_fmin_best_results(mocker, caplog):
|
|||||||
|
|
||||||
def test_fmin_throw_value_error(mocker, caplog):
|
def test_fmin_throw_value_error(mocker, caplog):
|
||||||
mocker.patch('freqtrade.optimize.hyperopt.MongoTrials', return_value=create_trials(mocker))
|
mocker.patch('freqtrade.optimize.hyperopt.MongoTrials', return_value=create_trials(mocker))
|
||||||
mocker.patch('freqtrade.optimize.preprocess')
|
mocker.patch('freqtrade.optimize.tickerdata_to_dataframe')
|
||||||
mocker.patch('freqtrade.optimize.load_data')
|
mocker.patch('freqtrade.optimize.load_data')
|
||||||
mocker.patch('freqtrade.optimize.hyperopt.fmin', side_effect=ValueError())
|
mocker.patch('freqtrade.optimize.hyperopt.fmin', side_effect=ValueError())
|
||||||
|
|
||||||
args = mocker.Mock(epochs=1, config='config.json.example')
|
args = mocker.Mock(epochs=1, config='config.json.example',
|
||||||
|
timerange=None)
|
||||||
start(args)
|
start(args)
|
||||||
|
|
||||||
exists = [
|
exists = [
|
||||||
@ -185,7 +190,8 @@ def test_resuming_previous_hyperopt_results_succeeds(mocker):
|
|||||||
return_value={})
|
return_value={})
|
||||||
args = mocker.Mock(epochs=1,
|
args = mocker.Mock(epochs=1,
|
||||||
config='config.json.example',
|
config='config.json.example',
|
||||||
mongodb=False)
|
mongodb=False,
|
||||||
|
timerange=None)
|
||||||
|
|
||||||
start(args)
|
start(args)
|
||||||
|
|
||||||
|
@ -174,3 +174,11 @@ def test_load_tickerdata_file():
|
|||||||
assert not load_tickerdata_file(None, 'BTC_UNITEST', 7)
|
assert not load_tickerdata_file(None, 'BTC_UNITEST', 7)
|
||||||
tickerdata = load_tickerdata_file(None, 'BTC_UNITEST', 1)
|
tickerdata = load_tickerdata_file(None, 'BTC_UNITEST', 1)
|
||||||
assert _btc_unittest_length == len(tickerdata)
|
assert _btc_unittest_length == len(tickerdata)
|
||||||
|
|
||||||
|
|
||||||
|
def test_tickerdata_to_dataframe():
|
||||||
|
timerange = ((None, 'line'), None, -100)
|
||||||
|
tick = load_tickerdata_file(None, 'BTC_UNITEST', 1, timerange=timerange)
|
||||||
|
tickerlist = {'BTC_UNITEST': tick}
|
||||||
|
data = optimize.tickerdata_to_dataframe(tickerlist)
|
||||||
|
assert 100 == len(data['BTC_UNITEST'])
|
||||||
|
@ -8,7 +8,7 @@ import pytest
|
|||||||
from jsonschema import ValidationError
|
from jsonschema import ValidationError
|
||||||
|
|
||||||
from freqtrade.misc import (common_args_parser, load_config, parse_args,
|
from freqtrade.misc import (common_args_parser, load_config, parse_args,
|
||||||
throttle)
|
throttle, parse_timerange)
|
||||||
|
|
||||||
|
|
||||||
def test_throttle():
|
def test_throttle():
|
||||||
@ -133,6 +133,13 @@ def test_parse_args_hyperopt_custom(mocker):
|
|||||||
assert call_args.func is not None
|
assert call_args.func is not None
|
||||||
|
|
||||||
|
|
||||||
|
def test_parse_timerange_incorrect():
|
||||||
|
assert ((None, 'line'), None, -200) == parse_timerange('-200')
|
||||||
|
assert (('line', None), 200, None) == parse_timerange('200-')
|
||||||
|
with pytest.raises(Exception, match=r'Incorrect syntax.*'):
|
||||||
|
parse_timerange('-')
|
||||||
|
|
||||||
|
|
||||||
def test_load_config(default_conf, mocker):
|
def test_load_config(default_conf, mocker):
|
||||||
file_mock = mocker.patch('freqtrade.misc.open', mocker.mock_open(
|
file_mock = mocker.patch('freqtrade.misc.open', mocker.mock_open(
|
||||||
read_data=json.dumps(default_conf)
|
read_data=json.dumps(default_conf)
|
||||||
|
Loading…
Reference in New Issue
Block a user