-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added Main Configuration File, Added Functionality
- Loading branch information
Showing
12 changed files
with
1,114 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
{ | ||
"max_open_trades": 10, | ||
"stake_currency": "BTC", | ||
"stake_amount": 0.1, | ||
"tradable_balance_ratio": 0.99, | ||
"fiat_display_currency": "USD", | ||
"timeframe": "5m", | ||
"dry_run": true, | ||
|
||
"exchange": { | ||
"name": "binance", | ||
"key": "", | ||
"secret": "", | ||
"ccxt_config": {"enableRateLimit": true}, | ||
"ccxt_async_config": { | ||
"enableRateLimit": true, | ||
"rateLimit": 200 | ||
}, | ||
"pair_whitelist": [ | ||
"ETH/BTC", | ||
"LINK/BTC", | ||
"BNB/BTC", | ||
"LTC/BTC", | ||
"XRP/BTC", | ||
"YFI/BTC", | ||
"INJ/BTC", | ||
"XMR/BTC" | ||
], | ||
"pair_blacklist": [ | ||
|
||
] | ||
}, | ||
"pairlists": [ | ||
{"method": "StaticPairList"} | ||
], | ||
"telegram": { | ||
"enabled": true, | ||
"token": "", | ||
"chat_id": "" | ||
}, | ||
"api_server": { | ||
"enabled": false, | ||
"listen_ip_address": "127.0.0.1", | ||
"listen_port": 8080, | ||
"verbosity": "info", | ||
"jwt_secret_key": "somethingrandom", | ||
"CORS_origins": [], | ||
"username": "", | ||
"password": "" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
{ | ||
"max_open_trades": 10, | ||
"stake_currency": "BTC", | ||
"stake_amount": 0.1, | ||
"tradable_balance_ratio": 0.99, | ||
"fiat_display_currency": "USD", | ||
"timeframe": "5m", | ||
"dry_run": true, | ||
|
||
"exchange": { | ||
"name": "binance", | ||
"key": "", | ||
"secret": "", | ||
"ccxt_config": {"enableRateLimit": true}, | ||
"ccxt_async_config": { | ||
"enableRateLimit": true, | ||
"rateLimit": 200 | ||
}, | ||
"pair_whitelist": [ | ||
"ETH/BTC", | ||
"LINK/BTC", | ||
"BNB/BTC", | ||
"LTC/BTC", | ||
"XRP/BTC", | ||
"YFI/BTC", | ||
"INJ/BTC", | ||
"XMR/BTC" | ||
], | ||
"pair_blacklist": [ | ||
|
||
] | ||
}, | ||
"pairlists": [ | ||
{"method": "StaticPairList"} | ||
], | ||
"telegram": { | ||
"enabled": true, | ||
"token": "", | ||
"chat_id": "" | ||
}, | ||
"api_server": { | ||
"enabled": false, | ||
"listen_ip_address": "127.0.0.1", | ||
"listen_port": 8080, | ||
"verbosity": "info", | ||
"jwt_secret_key": "somethingrandom", | ||
"CORS_origins": [], | ||
"username": "", | ||
"password": "" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
""" Finrl bot """ | ||
__version__ = '2021.02' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from finrl.config.configuration import Configuration |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
""" | ||
This module contains the configuration class | ||
""" | ||
import logging | ||
import warnings | ||
from copy import deepcopy | ||
from pathlib import Path | ||
from typing import Any, Callable, Dict, List, Optional | ||
|
||
from finrl import constants | ||
from finrl.config.load_config import load_config_file | ||
from finrl.loggers import setup_logging | ||
from finrl.misc import deep_merge_dicts, json_load | ||
from finrl.state import NON_UTIL_MODES, TRADING_MODES, RunMode | ||
|
||
|
||
logger = logging.getLogger(__name__) | ||
|
||
class Configuration: | ||
""" | ||
Class to read and init the bot configuration | ||
Reuse this class for the bot, backtesting, hyperopt and every script that required configuration | ||
""" | ||
|
||
def __init__(self, args: Dict[str, Any], runmode: RunMode = None) -> None: | ||
self.args = args | ||
self.config: Optional[Dict[str, Any]] = None | ||
self.runmode = runmode | ||
|
||
def get_config(self) -> Dict[str, Any]: | ||
""" | ||
Return the config. Use this method to get the bot config | ||
:return: Dict: Bot config | ||
""" | ||
if self.config is None: | ||
self.config = self.load_config() | ||
|
||
return self.config | ||
|
||
@staticmethod | ||
def from_files(files: List[str]) -> Dict[str, Any]: | ||
""" | ||
Iterate through the config files passed in, loading all of them | ||
and merging their contents. | ||
Files are loaded in sequence, parameters in later configuration files | ||
override the same parameter from an earlier file (last definition wins). | ||
Runs through the whole Configuration initialization, so all expected config entries | ||
are available to interactive environments. | ||
:param files: List of file paths | ||
:return: configuration dictionary | ||
""" | ||
c = Configuration({'config': files}, RunMode.OTHER) | ||
return c.get_config() | ||
|
||
def load_from_files(self, files: List[str]) -> Dict[str, Any]: | ||
|
||
# Keep this method as staticmethod, so it can be used from interactive environments | ||
config: Dict[str, Any] = {} | ||
|
||
if not files: | ||
return deepcopy(constants.MINIMAL_CONFIG) | ||
|
||
# We expect here a list of config filenames | ||
for path in files: | ||
logger.info(f'Using config: {path} ...') | ||
|
||
# Merge config options, overwriting old values | ||
config = deep_merge_dicts(load_config_file(path), config) | ||
|
||
# Normalize config | ||
if 'internals' not in config: | ||
config['internals'] = {} | ||
# TODO: This can be deleted along with removal of deprecated | ||
# experimental settings | ||
if 'ask_strategy' not in config: | ||
config['ask_strategy'] = {} | ||
|
||
if 'pairlists' not in config: | ||
config['pairlists'] = [] | ||
|
||
return config | ||
|
||
def load_config(self) -> Dict[str, Any]: | ||
""" | ||
Extract information for sys.argv and load the bot configuration | ||
:return: Configuration dictionary | ||
""" | ||
# Load all configs | ||
config: Dict[str, Any] = self.load_from_files(self.args.get("config", [])) | ||
|
||
# Keep a copy of the original configuration file | ||
config['original_config'] = deepcopy(config) | ||
|
||
self._resolve_pairs_list(config) | ||
|
||
return config | ||
|
||
def _resolve_pairs_list(self, config: Dict[str, Any]) -> None: | ||
""" | ||
Helper for download script. | ||
Takes first found: | ||
* -p (pairs argument) | ||
* --pairs-file | ||
* whitelist from config | ||
""" | ||
|
||
if "pairs" in config: | ||
return | ||
|
||
if "pairs_file" in self.args and self.args["pairs_file"]: | ||
pairs_file = Path(self.args["pairs_file"]) | ||
logger.info(f'Reading pairs file "{pairs_file}".') | ||
# Download pairs from the pairs file if no config is specified | ||
# or if pairs file is specified explicitely | ||
if not pairs_file.exists(): | ||
raise OperationalException(f'No pairs file found with path "{pairs_file}".') | ||
with pairs_file.open('r') as f: | ||
config['pairs'] = json_load(f) | ||
config['pairs'].sort() | ||
return | ||
|
||
if 'config' in self.args and self.args['config']: | ||
logger.info("Using pairlist from configuration.") | ||
config['pairs'] = config.get('exchange', {}).get('pair_whitelist') | ||
else: | ||
# Fall back to /dl_path/pairs.json | ||
pairs_file = config['datadir'] / 'pairs.json' | ||
if pairs_file.exists(): | ||
with pairs_file.open('r') as f: | ||
config['pairs'] = json_load(f) | ||
if 'pairs' in config: | ||
config['pairs'].sort() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
""" | ||
This module contain functions to load the configuration file | ||
""" | ||
import logging | ||
import re | ||
import sys | ||
from pathlib import Path | ||
from typing import Any, Dict | ||
|
||
import rapidjson | ||
|
||
from finrl.exceptions import OperationalException | ||
|
||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
CONFIG_PARSE_MODE = rapidjson.PM_COMMENTS | rapidjson.PM_TRAILING_COMMAS | ||
|
||
|
||
def log_config_error_range(path: str, errmsg: str) -> str: | ||
""" | ||
Parses configuration file and prints range around error | ||
""" | ||
if path != '-': | ||
offsetlist = re.findall(r'(?<=Parse\serror\sat\soffset\s)\d+', errmsg) | ||
if offsetlist: | ||
offset = int(offsetlist[0]) | ||
text = Path(path).read_text() | ||
# Fetch an offset of 80 characters around the error line | ||
subtext = text[offset-min(80, offset):offset+80] | ||
segments = subtext.split('\n') | ||
if len(segments) > 3: | ||
# Remove first and last lines, to avoid odd truncations | ||
return '\n'.join(segments[1:-1]) | ||
else: | ||
return subtext | ||
return '' | ||
|
||
|
||
def load_config_file(path: str) -> Dict[str, Any]: | ||
""" | ||
Loads a config file from the given path | ||
:param path: path as str | ||
:return: configuration as dictionary | ||
""" | ||
try: | ||
# Read config from stdin if requested in the options | ||
with open(path) if path != '-' else sys.stdin as file: | ||
config = rapidjson.load(file, parse_mode=CONFIG_PARSE_MODE) | ||
except FileNotFoundError: | ||
raise OperationalException( | ||
f'Config file "{path}" not found!' | ||
' Please create a config file or check whether it exists.') | ||
except rapidjson.JSONDecodeError as e: | ||
err_range = log_config_error_range(path, str(e)) | ||
raise OperationalException( | ||
f'{e}\n' | ||
f'Please verify the following segment of your configuration:\n{err_range}' | ||
if err_range else 'Please verify your configuration file for syntax errors.' | ||
) | ||
|
||
return config |
Oops, something went wrong.