Merge branch 'develop' into align_userdata
This commit is contained in:
@@ -6,6 +6,128 @@ A good way for this is using Jupyter (notebook or lab) - which provides an inter
|
||||
|
||||
The following helpers will help you loading the data into Pandas DataFrames, and may also give you some starting points in analyzing the results.
|
||||
|
||||
## Strategy development problem analysis
|
||||
|
||||
Debugging a strategy (are there no buy signals, ...) can be very time-consuming.
|
||||
FreqTrade tries to help you by exposing a few helper-functions, which can be very handy.
|
||||
|
||||
It's recommended using Juptyer Notebooks for analysis, since it offers a dynamic way to rerun certain parts of the code.
|
||||
|
||||
The following is a full code-snippet, which will be explained by both comments, and step by step below.
|
||||
|
||||
```python
|
||||
# Some necessary imports
|
||||
from pathlib import Path
|
||||
|
||||
from freqtrade.data.history import load_pair_history
|
||||
from freqtrade.resolvers import StrategyResolver
|
||||
# Define some constants
|
||||
ticker_interval = "5m"
|
||||
|
||||
# Name of the strategy class
|
||||
strategyname = 'Awesomestrategy'
|
||||
# Location of the strategy
|
||||
strategy_location = '../xmatt/strategies'
|
||||
# Location of the data
|
||||
data_location = '../freqtrade/user_data/data/binance/'
|
||||
# Only use one pair here
|
||||
pair = "XRP_ETH"
|
||||
|
||||
### End constants
|
||||
|
||||
# Load data
|
||||
bt_data = load_pair_history(datadir=Path(data_location),
|
||||
ticker_interval = ticker_interval,
|
||||
pair=pair)
|
||||
print(len(bt_data))
|
||||
|
||||
### Start strategy reload
|
||||
# Load strategy - best done in a new cell
|
||||
# Rerun each time the strategy-file is changed.
|
||||
strategy = StrategyResolver({'strategy': strategyname,
|
||||
'user_data_dir': Path.cwd(),
|
||||
'strategy_path': location}).strategy
|
||||
|
||||
# Run strategy (just like in backtesting)
|
||||
df = strategy.analyze_ticker(bt_data, {'pair': pair})
|
||||
print(f"Generated {df['buy'].sum()} buy signals")
|
||||
|
||||
# Reindex data to be "nicer" and show data
|
||||
data = df.set_index('date', drop=True)
|
||||
data.tail()
|
||||
|
||||
```
|
||||
|
||||
### Explanation
|
||||
|
||||
#### Imports and constant definition
|
||||
|
||||
``` python
|
||||
# Some necessary imports
|
||||
from pathlib import Path
|
||||
|
||||
from freqtrade.data.history import load_pair_history
|
||||
from freqtrade.resolvers import StrategyResolver
|
||||
# Define some constants
|
||||
ticker_interval = "5m"
|
||||
|
||||
# Name of the strategy class
|
||||
strategyname = 'Awesomestrategy'
|
||||
# Location of the strategy
|
||||
strategy_location = 'user_data/strategies'
|
||||
# Location of the data
|
||||
data_location = 'user_data/data/binance'
|
||||
# Only use one pair here
|
||||
pair = "XRP_ETH"
|
||||
```
|
||||
|
||||
This first section imports necessary modules, and defines some constants you'll probably need to adjust for your case.
|
||||
|
||||
#### Load candles
|
||||
|
||||
``` python
|
||||
# Load data
|
||||
bt_data = load_pair_history(datadir=Path(data_location),
|
||||
ticker_interval = ticker_interval,
|
||||
pair=pair)
|
||||
print(len(bt_data))
|
||||
```
|
||||
|
||||
This second section loads the historic data and prints the amount of candles in the DataFrame.
|
||||
You can also inspect this dataframe by using `bt_data.head()` or `bt_data.tail()`.
|
||||
|
||||
#### Run strategy and analyze results
|
||||
|
||||
Now, it's time to load and run your strategy.
|
||||
For this, I recommend using a new cell in your notebook, since you'll want to repeat this until you're satisfied with your strategy.
|
||||
|
||||
``` python
|
||||
# Load strategy - best done in a new cell
|
||||
# Needs to be ran each time the strategy-file is changed.
|
||||
strategy = StrategyResolver({'strategy': strategyname,
|
||||
'user_data_dir': Path.cwd(),
|
||||
'strategy_path': location}).strategy
|
||||
|
||||
# Run strategy (just like in backtesting)
|
||||
df = strategy.analyze_ticker(bt_data, {'pair': pair})
|
||||
print(f"Generated {df['buy'].sum()} buy signals")
|
||||
|
||||
# Reindex data to be "nicer" and show data
|
||||
data = df.set_index('date', drop=True)
|
||||
data.tail()
|
||||
```
|
||||
|
||||
The code snippet loads and analyzes the strategy, calculates and prints the number of buy signals.
|
||||
|
||||
The last 2 lines serve to analyze the dataframe in detail.
|
||||
This can be important if your strategy did not generate any buy signals.
|
||||
Note that using `data.head()` would also work, however this is misleading since most indicators have some "startup" time at the start of a backtested dataframe.
|
||||
|
||||
There can be many things wrong, some signs to look for are:
|
||||
|
||||
* Columns with NaN values at the end of the dataframe
|
||||
* Columns used in `crossed*()` functions with completely different units
|
||||
|
||||
## Backtesting
|
||||
|
||||
To analyze your backtest results, you can [export the trades](#exporting-trades-to-file).
|
||||
|
||||
10
docs/faq.md
10
docs/faq.md
@@ -45,6 +45,16 @@ the tutorial [here|Testing-new-strategies-with-Hyperopt](bot-usage.md#hyperopt-c
|
||||
|
||||
You can use the `/forcesell all` command from Telegram.
|
||||
|
||||
### I get the message "RESTRICTED_MARKET"
|
||||
|
||||
Currently known to happen for US Bittrex users.
|
||||
Bittrex split its exchange into US and International versions.
|
||||
The International version has more pairs available, however the API always returns all pairs, so there is currently no automated way to detect if you're affected by the restriction.
|
||||
|
||||
If you have restricted pairs in your whitelist, you'll get a warning message in the log on FreqTrade startup for each restricted pair.
|
||||
If you're an "International" Customer on the Bittrex exchange, then this warning will probably not impact you.
|
||||
If you're a US customer, the bot will fail to create orders for these pairs, and you should remove them from your Whitelist.
|
||||
|
||||
## Hyperopt module
|
||||
|
||||
### How many epoch do I need to get a good Hyperopt result?
|
||||
|
||||
@@ -303,8 +303,10 @@ Given the following result from hyperopt:
|
||||
|
||||
```
|
||||
Best result:
|
||||
135 trades. Avg profit 0.57%. Total profit 0.03871918 BTC (0.7722Σ%). Avg duration 180.4 mins.
|
||||
with values:
|
||||
|
||||
44/100: 135 trades. Avg profit 0.57%. Total profit 0.03871918 BTC (0.7722Σ%). Avg duration 180.4 mins. Objective: 1.94367
|
||||
|
||||
Buy hyperspace params:
|
||||
{ 'adx-value': 44,
|
||||
'rsi-value': 29,
|
||||
'adx-enabled': False,
|
||||
@@ -347,21 +349,15 @@ If you are optimizing ROI, you're result will look as follows and include a ROI
|
||||
|
||||
```
|
||||
Best result:
|
||||
135 trades. Avg profit 0.57%. Total profit 0.03871918 BTC (0.7722Σ%). Avg duration 180.4 mins.
|
||||
with values:
|
||||
|
||||
44/100: 135 trades. Avg profit 0.57%. Total profit 0.03871918 BTC (0.7722Σ%). Avg duration 180.4 mins. Objective: 1.94367
|
||||
|
||||
Buy hyperspace params:
|
||||
{ 'adx-value': 44,
|
||||
'rsi-value': 29,
|
||||
'adx-enabled': false,
|
||||
'adx-enabled': False,
|
||||
'rsi-enabled': True,
|
||||
'trigger': 'bb_lower',
|
||||
'roi_t1': 40,
|
||||
'roi_t2': 57,
|
||||
'roi_t3': 21,
|
||||
'roi_p1': 0.03634636907306948,
|
||||
'roi_p2': 0.055237357937802885,
|
||||
'roi_p3': 0.015163796015548354,
|
||||
'stoploss': -0.37996664668703606
|
||||
}
|
||||
'trigger': 'bb_lower'}
|
||||
ROI table:
|
||||
{ 0: 0.10674752302642071,
|
||||
21: 0.09158372701087236,
|
||||
@@ -372,9 +368,9 @@ ROI table:
|
||||
This would translate to the following ROI table:
|
||||
|
||||
``` python
|
||||
minimal_roi = {
|
||||
minimal_roi = {
|
||||
"118": 0,
|
||||
"78": 0.0363463,
|
||||
"78": 0.0363,
|
||||
"21": 0.0915,
|
||||
"0": 0.106
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user