For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/
Custom sizer enter trades more than I wanted
-
The strategy I'm trying to do is quite simple: Buy at -50% from a rolling 5-year peak, and sell after 2 years. Each trade will be allotted a size of 20% of the portfolio total value. Below is the code I wrote.
My problem is that it enters into trades many more times than my intention. But this issue only happens with a part of the trades. I think the problem is mainly with the sizer, because I tried my code with the built-in percent sizer (20% of cash), and that worked perfectly fine.
class dss(bt.Strategy): params = ( ('look_back_weeks', 260), ('drawdown_threshold', 0.5), ('hold_weeks', 104) ) def __init__(self): pass def start(self): self.eq_progression = [] self.trade_dates = [] self.bought_bars={d:0 for d in self.getdatanames()} self.cash_start = self.broker.get_cash() print("Date;Security;Size;Entry_Price;Exit_price") def next(self): self.trade_dates += [self.datetime.date()] self.eq_progression += [cerebro.broker.getvalue()] for i, d in enumerate(self.datas): if not self.getposition(d).size: if len(self) < self.params.look_back_weeks: drawdown = d[0]/max(d.get(size = len(self)).tolist()) else: drawdown = d[0]/max(d.get(size = self.params.look_back_weeks).tolist()) if drawdown < self.params.drawdown_threshold: self.buy(data = d) self.bought_bars[self.getdatanames()[i]] = len(self) elif (len(self) - self.bought_bars[self.getdatanames()[i]]) >= self.params.hold_weeks: print(self.datetime.date(),";", self.getdatanames()[i],";", self.broker.getposition(d).size,";", self.broker.getposition(d).price,";", d[0] ) self.sell(data = d) class ValuePercentSizer(bt.Sizer): params = ( ('percents', 20), ('retint', True),# return an int size or rather the float value ) def __init__(self): pass def _getsizing(self, comminfo, cash, data, isbuy): position = self.broker.getposition(data) accvalue = self.broker.getvalue() if not position: size = accvalue / data.close[0] * (self.params.percents / 100) else: size = position.size if self.p.retint: size = int(size) return size