In [ ]:
Copied!
!pip install hyperactive
# Re-install pandas 2.2
!pip install --upgrade pandas
!pip install hyperactive
# Re-install pandas 2.2
!pip install --upgrade pandas
Sample strategy¶
In [6]:
Copied!
# import talib.abstract as ta
from lettrade import DataFeed, Strategy, indicator as i
from lettrade.exchange.backtest import ForexBackTestAccount, let_backtest
from lettrade.indicator.vendor.qtpylib import inject_indicators
inject_indicators()
class SmaCross(Strategy):
ema1_window = 9
ema2_window = 21
def indicators(self, df: DataFeed):
# df["ema1"] = ta.EMA(df, timeperiod=self.ema1_window)
# df["ema2"] = ta.EMA(df, timeperiod=self.ema2_window)
df["ema1"] = df.close.ema(window=self.ema1_window)
df["ema2"] = df.close.ema(window=self.ema2_window)
df["signal_ema_crossover"] = i.crossover(df.ema1, df.ema2)
df["signal_ema_crossunder"] = i.crossunder(df.ema1, df.ema2)
def next(self, df: DataFeed):
if len(self.orders) > 0 or len(self.positions) > 0:
return
if df.l.signal_ema_crossover[-1]:
price = df.l.close[-1]
self.buy(size=0.1, sl=price - 0.001, tp=price + 0.001)
elif df.l.signal_ema_crossunder[-1]:
price = df.l.close[-1]
self.sell(size=0.1, sl=price + 0.001, tp=price - 0.001)
lt = let_backtest(
strategy=SmaCross,
datas="example/data/data/EURUSD_5m-0_10000.csv",
account=ForexBackTestAccount,
# plotter=None,
)
# import talib.abstract as ta
from lettrade import DataFeed, Strategy, indicator as i
from lettrade.exchange.backtest import ForexBackTestAccount, let_backtest
from lettrade.indicator.vendor.qtpylib import inject_indicators
inject_indicators()
class SmaCross(Strategy):
ema1_window = 9
ema2_window = 21
def indicators(self, df: DataFeed):
# df["ema1"] = ta.EMA(df, timeperiod=self.ema1_window)
# df["ema2"] = ta.EMA(df, timeperiod=self.ema2_window)
df["ema1"] = df.close.ema(window=self.ema1_window)
df["ema2"] = df.close.ema(window=self.ema2_window)
df["signal_ema_crossover"] = i.crossover(df.ema1, df.ema2)
df["signal_ema_crossunder"] = i.crossunder(df.ema1, df.ema2)
def next(self, df: DataFeed):
if len(self.orders) > 0 or len(self.positions) > 0:
return
if df.l.signal_ema_crossover[-1]:
price = df.l.close[-1]
self.buy(size=0.1, sl=price - 0.001, tp=price + 0.001)
elif df.l.signal_ema_crossunder[-1]:
price = df.l.close[-1]
self.sell(size=0.1, sl=price + 0.001, tp=price - 0.001)
lt = let_backtest(
strategy=SmaCross,
datas="example/data/data/EURUSD_5m-0_10000.csv",
account=ForexBackTestAccount,
# plotter=None,
)
Example¶
In [7]:
Copied!
from hyperactive import Hyperactive
from hyperactive.optimizers import HillClimbingOptimizer
# define the model in a function
def params_parser(args):
return {
"ema1_window": args["ema1_window"],
"ema2_window": args["ema2_window"],
}
def result_parser(result):
return result["equity"]
model = lt.optimize_model(
params_parser=params_parser,
result_parser=result_parser,
)
# search space determines the ranges of parameters you want the optimizer to search through
search_space = {
"ema1_window": list(range(5, 25, 1)),
"ema2_window": list(range(10, 50)),
}
optimizer = HillClimbingOptimizer(epsilon=0.1, distribution="laplace", n_neighbours=4)
# start the optimization run
hyper = Hyperactive()
hyper.add_search(model, search_space, optimizer=optimizer, n_iter=1000)
hyper.run()
from hyperactive import Hyperactive
from hyperactive.optimizers import HillClimbingOptimizer
# define the model in a function
def params_parser(args):
return {
"ema1_window": args["ema1_window"],
"ema2_window": args["ema2_window"],
}
def result_parser(result):
return result["equity"]
model = lt.optimize_model(
params_parser=params_parser,
result_parser=result_parser,
)
# search space determines the ranges of parameters you want the optimizer to search through
search_space = {
"ema1_window": list(range(5, 25, 1)),
"ema2_window": list(range(10, 50)),
}
optimizer = HillClimbingOptimizer(epsilon=0.1, distribution="laplace", n_neighbours=4)
# start the optimization run
hyper = Hyperactive()
hyper.add_search(model, search_space, optimizer=optimizer, n_iter=1000)
hyper.run()
[0] _optimize_model (Hill Climbing): 100%|──────────| 1000/1000 [00:46<00:00, 21.30it/s, best_iter=0, best_pos=[9 0], best_score=10176.96]
Results: '_optimize_model' Best score: 10176.96 Best parameter set: 'ema1_window' : 14.0 'ema2_window' : 10.0 Best iteration: 0 Random seed: 1466797877 Evaluation time : 45.75040030479431 sec [99.78 %] Optimization time : 0.10297703742980957 sec [0.22 %] Iteration time : 45.85337734222412 sec [21.81 iter/sec]
In [8]:
Copied!
df = hyper.search_data(model)
df
df = hyper.search_data(model)
df
Out[8]:
ema1_window | ema2_window | score | |
---|---|---|---|
0 | 21 | 38 | 9938.72 |
1 | 9 | 47 | 9988.94 |
2 | 11 | 23 | 9845.88 |
3 | 11 | 36 | 9935.88 |
4 | 17 | 23 | 9954.64 |
... | ... | ... | ... |
995 | 11 | 10 | 10170.22 |
996 | 13 | 13 | 10000.00 |
997 | 12 | 14 | 9933.10 |
998 | 14 | 16 | 9975.46 |
999 | 7 | 39 | 9875.98 |
1000 rows × 3 columns
Plot¶
In [9]:
Copied!
lt.plotter.heatmap()
lt.plotter.heatmap()
In [10]:
Copied!
lt.plotter.contour(x="ema1_window", y="ema2_window", z="equity")
lt.plotter.contour(x="ema1_window", y="ema2_window", z="equity")
Plot plotly¶
Init Plotly environment¶
In [11]:
Copied!
import plotly.io as pio
pio.renderers.default = "notebook"
pio.templates.default = "plotly_dark"
import plotly.io as pio
pio.renderers.default = "notebook"
pio.templates.default = "plotly_dark"
Type 1¶
In [12]:
Copied!
import plotly.express as px
fig = px.density_heatmap(
df,
x="ema1_window",
y="ema2_window",
z="score",
nbinsx=20,
nbinsy=40,
histfunc="max",
color_continuous_scale="Viridis",
)
fig.show()
import plotly.express as px
fig = px.density_heatmap(
df,
x="ema1_window",
y="ema2_window",
z="score",
nbinsx=20,
nbinsy=40,
histfunc="max",
color_continuous_scale="Viridis",
)
fig.show()
Type 2¶
In [13]:
Copied!
import plotly.express as px
fig = px.density_contour(
df,
x="ema1_window",
y="ema2_window",
z="score",
histfunc="max",
)
fig.update_traces(contours_coloring="fill", contours_showlabels=True)
fig.show()
import plotly.express as px
fig = px.density_contour(
df,
x="ema1_window",
y="ema2_window",
z="score",
histfunc="max",
)
fig.update_traces(contours_coloring="fill", contours_showlabels=True)
fig.show()