diff --git a/freqtrade/analyze.py b/freqtrade/analyze.py index 7f504e215..5c734b24e 100644 --- a/freqtrade/analyze.py +++ b/freqtrade/analyze.py @@ -8,8 +8,6 @@ from pandas import DataFrame, to_datetime from freqtrade.exchange import get_ticker_history from freqtrade.vendor.qtpylib.indicators import awesome_oscillator -logging.basicConfig(level=logging.DEBUG, - format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') logger = logging.getLogger(__name__) diff --git a/freqtrade/main.py b/freqtrade/main.py index 2371f90a9..1e31a0ca7 100755 --- a/freqtrade/main.py +++ b/freqtrade/main.py @@ -5,21 +5,19 @@ import logging import time import traceback from datetime import datetime -from typing import Dict, Optional from signal import signal, SIGINT, SIGABRT, SIGTERM +from typing import Dict, Optional import requests from jsonschema import validate from freqtrade import __version__, exchange, persistence from freqtrade.analyze import get_buy_signal -from freqtrade.misc import CONF_SCHEMA, State, get_state, update_state +from freqtrade.misc import CONF_SCHEMA, State, get_state, update_state, build_arg_parser from freqtrade.persistence import Trade from freqtrade.rpc import telegram -logging.basicConfig(level=logging.DEBUG, - format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') -logger = logging.getLogger(__name__) +logger = logging.getLogger('freqtrade') _CONF = {} @@ -42,7 +40,10 @@ def _process() -> bool: Trade.session.add(trade) state_changed = True else: - logging.info('Got no buy signal...') + logger.info( + 'Checked all whitelisted currencies. ' + 'Found no suitable entry positions for buying. Will keep looking ...' + ) except ValueError: logger.exception('Unable to create trade') @@ -85,7 +86,10 @@ def close_trade_if_fulfilled(trade: Trade) -> bool: and trade.close_rate is not None \ and trade.open_order_id is None: trade.is_open = False - logger.info('No open orders found and trade is fulfilled. Marking %s as closed ...', trade) + logger.info( + 'Marking %s as closed as the trade is fulfilled and found no open orders for it.', + trade + ) return True return False @@ -163,7 +167,10 @@ def create_trade(stake_amount: float) -> Optional[Trade]: if one pair triggers the buy_signal a new trade record gets created :param stake_amount: amount of btc to spend """ - logger.info('Creating new trade with stake_amount: %f ...', stake_amount) + logger.info( + 'Checking buy signals to create a new trade with stake_amount: %f ...', + stake_amount + ) whitelist = copy.deepcopy(_CONF['exchange']['pair_whitelist']) # Check if stake_amount is fulfilled if exchange.get_balance(_CONF['stake_currency']) < stake_amount: @@ -255,15 +262,28 @@ def main(): Loads and validates the config and handles the main loop :return: None """ - logger.info('Starting freqtrade %s', __version__) - global _CONF - with open('config.json') as file: - _CONF = json.load(file) + args = build_arg_parser().parse_args() + # Initialize logger + logging.basicConfig( + level=args.loglevel, + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', + ) + + logger.info( + 'Starting freqtrade %s (loglevel=%s)', + __version__, + logging.getLevelName(args.loglevel) + ) + + # Load and validate configuration + with open(args.config) as file: + _CONF = json.load(file) logger.info('Validating configuration ...') validate(_CONF, CONF_SCHEMA) + # Initialize all modules and start main loop init(_CONF) old_state = get_state() logger.info('Initial State: %s', old_state) @@ -273,7 +293,7 @@ def main(): # Log state transition if new_state != old_state: telegram.send_msg('*Status:* `{}`'.format(new_state.name.lower())) - logging.info('Changing state to: %s', new_state.name) + logger.info('Changing state to: %s', new_state.name) if new_state == State.STOPPED: time.sleep(1) diff --git a/freqtrade/misc.py b/freqtrade/misc.py index 585aee3de..4787ef2f9 100644 --- a/freqtrade/misc.py +++ b/freqtrade/misc.py @@ -1,7 +1,11 @@ +import argparse import enum +import logging from wrapt import synchronized +from freqtrade import __version__ + class State(enum.Enum): RUNNING = 0 @@ -32,6 +36,35 @@ def get_state() -> State: return _STATE +def build_arg_parser() -> argparse.ArgumentParser: + """ Builds and returns an ArgumentParser instance """ + parser = argparse.ArgumentParser( + description='Simple High Frequency Trading Bot for crypto currencies' + ) + parser.add_argument( + '-c', '--config', + help='specify configuration file (default: config.json)', + dest='config', + default='config.json', + type=str, + metavar='PATH', + ) + parser.add_argument( + '-v', '--verbose', + help='be verbose', + action='store_const', + dest='loglevel', + const=logging.DEBUG, + default=logging.INFO, + ) + parser.add_argument( + '--version', + action='version', + version='%(prog)s {}'.format(__version__), + ) + return parser + + # Required json-schema for user specified config CONF_SCHEMA = { 'type': 'object', diff --git a/freqtrade/persistence.py b/freqtrade/persistence.py index 8c23cf713..e48538754 100644 --- a/freqtrade/persistence.py +++ b/freqtrade/persistence.py @@ -11,8 +11,6 @@ from sqlalchemy.orm.scoping import scoped_session from sqlalchemy.orm.session import sessionmaker from sqlalchemy.pool import StaticPool -logging.basicConfig(level=logging.DEBUG, - format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') logger = logging.getLogger(__name__) _CONF = {}