Automatically generate documentation from jupyter notebook
This commit is contained in:
		| @@ -135,78 +135,9 @@ print(f"Loaded len(candles) rows of data for {pair} from {data_location}") | ||||
| candles.head() | ||||
| ``` | ||||
|  | ||||
| ## Strategy debugging example   | ||||
| Further Data analysis documents: | ||||
|  | ||||
| Debugging a strategy can be time-consuming. FreqTrade offers helper functions to visualize raw data. | ||||
|  | ||||
| ### Define variables used in analyses   | ||||
|  | ||||
| You can override strategy settings as demonstrated below. | ||||
|  | ||||
| ```python | ||||
| # Customize these according to your needs. | ||||
|  | ||||
| # Define some constants | ||||
| ticker_interval = "5m" | ||||
| # Name of the strategy class | ||||
| strategy_name = 'SampleStrategy' | ||||
| # Path to user data | ||||
| user_data_dir = 'user_data' | ||||
| # Location of the strategy | ||||
| strategy_location = Path(user_data_dir, 'strategies') | ||||
| # Location of the data | ||||
| data_location = Path(user_data_dir, 'data', 'binance') | ||||
| # Pair to analyze - Only use one pair here | ||||
| pair = "BTC_USDT" | ||||
| ``` | ||||
|  | ||||
| ### Load exchange data | ||||
|  | ||||
| ```python | ||||
| from pathlib import Path | ||||
| from freqtrade.data.history import load_pair_history | ||||
|  | ||||
| # Load data using values set above | ||||
| candles = load_pair_history(datadir=data_location, | ||||
|                             ticker_interval=ticker_interval, | ||||
|                             pair=pair) | ||||
|  | ||||
| # Confirm success | ||||
| print(f"Loaded {len(candles)} rows of data for {pair} from {data_location}") | ||||
| candles.head() | ||||
| ``` | ||||
|  | ||||
| ### Load and run strategy   | ||||
|  | ||||
| * Rerun each time the strategy file is changed | ||||
|  | ||||
| ```python | ||||
| from freqtrade.resolvers import StrategyResolver | ||||
|  | ||||
| # Load strategy using values set above | ||||
| strategy = StrategyResolver({'strategy': strategy_name, | ||||
|                             'user_data_dir': user_data_dir, | ||||
|                             'strategy_path': strategy_location}).strategy | ||||
|  | ||||
| # Generate buy/sell signals using strategy | ||||
| df = strategy.analyze_ticker(candles, {'pair': pair}) | ||||
| ``` | ||||
|  | ||||
| ### Display the trade details | ||||
|  | ||||
| * Note that using `data.tail()` is preferable to `data.head()` as most indicators have some "startup" data at the top of the dataframe. | ||||
| * Some possible problems | ||||
|     * Columns with NaN values at the end of the dataframe | ||||
|     * Columns used in `crossed*()` functions with completely different units | ||||
| * Comparison with full backtest | ||||
|     * having 200 buy signals as output for one pair from `analyze_ticker()` does not necessarily mean that 200 trades will be made during backtesting. | ||||
|     * Assuming you use only one condition such as, `df['rsi'] < 30` as buy condition, this will generate multiple "buy" signals for each pair in sequence (until rsi returns > 29). The bot will only buy on the first of these signals (and also only if a trade-slot ("max_open_trades") is still available), or on one of the middle signals, as soon as a "slot" becomes available.   | ||||
|  | ||||
| ```python | ||||
| # Report results | ||||
| print(f"Generated {df['buy'].sum()} buy signals") | ||||
| data = df.set_index('date', drop=True) | ||||
| data.tail() | ||||
| ``` | ||||
| * [Strategy debugging](strategy_analysis_example.md) | ||||
| * [Plotting](plotting.md) | ||||
|  | ||||
| Feel free to submit an issue or Pull Request enhancing this document if you would like to share ideas on how to best analyze the data. | ||||
|   | ||||
| @@ -149,6 +149,14 @@ print(datetime.utcnow()) | ||||
| The output will show the last entry from the Exchange as well as the current UTC date. | ||||
| If the day shows the same day, then the last candle can be assumed as incomplete and should be dropped (leave the setting `"ohlcv_partial_candle"` from the exchange-class untouched / True). Otherwise, set `"ohlcv_partial_candle"` to `False` to not drop Candles (shown in the example above). | ||||
|  | ||||
| ## Updating example notebooks | ||||
|  | ||||
| To keep the jupyter notebooks aligned with the documentation, the following should be ran after updating a example notebook. | ||||
|  | ||||
| ``` bash | ||||
| jupyter nbconvert --to markdown user_data/notebooks/strategy_analysis_example.ipynb --stdout > docs/strategy_analysis_example.md | ||||
| ``` | ||||
|  | ||||
| ## Creating a release | ||||
|  | ||||
| This part of the documentation is aimed at maintainers, and shows how to create a release. | ||||
|   | ||||
							
								
								
									
										95
									
								
								docs/strategy_analysis_example.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								docs/strategy_analysis_example.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | ||||
| ## Strategy debugging example | ||||
|  | ||||
| Debugging a strategy can be time-consuming. FreqTrade offers helper functions to visualize raw data. | ||||
|  | ||||
| ## Setup | ||||
|  | ||||
| ```python | ||||
| # Change directory | ||||
| # Modify this cell to insure that the output shows the correct path. | ||||
| import os | ||||
| from pathlib import Path | ||||
|  | ||||
| # Define all paths relative to the project root shown in the cell output | ||||
| project_root = "somedir/freqtrade" | ||||
| i=0 | ||||
| try: | ||||
|     os.chdirdir(project_root) | ||||
|     assert Path('LICENSE').is_file() | ||||
| except: | ||||
|     while i<4 and (not Path('LICENSE').is_file()): | ||||
|         os.chdir(Path(Path.cwd(), '../')) | ||||
|         i+=1 | ||||
|     project_root = Path.cwd() | ||||
| print(Path.cwd()) | ||||
| ``` | ||||
|  | ||||
|  | ||||
| ```python | ||||
| # Customize these according to your needs. | ||||
|  | ||||
| # Define some constants | ||||
| ticker_interval = "5m" | ||||
| # Name of the strategy class | ||||
| strategy_name = 'SampleStrategy' | ||||
| # Path to user data | ||||
| user_data_dir = 'user_data' | ||||
| # Location of the strategy | ||||
| strategy_location = Path(user_data_dir, 'strategies') | ||||
| # Location of the data | ||||
| data_location = Path(user_data_dir, 'data', 'binance') | ||||
| # Pair to analyze - Only use one pair here | ||||
| pair = "BTC_USDT" | ||||
| ``` | ||||
|  | ||||
|  | ||||
| ```python | ||||
| # Load data using values set above | ||||
| from pathlib import Path | ||||
| from freqtrade.data.history import load_pair_history | ||||
|  | ||||
| candles = load_pair_history(datadir=data_location, | ||||
|                             ticker_interval=ticker_interval, | ||||
|                             pair=pair) | ||||
|  | ||||
| # Confirm success | ||||
| print("Loaded " + str(len(candles)) + f" rows of data for {pair} from {data_location}") | ||||
| candles.head() | ||||
| ``` | ||||
|  | ||||
| ## Load and run strategy | ||||
| * Rerun each time the strategy file is changed | ||||
|  | ||||
|  | ||||
| ```python | ||||
| # Load strategy using values set above | ||||
| from freqtrade.resolvers import StrategyResolver | ||||
| strategy = StrategyResolver({'strategy': strategy_name, | ||||
|                             'user_data_dir': user_data_dir, | ||||
|                             'strategy_path': strategy_location}).strategy | ||||
|  | ||||
| # Generate buy/sell signals using strategy | ||||
| df = strategy.analyze_ticker(candles, {'pair': pair}) | ||||
| df.tail() | ||||
| ``` | ||||
|  | ||||
| ### Display the trade details | ||||
|  | ||||
| * Note that using `data.head()` would also work, however most indicators have some "startup" data at the top of the dataframe. | ||||
| * Some possible problems | ||||
|     * Columns with NaN values at the end of the dataframe | ||||
|     * Columns used in `crossed*()` functions with completely different units | ||||
| * Comparison with full backtest | ||||
|     * having 200 buy signals as output for one pair from `analyze_ticker()` does not necessarily mean that 200 trades will be made during backtesting. | ||||
|     * Assuming you use only one condition such as, `df['rsi'] < 30` as buy condition, this will generate multiple "buy" signals for each pair in sequence (until rsi returns > 29). The bot will only buy on the first of these signals (and also only if a trade-slot ("max_open_trades") is still available), or on one of the middle signals, as soon as a "slot" becomes available.   | ||||
|  | ||||
|  | ||||
|  | ||||
| ```python | ||||
| # Report results | ||||
| print(f"Generated {df['buy'].sum()} buy signals") | ||||
| data = df.set_index('date', drop=True) | ||||
| data.tail() | ||||
| ``` | ||||
|  | ||||
| Feel free to submit an issue or Pull Request enhancing this document if you would like to share ideas on how to best analyze the data. | ||||
| @@ -15,7 +15,9 @@ nav: | ||||
|     - Hyperopt: hyperopt.md | ||||
|     - Edge positioning: edge.md | ||||
|     - FAQ: faq.md | ||||
|     - Data Analysis: data-analysis.md | ||||
|     - Data Analysis: | ||||
|         - Jupyter Notebooks: data-analysis.md | ||||
|         - Strategy analysis: strategy_analysis_example.md | ||||
|         - Plotting: plotting.md | ||||
|     - SQL Cheatsheet: sql_cheatsheet.md | ||||
|     - Sandbox testing: sandbox-testing.md | ||||
|   | ||||
| @@ -12,3 +12,6 @@ pytest-asyncio==0.10.0 | ||||
| pytest-cov==2.7.1 | ||||
| pytest-mock==1.10.4 | ||||
| pytest-random-order==1.0.4 | ||||
|  | ||||
| # Convert jupyter notebooks to markdown documents | ||||
| nbconvert==5.6.0 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user