First commit about ignoring expired candle
Signed-off-by: hoeckxer <hawkeyenl@yahoo.com>
This commit is contained in:
parent
cce4d7e42c
commit
614a996597
@ -121,6 +121,8 @@ Mandatory parameters are marked as **Required**, which means that they are requi
|
||||
| `user_data_dir` | Directory containing user data. <br> *Defaults to `./user_data/`*. <br> **Datatype:** String
|
||||
| `dataformat_ohlcv` | Data format to use to store historical candle (OHLCV) data. <br> *Defaults to `json`*. <br> **Datatype:** String
|
||||
| `dataformat_trades` | Data format to use to store historical trades data. <br> *Defaults to `jsongz`*. <br> **Datatype:** String
|
||||
| `ignore_buying_expired_candle` | Enables usage of skipping buys on candles that are older than a specified period. <br>*Defaults to `False`* <br> **Datatype:** Boolean
|
||||
| `ignore_buying_expired_candle_after` | Specifies the number of seconds until a buy signal is no longer used when setting `ignore_buying_expired_candle`. <br> **Datatype:** Integer
|
||||
|
||||
### Parameters in the strategy
|
||||
|
||||
@ -144,6 +146,8 @@ Values set in the configuration file always overwrite values set in the strategy
|
||||
* `use_sell_signal` (ask_strategy)
|
||||
* `sell_profit_only` (ask_strategy)
|
||||
* `ignore_roi_if_buy_signal` (ask_strategy)
|
||||
* `ignore_buying_expired_candle`
|
||||
* `ignore_buying_expired_candle_after`
|
||||
|
||||
### Configuring amount per trade
|
||||
|
||||
@ -671,6 +675,19 @@ export HTTPS_PROXY="http://addr:port"
|
||||
freqtrade
|
||||
```
|
||||
|
||||
## Ignoring expired candles
|
||||
|
||||
When working with larger timeframes (for example 1h or more) and using a low `max_trades` value, the last candle can be processed as soon as a trade slot becomes available. When processing the last candle, this can lead to a situation where it may not be desirable to use the buy signal on that candle. For example, when using a condition in your strategy where you use a cross-over, that point may have passed too long ago for you to start a trade on it.
|
||||
|
||||
In these situations, you can enable the functionality to ignore candles that are beyond a specified period by setting `ignore_buying_expired_candle` to `True`. After this, you can set `ignore_buying_expired_candle_after` to the number of seconds after which the candle becomes expired.
|
||||
|
||||
For example, if your strategy is using a 1h timeframe, and you only want to buy within the first 5 minutes when a new candle comes in, you can add the following configuration to your strategy:
|
||||
|
||||
``` json
|
||||
ignore_buying_expired_candle = True
|
||||
ignore_buying_expired_candle_after = 300 # 5 minutes
|
||||
```
|
||||
|
||||
## Embedding Strategies
|
||||
|
||||
Freqtrade provides you with with an easy way to embed the strategy into your configuration file.
|
||||
|
@ -5,7 +5,7 @@ This module defines the interface to apply for strategies
|
||||
import logging
|
||||
import warnings
|
||||
from abc import ABC, abstractmethod
|
||||
from datetime import datetime, timezone
|
||||
from datetime import datetime, timezone, timedelta
|
||||
from enum import Enum
|
||||
from typing import Dict, List, NamedTuple, Optional, Tuple
|
||||
|
||||
@ -113,6 +113,11 @@ class IStrategy(ABC):
|
||||
# run "populate_indicators" only for new candle
|
||||
process_only_new_candles: bool = False
|
||||
|
||||
# Don't analyze too old candles
|
||||
ignore_buying_expired_candle: bool = False
|
||||
# Number of seconds after which the candle will no longer result in a buy
|
||||
ignore_buying_expired_candle_after: int = 0
|
||||
|
||||
# Disable checking the dataframe (converts the error into a warning message)
|
||||
disable_dataframe_checks: bool = False
|
||||
|
||||
@ -476,8 +481,21 @@ class IStrategy(ABC):
|
||||
(buy, sell) = latest[SignalType.BUY.value] == 1, latest[SignalType.SELL.value] == 1
|
||||
logger.debug('trigger: %s (pair=%s) buy=%s sell=%s',
|
||||
latest['date'], pair, str(buy), str(sell))
|
||||
if self.ignore_expired_candle(dataframe=dataframe, buy=buy):
|
||||
return False, sell
|
||||
return buy, sell
|
||||
|
||||
def ignore_expired_candle(self, dataframe: DataFrame, buy: bool):
|
||||
if self.ignore_buying_expired_candle and buy:
|
||||
current_time = datetime.now(timezone.utc) - timedelta(seconds=self.ignore_buying_expired_candle_after)
|
||||
candle_time = dataframe['date'].tail(1).iat[0]
|
||||
time_delta = current_time - candle_time
|
||||
if time_delta.total_seconds() > self.ignore_buying_expired_candle_after:
|
||||
logger.debug('ignoring buy signals because candle exceeded ignore_buying_expired_candle_after of %s seconds', self.ignore_buying_expired_candle_after)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def should_sell(self, trade: Trade, rate: float, date: datetime, buy: bool,
|
||||
sell: bool, low: float = None, high: float = None,
|
||||
force_stoploss: float = 0) -> SellCheckTuple:
|
||||
@ -672,6 +690,7 @@ class IStrategy(ABC):
|
||||
:return: DataFrame with buy column
|
||||
"""
|
||||
logger.debug(f"Populating buy signals for pair {metadata.get('pair')}.")
|
||||
|
||||
if self._buy_fun_len == 2:
|
||||
warnings.warn("deprecated - check out the Sample strategy to see "
|
||||
"the current function headers!", DeprecationWarning)
|
||||
|
@ -106,6 +106,23 @@ def test_get_signal_old_dataframe(default_conf, mocker, caplog, ohlcv_history):
|
||||
assert log_has('Outdated history for pair xyz. Last tick is 16 minutes old', caplog)
|
||||
|
||||
|
||||
def test_ignore_expired_candle(default_conf, ohlcv_history):
|
||||
default_conf.update({'strategy': 'DefaultStrategy'})
|
||||
strategy = StrategyResolver.load_strategy(default_conf)
|
||||
strategy.ignore_buying_expired_candle = True
|
||||
strategy.ignore_buying_expired_candle_after = 60
|
||||
|
||||
ohlcv_history.loc[-1, 'date'] = arrow.utcnow().shift(minutes=-3)
|
||||
# Take a copy to correctly modify the call
|
||||
mocked_history = ohlcv_history.copy()
|
||||
mocked_history['sell'] = 0
|
||||
mocked_history['buy'] = 0
|
||||
mocked_history.loc[1, 'buy'] = 1
|
||||
mocked_history.loc[1, 'sell'] = 1
|
||||
|
||||
assert strategy.ignore_expired_candle(mocked_history, True) == True
|
||||
|
||||
|
||||
def test_assert_df_raise(mocker, caplog, ohlcv_history):
|
||||
ohlcv_history.loc[1, 'date'] = arrow.utcnow().shift(minutes=-16)
|
||||
# Take a copy to correctly modify the call
|
||||
|
Loading…
Reference in New Issue
Block a user