add mongodb support for hyperopt parallelization

This commit is contained in:
gcarq 2017-11-25 02:04:37 +01:00
parent 5bf583cba4
commit e27a6a7a91
6 changed files with 74 additions and 23 deletions

1
.gitignore vendored
View File

@ -76,6 +76,7 @@ target/
config.json config.json
preprocessor.py preprocessor.py
*.sqlite *.sqlite
.mongodb
.env .env
.venv .venv

View File

@ -167,6 +167,13 @@ def build_subcommands(parser: argparse.ArgumentParser) -> None:
type=int, type=int,
metavar='INT', metavar='INT',
) )
hyperopt_cmd.add_argument(
'--use-mongodb',
help='parallelize evaluations with mongodb (requires mongod in PATH)',
dest='mongodb',
action='store_true',
)
# Required json-schema for user specified config # Required json-schema for user specified config
CONF_SCHEMA = { CONF_SCHEMA = {

View File

@ -118,36 +118,38 @@ def backtest(config: Dict, processed: Dict[str, DataFrame],
def start(args): def start(args):
print('') # Initialize logger
logging.basicConfig(
level=args.loglevel,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
)
exchange._API = Bittrex({'key': '', 'secret': ''}) exchange._API = Bittrex({'key': '', 'secret': ''})
print('Using config: {} ...'.format(args.config)) logger.info('Using config: %s ...', args.config)
config = load_config(args.config) config = load_config(args.config)
print('Using ticker_interval: {} ...'.format(args.ticker_interval)) logger.info('Using ticker_interval: %s ...', args.ticker_interval)
data = {} data = {}
if args.live: if args.live:
print('Downloading data for all pairs in whitelist ...') logger.info('Downloading data for all pairs in whitelist ...')
for pair in config['exchange']['pair_whitelist']: for pair in config['exchange']['pair_whitelist']:
data[pair] = exchange.get_ticker_history(pair, args.ticker_interval) data[pair] = exchange.get_ticker_history(pair, args.ticker_interval)
else: else:
print('Using local backtesting data (ignoring whitelist in given config)...') logger.info('Using local backtesting data (ignoring whitelist in given config) ...')
data = load_data(args.ticker_interval) data = load_data(args.ticker_interval)
print('Using stake_currency: {} ...\nUsing stake_amount: {} ...'.format( logger.info('Using stake_currency: %s ...', config['stake_currency'])
config['stake_currency'], config['stake_amount'] logger.info('Using stake_amount: %s ...', config['stake_amount'])
))
# Print timeframe # Print timeframe
min_date, max_date = get_timeframe(data) min_date, max_date = get_timeframe(data)
print('Measuring data from {} up to {} ...'.format( logger.info('Measuring data from %s up to %s ...', min_date.isoformat(), max_date.isoformat())
min_date.isoformat(), max_date.isoformat()
))
max_open_trades = 0 max_open_trades = 0
if args.realistic_simulation: if args.realistic_simulation:
print('Using max_open_trades: {} ...'.format(config['max_open_trades'])) logger.info('Using max_open_trades: %s ...', config['max_open_trades'])
max_open_trades = config['max_open_trades'] max_open_trades = config['max_open_trades']
# Monkey patch config # Monkey patch config
@ -158,5 +160,7 @@ def start(args):
results = backtest( results = backtest(
config, preprocess(data), max_open_trades, args.realistic_simulation config, preprocess(data), max_open_trades, args.realistic_simulation
) )
print('====================== BACKTESTING REPORT ======================================\n\n') logger.info(
print(generate_text_table(data, results, config['stake_currency'])) '\n====================== BACKTESTING REPORT ======================================\n%s',
generate_text_table(data, results, config['stake_currency'])
)

View File

@ -2,11 +2,13 @@
import json import json
import logging
from functools import reduce from functools import reduce
from math import exp from math import exp
from operator import itemgetter from operator import itemgetter
from hyperopt import fmin, tpe, hp, Trials, STATUS_OK from hyperopt import fmin, tpe, hp, Trials, STATUS_OK
from hyperopt.mongoexp import MongoTrials
from pandas import DataFrame from pandas import DataFrame
from freqtrade import exchange, optimize from freqtrade import exchange, optimize
@ -14,6 +16,9 @@ from freqtrade.exchange import Bittrex
from freqtrade.optimize.backtesting import backtest from freqtrade.optimize.backtesting import backtest
from freqtrade.vendor.qtpylib.indicators import crossed_above from freqtrade.vendor.qtpylib.indicators import crossed_above
logger = logging.getLogger(__name__)
# set TARGET_TRADES to suit your number concurrent trades so its realistic to 20days of data # set TARGET_TRADES to suit your number concurrent trades so its realistic to 20days of data
TARGET_TRADES = 1100 TARGET_TRADES = 1100
TOTAL_TRIES = 4 TOTAL_TRIES = 4
@ -34,6 +39,11 @@ OPTIMIZE_CONFIG = {
'stoploss': -0.10, 'stoploss': -0.10,
} }
# Monkey patch config
from freqtrade import main
main._CONF = OPTIMIZE_CONFIG
SPACE = { SPACE = {
'mfi': hp.choice('mfi', [ 'mfi': hp.choice('mfi', [
{'enabled': False}, {'enabled': False},
@ -101,7 +111,7 @@ def optimizer(params):
profit_loss = max(0, 1 - total_profit / 10000) # max profit 10000 profit_loss = max(0, 1 - total_profit / 10000) # max profit 10000
_CURRENT_TRIES += 1 _CURRENT_TRIES += 1
print('{:5d}/{}: {}'.format(_CURRENT_TRIES, TOTAL_TRIES, result)) logger.info('{:5d}/{}: {}'.format(_CURRENT_TRIES, TOTAL_TRIES, result))
return { return {
'loss': trade_loss + profit_loss, 'loss': trade_loss + profit_loss,
@ -169,15 +179,27 @@ def start(args):
global TOTAL_TRIES global TOTAL_TRIES
TOTAL_TRIES = args.epochs TOTAL_TRIES = args.epochs
# Monkey patch config
from freqtrade import main
main._CONF = OPTIMIZE_CONFIG
exchange._API = Bittrex({'key': '', 'secret': ''}) exchange._API = Bittrex({'key': '', 'secret': ''})
trials = Trials() # Initialize logger
logging.basicConfig(
level=args.loglevel,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
)
if args.mongodb:
logger.info('Using mongodb.')
logger.info('Start scripts/start-mongodb.sh and start-hyperopt-worker.sh manually')
db_name = 'freqtrade_hyperopt'
trials = MongoTrials('mongo://127.0.0.1:1234/{}/jobs'.format(db_name), exp_key='exp1')
else:
trials = Trials()
best = fmin(fn=optimizer, space=SPACE, algo=tpe.suggest, max_evals=TOTAL_TRIES, trials=trials) best = fmin(fn=optimizer, space=SPACE, algo=tpe.suggest, max_evals=TOTAL_TRIES, trials=trials)
print('\n==================== HYPEROPT BACKTESTING REPORT ==============================\n') logger.info(
print('Best parameters: {}'.format(json.dumps(best, indent=4))) '\n==================== HYPEROPT BACKTESTING REPORT ==============================\n'
)
logger.info('Best parameters:\n%s', json.dumps(best, indent=4))
results = sorted(trials.results, key=itemgetter('loss')) results = sorted(trials.results, key=itemgetter('loss'))
print('Best Result: {}\n'.format(results[0]['result'])) logger.info('Best Result:\n%s', results[0]['result'])

View File

@ -0,0 +1,5 @@
#!/bin/bash
DB_NAME=freqtrade_hyperopt
hyperopt-mongo-worker --mongo=127.0.0.1:1234/${DB_NAME} --poll-interval=0.1

12
scripts/start-mongodb.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash -e
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
DB_PATH="${DIR}/../.mongodb"
mkdir -p ${DB_PATH}
mongod --dbpath ${DB_PATH} \
--bind_ip 127.0.0.1 \
--port 1234 \
--directoryperdb \
--journal \
--nohttpinterface