Merge pull request #2343 from hroff-1902/move-experimental
Move experimental settings to ask_strategy
This commit is contained in:
commit
85c4546333
@ -22,7 +22,10 @@
|
|||||||
"ask_strategy":{
|
"ask_strategy":{
|
||||||
"use_order_book": false,
|
"use_order_book": false,
|
||||||
"order_book_min": 1,
|
"order_book_min": 1,
|
||||||
"order_book_max": 9
|
"order_book_max": 9,
|
||||||
|
"use_sell_signal": true,
|
||||||
|
"sell_profit_only": false,
|
||||||
|
"ignore_roi_if_buy_signal": false
|
||||||
},
|
},
|
||||||
"exchange": {
|
"exchange": {
|
||||||
"name": "bittrex",
|
"name": "bittrex",
|
||||||
@ -49,11 +52,6 @@
|
|||||||
"DOGE/BTC"
|
"DOGE/BTC"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"experimental": {
|
|
||||||
"use_sell_signal": false,
|
|
||||||
"sell_profit_only": false,
|
|
||||||
"ignore_roi_if_buy_signal": false
|
|
||||||
},
|
|
||||||
"edge": {
|
"edge": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"process_throttle_secs": 3600,
|
"process_throttle_secs": 3600,
|
||||||
|
@ -22,7 +22,10 @@
|
|||||||
"ask_strategy":{
|
"ask_strategy":{
|
||||||
"use_order_book": false,
|
"use_order_book": false,
|
||||||
"order_book_min": 1,
|
"order_book_min": 1,
|
||||||
"order_book_max": 9
|
"order_book_max": 9,
|
||||||
|
"use_sell_signal": true,
|
||||||
|
"sell_profit_only": false,
|
||||||
|
"ignore_roi_if_buy_signal": false
|
||||||
},
|
},
|
||||||
"exchange": {
|
"exchange": {
|
||||||
"name": "binance",
|
"name": "binance",
|
||||||
@ -51,11 +54,6 @@
|
|||||||
"BNB/BTC"
|
"BNB/BTC"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"experimental": {
|
|
||||||
"use_sell_signal": false,
|
|
||||||
"sell_profit_only": false,
|
|
||||||
"ignore_roi_if_buy_signal": false
|
|
||||||
},
|
|
||||||
"edge": {
|
"edge": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"process_throttle_secs": 3600,
|
"process_throttle_secs": 3600,
|
||||||
|
@ -33,7 +33,10 @@
|
|||||||
"ask_strategy":{
|
"ask_strategy":{
|
||||||
"use_order_book": false,
|
"use_order_book": false,
|
||||||
"order_book_min": 1,
|
"order_book_min": 1,
|
||||||
"order_book_max": 9
|
"order_book_max": 9,
|
||||||
|
"use_sell_signal": true,
|
||||||
|
"sell_profit_only": false,
|
||||||
|
"ignore_roi_if_buy_signal": false
|
||||||
},
|
},
|
||||||
"order_types": {
|
"order_types": {
|
||||||
"buy": "limit",
|
"buy": "limit",
|
||||||
@ -100,11 +103,6 @@
|
|||||||
"max_trade_duration_minute": 1440,
|
"max_trade_duration_minute": 1440,
|
||||||
"remove_pumps": false
|
"remove_pumps": false
|
||||||
},
|
},
|
||||||
"experimental": {
|
|
||||||
"use_sell_signal": false,
|
|
||||||
"sell_profit_only": false,
|
|
||||||
"ignore_roi_if_buy_signal": false
|
|
||||||
},
|
|
||||||
"telegram": {
|
"telegram": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"token": "your_telegram_token",
|
"token": "your_telegram_token",
|
||||||
|
@ -22,7 +22,11 @@
|
|||||||
"ask_strategy":{
|
"ask_strategy":{
|
||||||
"use_order_book": false,
|
"use_order_book": false,
|
||||||
"order_book_min": 1,
|
"order_book_min": 1,
|
||||||
"order_book_max": 9
|
"order_book_max": 9,
|
||||||
|
"use_sell_signal": true,
|
||||||
|
"sell_profit_only": false,
|
||||||
|
"ignore_roi_if_buy_signal": false
|
||||||
|
|
||||||
},
|
},
|
||||||
"exchange": {
|
"exchange": {
|
||||||
"name": "kraken",
|
"name": "kraken",
|
||||||
|
@ -59,12 +59,15 @@ Mandatory parameters are marked as **Required**, which means that they are requi
|
|||||||
| `unfilledtimeout.sell` | 10 | **Required.** How long (in minutes) the bot will wait for an unfilled sell order to complete, after which the order will be cancelled.
|
| `unfilledtimeout.sell` | 10 | **Required.** How long (in minutes) the bot will wait for an unfilled sell order to complete, after which the order will be cancelled.
|
||||||
| `bid_strategy.ask_last_balance` | 0.0 | **Required.** Set the bidding price. More information [below](#understand-ask_last_balance).
|
| `bid_strategy.ask_last_balance` | 0.0 | **Required.** Set the bidding price. More information [below](#understand-ask_last_balance).
|
||||||
| `bid_strategy.use_order_book` | false | Allows buying of pair using the rates in Order Book Bids.
|
| `bid_strategy.use_order_book` | false | Allows buying of pair using the rates in Order Book Bids.
|
||||||
| `bid_strategy.order_book_top` | 0 | Bot will use the top N rate in Order Book Bids. Ie. a value of 2 will allow the bot to pick the 2nd bid rate in Order Book Bids.
|
| `bid_strategy.order_book_top` | 0 | Bot will use the top N rate in Order Book Bids. I.e. a value of 2 will allow the bot to pick the 2nd bid rate in Order Book Bids.
|
||||||
| `bid_strategy. check_depth_of_market.enabled` | false | Does not buy if the % difference of buy orders and sell orders is met in Order Book.
|
| `bid_strategy. check_depth_of_market.enabled` | false | Does not buy if the % difference of buy orders and sell orders is met in Order Book.
|
||||||
| `bid_strategy. check_depth_of_market.bids_to_ask_delta` | 0 | The % difference of buy orders and sell orders found in Order Book. A value lesser than 1 means sell orders is greater, while value greater than 1 means buy orders is higher.
|
| `bid_strategy. check_depth_of_market.bids_to_ask_delta` | 0 | The % difference of buy orders and sell orders found in Order Book. A value lesser than 1 means sell orders is greater, while value greater than 1 means buy orders is higher.
|
||||||
| `ask_strategy.use_order_book` | false | Allows selling of open traded pair using the rates in Order Book Asks.
|
| `ask_strategy.use_order_book` | false | Allows selling of open traded pair using the rates in Order Book Asks.
|
||||||
| `ask_strategy.order_book_min` | 0 | Bot will scan from the top min to max Order Book Asks searching for a profitable rate.
|
| `ask_strategy.order_book_min` | 0 | Bot will scan from the top min to max Order Book Asks searching for a profitable rate.
|
||||||
| `ask_strategy.order_book_max` | 0 | Bot will scan from the top min to max Order Book Asks searching for a profitable rate.
|
| `ask_strategy.order_book_max` | 0 | Bot will scan from the top min to max Order Book Asks searching for a profitable rate.
|
||||||
|
| `ask_strategy.use_sell_signal` | true | Use sell signals produced by the strategy in addition to the `minimal_roi`. [Strategy Override](#parameters-in-the-strategy).
|
||||||
|
| `ask_strategy.sell_profit_only` | false | Wait until the bot makes a positive profit before taking a sell decision. [Strategy Override](#parameters-in-the-strategy).
|
||||||
|
| `ask_strategy.ignore_roi_if_buy_signal` | false | Do not sell if the buy signal is still active. This setting takes preference over `minimal_roi` and `use_sell_signal`. [Strategy Override](#parameters-in-the-strategy).
|
||||||
| `order_types` | None | Configure order-types depending on the action (`"buy"`, `"sell"`, `"stoploss"`, `"stoploss_on_exchange"`). [More information below](#understand-order_types). [Strategy Override](#parameters-in-the-strategy).
|
| `order_types` | None | Configure order-types depending on the action (`"buy"`, `"sell"`, `"stoploss"`, `"stoploss_on_exchange"`). [More information below](#understand-order_types). [Strategy Override](#parameters-in-the-strategy).
|
||||||
| `order_time_in_force` | None | Configure time in force for buy and sell orders. [More information below](#understand-order_time_in_force). [Strategy Override](#parameters-in-the-strategy).
|
| `order_time_in_force` | None | Configure time in force for buy and sell orders. [More information below](#understand-order_time_in_force). [Strategy Override](#parameters-in-the-strategy).
|
||||||
| `exchange.name` | | **Required.** Name of the exchange class to use. [List below](#user-content-what-values-for-exchangename).
|
| `exchange.name` | | **Required.** Name of the exchange class to use. [List below](#user-content-what-values-for-exchangename).
|
||||||
@ -78,9 +81,6 @@ Mandatory parameters are marked as **Required**, which means that they are requi
|
|||||||
| `exchange.ccxt_async_config` | None | Additional CCXT parameters passed to the async ccxt instance. Parameters may differ from exchange to exchange and are documented in the [ccxt documentation](https://ccxt.readthedocs.io/en/latest/manual.html#instantiation)
|
| `exchange.ccxt_async_config` | None | Additional CCXT parameters passed to the async ccxt instance. Parameters may differ from exchange to exchange and are documented in the [ccxt documentation](https://ccxt.readthedocs.io/en/latest/manual.html#instantiation)
|
||||||
| `exchange.markets_refresh_interval` | 60 | The interval in minutes in which markets are reloaded.
|
| `exchange.markets_refresh_interval` | 60 | The interval in minutes in which markets are reloaded.
|
||||||
| `edge` | false | Please refer to [edge configuration document](edge.md) for detailed explanation.
|
| `edge` | false | Please refer to [edge configuration document](edge.md) for detailed explanation.
|
||||||
| `experimental.use_sell_signal` | false | Use your sell strategy in addition of the `minimal_roi`. [Strategy Override](#parameters-in-the-strategy).
|
|
||||||
| `experimental.sell_profit_only` | false | Waits until you have made a positive profit before taking a sell decision. [Strategy Override](#parameters-in-the-strategy).
|
|
||||||
| `experimental.ignore_roi_if_buy_signal` | false | Does not sell if the buy-signal is still active. Takes preference over `minimal_roi` and `use_sell_signal`. [Strategy Override](#parameters-in-the-strategy).
|
|
||||||
| `experimental.block_bad_exchanges` | true | Block exchanges known to not work with freqtrade. Leave on default unless you want to test if that exchange works now.
|
| `experimental.block_bad_exchanges` | true | Block exchanges known to not work with freqtrade. Leave on default unless you want to test if that exchange works now.
|
||||||
| `pairlist.method` | StaticPairList | Use static or dynamic volume-based pairlist. [More information below](#dynamic-pairlists).
|
| `pairlist.method` | StaticPairList | Use static or dynamic volume-based pairlist. [More information below](#dynamic-pairlists).
|
||||||
| `pairlist.config` | None | Additional configuration for dynamic pairlists. [More information below](#dynamic-pairlists).
|
| `pairlist.config` | None | Additional configuration for dynamic pairlists. [More information below](#dynamic-pairlists).
|
||||||
@ -116,9 +116,9 @@ Values set in the configuration file always overwrite values set in the strategy
|
|||||||
* `process_only_new_candles`
|
* `process_only_new_candles`
|
||||||
* `order_types`
|
* `order_types`
|
||||||
* `order_time_in_force`
|
* `order_time_in_force`
|
||||||
* `use_sell_signal` (experimental)
|
* `use_sell_signal` (ask_strategy)
|
||||||
* `sell_profit_only` (experimental)
|
* `sell_profit_only` (ask_strategy)
|
||||||
* `ignore_roi_if_buy_signal` (experimental)
|
* `ignore_roi_if_buy_signal` (ask_strategy)
|
||||||
|
|
||||||
### Understand stake_amount
|
### Understand stake_amount
|
||||||
|
|
||||||
|
@ -9,8 +9,9 @@ from typing import Any, Callable, Dict, List, Optional
|
|||||||
|
|
||||||
from freqtrade import OperationalException, constants
|
from freqtrade import OperationalException, constants
|
||||||
from freqtrade.configuration.check_exchange import check_exchange
|
from freqtrade.configuration.check_exchange import check_exchange
|
||||||
from freqtrade.configuration.config_validation import (
|
from freqtrade.configuration.config_validation import (validate_config_consistency,
|
||||||
validate_config_consistency, validate_config_schema)
|
validate_config_schema)
|
||||||
|
from freqtrade.configuration.deprecated_settings import process_temporary_deprecated_settings
|
||||||
from freqtrade.configuration.directory_operations import (create_datadir,
|
from freqtrade.configuration.directory_operations import (create_datadir,
|
||||||
create_userdata_dir)
|
create_userdata_dir)
|
||||||
from freqtrade.configuration.load_config import load_config_file
|
from freqtrade.configuration.load_config import load_config_file
|
||||||
@ -75,6 +76,10 @@ class Configuration:
|
|||||||
# Normalize config
|
# Normalize config
|
||||||
if 'internals' not in config:
|
if 'internals' not in config:
|
||||||
config['internals'] = {}
|
config['internals'] = {}
|
||||||
|
# TODO: This can be deleted along with removal of deprecated
|
||||||
|
# experimental settings
|
||||||
|
if 'ask_strategy' not in config:
|
||||||
|
config['ask_strategy'] = {}
|
||||||
|
|
||||||
# validate configuration before returning
|
# validate configuration before returning
|
||||||
logger.info('Validating configuration ...')
|
logger.info('Validating configuration ...')
|
||||||
@ -106,6 +111,8 @@ class Configuration:
|
|||||||
|
|
||||||
self._resolve_pairs_list(config)
|
self._resolve_pairs_list(config)
|
||||||
|
|
||||||
|
process_temporary_deprecated_settings(config)
|
||||||
|
|
||||||
validate_config_consistency(config)
|
validate_config_consistency(config)
|
||||||
|
|
||||||
return config
|
return config
|
||||||
|
59
freqtrade/configuration/deprecated_settings.py
Normal file
59
freqtrade/configuration/deprecated_settings.py
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
"""
|
||||||
|
Functions to handle deprecated settings
|
||||||
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
|
from freqtrade import OperationalException
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def check_conflicting_settings(config: Dict[str, Any],
|
||||||
|
section1: str, name1: str,
|
||||||
|
section2: str, name2: str):
|
||||||
|
section1_config = config.get(section1, {})
|
||||||
|
section2_config = config.get(section2, {})
|
||||||
|
if name1 in section1_config and name2 in section2_config:
|
||||||
|
raise OperationalException(
|
||||||
|
f"Conflicting settings `{section1}.{name1}` and `{section2}.{name2}` "
|
||||||
|
"(DEPRECATED) detected in the configuration file. "
|
||||||
|
"This deprecated setting will be removed in the next versions of Freqtrade. "
|
||||||
|
f"Please delete it from your configuration and use the `{section1}.{name1}` "
|
||||||
|
"setting instead."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def process_deprecated_setting(config: Dict[str, Any],
|
||||||
|
section1: str, name1: str,
|
||||||
|
section2: str, name2: str):
|
||||||
|
section2_config = config.get(section2, {})
|
||||||
|
|
||||||
|
if name2 in section2_config:
|
||||||
|
logger.warning(
|
||||||
|
"DEPRECATED: "
|
||||||
|
f"The `{section2}.{name2}` setting is deprecated and "
|
||||||
|
"will be removed in the next versions of Freqtrade. "
|
||||||
|
f"Please use the `{section1}.{name1}` setting in your configuration instead."
|
||||||
|
)
|
||||||
|
section1_config = config.get(section1, {})
|
||||||
|
section1_config[name1] = section2_config[name2]
|
||||||
|
|
||||||
|
|
||||||
|
def process_temporary_deprecated_settings(config: Dict[str, Any]) -> None:
|
||||||
|
|
||||||
|
check_conflicting_settings(config, 'ask_strategy', 'use_sell_signal',
|
||||||
|
'experimental', 'use_sell_signal')
|
||||||
|
check_conflicting_settings(config, 'ask_strategy', 'sell_profit_only',
|
||||||
|
'experimental', 'sell_profit_only')
|
||||||
|
check_conflicting_settings(config, 'ask_strategy', 'ignore_roi_if_buy_signal',
|
||||||
|
'experimental', 'ignore_roi_if_buy_signal')
|
||||||
|
|
||||||
|
process_deprecated_setting(config, 'ask_strategy', 'use_sell_signal',
|
||||||
|
'experimental', 'use_sell_signal')
|
||||||
|
process_deprecated_setting(config, 'ask_strategy', 'sell_profit_only',
|
||||||
|
'experimental', 'sell_profit_only')
|
||||||
|
process_deprecated_setting(config, 'ask_strategy', 'ignore_roi_if_buy_signal',
|
||||||
|
'experimental', 'ignore_roi_if_buy_signal')
|
@ -114,7 +114,10 @@ CONF_SCHEMA = {
|
|||||||
'properties': {
|
'properties': {
|
||||||
'use_order_book': {'type': 'boolean'},
|
'use_order_book': {'type': 'boolean'},
|
||||||
'order_book_min': {'type': 'number', 'minimum': 1},
|
'order_book_min': {'type': 'number', 'minimum': 1},
|
||||||
'order_book_max': {'type': 'number', 'minimum': 1, 'maximum': 50}
|
'order_book_max': {'type': 'number', 'minimum': 1, 'maximum': 50},
|
||||||
|
'use_sell_signal': {'type': 'boolean'},
|
||||||
|
'sell_profit_only': {'type': 'boolean'},
|
||||||
|
'ignore_roi_if_buy_signal': {'type': 'boolean'}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'order_types': {
|
'order_types': {
|
||||||
@ -144,7 +147,8 @@ CONF_SCHEMA = {
|
|||||||
'properties': {
|
'properties': {
|
||||||
'use_sell_signal': {'type': 'boolean'},
|
'use_sell_signal': {'type': 'boolean'},
|
||||||
'sell_profit_only': {'type': 'boolean'},
|
'sell_profit_only': {'type': 'boolean'},
|
||||||
'ignore_roi_if_buy_signal_true': {'type': 'boolean'}
|
'ignore_roi_if_buy_signal': {'type': 'boolean'},
|
||||||
|
'block_bad_exchanges': {'type': 'boolean'}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'pairlist': {
|
'pairlist': {
|
||||||
|
@ -575,13 +575,15 @@ class FreqtradeBot:
|
|||||||
logger.debug('Handling %s ...', trade)
|
logger.debug('Handling %s ...', trade)
|
||||||
|
|
||||||
(buy, sell) = (False, False)
|
(buy, sell) = (False, False)
|
||||||
experimental = self.config.get('experimental', {})
|
|
||||||
if experimental.get('use_sell_signal') or experimental.get('ignore_roi_if_buy_signal'):
|
config_ask_strategy = self.config.get('ask_strategy', {})
|
||||||
|
|
||||||
|
if (config_ask_strategy.get('use_sell_signal', True) or
|
||||||
|
config_ask_strategy.get('ignore_roi_if_buy_signal')):
|
||||||
(buy, sell) = self.strategy.get_signal(
|
(buy, sell) = self.strategy.get_signal(
|
||||||
trade.pair, self.strategy.ticker_interval,
|
trade.pair, self.strategy.ticker_interval,
|
||||||
self.dataprovider.ohlcv(trade.pair, self.strategy.ticker_interval))
|
self.dataprovider.ohlcv(trade.pair, self.strategy.ticker_interval))
|
||||||
|
|
||||||
config_ask_strategy = self.config.get('ask_strategy', {})
|
|
||||||
if config_ask_strategy.get('use_order_book', False):
|
if config_ask_strategy.get('use_order_book', False):
|
||||||
logger.info('Using order book for selling...')
|
logger.info('Using order book for selling...')
|
||||||
# logger.debug('Order book %s',orderBook)
|
# logger.debug('Order book %s',orderBook)
|
||||||
|
@ -98,10 +98,10 @@ class Hyperopt:
|
|||||||
self.position_stacking = self.config.get('position_stacking', False)
|
self.position_stacking = self.config.get('position_stacking', False)
|
||||||
|
|
||||||
if self.has_space('sell'):
|
if self.has_space('sell'):
|
||||||
# Make sure experimental is enabled
|
# Make sure use_sell_signal is enabled
|
||||||
if 'experimental' not in self.config:
|
if 'ask_strategy' not in self.config:
|
||||||
self.config['experimental'] = {}
|
self.config['ask_strategy'] = {}
|
||||||
self.config['experimental']['use_sell_signal'] = True
|
self.config['ask_strategy']['use_sell_signal'] = True
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_lock_filename(config) -> str:
|
def get_lock_filename(config) -> str:
|
||||||
|
@ -38,13 +38,13 @@ class StrategyResolver(IResolver):
|
|||||||
config=config,
|
config=config,
|
||||||
extra_dir=config.get('strategy_path'))
|
extra_dir=config.get('strategy_path'))
|
||||||
|
|
||||||
# make sure experimental dict is available
|
# make sure ask_strategy dict is available
|
||||||
if 'experimental' not in config:
|
if 'ask_strategy' not in config:
|
||||||
config['experimental'] = {}
|
config['ask_strategy'] = {}
|
||||||
|
|
||||||
# Set attributes
|
# Set attributes
|
||||||
# Check if we need to override configuration
|
# Check if we need to override configuration
|
||||||
# (Attribute name, default, experimental)
|
# (Attribute name, default, ask_strategy)
|
||||||
attributes = [("minimal_roi", {"0": 10.0}, False),
|
attributes = [("minimal_roi", {"0": 10.0}, False),
|
||||||
("ticker_interval", None, False),
|
("ticker_interval", None, False),
|
||||||
("stoploss", None, False),
|
("stoploss", None, False),
|
||||||
@ -57,20 +57,20 @@ class StrategyResolver(IResolver):
|
|||||||
("order_time_in_force", None, False),
|
("order_time_in_force", None, False),
|
||||||
("stake_currency", None, False),
|
("stake_currency", None, False),
|
||||||
("stake_amount", None, False),
|
("stake_amount", None, False),
|
||||||
("use_sell_signal", False, True),
|
("use_sell_signal", True, True),
|
||||||
("sell_profit_only", False, True),
|
("sell_profit_only", False, True),
|
||||||
("ignore_roi_if_buy_signal", False, True),
|
("ignore_roi_if_buy_signal", False, True),
|
||||||
]
|
]
|
||||||
for attribute, default, experimental in attributes:
|
for attribute, default, ask_strategy in attributes:
|
||||||
if experimental:
|
if ask_strategy:
|
||||||
self._override_attribute_helper(config['experimental'], attribute, default)
|
self._override_attribute_helper(config['ask_strategy'], attribute, default)
|
||||||
else:
|
else:
|
||||||
self._override_attribute_helper(config, attribute, default)
|
self._override_attribute_helper(config, attribute, default)
|
||||||
|
|
||||||
# Loop this list again to have output combined
|
# Loop this list again to have output combined
|
||||||
for attribute, _, exp in attributes:
|
for attribute, _, exp in attributes:
|
||||||
if exp and attribute in config['experimental']:
|
if exp and attribute in config['ask_strategy']:
|
||||||
logger.info("Strategy using %s: %s", attribute, config['experimental'][attribute])
|
logger.info("Strategy using %s: %s", attribute, config['ask_strategy'][attribute])
|
||||||
elif attribute in config:
|
elif attribute in config:
|
||||||
logger.info("Strategy using %s: %s", attribute, config[attribute])
|
logger.info("Strategy using %s: %s", attribute, config[attribute])
|
||||||
|
|
||||||
|
@ -309,9 +309,9 @@ class IStrategy(ABC):
|
|||||||
# Set current rate to high for backtesting sell
|
# Set current rate to high for backtesting sell
|
||||||
current_rate = high or rate
|
current_rate = high or rate
|
||||||
current_profit = trade.calc_profit_percent(current_rate)
|
current_profit = trade.calc_profit_percent(current_rate)
|
||||||
experimental = self.config.get('experimental', {})
|
config_ask_strategy = self.config.get('ask_strategy', {})
|
||||||
|
|
||||||
if buy and experimental.get('ignore_roi_if_buy_signal', False):
|
if buy and config_ask_strategy.get('ignore_roi_if_buy_signal', False):
|
||||||
# This one is noisy, commented out
|
# This one is noisy, commented out
|
||||||
# logger.debug(f"{trade.pair} - Buy signal still active. sell_flag=False")
|
# logger.debug(f"{trade.pair} - Buy signal still active. sell_flag=False")
|
||||||
return SellCheckTuple(sell_flag=False, sell_type=SellType.NONE)
|
return SellCheckTuple(sell_flag=False, sell_type=SellType.NONE)
|
||||||
@ -322,7 +322,7 @@ class IStrategy(ABC):
|
|||||||
f"sell_type=SellType.ROI")
|
f"sell_type=SellType.ROI")
|
||||||
return SellCheckTuple(sell_flag=True, sell_type=SellType.ROI)
|
return SellCheckTuple(sell_flag=True, sell_type=SellType.ROI)
|
||||||
|
|
||||||
if experimental.get('sell_profit_only', False):
|
if config_ask_strategy.get('sell_profit_only', False):
|
||||||
# This one is noisy, commented out
|
# This one is noisy, commented out
|
||||||
# logger.debug(f"{trade.pair} - Checking if trade is profitable...")
|
# logger.debug(f"{trade.pair} - Checking if trade is profitable...")
|
||||||
if trade.calc_profit(rate=rate) <= 0:
|
if trade.calc_profit(rate=rate) <= 0:
|
||||||
@ -330,7 +330,7 @@ class IStrategy(ABC):
|
|||||||
# logger.debug(f"{trade.pair} - Trade is not profitable. sell_flag=False")
|
# logger.debug(f"{trade.pair} - Trade is not profitable. sell_flag=False")
|
||||||
return SellCheckTuple(sell_flag=False, sell_type=SellType.NONE)
|
return SellCheckTuple(sell_flag=False, sell_type=SellType.NONE)
|
||||||
|
|
||||||
if sell and not buy and experimental.get('use_sell_signal', False):
|
if sell and not buy and config_ask_strategy.get('use_sell_signal', True):
|
||||||
logger.debug(f"{trade.pair} - Sell signal received. sell_flag=True, "
|
logger.debug(f"{trade.pair} - Sell signal received. sell_flag=True, "
|
||||||
f"sell_type=SellType.SELL_SIGNAL")
|
f"sell_type=SellType.SELL_SIGNAL")
|
||||||
return SellCheckTuple(sell_flag=True, sell_type=SellType.SELL_SIGNAL)
|
return SellCheckTuple(sell_flag=True, sell_type=SellType.SELL_SIGNAL)
|
||||||
|
@ -103,11 +103,6 @@
|
|||||||
"max_trade_duration_minute": 1440,
|
"max_trade_duration_minute": 1440,
|
||||||
"remove_pumps": false
|
"remove_pumps": false
|
||||||
},
|
},
|
||||||
"experimental": {
|
|
||||||
"use_sell_signal": false,
|
|
||||||
"sell_profit_only": false,
|
|
||||||
"ignore_roi_if_buy_signal": false
|
|
||||||
},
|
|
||||||
"telegram": {
|
"telegram": {
|
||||||
// We can now comment out some settings
|
// We can now comment out some settings
|
||||||
// "enabled": true,
|
// "enabled": true,
|
||||||
|
@ -301,7 +301,7 @@ def test_backtest_results(default_conf, fee, mocker, caplog, data) -> None:
|
|||||||
if data.trailing_stop_positive:
|
if data.trailing_stop_positive:
|
||||||
default_conf["trailing_stop_positive"] = data.trailing_stop_positive
|
default_conf["trailing_stop_positive"] = data.trailing_stop_positive
|
||||||
default_conf["trailing_stop_positive_offset"] = data.trailing_stop_positive_offset
|
default_conf["trailing_stop_positive_offset"] = data.trailing_stop_positive_offset
|
||||||
default_conf["experimental"] = {"use_sell_signal": data.use_sell_signal}
|
default_conf["ask_strategy"] = {"use_sell_signal": data.use_sell_signal}
|
||||||
|
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_fee", MagicMock(return_value=0.0))
|
mocker.patch("freqtrade.exchange.Exchange.get_fee", MagicMock(return_value=0.0))
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
|
@ -517,6 +517,7 @@ def test_backtesting_start_no_data(default_conf, mocker, caplog, testdatadir) ->
|
|||||||
|
|
||||||
|
|
||||||
def test_backtest(default_conf, fee, mocker, testdatadir) -> None:
|
def test_backtest(default_conf, fee, mocker, testdatadir) -> None:
|
||||||
|
default_conf['ask_strategy']['use_sell_signal'] = False
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
backtesting = Backtesting(default_conf)
|
backtesting = Backtesting(default_conf)
|
||||||
@ -571,6 +572,7 @@ def test_backtest(default_conf, fee, mocker, testdatadir) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_backtest_1min_ticker_interval(default_conf, fee, mocker, testdatadir) -> None:
|
def test_backtest_1min_ticker_interval(default_conf, fee, mocker, testdatadir) -> None:
|
||||||
|
default_conf['ask_strategy']['use_sell_signal'] = False
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
backtesting = Backtesting(default_conf)
|
backtesting = Backtesting(default_conf)
|
||||||
@ -613,8 +615,6 @@ def test_backtest_pricecontours(default_conf, fee, mocker, testdatadir) -> None:
|
|||||||
# TODO: Evaluate usefullness of this, the patterns and buy-signls are unrealistic
|
# TODO: Evaluate usefullness of this, the patterns and buy-signls are unrealistic
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||||
tests = [['raise', 19], ['lower', 0], ['sine', 35]]
|
tests = [['raise', 19], ['lower', 0], ['sine', 35]]
|
||||||
# We need to enable sell-signal - otherwise it sells on ROI!!
|
|
||||||
default_conf['experimental'] = {"use_sell_signal": True}
|
|
||||||
|
|
||||||
for [contour, numres] in tests:
|
for [contour, numres] in tests:
|
||||||
simple_backtest(default_conf, contour, numres, mocker, testdatadir)
|
simple_backtest(default_conf, contour, numres, mocker, testdatadir)
|
||||||
@ -655,8 +655,6 @@ def test_backtest_alternate_buy_sell(default_conf, fee, mocker, testdatadir):
|
|||||||
mocker.patch('freqtrade.optimize.backtesting.file_dump_json', MagicMock())
|
mocker.patch('freqtrade.optimize.backtesting.file_dump_json', MagicMock())
|
||||||
backtest_conf = _make_backtest_conf(mocker, conf=default_conf,
|
backtest_conf = _make_backtest_conf(mocker, conf=default_conf,
|
||||||
pair='UNITTEST/BTC', datadir=testdatadir)
|
pair='UNITTEST/BTC', datadir=testdatadir)
|
||||||
# We need to enable sell-signal - otherwise it sells on ROI!!
|
|
||||||
default_conf['experimental'] = {"use_sell_signal": True}
|
|
||||||
default_conf['ticker_interval'] = '1m'
|
default_conf['ticker_interval'] = '1m'
|
||||||
backtesting = Backtesting(default_conf)
|
backtesting = Backtesting(default_conf)
|
||||||
backtesting.strategy.advise_buy = _trend_alternate # Override
|
backtesting.strategy.advise_buy = _trend_alternate # Override
|
||||||
@ -697,8 +695,6 @@ def test_backtest_multi_pair(default_conf, fee, mocker, tres, pair, testdatadir)
|
|||||||
|
|
||||||
# Remove data for one pair from the beginning of the data
|
# Remove data for one pair from the beginning of the data
|
||||||
data[pair] = data[pair][tres:].reset_index()
|
data[pair] = data[pair][tres:].reset_index()
|
||||||
# We need to enable sell-signal - otherwise it sells on ROI!!
|
|
||||||
default_conf['experimental'] = {"use_sell_signal": True}
|
|
||||||
default_conf['ticker_interval'] = '5m'
|
default_conf['ticker_interval'] = '5m'
|
||||||
|
|
||||||
backtesting = Backtesting(default_conf)
|
backtesting = Backtesting(default_conf)
|
||||||
|
@ -256,23 +256,23 @@ def test_strategy_override_use_sell_signal(caplog, default_conf):
|
|||||||
'strategy': 'DefaultStrategy',
|
'strategy': 'DefaultStrategy',
|
||||||
})
|
})
|
||||||
resolver = StrategyResolver(default_conf)
|
resolver = StrategyResolver(default_conf)
|
||||||
assert not resolver.strategy.use_sell_signal
|
assert resolver.strategy.use_sell_signal
|
||||||
assert isinstance(resolver.strategy.use_sell_signal, bool)
|
assert isinstance(resolver.strategy.use_sell_signal, bool)
|
||||||
# must be inserted to configuration
|
# must be inserted to configuration
|
||||||
assert 'use_sell_signal' in default_conf['experimental']
|
assert 'use_sell_signal' in default_conf['ask_strategy']
|
||||||
assert not default_conf['experimental']['use_sell_signal']
|
assert default_conf['ask_strategy']['use_sell_signal']
|
||||||
|
|
||||||
default_conf.update({
|
default_conf.update({
|
||||||
'strategy': 'DefaultStrategy',
|
'strategy': 'DefaultStrategy',
|
||||||
'experimental': {
|
'ask_strategy': {
|
||||||
'use_sell_signal': True,
|
'use_sell_signal': False,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
resolver = StrategyResolver(default_conf)
|
resolver = StrategyResolver(default_conf)
|
||||||
|
|
||||||
assert resolver.strategy.use_sell_signal
|
assert not resolver.strategy.use_sell_signal
|
||||||
assert isinstance(resolver.strategy.use_sell_signal, bool)
|
assert isinstance(resolver.strategy.use_sell_signal, bool)
|
||||||
assert log_has("Override strategy 'use_sell_signal' with value in config file: True.", caplog)
|
assert log_has("Override strategy 'use_sell_signal' with value in config file: False.", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_strategy_override_use_sell_profit_only(caplog, default_conf):
|
def test_strategy_override_use_sell_profit_only(caplog, default_conf):
|
||||||
@ -284,12 +284,12 @@ def test_strategy_override_use_sell_profit_only(caplog, default_conf):
|
|||||||
assert not resolver.strategy.sell_profit_only
|
assert not resolver.strategy.sell_profit_only
|
||||||
assert isinstance(resolver.strategy.sell_profit_only, bool)
|
assert isinstance(resolver.strategy.sell_profit_only, bool)
|
||||||
# must be inserted to configuration
|
# must be inserted to configuration
|
||||||
assert 'sell_profit_only' in default_conf['experimental']
|
assert 'sell_profit_only' in default_conf['ask_strategy']
|
||||||
assert not default_conf['experimental']['sell_profit_only']
|
assert not default_conf['ask_strategy']['sell_profit_only']
|
||||||
|
|
||||||
default_conf.update({
|
default_conf.update({
|
||||||
'strategy': 'DefaultStrategy',
|
'strategy': 'DefaultStrategy',
|
||||||
'experimental': {
|
'ask_strategy': {
|
||||||
'sell_profit_only': True,
|
'sell_profit_only': True,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -14,6 +14,9 @@ from freqtrade.configuration import (Arguments, Configuration,
|
|||||||
validate_config_consistency)
|
validate_config_consistency)
|
||||||
from freqtrade.configuration.check_exchange import check_exchange
|
from freqtrade.configuration.check_exchange import check_exchange
|
||||||
from freqtrade.configuration.config_validation import validate_config_schema
|
from freqtrade.configuration.config_validation import validate_config_schema
|
||||||
|
from freqtrade.configuration.deprecated_settings import (check_conflicting_settings,
|
||||||
|
process_deprecated_setting,
|
||||||
|
process_temporary_deprecated_settings)
|
||||||
from freqtrade.configuration.directory_operations import (create_datadir,
|
from freqtrade.configuration.directory_operations import (create_datadir,
|
||||||
create_userdata_dir)
|
create_userdata_dir)
|
||||||
from freqtrade.configuration.load_config import load_config_file
|
from freqtrade.configuration.load_config import load_config_file
|
||||||
@ -897,3 +900,126 @@ def test_pairlist_resolving_fallback(mocker):
|
|||||||
assert config['pairs'] == ['ETH/BTC', 'XRP/BTC']
|
assert config['pairs'] == ['ETH/BTC', 'XRP/BTC']
|
||||||
assert config['exchange']['name'] == 'binance'
|
assert config['exchange']['name'] == 'binance'
|
||||||
assert config['datadir'] == str(Path.cwd() / "user_data/data/binance")
|
assert config['datadir'] == str(Path.cwd() / "user_data/data/binance")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("setting", [
|
||||||
|
("ask_strategy", "use_sell_signal", True,
|
||||||
|
"experimental", "use_sell_signal", False),
|
||||||
|
("ask_strategy", "sell_profit_only", False,
|
||||||
|
"experimental", "sell_profit_only", True),
|
||||||
|
("ask_strategy", "ignore_roi_if_buy_signal", False,
|
||||||
|
"experimental", "ignore_roi_if_buy_signal", True),
|
||||||
|
])
|
||||||
|
def test_process_temporary_deprecated_settings(mocker, default_conf, setting, caplog):
|
||||||
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
|
|
||||||
|
# Create sections for new and deprecated settings
|
||||||
|
# (they may not exist in the config)
|
||||||
|
default_conf[setting[0]] = {}
|
||||||
|
default_conf[setting[3]] = {}
|
||||||
|
# Assign new setting
|
||||||
|
default_conf[setting[0]][setting[1]] = setting[2]
|
||||||
|
# Assign deprecated setting
|
||||||
|
default_conf[setting[3]][setting[4]] = setting[5]
|
||||||
|
|
||||||
|
# New and deprecated settings are conflicting ones
|
||||||
|
with pytest.raises(OperationalException, match=r'DEPRECATED'):
|
||||||
|
process_temporary_deprecated_settings(default_conf)
|
||||||
|
|
||||||
|
caplog.clear()
|
||||||
|
|
||||||
|
# Delete new setting
|
||||||
|
del default_conf[setting[0]][setting[1]]
|
||||||
|
|
||||||
|
process_temporary_deprecated_settings(default_conf)
|
||||||
|
assert log_has_re('DEPRECATED', caplog)
|
||||||
|
# The value of the new setting shall have been set to the
|
||||||
|
# value of the deprecated one
|
||||||
|
assert default_conf[setting[0]][setting[1]] == setting[5]
|
||||||
|
|
||||||
|
|
||||||
|
def test_check_conflicting_settings(mocker, default_conf, caplog):
|
||||||
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
|
|
||||||
|
# Create sections for new and deprecated settings
|
||||||
|
# (they may not exist in the config)
|
||||||
|
default_conf['sectionA'] = {}
|
||||||
|
default_conf['sectionB'] = {}
|
||||||
|
# Assign new setting
|
||||||
|
default_conf['sectionA']['new_setting'] = 'valA'
|
||||||
|
# Assign deprecated setting
|
||||||
|
default_conf['sectionB']['deprecated_setting'] = 'valB'
|
||||||
|
|
||||||
|
# New and deprecated settings are conflicting ones
|
||||||
|
with pytest.raises(OperationalException, match=r'DEPRECATED'):
|
||||||
|
check_conflicting_settings(default_conf,
|
||||||
|
'sectionA', 'new_setting',
|
||||||
|
'sectionB', 'deprecated_setting')
|
||||||
|
|
||||||
|
caplog.clear()
|
||||||
|
|
||||||
|
# Delete new setting (deprecated exists)
|
||||||
|
del default_conf['sectionA']['new_setting']
|
||||||
|
check_conflicting_settings(default_conf,
|
||||||
|
'sectionA', 'new_setting',
|
||||||
|
'sectionB', 'deprecated_setting')
|
||||||
|
assert not log_has_re('DEPRECATED', caplog)
|
||||||
|
assert 'new_setting' not in default_conf['sectionA']
|
||||||
|
|
||||||
|
caplog.clear()
|
||||||
|
|
||||||
|
# Assign new setting
|
||||||
|
default_conf['sectionA']['new_setting'] = 'valA'
|
||||||
|
# Delete deprecated setting
|
||||||
|
del default_conf['sectionB']['deprecated_setting']
|
||||||
|
check_conflicting_settings(default_conf,
|
||||||
|
'sectionA', 'new_setting',
|
||||||
|
'sectionB', 'deprecated_setting')
|
||||||
|
assert not log_has_re('DEPRECATED', caplog)
|
||||||
|
assert default_conf['sectionA']['new_setting'] == 'valA'
|
||||||
|
|
||||||
|
|
||||||
|
def test_process_deprecated_setting(mocker, default_conf, caplog):
|
||||||
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
|
|
||||||
|
# Create sections for new and deprecated settings
|
||||||
|
# (they may not exist in the config)
|
||||||
|
default_conf['sectionA'] = {}
|
||||||
|
default_conf['sectionB'] = {}
|
||||||
|
# Assign new setting
|
||||||
|
default_conf['sectionA']['new_setting'] = 'valA'
|
||||||
|
# Assign deprecated setting
|
||||||
|
default_conf['sectionB']['deprecated_setting'] = 'valB'
|
||||||
|
|
||||||
|
# Both new and deprecated settings exists
|
||||||
|
process_deprecated_setting(default_conf,
|
||||||
|
'sectionA', 'new_setting',
|
||||||
|
'sectionB', 'deprecated_setting')
|
||||||
|
assert log_has_re('DEPRECATED', caplog)
|
||||||
|
# The value of the new setting shall have been set to the
|
||||||
|
# value of the deprecated one
|
||||||
|
assert default_conf['sectionA']['new_setting'] == 'valB'
|
||||||
|
|
||||||
|
caplog.clear()
|
||||||
|
|
||||||
|
# Delete new setting (deprecated exists)
|
||||||
|
del default_conf['sectionA']['new_setting']
|
||||||
|
process_deprecated_setting(default_conf,
|
||||||
|
'sectionA', 'new_setting',
|
||||||
|
'sectionB', 'deprecated_setting')
|
||||||
|
assert log_has_re('DEPRECATED', caplog)
|
||||||
|
# The value of the new setting shall have been set to the
|
||||||
|
# value of the deprecated one
|
||||||
|
assert default_conf['sectionA']['new_setting'] == 'valB'
|
||||||
|
|
||||||
|
caplog.clear()
|
||||||
|
|
||||||
|
# Assign new setting
|
||||||
|
default_conf['sectionA']['new_setting'] = 'valA'
|
||||||
|
# Delete deprecated setting
|
||||||
|
del default_conf['sectionB']['deprecated_setting']
|
||||||
|
process_deprecated_setting(default_conf,
|
||||||
|
'sectionA', 'new_setting',
|
||||||
|
'sectionB', 'deprecated_setting')
|
||||||
|
assert not log_has_re('DEPRECATED', caplog)
|
||||||
|
assert default_conf['sectionA']['new_setting'] == 'valA'
|
||||||
|
@ -1772,8 +1772,6 @@ def test_handle_trade(default_conf, limit_buy_order, limit_sell_order,
|
|||||||
|
|
||||||
def test_handle_overlpapping_signals(default_conf, ticker, limit_buy_order,
|
def test_handle_overlpapping_signals(default_conf, ticker, limit_buy_order,
|
||||||
fee, markets, mocker) -> None:
|
fee, markets, mocker) -> None:
|
||||||
default_conf.update({'experimental': {'use_sell_signal': True}})
|
|
||||||
|
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
@ -1828,7 +1826,6 @@ def test_handle_overlpapping_signals(default_conf, ticker, limit_buy_order,
|
|||||||
def test_handle_trade_roi(default_conf, ticker, limit_buy_order,
|
def test_handle_trade_roi(default_conf, ticker, limit_buy_order,
|
||||||
fee, mocker, markets, caplog) -> None:
|
fee, mocker, markets, caplog) -> None:
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
default_conf.update({'experimental': {'use_sell_signal': True}})
|
|
||||||
|
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
@ -1860,10 +1857,10 @@ def test_handle_trade_roi(default_conf, ticker, limit_buy_order,
|
|||||||
caplog)
|
caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_handle_trade_experimental(
|
def test_handle_trade_use_sell_signal(
|
||||||
default_conf, ticker, limit_buy_order, fee, mocker, markets, caplog) -> None:
|
default_conf, ticker, limit_buy_order, fee, mocker, markets, caplog) -> None:
|
||||||
|
# use_sell_signal is True buy default
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
default_conf.update({'experimental': {'use_sell_signal': True}})
|
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
@ -2713,7 +2710,7 @@ def test_sell_profit_only_enable_profit(default_conf, limit_buy_order,
|
|||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets)
|
markets=PropertyMock(return_value=markets)
|
||||||
)
|
)
|
||||||
default_conf['experimental'] = {
|
default_conf['ask_strategy'] = {
|
||||||
'use_sell_signal': True,
|
'use_sell_signal': True,
|
||||||
'sell_profit_only': True,
|
'sell_profit_only': True,
|
||||||
}
|
}
|
||||||
@ -2745,7 +2742,7 @@ def test_sell_profit_only_disable_profit(default_conf, limit_buy_order,
|
|||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets)
|
markets=PropertyMock(return_value=markets)
|
||||||
)
|
)
|
||||||
default_conf['experimental'] = {
|
default_conf['ask_strategy'] = {
|
||||||
'use_sell_signal': True,
|
'use_sell_signal': True,
|
||||||
'sell_profit_only': False,
|
'sell_profit_only': False,
|
||||||
}
|
}
|
||||||
@ -2775,7 +2772,7 @@ def test_sell_profit_only_enable_loss(default_conf, limit_buy_order, fee, market
|
|||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets)
|
markets=PropertyMock(return_value=markets)
|
||||||
)
|
)
|
||||||
default_conf['experimental'] = {
|
default_conf['ask_strategy'] = {
|
||||||
'use_sell_signal': True,
|
'use_sell_signal': True,
|
||||||
'sell_profit_only': True,
|
'sell_profit_only': True,
|
||||||
}
|
}
|
||||||
@ -2805,7 +2802,7 @@ def test_sell_profit_only_disable_loss(default_conf, limit_buy_order, fee, marke
|
|||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets)
|
markets=PropertyMock(return_value=markets)
|
||||||
)
|
)
|
||||||
default_conf['experimental'] = {
|
default_conf['ask_strategy'] = {
|
||||||
'use_sell_signal': True,
|
'use_sell_signal': True,
|
||||||
'sell_profit_only': False,
|
'sell_profit_only': False,
|
||||||
}
|
}
|
||||||
@ -2874,7 +2871,7 @@ def test_ignore_roi_if_buy_signal(default_conf, limit_buy_order, fee, markets, m
|
|||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets)
|
markets=PropertyMock(return_value=markets)
|
||||||
)
|
)
|
||||||
default_conf['experimental'] = {
|
default_conf['ask_strategy'] = {
|
||||||
'ignore_roi_if_buy_signal': True
|
'ignore_roi_if_buy_signal': True
|
||||||
}
|
}
|
||||||
freqtrade = FreqtradeBot(default_conf)
|
freqtrade = FreqtradeBot(default_conf)
|
||||||
@ -3142,7 +3139,7 @@ def test_disable_ignore_roi_if_buy_signal(default_conf, limit_buy_order,
|
|||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets)
|
markets=PropertyMock(return_value=markets)
|
||||||
)
|
)
|
||||||
default_conf['experimental'] = {
|
default_conf['ask_strategy'] = {
|
||||||
'ignore_roi_if_buy_signal': False
|
'ignore_roi_if_buy_signal': False
|
||||||
}
|
}
|
||||||
freqtrade = FreqtradeBot(default_conf)
|
freqtrade = FreqtradeBot(default_conf)
|
||||||
|
@ -27,12 +27,12 @@ class SampleStrategy(IStrategy):
|
|||||||
- the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend,
|
- the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend,
|
||||||
populate_sell_trend, hyperopt_space, buy_strategy_generator
|
populate_sell_trend, hyperopt_space, buy_strategy_generator
|
||||||
"""
|
"""
|
||||||
# Strategy intervace version - allow new iterations of the strategy interface.
|
# Strategy interface version - allow new iterations of the strategy interface.
|
||||||
# Check the documentation or the Sample strategy to get the latest version.
|
# Check the documentation or the Sample strategy to get the latest version.
|
||||||
INTERFACE_VERSION = 2
|
INTERFACE_VERSION = 2
|
||||||
|
|
||||||
# Minimal ROI designed for the strategy.
|
# Minimal ROI designed for the strategy.
|
||||||
# This attribute will be overridden if the config file contains "minimal_roi"
|
# This attribute will be overridden if the config file contains "minimal_roi".
|
||||||
minimal_roi = {
|
minimal_roi = {
|
||||||
"40": 0.0,
|
"40": 0.0,
|
||||||
"30": 0.01,
|
"30": 0.01,
|
||||||
@ -40,27 +40,27 @@ class SampleStrategy(IStrategy):
|
|||||||
"0": 0.04
|
"0": 0.04
|
||||||
}
|
}
|
||||||
|
|
||||||
# Optimal stoploss designed for the strategy
|
# Optimal stoploss designed for the strategy.
|
||||||
# This attribute will be overridden if the config file contains "stoploss"
|
# This attribute will be overridden if the config file contains "stoploss".
|
||||||
stoploss = -0.10
|
stoploss = -0.10
|
||||||
|
|
||||||
# trailing stoploss
|
# Trailing stoploss
|
||||||
trailing_stop = False
|
trailing_stop = False
|
||||||
# trailing_stop_positive = 0.01
|
# trailing_stop_positive = 0.01
|
||||||
# trailing_stop_positive_offset = 0.0 # Disabled / not configured
|
# trailing_stop_positive_offset = 0.0 # Disabled / not configured
|
||||||
|
|
||||||
# Optimal ticker interval for the strategy
|
# Optimal ticker interval for the strategy.
|
||||||
ticker_interval = '5m'
|
ticker_interval = '5m'
|
||||||
|
|
||||||
# run "populate_indicators" only for new candle
|
# Run "populate_indicators()" only for new candle.
|
||||||
process_only_new_candles = False
|
process_only_new_candles = False
|
||||||
|
|
||||||
# Experimental settings (configuration will overide these if set)
|
# These values can be overridden in the "ask_strategy" section in the config.
|
||||||
use_sell_signal = False
|
use_sell_signal = True
|
||||||
sell_profit_only = False
|
sell_profit_only = False
|
||||||
ignore_roi_if_buy_signal = False
|
ignore_roi_if_buy_signal = False
|
||||||
|
|
||||||
# Optional order type mapping
|
# Optional order type mapping.
|
||||||
order_types = {
|
order_types = {
|
||||||
'buy': 'limit',
|
'buy': 'limit',
|
||||||
'sell': 'limit',
|
'sell': 'limit',
|
||||||
@ -68,7 +68,7 @@ class SampleStrategy(IStrategy):
|
|||||||
'stoploss_on_exchange': False
|
'stoploss_on_exchange': False
|
||||||
}
|
}
|
||||||
|
|
||||||
# Optional order time in force
|
# Optional order time in force.
|
||||||
order_time_in_force = {
|
order_time_in_force = {
|
||||||
'buy': 'gtc',
|
'buy': 'gtc',
|
||||||
'sell': 'gtc'
|
'sell': 'gtc'
|
||||||
|
Loading…
Reference in New Issue
Block a user