Merge pull request #10553 from freqtrade/dependabot/pip/develop/ruff-0.6.1
chore(deps-dev): bump ruff from 0.5.7 to 0.6.1
This commit is contained in:
@@ -31,7 +31,7 @@ repos:
|
|||||||
|
|
||||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||||
# Ruff version.
|
# Ruff version.
|
||||||
rev: 'v0.5.7'
|
rev: 'v0.6.1'
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff
|
- id: ruff
|
||||||
|
|
||||||
|
|||||||
@@ -13,19 +13,22 @@ Please follow the [documentation](https://www.freqtrade.io/en/stable/data-downlo
|
|||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
# Change directory
|
# Change directory
|
||||||
# Modify this cell to insure that the output shows the correct path.
|
# Modify this cell to insure that the output shows the correct path.
|
||||||
# Define all paths relative to the project root shown in the cell output
|
# Define all paths relative to the project root shown in the cell output
|
||||||
project_root = "somedir/freqtrade"
|
project_root = "somedir/freqtrade"
|
||||||
i=0
|
i = 0
|
||||||
try:
|
try:
|
||||||
os.chdir(project_root)
|
os.chdir(project_root)
|
||||||
assert Path('LICENSE').is_file()
|
if not Path("LICENSE").is_file():
|
||||||
except:
|
i = 0
|
||||||
while i<4 and (not Path('LICENSE').is_file()):
|
while i < 4 and (not Path("LICENSE").is_file()):
|
||||||
os.chdir(Path(Path.cwd(), '../'))
|
os.chdir(Path(Path.cwd(), "../"))
|
||||||
i+=1
|
i += 1
|
||||||
project_root = Path.cwd()
|
project_root = Path.cwd()
|
||||||
|
except FileNotFoundError:
|
||||||
|
print("Please define the project root relative to the current directory")
|
||||||
print(Path.cwd())
|
print(Path.cwd())
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -35,6 +38,7 @@ print(Path.cwd())
|
|||||||
```python
|
```python
|
||||||
from freqtrade.configuration import Configuration
|
from freqtrade.configuration import Configuration
|
||||||
|
|
||||||
|
|
||||||
# Customize these according to your needs.
|
# Customize these according to your needs.
|
||||||
|
|
||||||
# Initialize empty configuration object
|
# Initialize empty configuration object
|
||||||
@@ -58,12 +62,14 @@ pair = "BTC/USDT"
|
|||||||
from freqtrade.data.history import load_pair_history
|
from freqtrade.data.history import load_pair_history
|
||||||
from freqtrade.enums import CandleType
|
from freqtrade.enums import CandleType
|
||||||
|
|
||||||
candles = load_pair_history(datadir=data_location,
|
|
||||||
timeframe=config["timeframe"],
|
candles = load_pair_history(
|
||||||
pair=pair,
|
datadir=data_location,
|
||||||
data_format = "json", # Make sure to update this to your data
|
timeframe=config["timeframe"],
|
||||||
candle_type=CandleType.SPOT,
|
pair=pair,
|
||||||
)
|
data_format="json", # Make sure to update this to your data
|
||||||
|
candle_type=CandleType.SPOT,
|
||||||
|
)
|
||||||
|
|
||||||
# Confirm success
|
# Confirm success
|
||||||
print(f"Loaded {len(candles)} rows of data for {pair} from {data_location}")
|
print(f"Loaded {len(candles)} rows of data for {pair} from {data_location}")
|
||||||
@@ -76,14 +82,16 @@ candles.head()
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
# Load strategy using values set above
|
# Load strategy using values set above
|
||||||
from freqtrade.resolvers import StrategyResolver
|
|
||||||
from freqtrade.data.dataprovider import DataProvider
|
from freqtrade.data.dataprovider import DataProvider
|
||||||
|
from freqtrade.resolvers import StrategyResolver
|
||||||
|
|
||||||
|
|
||||||
strategy = StrategyResolver.load_strategy(config)
|
strategy = StrategyResolver.load_strategy(config)
|
||||||
strategy.dp = DataProvider(config, None, None)
|
strategy.dp = DataProvider(config, None, None)
|
||||||
strategy.ft_bot_start()
|
strategy.ft_bot_start()
|
||||||
|
|
||||||
# Generate buy/sell signals using strategy
|
# Generate buy/sell signals using strategy
|
||||||
df = strategy.analyze_ticker(candles, {'pair': pair})
|
df = strategy.analyze_ticker(candles, {"pair": pair})
|
||||||
df.tail()
|
df.tail()
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -102,7 +110,7 @@ df.tail()
|
|||||||
```python
|
```python
|
||||||
# Report results
|
# Report results
|
||||||
print(f"Generated {df['enter_long'].sum()} entry signals")
|
print(f"Generated {df['enter_long'].sum()} entry signals")
|
||||||
data = df.set_index('date', drop=False)
|
data = df.set_index("date", drop=False)
|
||||||
data.tail()
|
data.tail()
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -119,10 +127,13 @@ Analyze a trades dataframe (also used below for plotting)
|
|||||||
```python
|
```python
|
||||||
from freqtrade.data.btanalysis import load_backtest_data, load_backtest_stats
|
from freqtrade.data.btanalysis import load_backtest_data, load_backtest_stats
|
||||||
|
|
||||||
|
|
||||||
# if backtest_dir points to a directory, it'll automatically load the last backtest file.
|
# if backtest_dir points to a directory, it'll automatically load the last backtest file.
|
||||||
backtest_dir = config["user_data_dir"] / "backtest_results"
|
backtest_dir = config["user_data_dir"] / "backtest_results"
|
||||||
# backtest_dir can also point to a specific file
|
# backtest_dir can also point to a specific file
|
||||||
# backtest_dir = config["user_data_dir"] / "backtest_results/backtest-result-2020-07-01_20-04-22.json"
|
# backtest_dir = (
|
||||||
|
# config["user_data_dir"] / "backtest_results/backtest-result-2020-07-01_20-04-22.json"
|
||||||
|
# )
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -131,24 +142,24 @@ backtest_dir = config["user_data_dir"] / "backtest_results"
|
|||||||
# This contains all information used to generate the backtest result.
|
# This contains all information used to generate the backtest result.
|
||||||
stats = load_backtest_stats(backtest_dir)
|
stats = load_backtest_stats(backtest_dir)
|
||||||
|
|
||||||
strategy = 'SampleStrategy'
|
strategy = "SampleStrategy"
|
||||||
# All statistics are available per strategy, so if `--strategy-list` was used during backtest, this will be reflected here as well.
|
# All statistics are available per strategy, so if `--strategy-list` was used during backtest,
|
||||||
|
# this will be reflected here as well.
|
||||||
# Example usages:
|
# Example usages:
|
||||||
print(stats['strategy'][strategy]['results_per_pair'])
|
print(stats["strategy"][strategy]["results_per_pair"])
|
||||||
# Get pairlist used for this backtest
|
# Get pairlist used for this backtest
|
||||||
print(stats['strategy'][strategy]['pairlist'])
|
print(stats["strategy"][strategy]["pairlist"])
|
||||||
# Get market change (average change of all pairs from start to end of the backtest period)
|
# Get market change (average change of all pairs from start to end of the backtest period)
|
||||||
print(stats['strategy'][strategy]['market_change'])
|
print(stats["strategy"][strategy]["market_change"])
|
||||||
# Maximum drawdown ()
|
# Maximum drawdown ()
|
||||||
print(stats['strategy'][strategy]['max_drawdown'])
|
print(stats["strategy"][strategy]["max_drawdown"])
|
||||||
# Maximum drawdown start and end
|
# Maximum drawdown start and end
|
||||||
print(stats['strategy'][strategy]['drawdown_start'])
|
print(stats["strategy"][strategy]["drawdown_start"])
|
||||||
print(stats['strategy'][strategy]['drawdown_end'])
|
print(stats["strategy"][strategy]["drawdown_end"])
|
||||||
|
|
||||||
|
|
||||||
# Get strategy comparison (only relevant if multiple strategies were compared)
|
# Get strategy comparison (only relevant if multiple strategies were compared)
|
||||||
print(stats['strategy_comparison'])
|
print(stats["strategy_comparison"])
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -166,24 +177,25 @@ trades.groupby("pair")["exit_reason"].value_counts()
|
|||||||
```python
|
```python
|
||||||
# Plotting equity line (starting with 0 on day 1 and adding daily profit for each backtested day)
|
# Plotting equity line (starting with 0 on day 1 and adding daily profit for each backtested day)
|
||||||
|
|
||||||
|
import pandas as pd
|
||||||
|
import plotly.express as px
|
||||||
|
|
||||||
from freqtrade.configuration import Configuration
|
from freqtrade.configuration import Configuration
|
||||||
from freqtrade.data.btanalysis import load_backtest_stats
|
from freqtrade.data.btanalysis import load_backtest_stats
|
||||||
import plotly.express as px
|
|
||||||
import pandas as pd
|
|
||||||
|
|
||||||
# strategy = 'SampleStrategy'
|
# strategy = 'SampleStrategy'
|
||||||
# config = Configuration.from_files(["user_data/config.json"])
|
# config = Configuration.from_files(["user_data/config.json"])
|
||||||
# backtest_dir = config["user_data_dir"] / "backtest_results"
|
# backtest_dir = config["user_data_dir"] / "backtest_results"
|
||||||
|
|
||||||
stats = load_backtest_stats(backtest_dir)
|
stats = load_backtest_stats(backtest_dir)
|
||||||
strategy_stats = stats['strategy'][strategy]
|
strategy_stats = stats["strategy"][strategy]
|
||||||
|
|
||||||
df = pd.DataFrame(columns=['dates','equity'], data=strategy_stats['daily_profit'])
|
df = pd.DataFrame(columns=["dates", "equity"], data=strategy_stats["daily_profit"])
|
||||||
df['equity_daily'] = df['equity'].cumsum()
|
df["equity_daily"] = df["equity"].cumsum()
|
||||||
|
|
||||||
fig = px.line(df, x="dates", y="equity_daily")
|
fig = px.line(df, x="dates", y="equity_daily")
|
||||||
fig.show()
|
fig.show()
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Load live trading results into a pandas dataframe
|
### Load live trading results into a pandas dataframe
|
||||||
@@ -194,6 +206,7 @@ In case you did already some trading and want to analyze your performance
|
|||||||
```python
|
```python
|
||||||
from freqtrade.data.btanalysis import load_trades_from_db
|
from freqtrade.data.btanalysis import load_trades_from_db
|
||||||
|
|
||||||
|
|
||||||
# Fetch trades from database
|
# Fetch trades from database
|
||||||
trades = load_trades_from_db("sqlite:///tradesv3.sqlite")
|
trades = load_trades_from_db("sqlite:///tradesv3.sqlite")
|
||||||
|
|
||||||
@@ -210,8 +223,9 @@ This can be useful to find the best `max_open_trades` parameter, when used with
|
|||||||
```python
|
```python
|
||||||
from freqtrade.data.btanalysis import analyze_trade_parallelism
|
from freqtrade.data.btanalysis import analyze_trade_parallelism
|
||||||
|
|
||||||
|
|
||||||
# Analyze the above
|
# Analyze the above
|
||||||
parallel_trades = analyze_trade_parallelism(trades, '5m')
|
parallel_trades = analyze_trade_parallelism(trades, "5m")
|
||||||
|
|
||||||
parallel_trades.plot()
|
parallel_trades.plot()
|
||||||
```
|
```
|
||||||
@@ -222,23 +236,23 @@ Freqtrade offers interactive plotting capabilities based on plotly.
|
|||||||
|
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from freqtrade.plot.plotting import generate_candlestick_graph
|
from freqtrade.plot.plotting import generate_candlestick_graph
|
||||||
|
|
||||||
|
|
||||||
# Limit graph period to keep plotly quick and reactive
|
# Limit graph period to keep plotly quick and reactive
|
||||||
|
|
||||||
# Filter trades to one pair
|
# Filter trades to one pair
|
||||||
trades_red = trades.loc[trades['pair'] == pair]
|
trades_red = trades.loc[trades["pair"] == pair]
|
||||||
|
|
||||||
data_red = data['2019-06-01':'2019-06-10']
|
data_red = data["2019-06-01":"2019-06-10"]
|
||||||
# Generate candlestick graph
|
# Generate candlestick graph
|
||||||
graph = generate_candlestick_graph(pair=pair,
|
graph = generate_candlestick_graph(
|
||||||
data=data_red,
|
pair=pair,
|
||||||
trades=trades_red,
|
data=data_red,
|
||||||
indicators1=['sma20', 'ema50', 'ema55'],
|
trades=trades_red,
|
||||||
indicators2=['rsi', 'macd', 'macdsignal', 'macdhist']
|
indicators1=["sma20", "ema50", "ema55"],
|
||||||
)
|
indicators2=["rsi", "macd", "macdsignal", "macdhist"],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -248,7 +262,6 @@ graph = generate_candlestick_graph(pair=pair,
|
|||||||
|
|
||||||
# Render graph in a separate window
|
# Render graph in a separate window
|
||||||
graph.show(renderer="browser")
|
graph.show(renderer="browser")
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Plot average profit per trade as distribution graph
|
## Plot average profit per trade as distribution graph
|
||||||
@@ -257,12 +270,12 @@ graph.show(renderer="browser")
|
|||||||
```python
|
```python
|
||||||
import plotly.figure_factory as ff
|
import plotly.figure_factory as ff
|
||||||
|
|
||||||
|
|
||||||
hist_data = [trades.profit_ratio]
|
hist_data = [trades.profit_ratio]
|
||||||
group_labels = ['profit_ratio'] # name of the dataset
|
group_labels = ["profit_ratio"] # name of the dataset
|
||||||
|
|
||||||
fig = ff.create_distplot(hist_data, group_labels, bin_size=0.01)
|
fig = ff.create_distplot(hist_data, group_labels, bin_size=0.01)
|
||||||
fig.show()
|
fig.show()
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ async def channel_broadcaster(channel: WebSocketChannel, message_stream: Message
|
|||||||
" consumers."
|
" consumers."
|
||||||
)
|
)
|
||||||
|
|
||||||
await channel.send(message, timeout=True)
|
await channel.send(message, use_timeout=True)
|
||||||
|
|
||||||
|
|
||||||
async def _process_consumer_request(request: Dict[str, Any], channel: WebSocketChannel, rpc: RPC):
|
async def _process_consumer_request(request: Dict[str, Any], channel: WebSocketChannel, rpc: RPC):
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ class WebSocketChannel:
|
|||||||
self._send_high_limit = min(max(self.avg_send_time * 2, 1), 3)
|
self._send_high_limit = min(max(self.avg_send_time * 2, 1), 3)
|
||||||
|
|
||||||
async def send(
|
async def send(
|
||||||
self, message: Union[WSMessageSchemaType, Dict[str, Any]], timeout: bool = False
|
self, message: Union[WSMessageSchemaType, Dict[str, Any]], use_timeout: bool = False
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Send a message on the wrapped websocket. If the sending
|
Send a message on the wrapped websocket. If the sending
|
||||||
@@ -88,7 +88,7 @@ class WebSocketChannel:
|
|||||||
disconnect the connection.
|
disconnect the connection.
|
||||||
|
|
||||||
:param message: The message to send
|
:param message: The message to send
|
||||||
:param timeout: Enforce send high limit, defaults to False
|
:param use_timeout: Enforce send high limit, defaults to False
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
_ = time.time()
|
_ = time.time()
|
||||||
@@ -96,7 +96,8 @@ class WebSocketChannel:
|
|||||||
# a TimeoutError and bubble up to the
|
# a TimeoutError and bubble up to the
|
||||||
# message_endpoint to close the connection
|
# message_endpoint to close the connection
|
||||||
await asyncio.wait_for(
|
await asyncio.wait_for(
|
||||||
self._wrapped_ws.send(message), timeout=self._send_high_limit if timeout else None
|
self._wrapped_ws.send(message),
|
||||||
|
timeout=self._send_high_limit if use_timeout else None,
|
||||||
)
|
)
|
||||||
total_time = time.time() - _
|
total_time = time.time() - _
|
||||||
self._send_times.append(total_time)
|
self._send_times.append(total_time)
|
||||||
|
|||||||
@@ -29,19 +29,22 @@
|
|||||||
"import os\n",
|
"import os\n",
|
||||||
"from pathlib import Path\n",
|
"from pathlib import Path\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
"\n",
|
||||||
"# Change directory\n",
|
"# Change directory\n",
|
||||||
"# Modify this cell to insure that the output shows the correct path.\n",
|
"# Modify this cell to insure that the output shows the correct path.\n",
|
||||||
"# Define all paths relative to the project root shown in the cell output\n",
|
"# Define all paths relative to the project root shown in the cell output\n",
|
||||||
"project_root = \"somedir/freqtrade\"\n",
|
"project_root = \"somedir/freqtrade\"\n",
|
||||||
"i=0\n",
|
"i = 0\n",
|
||||||
"try:\n",
|
"try:\n",
|
||||||
" os.chdir(project_root)\n",
|
" os.chdir(project_root)\n",
|
||||||
" assert Path('LICENSE').is_file()\n",
|
" if not Path(\"LICENSE\").is_file():\n",
|
||||||
"except:\n",
|
" i = 0\n",
|
||||||
" while i<4 and (not Path('LICENSE').is_file()):\n",
|
" while i < 4 and (not Path(\"LICENSE\").is_file()):\n",
|
||||||
" os.chdir(Path(Path.cwd(), '../'))\n",
|
" os.chdir(Path(Path.cwd(), \"../\"))\n",
|
||||||
" i+=1\n",
|
" i += 1\n",
|
||||||
" project_root = Path.cwd()\n",
|
" project_root = Path.cwd()\n",
|
||||||
|
"except FileNotFoundError:\n",
|
||||||
|
" print(\"Please define the project root relative to the current directory\")\n",
|
||||||
"print(Path.cwd())"
|
"print(Path.cwd())"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -60,6 +63,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"from freqtrade.configuration import Configuration\n",
|
"from freqtrade.configuration import Configuration\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
"\n",
|
||||||
"# Customize these according to your needs.\n",
|
"# Customize these according to your needs.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Initialize empty configuration object\n",
|
"# Initialize empty configuration object\n",
|
||||||
@@ -87,12 +91,14 @@
|
|||||||
"from freqtrade.data.history import load_pair_history\n",
|
"from freqtrade.data.history import load_pair_history\n",
|
||||||
"from freqtrade.enums import CandleType\n",
|
"from freqtrade.enums import CandleType\n",
|
||||||
"\n",
|
"\n",
|
||||||
"candles = load_pair_history(datadir=data_location,\n",
|
"\n",
|
||||||
" timeframe=config[\"timeframe\"],\n",
|
"candles = load_pair_history(\n",
|
||||||
" pair=pair,\n",
|
" datadir=data_location,\n",
|
||||||
" data_format = \"json\", # Make sure to update this to your data\n",
|
" timeframe=config[\"timeframe\"],\n",
|
||||||
" candle_type=CandleType.SPOT,\n",
|
" pair=pair,\n",
|
||||||
" )\n",
|
" data_format=\"json\", # Make sure to update this to your data\n",
|
||||||
|
" candle_type=CandleType.SPOT,\n",
|
||||||
|
")\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Confirm success\n",
|
"# Confirm success\n",
|
||||||
"print(f\"Loaded {len(candles)} rows of data for {pair} from {data_location}\")\n",
|
"print(f\"Loaded {len(candles)} rows of data for {pair} from {data_location}\")\n",
|
||||||
@@ -114,14 +120,16 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"# Load strategy using values set above\n",
|
"# Load strategy using values set above\n",
|
||||||
"from freqtrade.resolvers import StrategyResolver\n",
|
|
||||||
"from freqtrade.data.dataprovider import DataProvider\n",
|
"from freqtrade.data.dataprovider import DataProvider\n",
|
||||||
|
"from freqtrade.resolvers import StrategyResolver\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
"strategy = StrategyResolver.load_strategy(config)\n",
|
"strategy = StrategyResolver.load_strategy(config)\n",
|
||||||
"strategy.dp = DataProvider(config, None, None)\n",
|
"strategy.dp = DataProvider(config, None, None)\n",
|
||||||
"strategy.ft_bot_start()\n",
|
"strategy.ft_bot_start()\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Generate buy/sell signals using strategy\n",
|
"# Generate buy/sell signals using strategy\n",
|
||||||
"df = strategy.analyze_ticker(candles, {'pair': pair})\n",
|
"df = strategy.analyze_ticker(candles, {\"pair\": pair})\n",
|
||||||
"df.tail()"
|
"df.tail()"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -148,7 +156,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"# Report results\n",
|
"# Report results\n",
|
||||||
"print(f\"Generated {df['enter_long'].sum()} entry signals\")\n",
|
"print(f\"Generated {df['enter_long'].sum()} entry signals\")\n",
|
||||||
"data = df.set_index('date', drop=False)\n",
|
"data = df.set_index(\"date\", drop=False)\n",
|
||||||
"data.tail()"
|
"data.tail()"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -179,10 +187,13 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"from freqtrade.data.btanalysis import load_backtest_data, load_backtest_stats\n",
|
"from freqtrade.data.btanalysis import load_backtest_data, load_backtest_stats\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
"\n",
|
||||||
"# if backtest_dir points to a directory, it'll automatically load the last backtest file.\n",
|
"# if backtest_dir points to a directory, it'll automatically load the last backtest file.\n",
|
||||||
"backtest_dir = config[\"user_data_dir\"] / \"backtest_results\"\n",
|
"backtest_dir = config[\"user_data_dir\"] / \"backtest_results\"\n",
|
||||||
"# backtest_dir can also point to a specific file\n",
|
"# backtest_dir can also point to a specific file\n",
|
||||||
"# backtest_dir = config[\"user_data_dir\"] / \"backtest_results/backtest-result-2020-07-01_20-04-22.json\""
|
"# backtest_dir = (\n",
|
||||||
|
"# config[\"user_data_dir\"] / \"backtest_results/backtest-result-2020-07-01_20-04-22.json\"\n",
|
||||||
|
"# )"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -195,23 +206,24 @@
|
|||||||
"# This contains all information used to generate the backtest result.\n",
|
"# This contains all information used to generate the backtest result.\n",
|
||||||
"stats = load_backtest_stats(backtest_dir)\n",
|
"stats = load_backtest_stats(backtest_dir)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"strategy = 'SampleStrategy'\n",
|
"strategy = \"SampleStrategy\"\n",
|
||||||
"# All statistics are available per strategy, so if `--strategy-list` was used during backtest, this will be reflected here as well.\n",
|
"# All statistics are available per strategy, so if `--strategy-list` was used during backtest,\n",
|
||||||
|
"# this will be reflected here as well.\n",
|
||||||
"# Example usages:\n",
|
"# Example usages:\n",
|
||||||
"print(stats['strategy'][strategy]['results_per_pair'])\n",
|
"print(stats[\"strategy\"][strategy][\"results_per_pair\"])\n",
|
||||||
"# Get pairlist used for this backtest\n",
|
"# Get pairlist used for this backtest\n",
|
||||||
"print(stats['strategy'][strategy]['pairlist'])\n",
|
"print(stats[\"strategy\"][strategy][\"pairlist\"])\n",
|
||||||
"# Get market change (average change of all pairs from start to end of the backtest period)\n",
|
"# Get market change (average change of all pairs from start to end of the backtest period)\n",
|
||||||
"print(stats['strategy'][strategy]['market_change'])\n",
|
"print(stats[\"strategy\"][strategy][\"market_change\"])\n",
|
||||||
"# Maximum drawdown ()\n",
|
"# Maximum drawdown ()\n",
|
||||||
"print(stats['strategy'][strategy]['max_drawdown'])\n",
|
"print(stats[\"strategy\"][strategy][\"max_drawdown\"])\n",
|
||||||
"# Maximum drawdown start and end\n",
|
"# Maximum drawdown start and end\n",
|
||||||
"print(stats['strategy'][strategy]['drawdown_start'])\n",
|
"print(stats[\"strategy\"][strategy][\"drawdown_start\"])\n",
|
||||||
"print(stats['strategy'][strategy]['drawdown_end'])\n",
|
"print(stats[\"strategy\"][strategy][\"drawdown_end\"])\n",
|
||||||
"\n",
|
"\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Get strategy comparison (only relevant if multiple strategies were compared)\n",
|
"# Get strategy comparison (only relevant if multiple strategies were compared)\n",
|
||||||
"print(stats['strategy_comparison'])\n"
|
"print(stats[\"strategy_comparison\"])"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -242,23 +254,25 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"# Plotting equity line (starting with 0 on day 1 and adding daily profit for each backtested day)\n",
|
"# Plotting equity line (starting with 0 on day 1 and adding daily profit for each backtested day)\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
"import pandas as pd\n",
|
||||||
|
"import plotly.express as px\n",
|
||||||
|
"\n",
|
||||||
"from freqtrade.configuration import Configuration\n",
|
"from freqtrade.configuration import Configuration\n",
|
||||||
"from freqtrade.data.btanalysis import load_backtest_stats\n",
|
"from freqtrade.data.btanalysis import load_backtest_stats\n",
|
||||||
"import plotly.express as px\n",
|
"\n",
|
||||||
"import pandas as pd\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
"# strategy = 'SampleStrategy'\n",
|
"# strategy = 'SampleStrategy'\n",
|
||||||
"# config = Configuration.from_files([\"user_data/config.json\"])\n",
|
"# config = Configuration.from_files([\"user_data/config.json\"])\n",
|
||||||
"# backtest_dir = config[\"user_data_dir\"] / \"backtest_results\"\n",
|
"# backtest_dir = config[\"user_data_dir\"] / \"backtest_results\"\n",
|
||||||
"\n",
|
"\n",
|
||||||
"stats = load_backtest_stats(backtest_dir)\n",
|
"stats = load_backtest_stats(backtest_dir)\n",
|
||||||
"strategy_stats = stats['strategy'][strategy]\n",
|
"strategy_stats = stats[\"strategy\"][strategy]\n",
|
||||||
"\n",
|
"\n",
|
||||||
"df = pd.DataFrame(columns=['dates','equity'], data=strategy_stats['daily_profit'])\n",
|
"df = pd.DataFrame(columns=[\"dates\", \"equity\"], data=strategy_stats[\"daily_profit\"])\n",
|
||||||
"df['equity_daily'] = df['equity'].cumsum()\n",
|
"df[\"equity_daily\"] = df[\"equity\"].cumsum()\n",
|
||||||
"\n",
|
"\n",
|
||||||
"fig = px.line(df, x=\"dates\", y=\"equity_daily\")\n",
|
"fig = px.line(df, x=\"dates\", y=\"equity_daily\")\n",
|
||||||
"fig.show()\n"
|
"fig.show()"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -278,6 +292,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"from freqtrade.data.btanalysis import load_trades_from_db\n",
|
"from freqtrade.data.btanalysis import load_trades_from_db\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
"\n",
|
||||||
"# Fetch trades from database\n",
|
"# Fetch trades from database\n",
|
||||||
"trades = load_trades_from_db(\"sqlite:///tradesv3.sqlite\")\n",
|
"trades = load_trades_from_db(\"sqlite:///tradesv3.sqlite\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
@@ -303,8 +318,9 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"from freqtrade.data.btanalysis import analyze_trade_parallelism\n",
|
"from freqtrade.data.btanalysis import analyze_trade_parallelism\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
"\n",
|
||||||
"# Analyze the above\n",
|
"# Analyze the above\n",
|
||||||
"parallel_trades = analyze_trade_parallelism(trades, '5m')\n",
|
"parallel_trades = analyze_trade_parallelism(trades, \"5m\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
"parallel_trades.plot()"
|
"parallel_trades.plot()"
|
||||||
]
|
]
|
||||||
@@ -324,22 +340,23 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"from freqtrade.plot.plotting import generate_candlestick_graph\n",
|
"from freqtrade.plot.plotting import generate_candlestick_graph\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
"# Limit graph period to keep plotly quick and reactive\n",
|
"# Limit graph period to keep plotly quick and reactive\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Filter trades to one pair\n",
|
"# Filter trades to one pair\n",
|
||||||
"trades_red = trades.loc[trades['pair'] == pair]\n",
|
"trades_red = trades.loc[trades[\"pair\"] == pair]\n",
|
||||||
"\n",
|
"\n",
|
||||||
"data_red = data['2019-06-01':'2019-06-10']\n",
|
"data_red = data[\"2019-06-01\":\"2019-06-10\"]\n",
|
||||||
"# Generate candlestick graph\n",
|
"# Generate candlestick graph\n",
|
||||||
"graph = generate_candlestick_graph(pair=pair,\n",
|
"graph = generate_candlestick_graph(\n",
|
||||||
" data=data_red,\n",
|
" pair=pair,\n",
|
||||||
" trades=trades_red,\n",
|
" data=data_red,\n",
|
||||||
" indicators1=['sma20', 'ema50', 'ema55'],\n",
|
" trades=trades_red,\n",
|
||||||
" indicators2=['rsi', 'macd', 'macdsignal', 'macdhist']\n",
|
" indicators1=[\"sma20\", \"ema50\", \"ema55\"],\n",
|
||||||
" )\n",
|
" indicators2=[\"rsi\", \"macd\", \"macdsignal\", \"macdhist\"],\n",
|
||||||
"\n",
|
")"
|
||||||
"\n"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -352,7 +369,7 @@
|
|||||||
"# graph.show()\n",
|
"# graph.show()\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Render graph in a separate window\n",
|
"# Render graph in a separate window\n",
|
||||||
"graph.show(renderer=\"browser\")\n"
|
"graph.show(renderer=\"browser\")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -370,11 +387,12 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"import plotly.figure_factory as ff\n",
|
"import plotly.figure_factory as ff\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
"\n",
|
||||||
"hist_data = [trades.profit_ratio]\n",
|
"hist_data = [trades.profit_ratio]\n",
|
||||||
"group_labels = ['profit_ratio'] # name of the dataset\n",
|
"group_labels = [\"profit_ratio\"] # name of the dataset\n",
|
||||||
"\n",
|
"\n",
|
||||||
"fig = ff.create_distplot(hist_data, group_labels, bin_size=0.01)\n",
|
"fig = ff.create_distplot(hist_data, group_labels, bin_size=0.01)\n",
|
||||||
"fig.show()\n"
|
"fig.show()"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
-r docs/requirements-docs.txt
|
-r docs/requirements-docs.txt
|
||||||
|
|
||||||
coveralls==4.0.1
|
coveralls==4.0.1
|
||||||
ruff==0.5.7
|
ruff==0.6.1
|
||||||
mypy==1.11.1
|
mypy==1.11.1
|
||||||
pre-commit==3.8.0
|
pre-commit==3.8.0
|
||||||
pytest==8.3.2
|
pytest==8.3.2
|
||||||
|
|||||||
Reference in New Issue
Block a user