Optimize with LetTrade Grid Search¶
Grid Search¶
Sample Strategy¶
In [1]:
Copied!
from lettrade import DataFeed, Strategy
from lettrade.exchange.backtest import ForexBackTestAccount, let_backtest
class SmaCross(Strategy):
ema1_window = 9
ema2_window = 21
def indicators(self, df: DataFeed):
df["ema1"] = df.i.ema(window=self.ema1_window)
df["ema2"] = df.i.ema(window=self.ema2_window)
df["signal_ema_crossover"] = df.i.crossover(df.ema1, df.ema2)
df["signal_ema_crossunder"] = df.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,
)
from lettrade import DataFeed, Strategy
from lettrade.exchange.backtest import ForexBackTestAccount, let_backtest
class SmaCross(Strategy):
ema1_window = 9
ema2_window = 21
def indicators(self, df: DataFeed):
df["ema1"] = df.i.ema(window=self.ema1_window)
df["ema2"] = df.i.ema(window=self.ema2_window)
df["signal_ema_crossover"] = df.i.crossover(df.ema1, df.ema2)
df["signal_ema_crossunder"] = df.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,
)
Optimize¶
LetTrade
will auto cache optimize result
In [2]:
Copied!
lt.optimize(ema1_window=[5, 6, 7, 8, 9, 10], ema2_window=range(10, 50, 1))
lt.optimize(ema1_window=[5, 6, 7, 8, 9, 10], ema2_window=range(10, 50, 1))
Optimizing ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% [240/240] 0:00:00 0:00:05m 0:00:0500:04
Rerun Optimize will reuse optimize result cached
In [3]:
Copied!
lt.optimize(ema1_window=range(5, 25), ema2_window=range(10, 50, 1))
lt.optimize(ema1_window=range(5, 25), ema2_window=range(10, 50, 1))
Optimizing ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% [800/800] 0:00:00 0:00:10m 0:00:1000:10
Plot¶
In [4]:
Copied!
lt.plotter.heatmap(x="ema1_window", y="ema2_window", z="equity")
lt.plotter.heatmap(x="ema1_window", y="ema2_window", z="equity")
In [5]:
Copied!
lt.plotter.contour(x="ema1_window", y="ema2_window", z="equity")
lt.plotter.contour(x="ema1_window", y="ema2_window", z="equity")
Optimize from cache¶
Load optimize result from cache
In [6]:
Copied!
lt.optimize_cache()
lt.optimize_cache()
Plot¶
In [7]:
Copied!
lt.plotter.heatmap()
lt.plotter.heatmap()
In [8]:
Copied!
lt.plotter.contour()
lt.plotter.contour()