define constants on module level (#596)
This commit is contained in:
parent
9cb5591007
commit
9019f6492f
@ -8,8 +8,7 @@ import os
|
||||
import re
|
||||
from typing import List, Tuple, Optional
|
||||
|
||||
from freqtrade import __version__
|
||||
from freqtrade.constants import Constants
|
||||
from freqtrade import __version__, constants
|
||||
|
||||
|
||||
class Arguments(object):
|
||||
@ -98,7 +97,7 @@ class Arguments(object):
|
||||
help='dynamically generate and update whitelist \
|
||||
based on 24h BaseVolume (Default 20 currencies)', # noqa
|
||||
dest='dynamic_whitelist',
|
||||
const=Constants.DYNAMIC_WHITELIST,
|
||||
const=constants.DYNAMIC_WHITELIST,
|
||||
type=int,
|
||||
metavar='INT',
|
||||
nargs='?',
|
||||
@ -170,7 +169,7 @@ class Arguments(object):
|
||||
'-e', '--epochs',
|
||||
help='specify number of epochs (default: %(default)d)',
|
||||
dest='epochs',
|
||||
default=Constants.HYPEROPT_EPOCH,
|
||||
default=constants.HYPEROPT_EPOCH,
|
||||
type=int,
|
||||
metavar='INT',
|
||||
)
|
||||
|
@ -10,7 +10,7 @@ from typing import Dict, Any
|
||||
from jsonschema import Draft4Validator, validate
|
||||
from jsonschema.exceptions import ValidationError, best_match
|
||||
|
||||
from freqtrade.constants import Constants
|
||||
from freqtrade import constants
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -34,7 +34,7 @@ class Configuration(object):
|
||||
config = self._load_config_file(self.args.config)
|
||||
|
||||
# Set strategy if not specified in config and or if it's non default
|
||||
if self.args.strategy != Constants.DEFAULT_STRATEGY or not config.get('strategy'):
|
||||
if self.args.strategy != constants.DEFAULT_STRATEGY or not config.get('strategy'):
|
||||
config.update({'strategy': self.args.strategy})
|
||||
|
||||
if self.args.strategy_path:
|
||||
@ -186,7 +186,7 @@ class Configuration(object):
|
||||
:return: Returns the config if valid, otherwise throw an exception
|
||||
"""
|
||||
try:
|
||||
validate(conf, Constants.CONF_SCHEMA)
|
||||
validate(conf, constants.CONF_SCHEMA)
|
||||
return conf
|
||||
except ValidationError as exception:
|
||||
logger.fatal(
|
||||
@ -194,7 +194,7 @@ class Configuration(object):
|
||||
exception
|
||||
)
|
||||
raise ValidationError(
|
||||
best_match(Draft4Validator(Constants.CONF_SCHEMA).iter_errors(conf)).message
|
||||
best_match(Draft4Validator(constants.CONF_SCHEMA).iter_errors(conf)).message
|
||||
)
|
||||
|
||||
def get_config(self) -> Dict[str, Any]:
|
||||
|
@ -1,122 +1,116 @@
|
||||
# pragma pylint: disable=too-few-public-methods
|
||||
|
||||
"""
|
||||
List bot constants
|
||||
bot constants
|
||||
"""
|
||||
DYNAMIC_WHITELIST = 20 # pairs
|
||||
PROCESS_THROTTLE_SECS = 5 # sec
|
||||
TICKER_INTERVAL = 5 # min
|
||||
HYPEROPT_EPOCH = 100 # epochs
|
||||
RETRY_TIMEOUT = 30 # sec
|
||||
DEFAULT_STRATEGY = 'DefaultStrategy'
|
||||
|
||||
|
||||
class Constants(object):
|
||||
"""
|
||||
Static class that contain all bot constants
|
||||
"""
|
||||
DYNAMIC_WHITELIST = 20 # pairs
|
||||
PROCESS_THROTTLE_SECS = 5 # sec
|
||||
TICKER_INTERVAL = 5 # min
|
||||
HYPEROPT_EPOCH = 100 # epochs
|
||||
RETRY_TIMEOUT = 30 # sec
|
||||
DEFAULT_STRATEGY = 'DefaultStrategy'
|
||||
|
||||
# Required json-schema for user specified config
|
||||
CONF_SCHEMA = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'max_open_trades': {'type': 'integer', 'minimum': 1},
|
||||
'ticker_interval': {'type': 'integer', 'enum': [1, 5, 30, 60, 1440]},
|
||||
'stake_currency': {'type': 'string', 'enum': ['BTC', 'ETH', 'USDT']},
|
||||
'stake_amount': {'type': 'number', 'minimum': 0.0005},
|
||||
'fiat_display_currency': {'type': 'string', 'enum': ['AUD', 'BRL', 'CAD', 'CHF',
|
||||
'CLP', 'CNY', 'CZK', 'DKK',
|
||||
'EUR', 'GBP', 'HKD', 'HUF',
|
||||
'IDR', 'ILS', 'INR', 'JPY',
|
||||
'KRW', 'MXN', 'MYR', 'NOK',
|
||||
'NZD', 'PHP', 'PKR', 'PLN',
|
||||
'RUB', 'SEK', 'SGD', 'THB',
|
||||
'TRY', 'TWD', 'ZAR', 'USD']},
|
||||
'dry_run': {'type': 'boolean'},
|
||||
'minimal_roi': {
|
||||
'type': 'object',
|
||||
'patternProperties': {
|
||||
'^[0-9.]+$': {'type': 'number'}
|
||||
# Required json-schema for user specified config
|
||||
CONF_SCHEMA = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'max_open_trades': {'type': 'integer', 'minimum': 1},
|
||||
'ticker_interval': {'type': 'integer', 'enum': [1, 5, 30, 60, 1440]},
|
||||
'stake_currency': {'type': 'string', 'enum': ['BTC', 'ETH', 'USDT']},
|
||||
'stake_amount': {'type': 'number', 'minimum': 0.0005},
|
||||
'fiat_display_currency': {'type': 'string', 'enum': ['AUD', 'BRL', 'CAD', 'CHF',
|
||||
'CLP', 'CNY', 'CZK', 'DKK',
|
||||
'EUR', 'GBP', 'HKD', 'HUF',
|
||||
'IDR', 'ILS', 'INR', 'JPY',
|
||||
'KRW', 'MXN', 'MYR', 'NOK',
|
||||
'NZD', 'PHP', 'PKR', 'PLN',
|
||||
'RUB', 'SEK', 'SGD', 'THB',
|
||||
'TRY', 'TWD', 'ZAR', 'USD']},
|
||||
'dry_run': {'type': 'boolean'},
|
||||
'minimal_roi': {
|
||||
'type': 'object',
|
||||
'patternProperties': {
|
||||
'^[0-9.]+$': {'type': 'number'}
|
||||
},
|
||||
'minProperties': 1
|
||||
},
|
||||
'stoploss': {'type': 'number', 'maximum': 0, 'exclusiveMaximum': True},
|
||||
'unfilledtimeout': {'type': 'integer', 'minimum': 0},
|
||||
'bid_strategy': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'ask_last_balance': {
|
||||
'type': 'number',
|
||||
'minimum': 0,
|
||||
'maximum': 1,
|
||||
'exclusiveMaximum': False
|
||||
},
|
||||
'minProperties': 1
|
||||
},
|
||||
'stoploss': {'type': 'number', 'maximum': 0, 'exclusiveMaximum': True},
|
||||
'unfilledtimeout': {'type': 'integer', 'minimum': 0},
|
||||
'bid_strategy': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'ask_last_balance': {
|
||||
'type': 'number',
|
||||
'minimum': 0,
|
||||
'maximum': 1,
|
||||
'exclusiveMaximum': False
|
||||
},
|
||||
},
|
||||
'required': ['ask_last_balance']
|
||||
},
|
||||
'exchange': {'$ref': '#/definitions/exchange'},
|
||||
'experimental': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'use_sell_signal': {'type': 'boolean'},
|
||||
'sell_profit_only': {'type': 'boolean'}
|
||||
}
|
||||
},
|
||||
'telegram': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'enabled': {'type': 'boolean'},
|
||||
'token': {'type': 'string'},
|
||||
'chat_id': {'type': 'string'},
|
||||
},
|
||||
'required': ['enabled', 'token', 'chat_id']
|
||||
},
|
||||
'initial_state': {'type': 'string', 'enum': ['running', 'stopped']},
|
||||
'internals': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'process_throttle_secs': {'type': 'number'},
|
||||
'interval': {'type': 'integer'}
|
||||
}
|
||||
'required': ['ask_last_balance']
|
||||
},
|
||||
'exchange': {'$ref': '#/definitions/exchange'},
|
||||
'experimental': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'use_sell_signal': {'type': 'boolean'},
|
||||
'sell_profit_only': {'type': 'boolean'}
|
||||
}
|
||||
},
|
||||
'definitions': {
|
||||
'exchange': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'name': {'type': 'string'},
|
||||
'key': {'type': 'string'},
|
||||
'secret': {'type': 'string'},
|
||||
'pair_whitelist': {
|
||||
'type': 'array',
|
||||
'items': {
|
||||
'type': 'string',
|
||||
'pattern': '^[0-9A-Z]+_[0-9A-Z]+$'
|
||||
},
|
||||
'uniqueItems': True
|
||||
},
|
||||
'pair_blacklist': {
|
||||
'type': 'array',
|
||||
'items': {
|
||||
'type': 'string',
|
||||
'pattern': '^[0-9A-Z]+_[0-9A-Z]+$'
|
||||
},
|
||||
'uniqueItems': True
|
||||
}
|
||||
},
|
||||
'required': ['name', 'key', 'secret', 'pair_whitelist']
|
||||
}
|
||||
'telegram': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'enabled': {'type': 'boolean'},
|
||||
'token': {'type': 'string'},
|
||||
'chat_id': {'type': 'string'},
|
||||
},
|
||||
'required': ['enabled', 'token', 'chat_id']
|
||||
},
|
||||
'anyOf': [
|
||||
{'required': ['exchange']}
|
||||
],
|
||||
'required': [
|
||||
'max_open_trades',
|
||||
'stake_currency',
|
||||
'stake_amount',
|
||||
'fiat_display_currency',
|
||||
'dry_run',
|
||||
'bid_strategy',
|
||||
'telegram'
|
||||
]
|
||||
}
|
||||
'initial_state': {'type': 'string', 'enum': ['running', 'stopped']},
|
||||
'internals': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'process_throttle_secs': {'type': 'number'},
|
||||
'interval': {'type': 'integer'}
|
||||
}
|
||||
}
|
||||
},
|
||||
'definitions': {
|
||||
'exchange': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'name': {'type': 'string'},
|
||||
'key': {'type': 'string'},
|
||||
'secret': {'type': 'string'},
|
||||
'pair_whitelist': {
|
||||
'type': 'array',
|
||||
'items': {
|
||||
'type': 'string',
|
||||
'pattern': '^[0-9A-Z]+_[0-9A-Z]+$'
|
||||
},
|
||||
'uniqueItems': True
|
||||
},
|
||||
'pair_blacklist': {
|
||||
'type': 'array',
|
||||
'items': {
|
||||
'type': 'string',
|
||||
'pattern': '^[0-9A-Z]+_[0-9A-Z]+$'
|
||||
},
|
||||
'uniqueItems': True
|
||||
}
|
||||
},
|
||||
'required': ['name', 'key', 'secret', 'pair_whitelist']
|
||||
}
|
||||
},
|
||||
'anyOf': [
|
||||
{'required': ['exchange']}
|
||||
],
|
||||
'required': [
|
||||
'max_open_trades',
|
||||
'stake_currency',
|
||||
'stake_amount',
|
||||
'fiat_display_currency',
|
||||
'dry_run',
|
||||
'bid_strategy',
|
||||
'telegram'
|
||||
]
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ from freqtrade import (
|
||||
DependencyException, OperationalException, exchange, persistence, __version__
|
||||
)
|
||||
from freqtrade.analyze import Analyze
|
||||
from freqtrade.constants import Constants
|
||||
from freqtrade import constants
|
||||
from freqtrade.fiat_convert import CryptoToFiatConverter
|
||||
from freqtrade.persistence import Trade
|
||||
from freqtrade.rpc.rpc_manager import RPCManager
|
||||
@ -111,7 +111,7 @@ class FreqtradeBot(object):
|
||||
elif state == State.RUNNING:
|
||||
min_secs = self.config.get('internals', {}).get(
|
||||
'process_throttle_secs',
|
||||
Constants.PROCESS_THROTTLE_SECS
|
||||
constants.PROCESS_THROTTLE_SECS
|
||||
)
|
||||
|
||||
nb_assets = self.config.get('dynamic_whitelist', None)
|
||||
@ -175,7 +175,7 @@ class FreqtradeBot(object):
|
||||
|
||||
except (requests.exceptions.RequestException, json.JSONDecodeError) as error:
|
||||
logger.warning('%s, retrying in 30 seconds...', error)
|
||||
time.sleep(Constants.RETRY_TIMEOUT)
|
||||
time.sleep(constants.RETRY_TIMEOUT)
|
||||
except OperationalException:
|
||||
self.rpc.send_msg(
|
||||
'*Status:* OperationalException:\n```\n{traceback}```{hint}'
|
||||
|
@ -10,7 +10,7 @@ import os
|
||||
from collections import OrderedDict
|
||||
from typing import Optional, Dict, Type
|
||||
|
||||
from freqtrade.constants import Constants
|
||||
from freqtrade import constants
|
||||
from freqtrade.strategy.interface import IStrategy
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ class StrategyResolver(object):
|
||||
config = config or {}
|
||||
|
||||
# Verify the strategy is in the configuration, otherwise fallback to the default strategy
|
||||
strategy_name = config.get('strategy') or Constants.DEFAULT_STRATEGY
|
||||
strategy_name = config.get('strategy') or constants.DEFAULT_STRATEGY
|
||||
self.strategy = self._load_strategy(strategy_name, extra_dir=config.get('strategy_path'))
|
||||
|
||||
# Set attributes
|
||||
|
@ -12,7 +12,7 @@ from sqlalchemy import create_engine
|
||||
from telegram import Chat, Message, Update
|
||||
|
||||
from freqtrade.analyze import Analyze
|
||||
from freqtrade.constants import Constants
|
||||
from freqtrade import constants
|
||||
from freqtrade.freqtradebot import FreqtradeBot
|
||||
|
||||
logging.getLogger('').setLevel(logging.INFO)
|
||||
@ -88,7 +88,7 @@ def default_conf():
|
||||
"initial_state": "running",
|
||||
"loglevel": logging.DEBUG
|
||||
}
|
||||
validate(configuration, Constants.CONF_SCHEMA)
|
||||
validate(configuration, constants.CONF_SCHEMA)
|
||||
return configuration
|
||||
|
||||
|
||||
|
@ -2,25 +2,24 @@
|
||||
Unit test file for constants.py
|
||||
"""
|
||||
|
||||
from freqtrade.constants import Constants
|
||||
from freqtrade import constants
|
||||
|
||||
|
||||
def test_constant_object() -> None:
|
||||
"""
|
||||
Test the Constants object has the mandatory Constants
|
||||
"""
|
||||
assert hasattr(Constants, 'CONF_SCHEMA')
|
||||
assert hasattr(Constants, 'DYNAMIC_WHITELIST')
|
||||
assert hasattr(Constants, 'PROCESS_THROTTLE_SECS')
|
||||
assert hasattr(Constants, 'TICKER_INTERVAL')
|
||||
assert hasattr(Constants, 'HYPEROPT_EPOCH')
|
||||
assert hasattr(Constants, 'RETRY_TIMEOUT')
|
||||
assert hasattr(Constants, 'DEFAULT_STRATEGY')
|
||||
assert hasattr(constants, 'CONF_SCHEMA')
|
||||
assert hasattr(constants, 'DYNAMIC_WHITELIST')
|
||||
assert hasattr(constants, 'PROCESS_THROTTLE_SECS')
|
||||
assert hasattr(constants, 'TICKER_INTERVAL')
|
||||
assert hasattr(constants, 'HYPEROPT_EPOCH')
|
||||
assert hasattr(constants, 'RETRY_TIMEOUT')
|
||||
assert hasattr(constants, 'DEFAULT_STRATEGY')
|
||||
|
||||
|
||||
def test_conf_schema() -> None:
|
||||
"""
|
||||
Test the CONF_SCHEMA is from the right type
|
||||
"""
|
||||
constant = Constants()
|
||||
assert isinstance(constant.CONF_SCHEMA, dict)
|
||||
assert isinstance(constants.CONF_SCHEMA, dict)
|
||||
|
Loading…
Reference in New Issue
Block a user