Merge pull request #1700 from freqtrade/dataprovider/backtesting
Dataprovider during backtesting
This commit is contained in:
commit
52012003e9
@ -260,12 +260,9 @@ class Awesomestrategy(IStrategy):
|
|||||||
|
|
||||||
The strategy provides access to the `DataProvider`. This allows you to get additional data to use in your strategy.
|
The strategy provides access to the `DataProvider`. This allows you to get additional data to use in your strategy.
|
||||||
|
|
||||||
!!! Note
|
|
||||||
The DataProvier is currently not available during backtesting / hyperopt, but this is planned for the future.
|
|
||||||
|
|
||||||
All methods return `None` in case of failure (do not raise an exception).
|
All methods return `None` in case of failure (do not raise an exception).
|
||||||
|
|
||||||
Please always check if the `DataProvider` is available to avoid failures during backtesting.
|
Please always check the mode of operation to select the correct method to get data (samples see below).
|
||||||
|
|
||||||
#### Possible options for DataProvider
|
#### Possible options for DataProvider
|
||||||
|
|
||||||
@ -292,6 +289,9 @@ if self.dp:
|
|||||||
Be carefull when using dataprovider in backtesting. `historic_ohlcv()` provides the full time-range in one go,
|
Be carefull when using dataprovider in backtesting. `historic_ohlcv()` provides the full time-range in one go,
|
||||||
so please be aware of it and make sure to not "look into the future" to avoid surprises when running in dry/live mode).
|
so please be aware of it and make sure to not "look into the future" to avoid surprises when running in dry/live mode).
|
||||||
|
|
||||||
|
!!! Warning Warning in hyperopt
|
||||||
|
This option cannot currently be used during hyperopt.
|
||||||
|
|
||||||
#### Available Pairs
|
#### Available Pairs
|
||||||
|
|
||||||
``` python
|
``` python
|
||||||
|
@ -18,6 +18,7 @@ from freqtrade import DependencyException, constants
|
|||||||
from freqtrade.arguments import Arguments
|
from freqtrade.arguments import Arguments
|
||||||
from freqtrade.configuration import Configuration
|
from freqtrade.configuration import Configuration
|
||||||
from freqtrade.data import history
|
from freqtrade.data import history
|
||||||
|
from freqtrade.data.dataprovider import DataProvider
|
||||||
from freqtrade.misc import file_dump_json
|
from freqtrade.misc import file_dump_json
|
||||||
from freqtrade.persistence import Trade
|
from freqtrade.persistence import Trade
|
||||||
from freqtrade.resolvers import ExchangeResolver, StrategyResolver
|
from freqtrade.resolvers import ExchangeResolver, StrategyResolver
|
||||||
@ -64,6 +65,15 @@ class Backtesting(object):
|
|||||||
self.config['exchange']['uid'] = ''
|
self.config['exchange']['uid'] = ''
|
||||||
self.config['dry_run'] = True
|
self.config['dry_run'] = True
|
||||||
self.strategylist: List[IStrategy] = []
|
self.strategylist: List[IStrategy] = []
|
||||||
|
|
||||||
|
exchange_name = self.config.get('exchange', {}).get('name', 'bittrex').title()
|
||||||
|
self.exchange = ExchangeResolver(exchange_name, self.config).exchange
|
||||||
|
self.fee = self.exchange.get_fee()
|
||||||
|
|
||||||
|
if self.config.get('runmode') != RunMode.HYPEROPT:
|
||||||
|
self.dataprovider = DataProvider(self.config, self.exchange)
|
||||||
|
IStrategy.dp = self.dataprovider
|
||||||
|
|
||||||
if self.config.get('strategy_list', None):
|
if self.config.get('strategy_list', None):
|
||||||
# Force one interval
|
# Force one interval
|
||||||
self.ticker_interval = str(self.config.get('ticker_interval'))
|
self.ticker_interval = str(self.config.get('ticker_interval'))
|
||||||
@ -78,15 +88,13 @@ class Backtesting(object):
|
|||||||
self.strategylist.append(StrategyResolver(self.config).strategy)
|
self.strategylist.append(StrategyResolver(self.config).strategy)
|
||||||
# Load one strategy
|
# Load one strategy
|
||||||
self._set_strategy(self.strategylist[0])
|
self._set_strategy(self.strategylist[0])
|
||||||
exchange_name = self.config.get('exchange', {}).get('name', 'bittrex').title()
|
|
||||||
self.exchange = ExchangeResolver(exchange_name, self.config).exchange
|
|
||||||
self.fee = self.exchange.get_fee()
|
|
||||||
|
|
||||||
def _set_strategy(self, strategy):
|
def _set_strategy(self, strategy):
|
||||||
"""
|
"""
|
||||||
Load strategy into backtesting
|
Load strategy into backtesting
|
||||||
"""
|
"""
|
||||||
self.strategy = strategy
|
self.strategy = strategy
|
||||||
|
|
||||||
self.ticker_interval = self.config.get('ticker_interval')
|
self.ticker_interval = self.config.get('ticker_interval')
|
||||||
self.ticker_interval_mins = constants.TICKER_INTERVAL_MINUTES[self.ticker_interval]
|
self.ticker_interval_mins = constants.TICKER_INTERVAL_MINUTES[self.ticker_interval]
|
||||||
self.tickerdata_to_dataframe = strategy.tickerdata_to_dataframe
|
self.tickerdata_to_dataframe = strategy.tickerdata_to_dataframe
|
||||||
|
@ -16,6 +16,7 @@ from freqtrade.arguments import Arguments, TimeRange
|
|||||||
from freqtrade.data import history
|
from freqtrade.data import history
|
||||||
from freqtrade.data.btanalysis import evaluate_result_multi
|
from freqtrade.data.btanalysis import evaluate_result_multi
|
||||||
from freqtrade.data.converter import parse_ticker_dataframe
|
from freqtrade.data.converter import parse_ticker_dataframe
|
||||||
|
from freqtrade.data.dataprovider import DataProvider
|
||||||
from freqtrade.optimize import get_timeframe
|
from freqtrade.optimize import get_timeframe
|
||||||
from freqtrade.optimize.backtesting import (Backtesting, setup_configuration,
|
from freqtrade.optimize.backtesting import (Backtesting, setup_configuration,
|
||||||
start)
|
start)
|
||||||
@ -346,6 +347,7 @@ def test_backtesting_init(mocker, default_conf, order_types) -> None:
|
|||||||
assert callable(backtesting.strategy.tickerdata_to_dataframe)
|
assert callable(backtesting.strategy.tickerdata_to_dataframe)
|
||||||
assert callable(backtesting.advise_buy)
|
assert callable(backtesting.advise_buy)
|
||||||
assert callable(backtesting.advise_sell)
|
assert callable(backtesting.advise_sell)
|
||||||
|
assert isinstance(backtesting.strategy.dp, DataProvider)
|
||||||
get_fee.assert_called()
|
get_fee.assert_called()
|
||||||
assert backtesting.fee == 0.5
|
assert backtesting.fee == 0.5
|
||||||
assert not backtesting.strategy.order_types["stoploss_on_exchange"]
|
assert not backtesting.strategy.order_types["stoploss_on_exchange"]
|
||||||
|
@ -13,12 +13,14 @@ import requests
|
|||||||
|
|
||||||
from freqtrade import (DependencyException, OperationalException,
|
from freqtrade import (DependencyException, OperationalException,
|
||||||
TemporaryError, constants)
|
TemporaryError, constants)
|
||||||
|
from freqtrade.data.dataprovider import DataProvider
|
||||||
from freqtrade.freqtradebot import FreqtradeBot
|
from freqtrade.freqtradebot import FreqtradeBot
|
||||||
from freqtrade.persistence import Trade
|
from freqtrade.persistence import Trade
|
||||||
from freqtrade.rpc import RPCMessageType
|
from freqtrade.rpc import RPCMessageType
|
||||||
from freqtrade.state import State
|
from freqtrade.state import State
|
||||||
from freqtrade.strategy.interface import SellType, SellCheckTuple
|
from freqtrade.strategy.interface import SellCheckTuple, SellType
|
||||||
from freqtrade.tests.conftest import log_has, log_has_re, patch_exchange, patch_edge, patch_wallet
|
from freqtrade.tests.conftest import (log_has, log_has_re, patch_edge,
|
||||||
|
patch_exchange, patch_wallet)
|
||||||
|
|
||||||
|
|
||||||
# Functions for recurrent object patching
|
# Functions for recurrent object patching
|
||||||
@ -88,6 +90,10 @@ def test_worker_running(mocker, default_conf, caplog) -> None:
|
|||||||
assert state is State.RUNNING
|
assert state is State.RUNNING
|
||||||
assert log_has('Changing state to: RUNNING', caplog.record_tuples)
|
assert log_has('Changing state to: RUNNING', caplog.record_tuples)
|
||||||
assert mock_throttle.call_count == 1
|
assert mock_throttle.call_count == 1
|
||||||
|
# Check strategy is loaded, and received a dataprovider object
|
||||||
|
assert freqtrade.strategy
|
||||||
|
assert freqtrade.strategy.dp
|
||||||
|
assert isinstance(freqtrade.strategy.dp, DataProvider)
|
||||||
|
|
||||||
|
|
||||||
def test_worker_stopped(mocker, default_conf, caplog) -> None:
|
def test_worker_stopped(mocker, default_conf, caplog) -> None:
|
||||||
|
Loading…
Reference in New Issue
Block a user