mirror of
https://github.com/aljazceru/hummingbot-dashboard.git
synced 2026-01-07 15:34:23 +01:00
Merge pull request #108 from hummingbot/feat/supertrend_multitimeframe_example
Feat/supertrend multitimeframe example
This commit is contained in:
2161
data/candles/candles_binance_perpetual_WLD-USDT_1h.csv
Normal file
2161
data/candles/candles_binance_perpetual_WLD-USDT_1h.csv
Normal file
File diff suppressed because it is too large
Load Diff
43201
data/candles/candles_binance_perpetual_WLD-USDT_3m.csv
Normal file
43201
data/candles/candles_binance_perpetual_WLD-USDT_3m.csv
Normal file
File diff suppressed because it is too large
Load Diff
89
quants_lab/controllers/supertrend_multitimeframe.py
Normal file
89
quants_lab/controllers/supertrend_multitimeframe.py
Normal file
@@ -0,0 +1,89 @@
|
||||
import time
|
||||
from typing import Optional, Callable
|
||||
|
||||
import pandas as pd
|
||||
from pydantic import Field
|
||||
|
||||
from hummingbot.smart_components.executors.position_executor.position_executor import PositionExecutor
|
||||
from hummingbot.smart_components.strategy_frameworks.data_types import OrderLevel
|
||||
from hummingbot.smart_components.strategy_frameworks.directional_trading.directional_trading_controller_base import (
|
||||
DirectionalTradingControllerBase,
|
||||
DirectionalTradingControllerConfigBase,
|
||||
)
|
||||
|
||||
|
||||
class SuperTrendMTConfig(DirectionalTradingControllerConfigBase):
|
||||
strategy_name: str = "supertrend_multitimeframe"
|
||||
length: int = Field(default=20, ge=5, le=200)
|
||||
multiplier: float = Field(default=4.0, ge=2.0, le=7.0)
|
||||
percentage_threshold: float = Field(default=0.01, ge=0.005, le=0.05)
|
||||
|
||||
|
||||
class SuperTrendMT(DirectionalTradingControllerBase):
|
||||
def __init__(self, config: SuperTrendMTConfig):
|
||||
super().__init__(config)
|
||||
self.config = config
|
||||
|
||||
def early_stop_condition(self, executor: PositionExecutor, order_level: OrderLevel) -> bool:
|
||||
# If an executor has an active position, should we close it based on a condition. This feature is not available
|
||||
# for the backtesting yet
|
||||
return False
|
||||
|
||||
def cooldown_condition(self, executor: PositionExecutor, order_level: OrderLevel) -> bool:
|
||||
# After finishing an order, the executor will be in cooldown for a certain amount of time.
|
||||
# This prevents the executor from creating a new order immediately after finishing one and execute a lot
|
||||
# of orders in a short period of time from the same side.
|
||||
if executor.close_timestamp and executor.close_timestamp + order_level.cooldown_time > time.time():
|
||||
return True
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def get_minutes_from_interval(interval: str):
|
||||
unit = interval[-1]
|
||||
quantity = int(interval[:-1])
|
||||
conversion = {"m": 1, "h": 60, "d": 1440}
|
||||
return conversion[unit] * quantity
|
||||
|
||||
def ordered_market_data_dfs(self):
|
||||
market_data = {f"{candles.name}_{candles.interval}": candles.candles_df for candles in self.candles}
|
||||
return sorted(market_data.items(), key=lambda x: self.get_minutes_from_interval(x[0].split("_")[-1]))
|
||||
|
||||
def get_dataframes_merged_by_min_resolution(self, add_indicators_func: Optional[Callable] = None):
|
||||
ordered_data = self.ordered_market_data_dfs()
|
||||
if add_indicators_func:
|
||||
processed_data = []
|
||||
for interval, df in ordered_data:
|
||||
processed_df = add_indicators_func(df)
|
||||
processed_data.append((interval, processed_df))
|
||||
else:
|
||||
processed_data = ordered_data
|
||||
interval_suffixes = {key: f'_{key.split("_")[-1]}' for key, _ in processed_data}
|
||||
merged_df = None
|
||||
for interval, df in processed_data:
|
||||
if merged_df is None:
|
||||
merged_df = df.copy()
|
||||
else:
|
||||
merged_df = pd.merge_asof(merged_df, df.add_suffix(interval_suffixes[interval]),
|
||||
left_on=f"timestamp", right_on=f"timestamp{interval_suffixes[interval]}",
|
||||
direction="backward")
|
||||
return merged_df
|
||||
|
||||
def add_indicators(self, df):
|
||||
df.ta.supertrend(length=self.config.length, multiplier=self.config.multiplier, append=True)
|
||||
return df
|
||||
|
||||
def get_processed_data(self) -> pd.DataFrame:
|
||||
df = self.get_dataframes_merged_by_min_resolution(self.add_indicators)
|
||||
df["percentage_distance"] = abs(df["close"] - df[f"SUPERT_{self.config.length}_{self.config.multiplier}"]) / df["close"]
|
||||
|
||||
columns_with_supertrend = [col for col in df.columns if "SUPERTd" in col]
|
||||
|
||||
# Conditions for long and short signals
|
||||
long_condition = df[columns_with_supertrend].apply(lambda x: all(item == 1 for item in x), axis=1)
|
||||
short_condition = df[columns_with_supertrend].apply(lambda x: all(item == -1 for item in x), axis=1)
|
||||
|
||||
# Choose side
|
||||
df['signal'] = 0
|
||||
df.loc[long_condition, 'signal'] = 1
|
||||
df.loc[short_condition, 'signal'] = -1
|
||||
return df
|
||||
10911
quants_lab/research_notebooks/01_analyze_optimization_results.ipynb
Normal file
10911
quants_lab/research_notebooks/01_analyze_optimization_results.ipynb
Normal file
File diff suppressed because one or more lines are too long
@@ -1,215 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"# RESEARCH NOTEBOOK --> SUPERTREND"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pandas as pd\n",
|
||||
"import pandas_ta as ta # noqa: F401\n",
|
||||
"\n",
|
||||
"candles = pd.read_csv(\n",
|
||||
" \"/Users/dardonacci/Documents/work/dashboard/data/candles/candles_binance_perpetual_WLD-USDT_3m.csv\")"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"candles.head()"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"super_trend_lenght = 20\n",
|
||||
"super_trend_multiplier = 3\n",
|
||||
"candles.ta.supertrend(length=super_trend_lenght, multiplier=super_trend_multiplier)"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"candles.ta.supertrend(length=super_trend_lenght, multiplier=super_trend_multiplier, append=True)"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"candles[\"date\"] = pd.to_datetime(candles[\"timestamp\"], unit='ms')\n",
|
||||
"candles.head()"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import plotly.graph_objects as go\n",
|
||||
"\n",
|
||||
"# We are going to use just a subset to see the graph better\n",
|
||||
"candles = candles.tail(800)\n",
|
||||
"\n",
|
||||
"# Create a candlestick chart\n",
|
||||
"fig = go.Figure(data=[go.Candlestick(\n",
|
||||
" x=candles['date'],\n",
|
||||
" open=candles['open'],\n",
|
||||
" high=candles['high'],\n",
|
||||
" low=candles['low'],\n",
|
||||
" close=candles['close'])\n",
|
||||
"])\n",
|
||||
"fig.show()"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"super_trend_long = candles[candles[\"SUPERTd_20_3.0\"] == 1]\n",
|
||||
"super_trend_short = candles[candles[\"SUPERTd_20_3.0\"] == -1]\n",
|
||||
"# Add the SuperTrend line\n",
|
||||
"fig.add_trace(go.Scatter(x=super_trend_long['date'], y=super_trend_long['SUPERT_20_3.0'],\n",
|
||||
" mode='markers',\n",
|
||||
" name='SuperTrend Long',\n",
|
||||
" line=dict(color=\"green\"),\n",
|
||||
" ))\n",
|
||||
"# Add the SuperTrend line\n",
|
||||
"fig.add_trace(go.Scatter(x=super_trend_short['date'], y=super_trend_short['SUPERT_20_3.0'],\n",
|
||||
" mode='markers',\n",
|
||||
" name='SuperTrend Short',\n",
|
||||
" line=dict(color=\"red\")))"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"percentage_threshold = 0.01 # This is an example threshold value\n",
|
||||
"\n",
|
||||
"candles[\"percentage_distance\"] = abs(candles[\"close\"] - candles[\"SUPERT_20_3.0\"]) / candles[\"close\"]\n",
|
||||
"\n",
|
||||
"candles[\"signal\"] = 0\n",
|
||||
"long_condition = (candles[\"SUPERTd_20_3.0\"] == 1) & (candles[\"percentage_distance\"] < percentage_threshold)\n",
|
||||
"short_condition = (candles[\"SUPERTd_20_3.0\"] == -1) & (candles[\"percentage_distance\"] < percentage_threshold)\n",
|
||||
"\n",
|
||||
"candles.loc[long_condition, \"signal\"] = 1\n",
|
||||
"candles.loc[short_condition, \"signal\"] = -1"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from plotly.subplots import make_subplots\n",
|
||||
"\n",
|
||||
"fig = make_subplots(rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.02, subplot_titles=('OHLC', 'Signal'),\n",
|
||||
" row_heights=[0.7, 0.3])\n",
|
||||
"\n",
|
||||
"# Add candlestick\n",
|
||||
"fig.add_trace(go.Candlestick(\n",
|
||||
" x=candles['date'],\n",
|
||||
" open=candles['open'],\n",
|
||||
" high=candles['high'],\n",
|
||||
" low=candles['low'],\n",
|
||||
" close=candles['close']),\n",
|
||||
" row=1, col=1)\n",
|
||||
"\n",
|
||||
"# Add the SuperTrend line\n",
|
||||
"fig.add_trace(go.Scatter(x=super_trend_long['date'], y=super_trend_long['SUPERT_20_3.0'],\n",
|
||||
" mode='markers',\n",
|
||||
" name='SuperTrend Long',\n",
|
||||
" line=dict(color=\"green\")),\n",
|
||||
" row=1, col=1)\n",
|
||||
"# Add the SuperTrend line\n",
|
||||
"fig.add_trace(go.Scatter(x=super_trend_short['date'], y=super_trend_short['SUPERT_20_3.0'],\n",
|
||||
" mode='markers',\n",
|
||||
" name='SuperTrend Short',\n",
|
||||
" line=dict(color=\"red\")),\n",
|
||||
" row=1, col=1)\n",
|
||||
"\n",
|
||||
"# Add the signal line\n",
|
||||
"fig.add_trace(go.Scatter(x=candles['date'], y=candles['signal'],\n",
|
||||
" mode='lines',\n",
|
||||
" name='SuperTrend',\n",
|
||||
" line=dict(color=\"white\")),\n",
|
||||
" row=2, col=1)\n",
|
||||
"\n",
|
||||
"# Update x-axis and grid properties\n",
|
||||
"fig.update_xaxes(showline=True, linewidth=2, linecolor='grey', gridcolor='lightgrey')\n",
|
||||
"fig.update_yaxes(showline=True, linewidth=2, linecolor='grey', gridcolor='lightgrey')\n",
|
||||
"\n",
|
||||
"# Update layout to adjust the size and title\n",
|
||||
"fig.update_layout(height=800, title_text=\"OHLC Chart with SuperTrend and Signals\",\n",
|
||||
" yaxis_title='Price',\n",
|
||||
" xaxis_rangeslider_visible=False)\n"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 2
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython2",
|
||||
"version": "2.7.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
}
|
||||
@@ -1,444 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"root_path = os.path.abspath(os.path.join(os.getcwd(), '../..'))\n",
|
||||
"sys.path.append(root_path)"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"\n",
|
||||
"from utils.optuna_database_manager import OptunaDBManager\n",
|
||||
"\n",
|
||||
"db_root_path = \"../../data/backtesting/\"\n",
|
||||
"db_name = \"backtesting_report.db\"\n",
|
||||
"\n",
|
||||
"optuna_db_manager = OptunaDBManager(db_name=db_name,\n",
|
||||
" db_root_path=db_root_path)"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"optuna_db_manager.studies"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"study_name = \"super_trend_optimization_1\"\n",
|
||||
"df = optuna_db_manager.merged_df[optuna_db_manager.merged_df[\"study_name\"] == study_name]"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### Bar Chart of Average Trading Time\n",
|
||||
"This bar chart compares the average trading time across trials. It helps to quickly identify trials with unusually long or short trading times.\n"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import plotly.express as px\n",
|
||||
"\n",
|
||||
"fig = px.bar(df, x='trial_id', y='avg_trading_time_in_hours', title='Average Trading Time per Trial')\n",
|
||||
"fig.show()"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### Scatter Plot of Accuracy vs. Average Trading Time\n",
|
||||
"This scatter plot shows the relationship between the accuracy and the average trading time of each trial. It can help to identify if there is any correlation between these two metrics.\n"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"fig = px.scatter(df, x='avg_trading_time_in_hours', y='accuracy', title='Accuracy vs. Average Trading Time')\n",
|
||||
"fig.show()\n"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### Histogram of Total Positions\n",
|
||||
"The histogram represents the distribution of total positions across all trials. This visualization is useful for understanding the general spread and most common values of positions.\n"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"fig = px.histogram(df, x='total_positions', title='Distribution of Total Positions')\n",
|
||||
"fig.show()"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### Pie Chart of Win Signals\n",
|
||||
"This pie chart shows the proportion of win signals in each trial, providing a visual representation of the success rate distribution across trials.\n"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"fig = px.pie(df, names='trial_id', values='win_signals', title='Proportion of Win Signals per Trial')\n",
|
||||
"fig.show()\n"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### Box Plot for Trial Value\n",
|
||||
"A box plot for trial values to identify the range, median, and any potential outliers in the trial values.\n"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"fig = px.box(df, y='value', title='Box Plot of Trial PNL')\n",
|
||||
"fig.show()"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### Heatmap for Correlation Analysis\n",
|
||||
"This heatmap illustrates the correlation between various numerical variables such as accuracy, average trading time, total positions, win signals, and value.\n"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import plotly.express as px\n",
|
||||
"\n",
|
||||
"# Calculate the correlation matrix\n",
|
||||
"correlation_matrix = df[['accuracy', 'avg_trading_time_in_hours', 'total_positions', 'win_signals', 'value']].corr()\n",
|
||||
"\n",
|
||||
"# Generate the heatmap\n",
|
||||
"fig = px.imshow(correlation_matrix,\n",
|
||||
" x=correlation_matrix.columns,\n",
|
||||
" y=correlation_matrix.columns,\n",
|
||||
" title='Correlation Heatmap',\n",
|
||||
" labels=dict(x=\"Variable\", y=\"Variable\", color=\"Correlation\"),\n",
|
||||
" color_continuous_scale='RdBu')\n",
|
||||
"\n",
|
||||
"fig.show()\n",
|
||||
"\n"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### Stacked Bar Chart for Win Signals vs Total Positions\n",
|
||||
"A stacked bar chart displaying the ratio of win signals to total positions for each trial. This helps in visualizing the efficiency and effectiveness of each trial.\n"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df['loss_signals'] = df['total_positions'] - df['win_signals']\n",
|
||||
"fig = px.bar(df, x='trial_id', y=['win_signals', 'loss_signals'], title='Win vs Loss Signals per Trial', labels={'value':'Number of Signals'}, hover_data=['total_positions'])\n",
|
||||
"fig.show()\n"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### Scatter Plots Against PNL\n",
|
||||
"These scatter plots show how various metrics behave in relation to the PNL (Profit and Loss). This analysis can help in understanding which factors have a stronger relationship with financial outcomes.\n"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Scatter Plot for Accuracy vs PNL\n",
|
||||
"fig_accuracy_pnl = px.scatter(df, x='accuracy', y='value', title='Accuracy vs PNL')\n",
|
||||
"fig_accuracy_pnl.show()\n",
|
||||
"\n",
|
||||
"# Scatter Plot for Average Trading Time vs PNL\n",
|
||||
"fig_tradingtime_pnl = px.scatter(df, x='avg_trading_time_in_hours', y='value', title='Average Trading Time vs PNL')\n",
|
||||
"fig_tradingtime_pnl.show()\n",
|
||||
"\n",
|
||||
"# Scatter Plot for Total Positions vs PNL\n",
|
||||
"fig_positions_pnl = px.scatter(df, x='total_positions', y='value', title='Total Positions vs PNL')\n",
|
||||
"fig_positions_pnl.show()\n",
|
||||
"\n",
|
||||
"# Scatter Plot for Win Signals vs PNL\n",
|
||||
"fig_winsignals_pnl = px.scatter(df, x='win_signals', y='value', title='Win Signals vs PNL')\n",
|
||||
"fig_winsignals_pnl.show()\n"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"### Scatter Matrix of All Variables\n",
|
||||
"A scatter matrix allows us to see both the distribution of single variables and the relationships between two variables. The diagonal shows histograms for each variable, and the scatter plots show correlations between them.\n"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import plotly.express as px\n",
|
||||
"\n",
|
||||
"# Selecting columns for scatter matrix\n",
|
||||
"selected_columns = ['accuracy', 'avg_trading_time_in_hours', 'total_positions', 'win_signals', 'value']\n",
|
||||
"\n",
|
||||
"# Creating scatter matrix\n",
|
||||
"fig_matrix = px.scatter_matrix(df[selected_columns], dimensions=selected_columns, title='Scatter Matrix of Variables', height=800)\n",
|
||||
"fig_matrix.show()\n"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import json\n",
|
||||
"from hummingbot.core.data_type.common import PositionMode\n",
|
||||
"from hummingbot.connector.connector_base import TradeType, OrderType\n",
|
||||
"from hummingbot.smart_components.utils.config_encoder_decoder import ConfigEncoderDecoder\n",
|
||||
"\n",
|
||||
"trial_to_analyze = 36\n",
|
||||
"\n",
|
||||
"trial = df[df[\"trial_id\"] == trial_to_analyze]"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"trial"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Transform trial config in a dictionary\n",
|
||||
"encoder_decoder = ConfigEncoderDecoder(TradeType, OrderType, PositionMode)\n",
|
||||
"trial_config = encoder_decoder.decode(json.loads(trial[\"config\"].item()))\n",
|
||||
"trial_config"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from quants_lab.controllers.supertrend import SuperTrend, SuperTrendConfig\n",
|
||||
"\n",
|
||||
"# In this case we are using the supertrend controller but we can also access to the controller by using the method load_controllers\n",
|
||||
"config = SuperTrendConfig(**trial_config)\n",
|
||||
"controller = SuperTrend(config)"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from quants_lab.strategy.strategy_analysis import StrategyAnalysis\n",
|
||||
"from hummingbot.smart_components.strategy_frameworks.directional_trading import DirectionalTradingBacktestingEngine\n",
|
||||
"\n",
|
||||
"# Backtest configuration\n",
|
||||
"trade_cost = 0.0006\n",
|
||||
"initial_portfolio_usd = 1000\n",
|
||||
"start = \"2023-01-01\"\n",
|
||||
"end = \"2024-01-02\"\n",
|
||||
"\n",
|
||||
"# Load the data\n",
|
||||
"engine = DirectionalTradingBacktestingEngine(controller=controller)\n",
|
||||
"engine.load_controller_data(\"../../data/candles\")\n",
|
||||
"backtesting_results = engine.run_backtesting(initial_portfolio_usd=initial_portfolio_usd,\n",
|
||||
" trade_cost=trade_cost,\n",
|
||||
" start=start, end=end)\n",
|
||||
"strategy_analysis = StrategyAnalysis(\n",
|
||||
" positions=backtesting_results[\"executors_df\"],\n",
|
||||
" candles_df=backtesting_results[\"processed_data\"],\n",
|
||||
")"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"strategy_analysis.create_base_figure(volume=False, positions=False, trade_pnl=True)\n",
|
||||
"strategy_analysis.figure()"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"strategy_analysis.pnl_over_time()"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 2
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython2",
|
||||
"version": "2.7.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -14,7 +14,7 @@
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"root_path = os.path.abspath(os.path.join(os.getcwd(), '../..'))\n",
|
||||
"root_path = os.path.abspath(os.path.join(os.getcwd(), '../../..'))\n",
|
||||
"sys.path.append(root_path)"
|
||||
]
|
||||
},
|
||||
@@ -150,7 +150,7 @@
|
||||
"\n",
|
||||
"# Creating the backtesting engine and loading the historical data\n",
|
||||
"engine = DirectionalTradingBacktestingEngine(controller=controller)\n",
|
||||
"engine.load_controller_data(\"../../data/candles\")"
|
||||
"engine.load_controller_data(\"../../../data/candles\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -8,7 +8,7 @@
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"root_path = os.path.abspath(os.path.join(os.getcwd(), '../..'))\n",
|
||||
"root_path = os.path.abspath(os.path.join(os.getcwd(), '../../..'))\n",
|
||||
"sys.path.append(root_path)"
|
||||
],
|
||||
"metadata": {
|
||||
@@ -93,7 +93,7 @@
|
||||
" )\n",
|
||||
" controller = SuperTrend(config=config)\n",
|
||||
" engine = DirectionalTradingBacktestingEngine(controller=controller)\n",
|
||||
" engine.load_controller_data(\"../../data/candles\")\n",
|
||||
" engine.load_controller_data(\"../../../data/candles\")\n",
|
||||
" backtesting_results = engine.run_backtesting(\n",
|
||||
" initial_portfolio_usd=initial_portfolio_usd,\n",
|
||||
" trade_cost=trade_cost,\n",
|
||||
@@ -133,7 +133,7 @@
|
||||
"\n",
|
||||
"# Now let's configure the parameters for the optimization\n",
|
||||
"study_name = \"super_trend_optimization_1\"\n",
|
||||
"storage= \"sqlite:///../../data/backtesting/backtesting_report.db\"\n",
|
||||
"storage= \"sqlite:///../../../data/backtesting/backtesting_report.db\"\n",
|
||||
"\n",
|
||||
"study = optuna.create_study(direction=\"maximize\", study_name=study_name,\n",
|
||||
" storage=storage,\n",
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,241 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"root_path = os.path.abspath(os.path.join(os.getcwd(), '../../..'))\n",
|
||||
"sys.path.append(root_path)"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import traceback\n",
|
||||
"from decimal import Decimal\n",
|
||||
"import pandas_ta as ta # noqa: F401\n",
|
||||
"\n",
|
||||
"from hummingbot.core.data_type.common import PositionMode, TradeType, OrderType\n",
|
||||
"from hummingbot.data_feed.candles_feed.candles_factory import CandlesConfig\n",
|
||||
"from hummingbot.smart_components.strategy_frameworks.data_types import TripleBarrierConf, OrderLevel\n",
|
||||
"from hummingbot.smart_components.strategy_frameworks.directional_trading import DirectionalTradingBacktestingEngine\n",
|
||||
"from hummingbot.smart_components.utils.config_encoder_decoder import ConfigEncoderDecoder\n",
|
||||
"from optuna import TrialPruned\n",
|
||||
"from hummingbot.smart_components.utils.order_level_builder import OrderLevelBuilder\n",
|
||||
"\n",
|
||||
"from quants_lab.controllers.supertrend_multitimeframe import SuperTrendMT, SuperTrendMTConfig\n",
|
||||
"\n",
|
||||
"# To run an optimization with optuna we need to define the objective function that will be executed for each trial\n",
|
||||
"\n",
|
||||
"def objective(trial):\n",
|
||||
" try:\n",
|
||||
" # Market configuration\n",
|
||||
" exchange = \"binance_perpetual\"\n",
|
||||
" trading_pair = \"WLD-USDT\"\n",
|
||||
" intervals = [\"3m\", \"1h\"]\n",
|
||||
"\n",
|
||||
" # Account configuration\n",
|
||||
" initial_portfolio_usd = 1000\n",
|
||||
" order_amount = Decimal(\"25\")\n",
|
||||
" n_levels = 1\n",
|
||||
" leverage = 20\n",
|
||||
" trade_cost = 0.0006\n",
|
||||
"\n",
|
||||
" # Backtest period\n",
|
||||
" start = \"2023-01-01\"\n",
|
||||
" end = \"2024-01-02\"\n",
|
||||
"\n",
|
||||
" # Triple barrier configuration\n",
|
||||
" stop_loss = trial.suggest_float('stop_loss', 0.01, 0.02, step=0.01)\n",
|
||||
" take_profit = trial.suggest_float('take_profit', 0.01, 0.04, step=0.01)\n",
|
||||
" time_limit = 60 * 60 * 12 # 12 hours\n",
|
||||
" trailing_stop_activation_price_delta = Decimal(\"0.008\")\n",
|
||||
" trailing_stop_trailing_delta = Decimal(\"0.004\")\n",
|
||||
"\n",
|
||||
" length = trial.suggest_int('length', 20, 200, step=20)\n",
|
||||
" multiplier = trial.suggest_float('multiplier', 2.0, 6.0, step=1.0)\n",
|
||||
" percentage_threshold = trial.suggest_float('percentage_threshold', 0.01, 0.03, step=0.01)\n",
|
||||
"\n",
|
||||
" # Building the order levels\n",
|
||||
" order_level_builder = OrderLevelBuilder(n_levels=n_levels)\n",
|
||||
" order_levels = order_level_builder.build_order_levels(\n",
|
||||
" amounts=order_amount,\n",
|
||||
" spreads=Decimal(\"0\"),\n",
|
||||
" triple_barrier_confs=TripleBarrierConf(\n",
|
||||
" stop_loss=stop_loss, take_profit=take_profit, time_limit=time_limit,\n",
|
||||
" trailing_stop_activation_price_delta=trailing_stop_activation_price_delta,\n",
|
||||
" trailing_stop_trailing_delta=trailing_stop_trailing_delta),\n",
|
||||
" )\n",
|
||||
" config = SuperTrendMTConfig(\n",
|
||||
" exchange=exchange,\n",
|
||||
" trading_pair=trading_pair,\n",
|
||||
" strategy_name='supertrend_multitimeframe',\n",
|
||||
" candles_config=[\n",
|
||||
" CandlesConfig(connector=exchange, trading_pair=trading_pair,\n",
|
||||
" interval=intervals[0], max_records=sys.maxsize),\n",
|
||||
" CandlesConfig(connector=exchange, trading_pair=trading_pair,\n",
|
||||
" interval=intervals[1], max_records=sys.maxsize),\n",
|
||||
" ],\n",
|
||||
" order_levels=order_levels,\n",
|
||||
" leverage=leverage,\n",
|
||||
" position_mode=PositionMode.HEDGE,\n",
|
||||
" length=length,\n",
|
||||
" multiplier=multiplier,\n",
|
||||
" percentage_threshold=percentage_threshold,\n",
|
||||
"\n",
|
||||
" )\n",
|
||||
" controller = SuperTrendMT(config=config)\n",
|
||||
" engine = DirectionalTradingBacktestingEngine(controller=controller)\n",
|
||||
" engine.load_controller_data(\"../../../data/candles\")\n",
|
||||
" backtesting_results = engine.run_backtesting(\n",
|
||||
" initial_portfolio_usd=initial_portfolio_usd,\n",
|
||||
" trade_cost=trade_cost,\n",
|
||||
" start=start, end=end)\n",
|
||||
"\n",
|
||||
" strategy_analysis = backtesting_results[\"results\"]\n",
|
||||
" encoder_decoder = ConfigEncoderDecoder(TradeType, OrderType, PositionMode)\n",
|
||||
"\n",
|
||||
" trial.set_user_attr(\"net_pnl_quote\", strategy_analysis[\"net_pnl_quote\"])\n",
|
||||
" trial.set_user_attr(\"net_pnl_pct\", strategy_analysis[\"net_pnl\"])\n",
|
||||
" trial.set_user_attr(\"max_drawdown_usd\", strategy_analysis[\"max_drawdown_usd\"])\n",
|
||||
" trial.set_user_attr(\"max_drawdown_pct\", strategy_analysis[\"max_drawdown_pct\"])\n",
|
||||
" trial.set_user_attr(\"sharpe_ratio\", strategy_analysis[\"sharpe_ratio\"])\n",
|
||||
" trial.set_user_attr(\"accuracy\", strategy_analysis[\"accuracy\"])\n",
|
||||
" trial.set_user_attr(\"total_positions\", strategy_analysis[\"total_positions\"])\n",
|
||||
" trial.set_user_attr(\"profit_factor\", strategy_analysis[\"profit_factor\"])\n",
|
||||
" trial.set_user_attr(\"duration_in_hours\", strategy_analysis[\"duration_minutes\"] / 60)\n",
|
||||
" trial.set_user_attr(\"avg_trading_time_in_hours\", strategy_analysis[\"avg_trading_time_minutes\"] / 60)\n",
|
||||
" trial.set_user_attr(\"win_signals\", strategy_analysis[\"win_signals\"])\n",
|
||||
" trial.set_user_attr(\"loss_signals\", strategy_analysis[\"loss_signals\"])\n",
|
||||
" trial.set_user_attr(\"config\", encoder_decoder.encode(config.dict()))\n",
|
||||
" return strategy_analysis[\"net_pnl\"]\n",
|
||||
" except Exception as e:\n",
|
||||
" traceback.print_exc()\n",
|
||||
" raise TrialPruned()\n"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2023-12-12T01:02:29.309413Z",
|
||||
"start_time": "2023-12-12T01:02:29.300687Z"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"[I 2023-12-11 22:02:37,318] A new study created in RDB with name: super_trend_optimization_mt\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import optuna\n",
|
||||
"\n",
|
||||
"# Now let's configure the parameters for the optimization\n",
|
||||
"study_name = \"super_trend_optimization_mt\"\n",
|
||||
"storage= \"sqlite:///../../../data/backtesting/backtesting_report.db\"\n",
|
||||
"\n",
|
||||
"study = optuna.create_study(direction=\"maximize\", study_name=study_name,\n",
|
||||
" storage=storage,\n",
|
||||
" load_if_exists=True # If the study already exists, we load it\n",
|
||||
" )"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2023-12-12T01:02:37.322291Z",
|
||||
"start_time": "2023-12-12T01:02:37.245002Z"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"[I 2023-12-11 22:03:00,563] Trial 0 finished with value: -0.35098199626293336 and parameters: {'stop_loss': 0.02, 'take_profit': 0.02, 'length': 40, 'multiplier': 6.0, 'percentage_threshold': 0.03}. Best is trial 0 with value: -0.35098199626293336.\n",
|
||||
"[I 2023-12-11 22:03:17,061] Trial 1 finished with value: 0.12488305093272298 and parameters: {'stop_loss': 0.02, 'take_profit': 0.03, 'length': 140, 'multiplier': 3.0, 'percentage_threshold': 0.01}. Best is trial 1 with value: 0.12488305093272298.\n",
|
||||
"[I 2023-12-11 22:03:33,423] Trial 2 finished with value: -0.4536291130718499 and parameters: {'stop_loss': 0.01, 'take_profit': 0.02, 'length': 120, 'multiplier': 5.0, 'percentage_threshold': 0.02}. Best is trial 1 with value: 0.12488305093272298.\n",
|
||||
"[I 2023-12-11 22:03:49,953] Trial 3 finished with value: -0.05073410868582624 and parameters: {'stop_loss': 0.01, 'take_profit': 0.03, 'length': 100, 'multiplier': 4.0, 'percentage_threshold': 0.01}. Best is trial 1 with value: 0.12488305093272298.\n",
|
||||
"[I 2023-12-11 22:04:07,164] Trial 4 finished with value: 0.1619153622180836 and parameters: {'stop_loss': 0.02, 'take_profit': 0.03, 'length': 200, 'multiplier': 6.0, 'percentage_threshold': 0.01}. Best is trial 4 with value: 0.1619153622180836.\n",
|
||||
"[I 2023-12-11 22:04:24,073] Trial 5 finished with value: -0.18547605063707406 and parameters: {'stop_loss': 0.02, 'take_profit': 0.01, 'length': 40, 'multiplier': 3.0, 'percentage_threshold': 0.02}. Best is trial 4 with value: 0.1619153622180836.\n",
|
||||
"[I 2023-12-11 22:04:41,109] Trial 6 finished with value: -0.3164755434895661 and parameters: {'stop_loss': 0.02, 'take_profit': 0.01, 'length': 180, 'multiplier': 6.0, 'percentage_threshold': 0.01}. Best is trial 4 with value: 0.1619153622180836.\n",
|
||||
"[I 2023-12-11 22:04:57,609] Trial 7 finished with value: -0.1038527397065552 and parameters: {'stop_loss': 0.01, 'take_profit': 0.02, 'length': 140, 'multiplier': 4.0, 'percentage_threshold': 0.03}. Best is trial 4 with value: 0.1619153622180836.\n",
|
||||
"[I 2023-12-11 22:05:15,271] Trial 8 finished with value: 0.7404879450347805 and parameters: {'stop_loss': 0.01, 'take_profit': 0.01, 'length': 40, 'multiplier': 2.0, 'percentage_threshold': 0.01}. Best is trial 8 with value: 0.7404879450347805.\n",
|
||||
"[I 2023-12-11 22:05:33,215] Trial 9 finished with value: -0.960719787819319 and parameters: {'stop_loss': 0.01, 'take_profit': 0.01, 'length': 60, 'multiplier': 6.0, 'percentage_threshold': 0.01}. Best is trial 8 with value: 0.7404879450347805.\n",
|
||||
"[I 2023-12-11 22:05:50,582] Trial 10 finished with value: 1.1998584529952074 and parameters: {'stop_loss': 0.01, 'take_profit': 0.04, 'length': 80, 'multiplier': 2.0, 'percentage_threshold': 0.02}. Best is trial 10 with value: 1.1998584529952074.\n",
|
||||
"[I 2023-12-11 22:06:07,814] Trial 11 finished with value: 1.1998584529952074 and parameters: {'stop_loss': 0.01, 'take_profit': 0.04, 'length': 80, 'multiplier': 2.0, 'percentage_threshold': 0.02}. Best is trial 10 with value: 1.1998584529952074.\n",
|
||||
"[I 2023-12-11 22:06:24,455] Trial 12 finished with value: 1.1998584529952074 and parameters: {'stop_loss': 0.01, 'take_profit': 0.04, 'length': 80, 'multiplier': 2.0, 'percentage_threshold': 0.02}. Best is trial 10 with value: 1.1998584529952074.\n",
|
||||
"[I 2023-12-11 22:06:41,101] Trial 13 finished with value: 1.1998584529952074 and parameters: {'stop_loss': 0.01, 'take_profit': 0.04, 'length': 80, 'multiplier': 2.0, 'percentage_threshold': 0.02}. Best is trial 10 with value: 1.1998584529952074.\n",
|
||||
"[I 2023-12-11 22:06:57,606] Trial 14 finished with value: 0.02047001353630673 and parameters: {'stop_loss': 0.01, 'take_profit': 0.04, 'length': 20, 'multiplier': 3.0, 'percentage_threshold': 0.03}. Best is trial 10 with value: 1.1998584529952074.\n",
|
||||
"[I 2023-12-11 22:07:14,208] Trial 15 finished with value: 0.9931433766610962 and parameters: {'stop_loss': 0.01, 'take_profit': 0.04, 'length': 100, 'multiplier': 2.0, 'percentage_threshold': 0.02}. Best is trial 10 with value: 1.1998584529952074.\n",
|
||||
"[I 2023-12-11 22:07:30,823] Trial 16 finished with value: 0.37864993105614836 and parameters: {'stop_loss': 0.01, 'take_profit': 0.03, 'length': 80, 'multiplier': 3.0, 'percentage_threshold': 0.02}. Best is trial 10 with value: 1.1998584529952074.\n",
|
||||
"[I 2023-12-11 22:07:47,525] Trial 17 finished with value: 1.089455391608849 and parameters: {'stop_loss': 0.01, 'take_profit': 0.04, 'length': 140, 'multiplier': 2.0, 'percentage_threshold': 0.03}. Best is trial 10 with value: 1.1998584529952074.\n",
|
||||
"[I 2023-12-11 22:08:04,394] Trial 18 finished with value: -0.2011129787326267 and parameters: {'stop_loss': 0.01, 'take_profit': 0.04, 'length': 60, 'multiplier': 5.0, 'percentage_threshold': 0.02}. Best is trial 10 with value: 1.1998584529952074.\n",
|
||||
"[I 2023-12-11 22:08:20,927] Trial 19 finished with value: 0.19209940796981184 and parameters: {'stop_loss': 0.01, 'take_profit': 0.03, 'length': 120, 'multiplier': 3.0, 'percentage_threshold': 0.02}. Best is trial 10 with value: 1.1998584529952074.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Not let's run the optimization!\n",
|
||||
"\n",
|
||||
"n_trials = 20\n",
|
||||
"study.optimize(objective, n_trials=n_trials)"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2023-12-12T01:08:20.930649Z",
|
||||
"start_time": "2023-12-12T01:02:43.228031Z"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 2
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython2",
|
||||
"version": "2.7.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
}
|
||||
@@ -23,7 +23,7 @@ class StrategyAnalysis:
|
||||
self.base_figure = make_subplots(rows=rows, cols=1, shared_xaxes=True, vertical_spacing=0.01,
|
||||
row_heights=heights, specs=specs)
|
||||
if candlestick:
|
||||
self.add_candles_graph()
|
||||
self.add_candles_graph(row=1, col=1)
|
||||
if volume:
|
||||
self.add_volume()
|
||||
if positions:
|
||||
@@ -81,17 +81,17 @@ class StrategyAnalysis:
|
||||
def figure(self):
|
||||
return self.base_figure
|
||||
|
||||
def add_candles_graph(self):
|
||||
def add_candles_graph(self, row, col, name_suffix='', timeframe_suffix=''):
|
||||
self.base_figure.add_trace(
|
||||
go.Candlestick(
|
||||
x=self.candles_df["timestamp"],
|
||||
open=self.candles_df["open"],
|
||||
high=self.candles_df["high"],
|
||||
low=self.candles_df["low"],
|
||||
close=self.candles_df["close"],
|
||||
name="OHLC"
|
||||
x=self.candles_df[f"timestamp{timeframe_suffix}"],
|
||||
open=self.candles_df[f"open{timeframe_suffix}"],
|
||||
high=self.candles_df[f"high{timeframe_suffix}"],
|
||||
low=self.candles_df[f"low{timeframe_suffix}"],
|
||||
close=self.candles_df[f"close{timeframe_suffix}"],
|
||||
name=f"OHLC_{name_suffix}"
|
||||
),
|
||||
row=1, col=1,
|
||||
row=row, col=col,
|
||||
)
|
||||
|
||||
def add_volume(self):
|
||||
@@ -185,7 +185,7 @@ class StrategyAnalysis:
|
||||
return returns.mean() / returns.std()
|
||||
|
||||
def profit_factor(self):
|
||||
total_won = self.win_signals().loc[:, "net_pnl_quote"].sum()
|
||||
total_won = self.win_signals().loc[:, "net_pnl_quote"].sum()
|
||||
total_loss = - self.loss_signals().loc[:, "net_pnl_quote"].sum()
|
||||
return total_won / total_loss
|
||||
|
||||
@@ -231,4 +231,4 @@ Strategy Performance Report:
|
||||
xaxis_title="N° Position",
|
||||
yaxis=dict(title="Net PnL USD", side="left", showgrid=False),
|
||||
)
|
||||
return fig
|
||||
return fig
|
||||
|
||||
@@ -3,6 +3,8 @@ import subprocess
|
||||
import importlib.util
|
||||
import inspect
|
||||
import os
|
||||
|
||||
import pandas as pd
|
||||
from hummingbot.smart_components.strategy_frameworks.directional_trading import DirectionalTradingControllerBase, DirectionalTradingControllerConfigBase
|
||||
|
||||
import yaml
|
||||
@@ -151,3 +153,12 @@ def execute_bash_command(command: str, shell: bool = True, wait: bool = False):
|
||||
process = subprocess.Popen(command, shell=shell)
|
||||
if wait:
|
||||
process.wait()
|
||||
|
||||
|
||||
def safe_read_csv(path):
|
||||
try:
|
||||
df = pd.read_csv(path)
|
||||
except pd.errors.ParserError as e:
|
||||
print("Error occurred while reading CSV:", str(e))
|
||||
df = pd.DataFrame()
|
||||
return df
|
||||
|
||||
Reference in New Issue
Block a user