Merge pull request #2317 from hroff-1902/list-timeframes

Add list-timeframes subcommand
This commit is contained in:
hroff-1902
2019-10-06 16:28:15 +03:00
committed by GitHub
8 changed files with 204 additions and 18 deletions

View File

@@ -31,6 +31,8 @@ ARGS_EDGE = ARGS_COMMON_OPTIMIZE + ["stoploss_range"]
ARGS_LIST_EXCHANGES = ["print_one_column", "list_exchanges_all"]
ARGS_LIST_TIMEFRAMES = ["exchange", "print_one_column"]
ARGS_CREATE_USERDIR = ["user_data_dir"]
ARGS_DOWNLOAD_DATA = ["pairs", "pairs_file", "days", "exchange", "timeframes", "erase"]
@@ -41,7 +43,7 @@ ARGS_PLOT_DATAFRAME = ["pairs", "indicators1", "indicators2", "plot_limit", "db_
ARGS_PLOT_PROFIT = ["pairs", "timerange", "export", "exportfilename", "db_url",
"trade_source", "ticker_interval"]
NO_CONF_REQURIED = ["download-data", "plot-dataframe", "plot-profit"]
NO_CONF_REQURIED = ["download-data", "list-timeframes", "plot-dataframe", "plot-profit"]
NO_CONF_ALLOWED = ["create-userdir", "list-exchanges"]
@@ -103,7 +105,8 @@ class Arguments:
:return: None
"""
from freqtrade.optimize import start_backtesting, start_hyperopt, start_edge
from freqtrade.utils import start_create_userdir, start_download_data, start_list_exchanges
from freqtrade.utils import (start_create_userdir, start_download_data,
start_list_exchanges, start_list_timeframes)
subparsers = self.parser.add_subparsers(dest='subparser')
@@ -136,6 +139,14 @@ class Arguments:
list_exchanges_cmd.set_defaults(func=start_list_exchanges)
self._build_args(optionlist=ARGS_LIST_EXCHANGES, parser=list_exchanges_cmd)
# Add list-timeframes subcommand
list_timeframes_cmd = subparsers.add_parser(
'list-timeframes',
help='Print available ticker intervals (timeframes) for the exchange.'
)
list_timeframes_cmd.set_defaults(func=start_list_timeframes)
self._build_args(optionlist=ARGS_LIST_TIMEFRAMES, parser=list_timeframes_cmd)
# Add download-data subcommand
download_data_cmd = subparsers.add_parser(
'download-data',

View File

@@ -203,6 +203,9 @@ class Exchange:
logger.info('Using Exchange "%s"', self.name)
# Check if timeframe is available
self.validate_timeframes(config.get('ticker_interval'))
# Converts the interval provided in minutes in config to seconds
self.markets_refresh_interval: int = exchange_config.get(
"markets_refresh_interval", 60) * 60
@@ -214,10 +217,6 @@ class Exchange:
self.validate_ordertypes(config.get('order_types', {}))
self.validate_order_time_in_force(config.get('order_time_in_force', {}))
if config.get('ticker_interval'):
# Check if timeframe is available
self.validate_timeframes(config['ticker_interval'])
def __del__(self):
"""
Destructor - clean up async stuff
@@ -269,6 +268,10 @@ class Exchange:
"""exchange ccxt id"""
return self._api.id
@property
def timeframes(self) -> List[str]:
return list((self._api.timeframes or {}).keys())
@property
def markets(self) -> Dict:
"""exchange ccxt markets"""
@@ -361,7 +364,7 @@ class Exchange:
return pair
raise DependencyException(f"Could not combine {curr_1} and {curr_2} to get a valid pair.")
def validate_timeframes(self, timeframe: List[str]) -> None:
def validate_timeframes(self, timeframe: Optional[str]) -> None:
"""
Checks if ticker interval from config is a supported timeframe on the exchange
"""
@@ -374,10 +377,9 @@ class Exchange:
f"for the exchange \"{self.name}\" and this exchange "
f"is therefore not supported. ccxt fetchOHLCV: {self.exchange_has('fetchOHLCV')}")
timeframes = self._api.timeframes
if timeframe not in timeframes:
if timeframe and (timeframe not in self.timeframes):
raise OperationalException(
f'Invalid ticker {timeframe}, this Exchange supports {timeframes}')
f"Invalid ticker interval '{timeframe}'. This exchange supports: {self.timeframes}")
def validate_ordertypes(self, order_types: Dict) -> None:
"""

View File

@@ -99,3 +99,21 @@ def start_download_data(args: Dict[str, Any]) -> None:
if pairs_not_available:
logger.info(f"Pairs [{','.join(pairs_not_available)}] not available "
f"on exchange {config['exchange']['name']}.")
def start_list_timeframes(args: Dict[str, Any]) -> None:
"""
Print ticker intervals (timeframes) available on Exchange
"""
config = setup_utils_configuration(args, RunMode.OTHER)
# Do not use ticker_interval set in the config
config['ticker_interval'] = None
# Init exchange
exchange = ExchangeResolver(config['exchange']['name'], config).exchange
if args['print_one_column']:
print('\n'.join(exchange.timeframes))
else:
print(f"Timeframes available for the exchange `{config['exchange']['name']}`: "
f"{', '.join(exchange.timeframes)}")