mirror of
https://github.com/freqtrade/freqtrade.git
synced 2024-11-10 10:21:59 +00:00
Merge branch 'develop' into strategy_version
This commit is contained in:
commit
50b572a657
|
@ -79,18 +79,18 @@ freqtrade backtesting --datadir user_data/data/bittrex-20180101
|
||||||
#### With a (custom) strategy file
|
#### With a (custom) strategy file
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
freqtrade -s TestStrategy backtesting
|
freqtrade -s SampleStrategy backtesting
|
||||||
```
|
```
|
||||||
|
|
||||||
Where `-s TestStrategy` refers to the class name within the strategy file `test_strategy.py` found in the `freqtrade/user_data/strategies` directory.
|
Where `-s SampleStrategy` refers to the class name within the strategy file `sample_strategy.py` found in the `freqtrade/user_data/strategies` directory.
|
||||||
|
|
||||||
#### Comparing multiple Strategies
|
#### Comparing multiple Strategies
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
freqtrade backtesting --strategy-list TestStrategy1 AwesomeStrategy --ticker-interval 5m
|
freqtrade backtesting --strategy-list SampleStrategy1 AwesomeStrategy --ticker-interval 5m
|
||||||
```
|
```
|
||||||
|
|
||||||
Where `TestStrategy1` and `AwesomeStrategy` refer to class names of strategies.
|
Where `SampleStrategy1` and `AwesomeStrategy` refer to class names of strategies.
|
||||||
|
|
||||||
#### Exporting trades to file
|
#### Exporting trades to file
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ The exported trades can be used for [further analysis](#further-backtest-result-
|
||||||
#### Exporting trades to file specifying a custom filename
|
#### Exporting trades to file specifying a custom filename
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
freqtrade backtesting --export trades --export-filename=backtest_teststrategy.json
|
freqtrade backtesting --export trades --export-filename=backtest_samplestrategy.json
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Running backtest with smaller testset
|
#### Running backtest with smaller testset
|
||||||
|
|
|
@ -61,8 +61,9 @@ Mandatory parameters are marked as **Required**.
|
||||||
| `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).
|
||||||
| `exchange.sandbox` | false | Use the 'sandbox' version of the exchange, where the exchange provides a sandbox for risk-free integration. See [here](sandbox-testing.md) in more details.
|
| `exchange.sandbox` | false | Use the 'sandbox' version of the exchange, where the exchange provides a sandbox for risk-free integration. See [here](sandbox-testing.md) in more details.
|
||||||
| `exchange.key` | '' | API key to use for the exchange. Only required when you are in production mode.
|
| `exchange.key` | '' | API key to use for the exchange. Only required when you are in production mode. ***Keep it in secrete, do not disclose publicly.***
|
||||||
| `exchange.secret` | '' | API secret to use for the exchange. Only required when you are in production mode.
|
| `exchange.secret` | '' | API secret to use for the exchange. Only required when you are in production mode. ***Keep it in secrete, do not disclose publicly.***
|
||||||
|
| `exchange.password` | '' | API password to use for the exchange. Only required when you are in production mode and for exchanges that use password for API requests. ***Keep it in secrete, do not disclose publicly.***
|
||||||
| `exchange.pair_whitelist` | [] | List of pairs to use by the bot for trading and to check for potential trades during backtesting. Can be overriden by dynamic pairlists (see [below](#dynamic-pairlists)).
|
| `exchange.pair_whitelist` | [] | List of pairs to use by the bot for trading and to check for potential trades during backtesting. Can be overriden by dynamic pairlists (see [below](#dynamic-pairlists)).
|
||||||
| `exchange.pair_blacklist` | [] | List of pairs the bot must absolutely avoid for trading and backtesting. Can be overriden by dynamic pairlists (see [below](#dynamic-pairlists)).
|
| `exchange.pair_blacklist` | [] | List of pairs the bot must absolutely avoid for trading and backtesting. Can be overriden by dynamic pairlists (see [below](#dynamic-pairlists)).
|
||||||
| `exchange.ccxt_config` | None | Additional CCXT parameters passed to the regular 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_config` | None | Additional CCXT parameters passed to the regular 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)
|
||||||
|
@ -76,8 +77,8 @@ Mandatory parameters are marked as **Required**.
|
||||||
| `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).
|
||||||
| `telegram.enabled` | true | **Required.** Enable or not the usage of Telegram.
|
| `telegram.enabled` | true | **Required.** Enable or not the usage of Telegram.
|
||||||
| `telegram.token` | token | Your Telegram bot token. Only required if `telegram.enabled` is `true`.
|
| `telegram.token` | token | Your Telegram bot token. Only required if `telegram.enabled` is `true`. ***Keep it in secrete, do not disclose publicly.***
|
||||||
| `telegram.chat_id` | chat_id | Your personal Telegram account id. Only required if `telegram.enabled` is `true`.
|
| `telegram.chat_id` | chat_id | Your personal Telegram account id. Only required if `telegram.enabled` is `true`. ***Keep it in secrete, do not disclose publicly.***
|
||||||
| `webhook.enabled` | false | Enable usage of Webhook notifications
|
| `webhook.enabled` | false | Enable usage of Webhook notifications
|
||||||
| `webhook.url` | false | URL for the webhook. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
|
| `webhook.url` | false | URL for the webhook. Only required if `webhook.enabled` is `true`. See the [webhook documentation](webhook-config.md) for more details.
|
||||||
| `webhook.webhookbuy` | false | Payload to send on buy. Only required if `webhook.enabled` is `true`. See the [webhook documentationV](webhook-config.md) for more details.
|
| `webhook.webhookbuy` | false | Payload to send on buy. Only required if `webhook.enabled` is `true`. See the [webhook documentationV](webhook-config.md) for more details.
|
||||||
|
|
|
@ -139,7 +139,7 @@ You can override strategy settings as demonstrated below.
|
||||||
# Define some constants
|
# Define some constants
|
||||||
ticker_interval = "5m"
|
ticker_interval = "5m"
|
||||||
# Name of the strategy class
|
# Name of the strategy class
|
||||||
strategy_name = 'TestStrategy'
|
strategy_name = 'SampleStrategy'
|
||||||
# Path to user data
|
# Path to user data
|
||||||
user_data_dir = 'user_data'
|
user_data_dir = 'user_data'
|
||||||
# Location of the strategy
|
# Location of the strategy
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
mkdocs-material==4.4.0
|
mkdocs-material==4.4.1
|
|
@ -24,7 +24,7 @@ strategy file will be updated on Github. Put your custom strategy file
|
||||||
into the directory `user_data/strategies`.
|
into the directory `user_data/strategies`.
|
||||||
|
|
||||||
Best copy the test-strategy and modify this copy to avoid having bot-updates override your changes.
|
Best copy the test-strategy and modify this copy to avoid having bot-updates override your changes.
|
||||||
`cp user_data/strategies/test_strategy.py user_data/strategies/awesome-strategy.py`
|
`cp user_data/strategies/sample_strategy.py user_data/strategies/awesome-strategy.py`
|
||||||
|
|
||||||
### Anatomy of a strategy
|
### Anatomy of a strategy
|
||||||
|
|
||||||
|
@ -36,8 +36,8 @@ A strategy file contains all the information needed to build a good strategy:
|
||||||
- Minimal ROI recommended
|
- Minimal ROI recommended
|
||||||
- Stoploss strongly recommended
|
- Stoploss strongly recommended
|
||||||
|
|
||||||
The bot includes a sample strategy called `TestStrategy` you can update: `user_data/strategies/test_strategy.py`.
|
The bot also include a sample strategy called `SampleStrategy` you can update: `user_data/strategies/sample_strategy.py`.
|
||||||
You can test it with the parameter: `--strategy TestStrategy`
|
You can test it with the parameter: `--strategy SampleStrategy`
|
||||||
|
|
||||||
Additionally, there is an attribute called `INTERFACE_VERSION`, which defines the version of the strategy interface the bot should use.
|
Additionally, there is an attribute called `INTERFACE_VERSION`, which defines the version of the strategy interface the bot should use.
|
||||||
The current version is 2 - which is also the default when it's not set explicitly in the strategy.
|
The current version is 2 - which is also the default when it's not set explicitly in the strategy.
|
||||||
|
@ -48,7 +48,7 @@ Future versions will require this to be set.
|
||||||
freqtrade --strategy AwesomeStrategy
|
freqtrade --strategy AwesomeStrategy
|
||||||
```
|
```
|
||||||
|
|
||||||
**For the following section we will use the [user_data/strategies/test_strategy.py](https://github.com/freqtrade/freqtrade/blob/develop/user_data/strategies/test_strategy.py)
|
**For the following section we will use the [user_data/strategies/sample_strategy.py](https://github.com/freqtrade/freqtrade/blob/develop/user_data/strategies/sample_strategy.py)
|
||||||
file as reference.**
|
file as reference.**
|
||||||
|
|
||||||
!!! Note Strategies and Backtesting
|
!!! Note Strategies and Backtesting
|
||||||
|
@ -114,9 +114,8 @@ def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame
|
||||||
return dataframe
|
return dataframe
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
!!! Note "Want more indicator examples?"
|
!!! Note "Want more indicator examples?"
|
||||||
Look into the [user_data/strategies/test_strategy.py](https://github.com/freqtrade/freqtrade/blob/develop/user_data/strategies/test_strategy.py).<br/>
|
Look into the [user_data/strategies/sample_strategy.py](https://github.com/freqtrade/freqtrade/blob/develop/user_data/strategies/sample_strategy.py).
|
||||||
Then uncomment indicators you need.
|
Then uncomment indicators you need.
|
||||||
|
|
||||||
### Buy signal rules
|
### Buy signal rules
|
||||||
|
@ -127,7 +126,7 @@ It's important to always return the dataframe without removing/modifying the col
|
||||||
|
|
||||||
This will method will also define a new column, `"buy"`, which needs to contain 1 for buys, and 0 for "no action".
|
This will method will also define a new column, `"buy"`, which needs to contain 1 for buys, and 0 for "no action".
|
||||||
|
|
||||||
Sample from `user_data/strategies/test_strategy.py`:
|
Sample from `user_data/strategies/sample_strategy.py`:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||||
|
@ -157,7 +156,7 @@ It's important to always return the dataframe without removing/modifying the col
|
||||||
|
|
||||||
This will method will also define a new column, `"sell"`, which needs to contain 1 for sells, and 0 for "no action".
|
This will method will also define a new column, `"sell"`, which needs to contain 1 for sells, and 0 for "no action".
|
||||||
|
|
||||||
Sample from `user_data/strategies/test_strategy.py`:
|
Sample from `user_data/strategies/sample_strategy.py`:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||||
|
|
|
@ -14,6 +14,7 @@ from typing import Any, Dict, List, Optional, Tuple
|
||||||
import arrow
|
import arrow
|
||||||
import ccxt
|
import ccxt
|
||||||
import ccxt.async_support as ccxt_async
|
import ccxt.async_support as ccxt_async
|
||||||
|
from ccxt.base.decimal_to_precision import ROUND_UP, ROUND_DOWN
|
||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
|
|
||||||
from freqtrade import (DependencyException, InvalidOrderException,
|
from freqtrade import (DependencyException, InvalidOrderException,
|
||||||
|
@ -808,11 +809,9 @@ def timeframe_to_prev_date(timeframe: str, date: datetime = None) -> datetime:
|
||||||
"""
|
"""
|
||||||
if not date:
|
if not date:
|
||||||
date = datetime.now(timezone.utc)
|
date = datetime.now(timezone.utc)
|
||||||
timeframe_secs = timeframe_to_seconds(timeframe)
|
|
||||||
# Get offset based on timerame_secs
|
new_timestamp = ccxt.Exchange.round_timeframe(timeframe, date.timestamp() * 1000,
|
||||||
offset = date.timestamp() % timeframe_secs
|
ROUND_DOWN) // 1000
|
||||||
# Subtract seconds passed since last offset
|
|
||||||
new_timestamp = date.timestamp() - offset
|
|
||||||
return datetime.fromtimestamp(new_timestamp, tz=timezone.utc)
|
return datetime.fromtimestamp(new_timestamp, tz=timezone.utc)
|
||||||
|
|
||||||
|
|
||||||
|
@ -823,9 +822,8 @@ def timeframe_to_next_date(timeframe: str, date: datetime = None) -> datetime:
|
||||||
:param date: date to use. Defaults to utcnow()
|
:param date: date to use. Defaults to utcnow()
|
||||||
:returns: date of next candle (with utc timezone)
|
:returns: date of next candle (with utc timezone)
|
||||||
"""
|
"""
|
||||||
prevdate = timeframe_to_prev_date(timeframe, date)
|
if not date:
|
||||||
timeframe_secs = timeframe_to_seconds(timeframe)
|
date = datetime.now(timezone.utc)
|
||||||
|
new_timestamp = ccxt.Exchange.round_timeframe(timeframe, date.timestamp() * 1000,
|
||||||
# Add one interval to previous candle
|
ROUND_UP) // 1000
|
||||||
new_timestamp = prevdate.timestamp() + timeframe_secs
|
|
||||||
return datetime.fromtimestamp(new_timestamp, tz=timezone.utc)
|
return datetime.fromtimestamp(new_timestamp, tz=timezone.utc)
|
||||||
|
|
|
@ -81,6 +81,12 @@ class Backtesting(object):
|
||||||
# No strategy list specified, only one strategy
|
# No strategy list specified, only one strategy
|
||||||
self.strategylist.append(StrategyResolver(self.config).strategy)
|
self.strategylist.append(StrategyResolver(self.config).strategy)
|
||||||
|
|
||||||
|
if "ticker_interval" not in self.config:
|
||||||
|
raise OperationalException("Ticker-interval needs to be set in either configuration "
|
||||||
|
"or as cli argument `--ticker-interval 5m`")
|
||||||
|
self.ticker_interval = str(self.config.get('ticker_interval'))
|
||||||
|
self.ticker_interval_mins = timeframe_to_minutes(self.ticker_interval)
|
||||||
|
|
||||||
# Load one (first) strategy
|
# Load one (first) strategy
|
||||||
self._set_strategy(self.strategylist[0])
|
self._set_strategy(self.strategylist[0])
|
||||||
|
|
||||||
|
@ -89,12 +95,6 @@ class Backtesting(object):
|
||||||
Load strategy into backtesting
|
Load strategy into backtesting
|
||||||
"""
|
"""
|
||||||
self.strategy = strategy
|
self.strategy = strategy
|
||||||
if "ticker_interval" not in self.config:
|
|
||||||
raise OperationalException("Ticker-interval needs to be set in either configuration "
|
|
||||||
"or as cli argument `--ticker-interval 5m`")
|
|
||||||
|
|
||||||
self.ticker_interval = self.config.get('ticker_interval')
|
|
||||||
self.ticker_interval_mins = timeframe_to_minutes(self.ticker_interval)
|
|
||||||
self.advise_buy = strategy.advise_buy
|
self.advise_buy = strategy.advise_buy
|
||||||
self.advise_sell = strategy.advise_sell
|
self.advise_sell = strategy.advise_sell
|
||||||
# Set stoploss_on_exchange to false for backtesting,
|
# Set stoploss_on_exchange to false for backtesting,
|
||||||
|
|
|
@ -1531,7 +1531,7 @@ def test_timeframe_to_prev_date():
|
||||||
assert timeframe_to_prev_date(interval, date) == result
|
assert timeframe_to_prev_date(interval, date) == result
|
||||||
|
|
||||||
date = datetime.now(tz=timezone.utc)
|
date = datetime.now(tz=timezone.utc)
|
||||||
assert timeframe_to_prev_date("5m", date) < date
|
assert timeframe_to_prev_date("5m") < date
|
||||||
|
|
||||||
|
|
||||||
def test_timeframe_to_next_date():
|
def test_timeframe_to_next_date():
|
||||||
|
@ -1556,4 +1556,4 @@ def test_timeframe_to_next_date():
|
||||||
assert timeframe_to_next_date(interval, date) == result
|
assert timeframe_to_next_date(interval, date) == result
|
||||||
|
|
||||||
date = datetime.now(tz=timezone.utc)
|
date = datetime.now(tz=timezone.utc)
|
||||||
assert timeframe_to_next_date("5m", date) > date
|
assert timeframe_to_next_date("5m") > date
|
||||||
|
|
|
@ -330,7 +330,7 @@ def test_backtesting_init_no_ticker_interval(mocker, default_conf, caplog) -> No
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
del default_conf['ticker_interval']
|
del default_conf['ticker_interval']
|
||||||
default_conf['strategy_list'] = ['DefaultStrategy',
|
default_conf['strategy_list'] = ['DefaultStrategy',
|
||||||
'TestStrategy']
|
'SampleStrategy']
|
||||||
|
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', MagicMock(return_value=0.5))
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', MagicMock(return_value=0.5))
|
||||||
with pytest.raises(OperationalException):
|
with pytest.raises(OperationalException):
|
||||||
|
@ -877,7 +877,7 @@ def test_backtest_start_multi_strat(default_conf, mocker, caplog):
|
||||||
'--disable-max-market-positions',
|
'--disable-max-market-positions',
|
||||||
'--strategy-list',
|
'--strategy-list',
|
||||||
'DefaultStrategy',
|
'DefaultStrategy',
|
||||||
'TestStrategy',
|
'SampleStrategy',
|
||||||
]
|
]
|
||||||
args = get_args(args)
|
args = get_args(args)
|
||||||
start_backtesting(args)
|
start_backtesting(args)
|
||||||
|
@ -898,7 +898,7 @@ def test_backtest_start_multi_strat(default_conf, mocker, caplog):
|
||||||
'up to 2017-11-14T22:58:00+00:00 (0 days)..',
|
'up to 2017-11-14T22:58:00+00:00 (0 days)..',
|
||||||
'Parameter --enable-position-stacking detected ...',
|
'Parameter --enable-position-stacking detected ...',
|
||||||
'Running backtesting for Strategy DefaultStrategy',
|
'Running backtesting for Strategy DefaultStrategy',
|
||||||
'Running backtesting for Strategy TestStrategy',
|
'Running backtesting for Strategy SampleStrategy',
|
||||||
]
|
]
|
||||||
|
|
||||||
for line in exists:
|
for line in exists:
|
||||||
|
|
|
@ -254,7 +254,7 @@ def test_start_failure(mocker, default_conf, caplog) -> None:
|
||||||
|
|
||||||
args = [
|
args = [
|
||||||
'--config', 'config.json',
|
'--config', 'config.json',
|
||||||
'--strategy', 'TestStrategy',
|
'--strategy', 'SampleStrategy',
|
||||||
'hyperopt',
|
'hyperopt',
|
||||||
'--epochs', '5'
|
'--epochs', '5'
|
||||||
]
|
]
|
||||||
|
|
|
@ -15,7 +15,7 @@ class TestStrategyLegacy(IStrategy):
|
||||||
"""
|
"""
|
||||||
This is a test strategy using the legacy function headers, which will be
|
This is a test strategy using the legacy function headers, which will be
|
||||||
removed in a future update.
|
removed in a future update.
|
||||||
Please do not use this as a template, but refer to user_data/strategy/TestStrategy.py
|
Please do not use this as a template, but refer to user_data/strategy/sample_strategy.py
|
||||||
for a uptodate version of this template.
|
for a uptodate version of this template.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -61,27 +61,27 @@ def test_search_strategy():
|
||||||
|
|
||||||
|
|
||||||
def test_load_strategy(default_conf, result):
|
def test_load_strategy(default_conf, result):
|
||||||
default_conf.update({'strategy': 'TestStrategy'})
|
default_conf.update({'strategy': 'SampleStrategy'})
|
||||||
resolver = StrategyResolver(default_conf)
|
resolver = StrategyResolver(default_conf)
|
||||||
assert 'adx' in resolver.strategy.advise_indicators(result, {'pair': 'ETH/BTC'})
|
assert 'adx' in resolver.strategy.advise_indicators(result, {'pair': 'ETH/BTC'})
|
||||||
|
|
||||||
|
|
||||||
def test_load_strategy_base64(result, caplog, default_conf):
|
def test_load_strategy_base64(result, caplog, default_conf):
|
||||||
with open("user_data/strategies/test_strategy.py", "rb") as file:
|
with open("user_data/strategies/sample_strategy.py", "rb") as file:
|
||||||
encoded_string = urlsafe_b64encode(file.read()).decode("utf-8")
|
encoded_string = urlsafe_b64encode(file.read()).decode("utf-8")
|
||||||
default_conf.update({'strategy': 'TestStrategy:{}'.format(encoded_string)})
|
default_conf.update({'strategy': 'SampleStrategy:{}'.format(encoded_string)})
|
||||||
|
|
||||||
resolver = StrategyResolver(default_conf)
|
resolver = StrategyResolver(default_conf)
|
||||||
assert 'adx' in resolver.strategy.advise_indicators(result, {'pair': 'ETH/BTC'})
|
assert 'adx' in resolver.strategy.advise_indicators(result, {'pair': 'ETH/BTC'})
|
||||||
# Make sure strategy was loaded from base64 (using temp directory)!!
|
# Make sure strategy was loaded from base64 (using temp directory)!!
|
||||||
assert log_has_re(r"Using resolved strategy TestStrategy from '"
|
assert log_has_re(r"Using resolved strategy SampleStrategy from '"
|
||||||
+ tempfile.gettempdir() + r"/.*/TestStrategy\.py'\.\.\.", caplog)
|
+ tempfile.gettempdir() + r"/.*/SampleStrategy\.py'\.\.\.", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_load_strategy_invalid_directory(result, caplog, default_conf):
|
def test_load_strategy_invalid_directory(result, caplog, default_conf):
|
||||||
resolver = StrategyResolver(default_conf)
|
resolver = StrategyResolver(default_conf)
|
||||||
extra_dir = Path.cwd() / 'some/path'
|
extra_dir = Path.cwd() / 'some/path'
|
||||||
resolver._load_strategy('TestStrategy', config=default_conf, extra_dir=extra_dir)
|
resolver._load_strategy('SampleStrategy', config=default_conf, extra_dir=extra_dir)
|
||||||
|
|
||||||
assert log_has_re(r'Path .*' + r'some.*path.*' + r'.* does not exist', caplog)
|
assert log_has_re(r'Path .*' + r'some.*path.*' + r'.* does not exist', caplog)
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ def test_parse_args_backtesting_custom() -> None:
|
||||||
'--refresh-pairs-cached',
|
'--refresh-pairs-cached',
|
||||||
'--strategy-list',
|
'--strategy-list',
|
||||||
'DefaultStrategy',
|
'DefaultStrategy',
|
||||||
'TestStrategy'
|
'SampleStrategy'
|
||||||
]
|
]
|
||||||
call_args = Arguments(args, '').get_parsed_arg()
|
call_args = Arguments(args, '').get_parsed_arg()
|
||||||
assert call_args.config == ['test_conf.json']
|
assert call_args.config == ['test_conf.json']
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# requirements without requirements installable via conda
|
# requirements without requirements installable via conda
|
||||||
# mainly used for Raspberry pi installs
|
# mainly used for Raspberry pi installs
|
||||||
ccxt==1.18.1068
|
ccxt==1.18.1085
|
||||||
SQLAlchemy==1.3.7
|
SQLAlchemy==1.3.7
|
||||||
python-telegram-bot==11.1.0
|
python-telegram-bot==11.1.0
|
||||||
arrow==0.14.5
|
arrow==0.14.5
|
||||||
|
|
|
@ -7,7 +7,7 @@ flake8==3.7.8
|
||||||
flake8-type-annotations==0.1.0
|
flake8-type-annotations==0.1.0
|
||||||
flake8-tidy-imports==2.0.0
|
flake8-tidy-imports==2.0.0
|
||||||
mypy==0.720
|
mypy==0.720
|
||||||
pytest==5.1.0
|
pytest==5.1.1
|
||||||
pytest-asyncio==0.10.0
|
pytest-asyncio==0.10.0
|
||||||
pytest-cov==2.7.1
|
pytest-cov==2.7.1
|
||||||
pytest-mock==1.10.4
|
pytest-mock==1.10.4
|
||||||
|
|
|
@ -2,5 +2,5 @@
|
||||||
-r requirements-common.txt
|
-r requirements-common.txt
|
||||||
|
|
||||||
numpy==1.17.0
|
numpy==1.17.0
|
||||||
pandas==0.25.0
|
pandas==0.25.1
|
||||||
scipy==1.3.1
|
scipy==1.3.1
|
||||||
|
|
4
setup.py
4
setup.py
|
@ -45,7 +45,7 @@ setup(name='freqtrade',
|
||||||
tests_require=['pytest', 'pytest-mock', 'pytest-cov'],
|
tests_require=['pytest', 'pytest-mock', 'pytest-cov'],
|
||||||
install_requires=[
|
install_requires=[
|
||||||
# from requirements-common.txt
|
# from requirements-common.txt
|
||||||
'ccxt>=1.18',
|
'ccxt>=1.18.1080',
|
||||||
'SQLAlchemy',
|
'SQLAlchemy',
|
||||||
'python-telegram-bot',
|
'python-telegram-bot',
|
||||||
'arrow',
|
'arrow',
|
||||||
|
@ -76,7 +76,7 @@ setup(name='freqtrade',
|
||||||
'plot': plot,
|
'plot': plot,
|
||||||
'all': all_extra,
|
'all': all_extra,
|
||||||
'jupyter': jupyter,
|
'jupyter': jupyter,
|
||||||
|
|
||||||
},
|
},
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
"# Define some constants\n",
|
"# Define some constants\n",
|
||||||
"ticker_interval = \"5m\"\n",
|
"ticker_interval = \"5m\"\n",
|
||||||
"# Name of the strategy class\n",
|
"# Name of the strategy class\n",
|
||||||
"strategy_name = 'TestStrategy'\n",
|
"strategy_name = 'SampleStrategy'\n",
|
||||||
"# Path to user data\n",
|
"# Path to user data\n",
|
||||||
"user_data_dir = 'user_data'\n",
|
"user_data_dir = 'user_data'\n",
|
||||||
"# Location of the strategy\n",
|
"# Location of the strategy\n",
|
||||||
|
|
|
@ -11,10 +11,9 @@ import numpy # noqa
|
||||||
|
|
||||||
|
|
||||||
# This class is a sample. Feel free to customize it.
|
# This class is a sample. Feel free to customize it.
|
||||||
class TestStrategy(IStrategy):
|
class SampleStrategy(IStrategy):
|
||||||
__test__ = False # pytest expects to find tests here because of the name
|
|
||||||
"""
|
"""
|
||||||
This is a test strategy to inspire you.
|
This is a sample strategy to inspire you.
|
||||||
More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md
|
More information in https://github.com/freqtrade/freqtrade/blob/develop/docs/bot-optimization.md
|
||||||
|
|
||||||
You can:
|
You can:
|
Loading…
Reference in New Issue
Block a user