I am looking to execute optimizations inside my algorithm and extract the resulting parameters to use them on the next timeperiod.
For example i want my algo to calculate the best parameters for the last 10 days of data, and then apply them into my trading strategy for the following 10 days. And then 10 days later, it will recalculate the last 10 days' optimized parameters and apply it... You got the point
I haven't been able to code it, but I have been trying just to proceed in doing several optimizations in a for loop, but unfortunately it didn't work
Do you have any idea on how to code such a program, or even do several optimizations and store values in a list ?
Thanks
Here is my code for now:
import backtrader as bt
import datetime
from datetime import timedelta
class MACrossOver1(bt.Strategy):
params = (
# period for the fast Moving Average
('fast', 10),
# period for the slow moving average
('slow', 40),
# moving average to use
('_movav', bt.ind.MovAv.SMA)
)
def __init__(self):
self.startcash = self.broker.getvalue()
sma_fast = self.p._movav(period=self.p.fast)
sma_slow = self.p._movav(period=self.p.slow)
self.buysig = bt.ind.CrossOver(sma_fast, sma_slow)
self.xz = 1
def next(self):
if self.position.size:
if self.buysig < 0:
self.sell()
elif self.buysig > 0:
self.buy()
# Create a cerebro entity
cerebro = bt.Cerebro(optreturn=False)
# Set our desired cash start
startcash = 1000
cerebro.broker.setcash(startcash)
# Set the commission
cerebro.broker.setcommission(commission=0.005)
# Add a sizer
cerebro.addsizer(bt.sizers.PercentSizer, percents=60)
fromdate = "19990101"
todate = "20171105"
fromdate1 = datetime.datetime.strptime(fromdate, "%Y%m%d").date()
todate1 = datetime.datetime.strptime(todate, "%Y%m%d").date()
delta = (todate1  fromdate1).days
daysToOptimize = 10
deltaValue = int(delta / daysToOptimize)
param_list = []
# Create a Data Feed
for x in range(1, deltaValue):
opt_runs = cerebro.run()
if x == 1:
endDate = fromdate1
elif x > 1:
endDate = fromdate1 + (timedelta(days=daysToOptimize) * (x  1))
beginningDate = endDate  timedelta(days=daysToOptimize)
data = bt.feeds.YahooFinanceData(dataname='SPY', fromdate=beginningDate, todate=endDate)
# Add the Data Feed to Cerebro
cerebro.adddata(data)
# Add a strategy
cerebro.optstrategy(MACrossOver1, fast=range(5, 60), slow=range(65, 230))
final_results_list = []
for run in opt_runs:
for strategy in run:
value = round(strategy.broker.get_value(), 2)
PnL = round(value  startcash, 2)
period1 = strategy.params.fast
period2 = strategy.params.slow
final_results_list.append([period1, period2, PnL])
by_PnL = sorted(final_results_list, key=lambda x: x[2], reverse=True)
by_PnL2 = by_PnL[:1]
for result in by_PnL2:
param_list.insert([result[0], result[1], result[2]])
print(param_list)
]]>I am looking to execute optimizations inside my algorithm and extract the resulting parameters to use them on the next timeperiod.
For example i want my algo to calculate the best parameters for the last 10 days of data, and then apply them into my trading strategy for the following 10 days. And then 10 days later, it will recalculate the last 10 days' optimized parameters and apply it... You got the point
I haven't been able to code it, but I have been trying just to proceed in doing several optimizations in a for loop, but unfortunately it didn't work
Do you have any idea on how to code such a program, or even do several optimizations and store values in a list ?
Thanks
Here is my code for now:
import backtrader as bt
import datetime
from datetime import timedelta
class MACrossOver1(bt.Strategy):
params = (
# period for the fast Moving Average
('fast', 10),
# period for the slow moving average
('slow', 40),
# moving average to use
('_movav', bt.ind.MovAv.SMA)
)
def __init__(self):
self.startcash = self.broker.getvalue()
sma_fast = self.p._movav(period=self.p.fast)
sma_slow = self.p._movav(period=self.p.slow)
self.buysig = bt.ind.CrossOver(sma_fast, sma_slow)
self.xz = 1
def next(self):
if self.position.size:
if self.buysig < 0:
self.sell()
elif self.buysig > 0:
self.buy()
# Create a cerebro entity
cerebro = bt.Cerebro(optreturn=False)
# Set our desired cash start
startcash = 1000
cerebro.broker.setcash(startcash)
# Set the commission
cerebro.broker.setcommission(commission=0.005)
# Add a sizer
cerebro.addsizer(bt.sizers.PercentSizer, percents=60)
fromdate = "19990101"
todate = "20171105"
fromdate1 = datetime.datetime.strptime(fromdate, "%Y%m%d").date()
todate1 = datetime.datetime.strptime(todate, "%Y%m%d").date()
delta = (todate1  fromdate1).days
daysToOptimize = 10
deltaValue = int(delta / daysToOptimize)
param_list = []
# Create a Data Feed
for x in range(1, deltaValue):
opt_runs = cerebro.run()
if x == 1:
endDate = fromdate1
elif x > 1:
endDate = fromdate1 + (timedelta(days=daysToOptimize) * (x  1))
beginningDate = endDate  timedelta(days=daysToOptimize)
data = bt.feeds.YahooFinanceData(dataname='SPY', fromdate=beginningDate, todate=endDate)
# Add the Data Feed to Cerebro
cerebro.adddata(data)
# Add a strategy
cerebro.optstrategy(MACrossOver1, fast=range(5, 60), slow=range(65, 230))
final_results_list = []
for run in opt_runs:
for strategy in run:
value = round(strategy.broker.get_value(), 2)
PnL = round(value  startcash, 2)
period1 = strategy.params.fast
period2 = strategy.params.slow
final_results_list.append([period1, period2, PnL])
by_PnL = sorted(final_results_list, key=lambda x: x[2], reverse=True)
by_PnL2 = by_PnL[:1]
for result in by_PnL2:
param_list.insert([result[0], result[1], result[2]])
print(param_list)
]]>For example i want my algo to calculate the best parameters for the last 10 days of data, and then apply them into my trading strategy for the following 10 days. And then 10 days later, it will recalculate the last 10 days' optimized parameters and apply it... You got the point
every x periods, optimize the last y periods and apply them to the next x periods
For me it looks like typical walk forward optimization. Here is the link to the good post on how to implement it in bt
