Merge branch 'develop' into data_handler
This commit is contained in:
@@ -11,34 +11,3 @@ if __version__ == 'develop':
|
||||
except Exception:
|
||||
# git not available, ignore
|
||||
pass
|
||||
|
||||
|
||||
class DependencyException(Exception):
|
||||
"""
|
||||
Indicates that an assumed dependency is not met.
|
||||
This could happen when there is currently not enough money on the account.
|
||||
"""
|
||||
|
||||
|
||||
class OperationalException(Exception):
|
||||
"""
|
||||
Requires manual intervention and will usually stop the bot.
|
||||
This happens when an exchange returns an unexpected error during runtime
|
||||
or given configuration is invalid.
|
||||
"""
|
||||
|
||||
|
||||
class InvalidOrderException(Exception):
|
||||
"""
|
||||
This is returned when the order is not valid. Example:
|
||||
If stoploss on exchange order is hit, then trying to cancel the order
|
||||
should return this exception.
|
||||
"""
|
||||
|
||||
|
||||
class TemporaryError(Exception):
|
||||
"""
|
||||
Temporary network or exchange related error.
|
||||
This could happen when an exchange is congested, unavailable, or the user
|
||||
has networking problems. Usually resolves itself after a time.
|
||||
"""
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import logging
|
||||
from typing import Any, Dict
|
||||
|
||||
from freqtrade import OperationalException
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.exchange import (available_exchanges, get_exchange_bad_reason,
|
||||
is_exchange_known_ccxt, is_exchange_bad,
|
||||
is_exchange_bad, is_exchange_known_ccxt,
|
||||
is_exchange_officially_supported)
|
||||
from freqtrade.state import RunMode
|
||||
|
||||
|
@@ -4,7 +4,8 @@ from typing import Any, Dict
|
||||
from jsonschema import Draft4Validator, validators
|
||||
from jsonschema.exceptions import ValidationError, best_match
|
||||
|
||||
from freqtrade import constants, OperationalException
|
||||
from freqtrade import constants
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.state import RunMode
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@@ -7,15 +7,16 @@ from copy import deepcopy
|
||||
from pathlib import Path
|
||||
from typing import Any, Callable, Dict, List, Optional
|
||||
|
||||
from freqtrade import OperationalException, constants
|
||||
from freqtrade import constants
|
||||
from freqtrade.configuration.check_exchange import check_exchange
|
||||
from freqtrade.configuration.deprecated_settings import process_temporary_deprecated_settings
|
||||
from freqtrade.configuration.directory_operations import (create_datadir,
|
||||
create_userdata_dir)
|
||||
from freqtrade.configuration.load_config import load_config_file
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.loggers import setup_logging
|
||||
from freqtrade.misc import deep_merge_dicts, json_load
|
||||
from freqtrade.state import RunMode, TRADING_MODES, NON_UTIL_MODES
|
||||
from freqtrade.state import NON_UTIL_MODES, TRADING_MODES, RunMode
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@@ -5,7 +5,7 @@ Functions to handle deprecated settings
|
||||
import logging
|
||||
from typing import Any, Dict
|
||||
|
||||
from freqtrade import OperationalException
|
||||
from freqtrade.exceptions import OperationalException
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@@ -3,7 +3,7 @@ import shutil
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
from freqtrade import OperationalException
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.constants import USER_DATA_FILES
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@@ -6,7 +6,7 @@ import logging
|
||||
import sys
|
||||
from typing import Any, Dict
|
||||
|
||||
from freqtrade import OperationalException
|
||||
from freqtrade.exceptions import OperationalException
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@@ -7,11 +7,11 @@ from typing import Dict, List, Optional, Tuple
|
||||
import arrow
|
||||
from pandas import DataFrame
|
||||
|
||||
from freqtrade import OperationalException
|
||||
from freqtrade.configuration import TimeRange
|
||||
from freqtrade.constants import DEFAULT_DATAFRAME_COLUMNS
|
||||
from freqtrade.data.converter import parse_ticker_dataframe, trades_to_ohlcv
|
||||
from freqtrade.data.history.idatahandler import IDataHandler, get_datahandler
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.exchange import Exchange
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@@ -8,12 +8,12 @@ import numpy as np
|
||||
import utils_find_1st as utf1st
|
||||
from pandas import DataFrame
|
||||
|
||||
from freqtrade import constants, OperationalException
|
||||
from freqtrade import constants
|
||||
from freqtrade.configuration import TimeRange
|
||||
from freqtrade.data import history
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.strategy.interface import SellType
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
37
freqtrade/exceptions.py
Normal file
37
freqtrade/exceptions.py
Normal file
@@ -0,0 +1,37 @@
|
||||
|
||||
|
||||
class FreqtradeException(Exception):
|
||||
"""
|
||||
Freqtrade base exception. Handled at the outermost level.
|
||||
All other exception types are subclasses of this exception type.
|
||||
"""
|
||||
|
||||
|
||||
class OperationalException(FreqtradeException):
|
||||
"""
|
||||
Requires manual intervention and will stop the bot.
|
||||
Most of the time, this is caused by an invalid Configuration.
|
||||
"""
|
||||
|
||||
|
||||
class DependencyException(FreqtradeException):
|
||||
"""
|
||||
Indicates that an assumed dependency is not met.
|
||||
This could happen when there is currently not enough money on the account.
|
||||
"""
|
||||
|
||||
|
||||
class InvalidOrderException(FreqtradeException):
|
||||
"""
|
||||
This is returned when the order is not valid. Example:
|
||||
If stoploss on exchange order is hit, then trying to cancel the order
|
||||
should return this exception.
|
||||
"""
|
||||
|
||||
|
||||
class TemporaryError(FreqtradeException):
|
||||
"""
|
||||
Temporary network or exchange related error.
|
||||
This could happen when an exchange is congested, unavailable, or the user
|
||||
has networking problems. Usually resolves itself after a time.
|
||||
"""
|
@@ -4,8 +4,8 @@ from typing import Dict
|
||||
|
||||
import ccxt
|
||||
|
||||
from freqtrade import (DependencyException, InvalidOrderException,
|
||||
OperationalException, TemporaryError)
|
||||
from freqtrade.exceptions import (DependencyException, InvalidOrderException,
|
||||
OperationalException, TemporaryError)
|
||||
from freqtrade.exchange import Exchange
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import logging
|
||||
|
||||
from freqtrade import DependencyException, TemporaryError
|
||||
from freqtrade.exceptions import DependencyException, TemporaryError
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@@ -17,9 +17,9 @@ import ccxt.async_support as ccxt_async
|
||||
from ccxt.base.decimal_to_precision import ROUND_DOWN, ROUND_UP
|
||||
from pandas import DataFrame
|
||||
|
||||
from freqtrade import (DependencyException, InvalidOrderException,
|
||||
OperationalException, TemporaryError)
|
||||
from freqtrade.data.converter import parse_ticker_dataframe
|
||||
from freqtrade.exceptions import (DependencyException, InvalidOrderException,
|
||||
OperationalException, TemporaryError)
|
||||
from freqtrade.exchange.common import BAD_EXCHANGES, retrier, retrier_async
|
||||
from freqtrade.misc import deep_merge_dicts
|
||||
|
||||
|
@@ -4,7 +4,7 @@ from typing import Dict
|
||||
|
||||
import ccxt
|
||||
|
||||
from freqtrade import OperationalException, TemporaryError
|
||||
from freqtrade.exceptions import OperationalException, TemporaryError
|
||||
from freqtrade.exchange import Exchange
|
||||
from freqtrade.exchange.exchange import retrier
|
||||
|
||||
|
@@ -12,17 +12,17 @@ from typing import Any, Dict, List, Optional, Tuple
|
||||
import arrow
|
||||
from requests.exceptions import RequestException
|
||||
|
||||
from freqtrade import (DependencyException, InvalidOrderException, __version__,
|
||||
constants, persistence)
|
||||
from freqtrade import __version__, constants, persistence
|
||||
from freqtrade.configuration import validate_config_consistency
|
||||
from freqtrade.data.converter import order_book_to_dataframe
|
||||
from freqtrade.data.dataprovider import DataProvider
|
||||
from freqtrade.edge import Edge
|
||||
from freqtrade.exceptions import DependencyException, InvalidOrderException
|
||||
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_next_date
|
||||
from freqtrade.pairlist.pairlistmanager import PairListManager
|
||||
from freqtrade.persistence import Trade
|
||||
from freqtrade.resolvers import ExchangeResolver, StrategyResolver
|
||||
from freqtrade.rpc import RPCManager, RPCMessageType
|
||||
from freqtrade.pairlist.pairlistmanager import PairListManager
|
||||
from freqtrade.state import State
|
||||
from freqtrade.strategy.interface import IStrategy, SellType
|
||||
from freqtrade.wallets import Wallets
|
||||
@@ -136,7 +136,7 @@ class FreqtradeBot:
|
||||
self.process_maybe_execute_sells(trades)
|
||||
|
||||
# Then looking for buy opportunities
|
||||
if len(trades) < self.config['max_open_trades']:
|
||||
if self.get_free_open_trades():
|
||||
self.process_maybe_execute_buys()
|
||||
|
||||
# Check and handle any timed out open orders
|
||||
@@ -173,6 +173,14 @@ class FreqtradeBot:
|
||||
"""
|
||||
return [(pair, self.config['ticker_interval']) for pair in pairs]
|
||||
|
||||
def get_free_open_trades(self):
|
||||
"""
|
||||
Return the number of free open trades slots or 0 if
|
||||
max number of open trades reached
|
||||
"""
|
||||
open_trades = len(Trade.get_open_trades())
|
||||
return max(0, self.config['max_open_trades'] - open_trades)
|
||||
|
||||
def get_target_bid(self, pair: str, tick: Dict = None) -> float:
|
||||
"""
|
||||
Calculates bid target between current ask price and last price
|
||||
@@ -204,14 +212,14 @@ class FreqtradeBot:
|
||||
|
||||
return used_rate
|
||||
|
||||
def _get_trade_stake_amount(self, pair) -> Optional[float]:
|
||||
def get_trade_stake_amount(self, pair) -> Optional[float]:
|
||||
"""
|
||||
Check if stake amount can be fulfilled with the available balance
|
||||
for the stake currency
|
||||
:return: float: Stake Amount
|
||||
Calculate stake amount for the trade
|
||||
:return: float: Stake amount
|
||||
"""
|
||||
stake_amount: Optional[float]
|
||||
if self.edge:
|
||||
return self.edge.stake_amount(
|
||||
stake_amount = self.edge.stake_amount(
|
||||
pair,
|
||||
self.wallets.get_free(self.config['stake_currency']),
|
||||
self.wallets.get_total(self.config['stake_currency']),
|
||||
@@ -219,18 +227,31 @@ class FreqtradeBot:
|
||||
)
|
||||
else:
|
||||
stake_amount = self.config['stake_amount']
|
||||
if stake_amount == constants.UNLIMITED_STAKE_AMOUNT:
|
||||
stake_amount = self._calculate_unlimited_stake_amount()
|
||||
|
||||
return self._check_available_stake_amount(stake_amount)
|
||||
|
||||
def _calculate_unlimited_stake_amount(self) -> Optional[float]:
|
||||
"""
|
||||
Calculate stake amount for "unlimited" stake amount
|
||||
:return: None if max number of trades reached
|
||||
"""
|
||||
free_open_trades = self.get_free_open_trades()
|
||||
if not free_open_trades:
|
||||
return None
|
||||
available_amount = self.wallets.get_free(self.config['stake_currency'])
|
||||
return available_amount / free_open_trades
|
||||
|
||||
def _check_available_stake_amount(self, stake_amount: Optional[float]) -> Optional[float]:
|
||||
"""
|
||||
Check if stake amount can be fulfilled with the available balance
|
||||
for the stake currency
|
||||
:return: float: Stake amount
|
||||
"""
|
||||
available_amount = self.wallets.get_free(self.config['stake_currency'])
|
||||
|
||||
if stake_amount == constants.UNLIMITED_STAKE_AMOUNT:
|
||||
open_trades = len(Trade.get_open_trades())
|
||||
if open_trades >= self.config['max_open_trades']:
|
||||
logger.warning("Can't open a new trade: max number of trades is reached")
|
||||
return None
|
||||
return available_amount / (self.config['max_open_trades'] - open_trades)
|
||||
|
||||
# Check if stake_amount is fulfilled
|
||||
if available_amount < stake_amount:
|
||||
if stake_amount is not None and available_amount < stake_amount:
|
||||
raise DependencyException(
|
||||
f"Available balance ({available_amount} {self.config['stake_currency']}) is "
|
||||
f"lower than stake amount ({stake_amount} {self.config['stake_currency']})"
|
||||
@@ -299,18 +320,23 @@ class FreqtradeBot:
|
||||
|
||||
buycount = 0
|
||||
# running get_signal on historical data fetched
|
||||
for _pair in whitelist:
|
||||
if self.strategy.is_pair_locked(_pair):
|
||||
logger.info(f"Pair {_pair} is currently locked.")
|
||||
for pair in whitelist:
|
||||
if self.strategy.is_pair_locked(pair):
|
||||
logger.info(f"Pair {pair} is currently locked.")
|
||||
continue
|
||||
|
||||
(buy, sell) = self.strategy.get_signal(
|
||||
_pair, self.strategy.ticker_interval,
|
||||
self.dataprovider.ohlcv(_pair, self.strategy.ticker_interval))
|
||||
pair, self.strategy.ticker_interval,
|
||||
self.dataprovider.ohlcv(pair, self.strategy.ticker_interval))
|
||||
|
||||
if buy and not sell and len(Trade.get_open_trades()) < self.config['max_open_trades']:
|
||||
stake_amount = self._get_trade_stake_amount(_pair)
|
||||
if buy and not sell:
|
||||
if not self.get_free_open_trades():
|
||||
logger.debug("Can't open a new trade: max number of trades is reached")
|
||||
continue
|
||||
|
||||
stake_amount = self.get_trade_stake_amount(pair)
|
||||
if not stake_amount:
|
||||
logger.debug("Stake amount is 0, ignoring possible trade for {pair}.")
|
||||
continue
|
||||
|
||||
logger.info(f"Buy signal found: about create a new trade with stake_amount: "
|
||||
@@ -320,11 +346,11 @@ class FreqtradeBot:
|
||||
get('check_depth_of_market', {})
|
||||
if (bidstrat_check_depth_of_market.get('enabled', False)) and\
|
||||
(bidstrat_check_depth_of_market.get('bids_to_ask_delta', 0) > 0):
|
||||
if self._check_depth_of_market_buy(_pair, bidstrat_check_depth_of_market):
|
||||
buycount += self.execute_buy(_pair, stake_amount)
|
||||
if self._check_depth_of_market_buy(pair, bidstrat_check_depth_of_market):
|
||||
buycount += self.execute_buy(pair, stake_amount)
|
||||
continue
|
||||
|
||||
buycount += self.execute_buy(_pair, stake_amount)
|
||||
buycount += self.execute_buy(pair, stake_amount)
|
||||
|
||||
return buycount > 0
|
||||
|
||||
@@ -351,7 +377,6 @@ class FreqtradeBot:
|
||||
:param pair: pair for which we want to create a LIMIT_BUY
|
||||
:return: None
|
||||
"""
|
||||
pair_s = pair.replace('_', '/')
|
||||
stake_currency = self.config['stake_currency']
|
||||
fiat_currency = self.config.get('fiat_display_currency', None)
|
||||
time_in_force = self.strategy.order_time_in_force['buy']
|
||||
@@ -362,10 +387,10 @@ class FreqtradeBot:
|
||||
# Calculate amount
|
||||
buy_limit_requested = self.get_target_bid(pair)
|
||||
|
||||
min_stake_amount = self._get_min_pair_stake_amount(pair_s, buy_limit_requested)
|
||||
min_stake_amount = self._get_min_pair_stake_amount(pair, buy_limit_requested)
|
||||
if min_stake_amount is not None and min_stake_amount > stake_amount:
|
||||
logger.warning(
|
||||
f"Can't open a new trade for {pair_s}: stake amount "
|
||||
f"Can't open a new trade for {pair}: stake amount "
|
||||
f"is too small ({stake_amount} < {min_stake_amount})"
|
||||
)
|
||||
return False
|
||||
@@ -388,7 +413,7 @@ class FreqtradeBot:
|
||||
if float(order['filled']) == 0:
|
||||
logger.warning('Buy %s order with time in force %s for %s is %s by %s.'
|
||||
' zero amount is fulfilled.',
|
||||
order_tif, order_type, pair_s, order_status, self.exchange.name)
|
||||
order_tif, order_type, pair, order_status, self.exchange.name)
|
||||
return False
|
||||
else:
|
||||
# the order is partially fulfilled
|
||||
@@ -396,7 +421,7 @@ class FreqtradeBot:
|
||||
# if the order is fulfilled fully or partially
|
||||
logger.warning('Buy %s order with time in force %s for %s is %s by %s.'
|
||||
' %s amount fulfilled out of %s (%s remaining which is canceled).',
|
||||
order_tif, order_type, pair_s, order_status, self.exchange.name,
|
||||
order_tif, order_type, pair, order_status, self.exchange.name,
|
||||
order['filled'], order['amount'], order['remaining']
|
||||
)
|
||||
stake_amount = order['cost']
|
||||
@@ -413,7 +438,7 @@ class FreqtradeBot:
|
||||
self.rpc.send_msg({
|
||||
'type': RPCMessageType.BUY_NOTIFICATION,
|
||||
'exchange': self.exchange.name.capitalize(),
|
||||
'pair': pair_s,
|
||||
'pair': pair,
|
||||
'limit': buy_limit_filled_price,
|
||||
'order_type': order_type,
|
||||
'stake_amount': stake_amount,
|
||||
@@ -892,6 +917,27 @@ class FreqtradeBot:
|
||||
# TODO: figure out how to handle partially complete sell orders
|
||||
return False
|
||||
|
||||
def _safe_sell_amount(self, pair: str, amount: float) -> float:
|
||||
"""
|
||||
Get sellable amount.
|
||||
Should be trade.amount - but will fall back to the available amount if necessary.
|
||||
This should cover cases where get_real_amount() was not able to update the amount
|
||||
for whatever reason.
|
||||
:param pair: Pair we're trying to sell
|
||||
:param amount: amount we expect to be available
|
||||
:return: amount to sell
|
||||
:raise: DependencyException: if available balance is not within 2% of the available amount.
|
||||
"""
|
||||
wallet_amount = self.wallets.get_free(pair.split('/')[0])
|
||||
logger.debug(f"{pair} - Wallet: {wallet_amount} - Trade-amount: {amount}")
|
||||
if wallet_amount > amount:
|
||||
return amount
|
||||
elif wallet_amount > amount * 0.98:
|
||||
logger.info(f"{pair} - Falling back to wallet-amount.")
|
||||
return wallet_amount
|
||||
else:
|
||||
raise DependencyException("Not enough amount to sell.")
|
||||
|
||||
def execute_sell(self, trade: Trade, limit: float, sell_reason: SellType) -> None:
|
||||
"""
|
||||
Executes a limit sell for the given trade and limit
|
||||
@@ -922,10 +968,12 @@ class FreqtradeBot:
|
||||
# Emergencysells (default to market!)
|
||||
ordertype = self.strategy.order_types.get("emergencysell", "market")
|
||||
|
||||
amount = self._safe_sell_amount(trade.pair, trade.amount)
|
||||
|
||||
# Execute sell and update trade record
|
||||
order = self.exchange.sell(pair=str(trade.pair),
|
||||
ordertype=ordertype,
|
||||
amount=trade.amount, rate=limit,
|
||||
amount=amount, rate=limit,
|
||||
time_in_force=self.strategy.order_time_in_force['sell']
|
||||
)
|
||||
|
||||
|
@@ -5,7 +5,7 @@ from logging import Formatter
|
||||
from logging.handlers import RotatingFileHandler, SysLogHandler
|
||||
from typing import Any, Dict, List
|
||||
|
||||
from freqtrade import OperationalException
|
||||
from freqtrade.exceptions import OperationalException
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@@ -4,6 +4,7 @@ Main Freqtrade bot script.
|
||||
Read the documentation to know what cli arguments you need.
|
||||
"""
|
||||
|
||||
from freqtrade.exceptions import FreqtradeException, OperationalException
|
||||
import sys
|
||||
# check min. python version
|
||||
if sys.version_info < (3, 6):
|
||||
@@ -13,7 +14,6 @@ if sys.version_info < (3, 6):
|
||||
import logging
|
||||
from typing import Any, List
|
||||
|
||||
from freqtrade import OperationalException
|
||||
from freqtrade.configuration import Arguments
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ def main(sysargv: List[str] = None) -> None:
|
||||
except KeyboardInterrupt:
|
||||
logger.info('SIGINT received, aborting ...')
|
||||
return_code = 0
|
||||
except OperationalException as e:
|
||||
except FreqtradeException as e:
|
||||
logger.error(str(e))
|
||||
return_code = 2
|
||||
except Exception:
|
||||
|
@@ -1,11 +1,11 @@
|
||||
import logging
|
||||
from typing import Any, Dict
|
||||
|
||||
from freqtrade import DependencyException, constants, OperationalException
|
||||
from freqtrade import constants
|
||||
from freqtrade.exceptions import DependencyException, OperationalException
|
||||
from freqtrade.state import RunMode
|
||||
from freqtrade.utils import setup_utils_configuration
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
@@ -12,12 +12,12 @@ from typing import Any, Dict, List, NamedTuple, Optional
|
||||
from pandas import DataFrame
|
||||
from tabulate import tabulate
|
||||
|
||||
from freqtrade import OperationalException
|
||||
from freqtrade.configuration import (TimeRange, remove_credentials,
|
||||
validate_config_consistency)
|
||||
from freqtrade.data import history
|
||||
from freqtrade.data.converter import trim_dataframe
|
||||
from freqtrade.data.dataprovider import DataProvider
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds
|
||||
from freqtrade.misc import file_dump_json
|
||||
from freqtrade.persistence import Trade
|
||||
|
@@ -12,8 +12,7 @@ from freqtrade import constants
|
||||
from freqtrade.configuration import (TimeRange, remove_credentials,
|
||||
validate_config_consistency)
|
||||
from freqtrade.edge import Edge
|
||||
from freqtrade.exchange import Exchange
|
||||
from freqtrade.resolvers import StrategyResolver
|
||||
from freqtrade.resolvers import StrategyResolver, ExchangeResolver
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -33,7 +32,7 @@ class EdgeCli:
|
||||
# Reset keys for edge
|
||||
remove_credentials(self.config)
|
||||
self.config['stake_amount'] = constants.UNLIMITED_STAKE_AMOUNT
|
||||
self.exchange = Exchange(self.config)
|
||||
self.exchange = ExchangeResolver.load_exchange(self.config['exchange']['name'], self.config)
|
||||
self.strategy = StrategyResolver.load_strategy(self.config)
|
||||
|
||||
validate_config_consistency(self.config)
|
||||
|
@@ -22,14 +22,14 @@ from joblib import (Parallel, cpu_count, delayed, dump, load,
|
||||
wrap_non_picklable_objects)
|
||||
from pandas import DataFrame
|
||||
|
||||
from freqtrade import OperationalException
|
||||
from freqtrade.data.history import get_timerange
|
||||
from freqtrade.data.converter import trim_dataframe
|
||||
from freqtrade.data.history import get_timerange
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.misc import plural, round_dict
|
||||
from freqtrade.optimize.backtesting import Backtesting
|
||||
# Import IHyperOpt and IHyperOptLoss to allow unpickling classes from these modules
|
||||
from freqtrade.optimize.hyperopt_interface import IHyperOpt # noqa: F4
|
||||
from freqtrade.optimize.hyperopt_loss_interface import IHyperOptLoss # noqa: F4
|
||||
from freqtrade.optimize.hyperopt_interface import IHyperOpt # noqa: F401
|
||||
from freqtrade.optimize.hyperopt_loss_interface import IHyperOptLoss # noqa: F401
|
||||
from freqtrade.resolvers.hyperopt_resolver import (HyperOptLossResolver,
|
||||
HyperOptResolver)
|
||||
|
||||
|
@@ -4,17 +4,15 @@ This module defines the interface to apply for hyperopt
|
||||
"""
|
||||
import logging
|
||||
import math
|
||||
|
||||
from abc import ABC
|
||||
from typing import Dict, Any, Callable, List
|
||||
from typing import Any, Callable, Dict, List
|
||||
|
||||
from skopt.space import Categorical, Dimension, Integer, Real
|
||||
|
||||
from freqtrade import OperationalException
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.exchange import timeframe_to_minutes
|
||||
from freqtrade.misc import round_dict
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
@@ -8,7 +8,7 @@ import logging
|
||||
from datetime import datetime
|
||||
from typing import Dict, List
|
||||
|
||||
from freqtrade import OperationalException
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.pairlist.IPairList import IPairList
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@@ -4,11 +4,12 @@ Static List provider
|
||||
Provides lists as configured in config.json
|
||||
|
||||
"""
|
||||
from cachetools import TTLCache, cached
|
||||
import logging
|
||||
from typing import Dict, List
|
||||
|
||||
from freqtrade import OperationalException
|
||||
from cachetools import TTLCache, cached
|
||||
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.pairlist.IPairList import IPairList
|
||||
from freqtrade.resolvers import PairListResolver
|
||||
|
||||
|
@@ -16,7 +16,7 @@ from sqlalchemy.orm.scoping import scoped_session
|
||||
from sqlalchemy.orm.session import sessionmaker
|
||||
from sqlalchemy.pool import StaticPool
|
||||
|
||||
from freqtrade import OperationalException
|
||||
from freqtrade.exceptions import OperationalException
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
from typing import Any, Dict
|
||||
|
||||
from freqtrade import OperationalException
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.state import RunMode
|
||||
from freqtrade.utils import setup_utils_configuration
|
||||
|
||||
|
@@ -7,8 +7,8 @@ import logging
|
||||
from pathlib import Path
|
||||
from typing import Dict
|
||||
|
||||
from freqtrade import OperationalException
|
||||
from freqtrade.constants import DEFAULT_HYPEROPT_LOSS, USERPATH_HYPEROPTS
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.optimize.hyperopt_interface import IHyperOpt
|
||||
from freqtrade.optimize.hyperopt_loss_interface import IHyperOptLoss
|
||||
from freqtrade.resolvers import IResolver
|
||||
|
@@ -9,7 +9,7 @@ import logging
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, Generator, List, Optional, Tuple, Type, Union
|
||||
|
||||
from freqtrade import OperationalException
|
||||
from freqtrade.exceptions import OperationalException
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@@ -11,9 +11,9 @@ from inspect import getfullargspec
|
||||
from pathlib import Path
|
||||
from typing import Dict, Optional
|
||||
|
||||
from freqtrade import OperationalException
|
||||
from freqtrade.constants import (REQUIRED_ORDERTIF, REQUIRED_ORDERTYPES,
|
||||
USERPATH_STRATEGY)
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.resolvers import IResolver
|
||||
from freqtrade.strategy.interface import IStrategy
|
||||
|
||||
|
@@ -11,7 +11,7 @@ from typing import Any, Dict, List, Optional, Tuple
|
||||
import arrow
|
||||
from numpy import NAN, mean
|
||||
|
||||
from freqtrade import DependencyException, TemporaryError
|
||||
from freqtrade.exceptions import DependencyException, TemporaryError
|
||||
from freqtrade.misc import shorten_date
|
||||
from freqtrade.persistence import Trade
|
||||
from freqtrade.rpc.fiat_convert import CryptoToFiatConverter
|
||||
@@ -142,7 +142,7 @@ class RPC:
|
||||
def _rpc_status_table(self, stake_currency, fiat_display_currency: str) -> Tuple[List, List]:
|
||||
trades = Trade.get_open_trades()
|
||||
if not trades:
|
||||
raise RPCException('no active order')
|
||||
raise RPCException('no active trade')
|
||||
else:
|
||||
trades_list = []
|
||||
for trade in trades:
|
||||
@@ -462,7 +462,7 @@ class RPC:
|
||||
raise RPCException(f'position for {pair} already open - id: {trade.id}')
|
||||
|
||||
# gen stake amount
|
||||
stakeamount = self._freqtrade._get_trade_stake_amount(pair)
|
||||
stakeamount = self._freqtrade.get_trade_stake_amount(pair)
|
||||
|
||||
# execute buy
|
||||
if self._freqtrade.execute_buy(pair, stakeamount, price):
|
||||
|
@@ -47,6 +47,7 @@ class {{ strategy }}(IStrategy):
|
||||
|
||||
# Trailing stoploss
|
||||
trailing_stop = False
|
||||
# trailing_only_offset_is_reached = False
|
||||
# trailing_stop_positive = 0.01
|
||||
# trailing_stop_positive_offset = 0.0 # Disabled / not configured
|
||||
|
||||
|
@@ -48,6 +48,7 @@ class SampleStrategy(IStrategy):
|
||||
|
||||
# Trailing stoploss
|
||||
trailing_stop = False
|
||||
# trailing_only_offset_is_reached = False
|
||||
# trailing_stop_positive = 0.01
|
||||
# trailing_stop_positive_offset = 0.0 # Disabled / not configured
|
||||
|
||||
|
@@ -11,7 +11,6 @@ import rapidjson
|
||||
from colorama import init as colorama_init
|
||||
from tabulate import tabulate
|
||||
|
||||
from freqtrade import OperationalException
|
||||
from freqtrade.configuration import (Configuration, TimeRange,
|
||||
remove_credentials)
|
||||
from freqtrade.configuration.directory_operations import (copy_sample_files,
|
||||
@@ -22,6 +21,7 @@ from freqtrade.data.converter import (convert_ohlcv_format,
|
||||
from freqtrade.data.history import (convert_trades_to_ohlcv,
|
||||
refresh_backtest_ohlcv_data,
|
||||
refresh_backtest_trades_data)
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.exchange import (available_exchanges, ccxt_exchanges,
|
||||
market_is_active, symbol_is_pair)
|
||||
from freqtrade.misc import plural, render_template
|
||||
|
@@ -8,9 +8,9 @@ from typing import Any, Callable, Dict, Optional
|
||||
|
||||
import sdnotify
|
||||
|
||||
from freqtrade import (OperationalException, TemporaryError, __version__,
|
||||
constants)
|
||||
from freqtrade import __version__, constants
|
||||
from freqtrade.configuration import Configuration
|
||||
from freqtrade.exceptions import OperationalException, TemporaryError
|
||||
from freqtrade.freqtradebot import FreqtradeBot
|
||||
from freqtrade.rpc import RPCMessageType
|
||||
from freqtrade.state import State
|
||||
|
Reference in New Issue
Block a user