|
|
|
|
@ -29,19 +29,22 @@
|
|
|
|
|
"import os\n",
|
|
|
|
|
"from pathlib import Path\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"# Change directory\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",
|
|
|
|
|
"project_root = \"somedir/freqtrade\"\n",
|
|
|
|
|
"i=0\n",
|
|
|
|
|
"i = 0\n",
|
|
|
|
|
"try:\n",
|
|
|
|
|
" os.chdir(project_root)\n",
|
|
|
|
|
" assert Path('LICENSE').is_file()\n",
|
|
|
|
|
"except:\n",
|
|
|
|
|
" while i<4 and (not Path('LICENSE').is_file()):\n",
|
|
|
|
|
" os.chdir(Path(Path.cwd(), '../'))\n",
|
|
|
|
|
" i+=1\n",
|
|
|
|
|
" project_root = Path.cwd()\n",
|
|
|
|
|
" if not Path(\"LICENSE\").is_file():\n",
|
|
|
|
|
" i = 0\n",
|
|
|
|
|
" while i < 4 and (not Path(\"LICENSE\").is_file()):\n",
|
|
|
|
|
" os.chdir(Path(Path.cwd(), \"../\"))\n",
|
|
|
|
|
" i += 1\n",
|
|
|
|
|
" project_root = Path.cwd()\n",
|
|
|
|
|
"except FileNotFoundError:\n",
|
|
|
|
|
" print(\"Please define the project root relative to the current directory\")\n",
|
|
|
|
|
"print(Path.cwd())"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
@ -60,6 +63,7 @@
|
|
|
|
|
"source": [
|
|
|
|
|
"from freqtrade.configuration import Configuration\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"# Customize these according to your needs.\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"# Initialize empty configuration object\n",
|
|
|
|
|
@ -87,12 +91,14 @@
|
|
|
|
|
"from freqtrade.data.history import load_pair_history\n",
|
|
|
|
|
"from freqtrade.enums import CandleType\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"candles = load_pair_history(datadir=data_location,\n",
|
|
|
|
|
" timeframe=config[\"timeframe\"],\n",
|
|
|
|
|
" pair=pair,\n",
|
|
|
|
|
" data_format = \"json\", # Make sure to update this to your data\n",
|
|
|
|
|
" candle_type=CandleType.SPOT,\n",
|
|
|
|
|
" )\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"candles = load_pair_history(\n",
|
|
|
|
|
" datadir=data_location,\n",
|
|
|
|
|
" timeframe=config[\"timeframe\"],\n",
|
|
|
|
|
" pair=pair,\n",
|
|
|
|
|
" data_format=\"json\", # Make sure to update this to your data\n",
|
|
|
|
|
" candle_type=CandleType.SPOT,\n",
|
|
|
|
|
")\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"# Confirm success\n",
|
|
|
|
|
"print(f\"Loaded {len(candles)} rows of data for {pair} from {data_location}\")\n",
|
|
|
|
|
@ -114,14 +120,16 @@
|
|
|
|
|
"outputs": [],
|
|
|
|
|
"source": [
|
|
|
|
|
"# Load strategy using values set above\n",
|
|
|
|
|
"from freqtrade.resolvers import StrategyResolver\n",
|
|
|
|
|
"from freqtrade.data.dataprovider import DataProvider\n",
|
|
|
|
|
"from freqtrade.resolvers import StrategyResolver\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"strategy = StrategyResolver.load_strategy(config)\n",
|
|
|
|
|
"strategy.dp = DataProvider(config, None, None)\n",
|
|
|
|
|
"strategy.ft_bot_start()\n",
|
|
|
|
|
"\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()"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
@ -148,7 +156,7 @@
|
|
|
|
|
"source": [
|
|
|
|
|
"# Report results\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()"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
@ -179,10 +187,13 @@
|
|
|
|
|
"source": [
|
|
|
|
|
"from freqtrade.data.btanalysis import load_backtest_data, load_backtest_stats\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"\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 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",
|
|
|
|
|
"stats = load_backtest_stats(backtest_dir)\n",
|
|
|
|
|
"\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",
|
|
|
|
|
"strategy = \"SampleStrategy\"\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",
|
|
|
|
|
"print(stats['strategy'][strategy]['results_per_pair'])\n",
|
|
|
|
|
"print(stats[\"strategy\"][strategy][\"results_per_pair\"])\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",
|
|
|
|
|
"print(stats['strategy'][strategy]['market_change'])\n",
|
|
|
|
|
"print(stats[\"strategy\"][strategy][\"market_change\"])\n",
|
|
|
|
|
"# Maximum drawdown ()\n",
|
|
|
|
|
"print(stats['strategy'][strategy]['max_drawdown'])\n",
|
|
|
|
|
"print(stats[\"strategy\"][strategy][\"max_drawdown\"])\n",
|
|
|
|
|
"# Maximum drawdown start and end\n",
|
|
|
|
|
"print(stats['strategy'][strategy]['drawdown_start'])\n",
|
|
|
|
|
"print(stats['strategy'][strategy]['drawdown_end'])\n",
|
|
|
|
|
"print(stats[\"strategy\"][strategy][\"drawdown_start\"])\n",
|
|
|
|
|
"print(stats[\"strategy\"][strategy][\"drawdown_end\"])\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"\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": [
|
|
|
|
|
"# Plotting equity line (starting with 0 on day 1 and adding daily profit for each backtested day)\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"import pandas as pd\n",
|
|
|
|
|
"import plotly.express as px\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"from freqtrade.configuration import Configuration\n",
|
|
|
|
|
"from freqtrade.data.btanalysis import load_backtest_stats\n",
|
|
|
|
|
"import plotly.express as px\n",
|
|
|
|
|
"import pandas as pd\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"# strategy = 'SampleStrategy'\n",
|
|
|
|
|
"# config = Configuration.from_files([\"user_data/config.json\"])\n",
|
|
|
|
|
"# backtest_dir = config[\"user_data_dir\"] / \"backtest_results\"\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"stats = load_backtest_stats(backtest_dir)\n",
|
|
|
|
|
"strategy_stats = stats['strategy'][strategy]\n",
|
|
|
|
|
"strategy_stats = stats[\"strategy\"][strategy]\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"df = pd.DataFrame(columns=['dates','equity'], data=strategy_stats['daily_profit'])\n",
|
|
|
|
|
"df['equity_daily'] = df['equity'].cumsum()\n",
|
|
|
|
|
"df = pd.DataFrame(columns=[\"dates\", \"equity\"], data=strategy_stats[\"daily_profit\"])\n",
|
|
|
|
|
"df[\"equity_daily\"] = df[\"equity\"].cumsum()\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"fig = px.line(df, x=\"dates\", y=\"equity_daily\")\n",
|
|
|
|
|
"fig.show()\n"
|
|
|
|
|
"fig.show()"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
@ -278,6 +292,7 @@
|
|
|
|
|
"source": [
|
|
|
|
|
"from freqtrade.data.btanalysis import load_trades_from_db\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"# Fetch trades from database\n",
|
|
|
|
|
"trades = load_trades_from_db(\"sqlite:///tradesv3.sqlite\")\n",
|
|
|
|
|
"\n",
|
|
|
|
|
@ -303,8 +318,9 @@
|
|
|
|
|
"source": [
|
|
|
|
|
"from freqtrade.data.btanalysis import analyze_trade_parallelism\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"# Analyze the above\n",
|
|
|
|
|
"parallel_trades = analyze_trade_parallelism(trades, '5m')\n",
|
|
|
|
|
"parallel_trades = analyze_trade_parallelism(trades, \"5m\")\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"parallel_trades.plot()"
|
|
|
|
|
]
|
|
|
|
|
@ -324,22 +340,23 @@
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"outputs": [],
|
|
|
|
|
"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",
|
|
|
|
|
"\n",
|
|
|
|
|
"# Filter trades to one pair\n",
|
|
|
|
|
"trades_red = trades.loc[trades['pair'] == pair]\n",
|
|
|
|
|
"trades_red = trades.loc[trades[\"pair\"] == pair]\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",
|
|
|
|
|
"graph = generate_candlestick_graph(pair=pair,\n",
|
|
|
|
|
" data=data_red,\n",
|
|
|
|
|
" trades=trades_red,\n",
|
|
|
|
|
" indicators1=['sma20', 'ema50', 'ema55'],\n",
|
|
|
|
|
" indicators2=['rsi', 'macd', 'macdsignal', 'macdhist']\n",
|
|
|
|
|
" )\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"\n"
|
|
|
|
|
"graph = generate_candlestick_graph(\n",
|
|
|
|
|
" pair=pair,\n",
|
|
|
|
|
" data=data_red,\n",
|
|
|
|
|
" trades=trades_red,\n",
|
|
|
|
|
" indicators1=[\"sma20\", \"ema50\", \"ema55\"],\n",
|
|
|
|
|
" indicators2=[\"rsi\", \"macd\", \"macdsignal\", \"macdhist\"],\n",
|
|
|
|
|
")"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
@ -352,7 +369,7 @@
|
|
|
|
|
"# graph.show()\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"# Render graph in a separate window\n",
|
|
|
|
|
"graph.show(renderer=\"browser\")\n"
|
|
|
|
|
"graph.show(renderer=\"browser\")"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
@ -370,11 +387,12 @@
|
|
|
|
|
"source": [
|
|
|
|
|
"import plotly.figure_factory as ff\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"\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",
|
|
|
|
|
"fig = ff.create_distplot(hist_data, group_labels, bin_size=0.01)\n",
|
|
|
|
|
"fig.show()\n"
|
|
|
|
|
"fig.show()"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
|