@ab_trader Hi, I'm working with coc, and read this thread. Is it not possible to have the order notification with cheat on close to allign with the order executation date?
Latest posts made by Gerry
-
RE: cheat-on-close not working?
-
Resample data and indicator
I am currently resampling data, and then using that in a simple moving average indicato. The output then is a second chart with the resampled data and moving average, however I would like to have the moving average (based on weekly data) to be plotted on the main layout, is this possible?
Code:
"""
class MovingAverage(bt.Strategy):params = ( ('ema5', 5), ('ema20', 8), ('ema50', 50), ('ema_200', 200), ('printlog', True), ('atr_mult', 2.0), ('rsi_period', 30), ('atr_period', 14), ) def log(self, txt, dt=None, doprint=False): if self.p.printlog or doprint: dt = dt or self.datas[0].datetime.date(0) print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): self.dataclose = self.data.close self.ema5 = bt.ind.EMA(self.data1, period=self.p.ema5) self.ema20 = bt.ind.EMA(self.data2, period=self.p.ema20) self.rsi = bt.ind.RSI_SMA(period=self.p.rsi_period, plot=True) self.atr = bt.ind.ATR(period=self.p.atr_period, plot=False) self.crossup = bt.ind.CrossUp(self.data0, self.ema5, plot=False) self.addminperiod(45) self.order = None
if name=='main':
cash = 10000
position = cash
cerebro = bt.Cerebro(optreturn=True, stdstats=True)data = bt.feeds.GenericCSVData( dataname="litecoin_unix_daily.csv", fromdate=datetime.datetime(2017, 1, 1), # todate=datetime.datetime(2022, 3, 30), timeframe=bt.TimeFrame.Minutes, compression=1, nullvalue=0.0, dtformat=2, datetime=0, open=1, high=2, low=3, close=4 ) cerebro.adddata(data, name='data') cerebro.resampledata(data, timeframe=bt.TimeFrame.Weeks, compression=1) cerebro.resampledata(data, timeframe=bt.TimeFrame.Months, compression=1)
"""
-
Close trade if not profitable after n days
Hi,
I am looking for a way to close an open trade if it is not profitable after n days, since it is not worth the time and capital to stick to a trade not going anywhere. I've searched but couldn't find anything to help with this, does anyone have any idea? -
Analyzers
Re: It's here - a beta you can use RIGHT NOW - Essential trade statistics - all in one place
I am trying to use the analyzer in this thread, and the final comment on how to use this in a module, but I get the following error:
"AttributeError: 'float' object has no attribute 'analyzers".
This looks like a really good analyzer, so I'm hoping that someone can help me. -
Fund Value / Net Asset Value
Hi Everyone,
I am able to see the "Fund Value" when I run my code, and how that changes, but how can I log that, to see how that changes with each day that passes, like closing prices are getting logged? I baiscally want to see the values behind the Fund Value portion of the graph.
-
RE: cerebro.plot() error
@lavenderfish
Hi, not sure if you ever had a resolution for this, but I came accross the same error when I wanted to plot without a strategy. The following resolved this issue for me:
cerebro = bt.Cerebro(stdstats=False)Found this solution to another problem here:
https://community.backtrader.com/topic/1515/memory-error -
RE: StopLoss
@run-out Thank you very much for the reply, appreciate the help. On the bracket order, I tried using the below code, but there seems to be an error, where am I going wrong?
'''
class CustomRsi(bt.Indicator):lines = ('signal', 'buysig', 'sellsig', ) params = (('period', 15), ('upperband', 80), ('lowerband', 33), ) def __init__(self): self.lines.signal = bt.indicators.RSI_SMA(period=self.p.period) self.lines.buysig = bt.ind.CrossUp(self.lines.signal, self.p.lowerband) self.lines.sellsig = bt.ind.CrossDown(self.signal, self.p.upperband)
class StopTrading(bt.Strategy):
params = ( ('lowerband', 30), ('upperband', 70), ) def print_signal(self): self.log("open {:.2f}\tclose {:.2f} \thigh {:.2f} rsi {:.2f} atr {:.2f}" .format(self.data.open[0], self.data.close[0], self.data.high[0], self.rsi[0], self.atr[0] ) ) def log(self, txt, dt=None): dt = dt or self.datas[0].datetime.date(0) print(dt.isoformat(), txt) def __init__(self): self.dataclose = self.data.close self.atr = bt.ind.ATR() self.rsi = bt.ind.RSI_SMA(period=15) self.crsi = CustomRsi() # create instance crsi self.buy_signal = self.crsi.buysig # access attributes of instance created self.sell_signal = self.crsi.sellsig # access attributes of instance created self.order=None def notify_order(self, order): if order.status in [order.Submitted, order.Accepted]: return if order.status in [order.Completed]: if order.isbuy(): self.log(f'Buy executed for long position {order.executed.price}') elif order.issell(): self.log(f'Close executed for long position {order.executed.price}') self.order = None def notify_trade(self, trade): if trade.isopen: return else: # Trade is closed, log profit / loss, barlen: amount of bars trade was open self.log(f'Profit {trade.pnl} Trade Length: {trade.barlen}') def next(self): self.print_signal() if self.order: return if not self.position: if self.buy_signal: self.order=self.buy_bracket(exectype=bt.Order.StopTrail, trailamount=300) self.log('Going long@{:.2f}, stoptrail {:.2f}'.format(self.dataclose[0], bt.Order.StopTrail))
'''
-
RE: StopLoss
@run-out I have, thanks. I am getting confused between this article and these two, and how to properly use them:
https://www.backtrader.com/blog/posts/2017-03-22-stoptrail/stoptrail/https://www.backtrader.com/docu/order-creation-execution/bracket/bracket/
Is it necessary to use the stoporder in the notify class or is it actually possible to do it under the next method?
-
StopLoss
Hi All,
I am trying to code a simple trailing stop loss strategy, but I just cant seem to get the hang of it after reading most of the blog posts on the topic and the docs. Feels like a silly thing to miss but maybe somebody can help. Appreciate the assistance.
'''
class CustomRsi(bt.Indicator):lines = ('signal', 'buysig', 'sellsig', ) params = (('period', 15), ('upperband', 80), ('lowerband', 33), ) def __init__(self): self.lines.signal = bt.indicators.RSI_SMA(period=self.p.period) self.lines.buysig = bt.ind.CrossUp(self.lines.signal, self.p.lowerband) self.lines.sellsig = bt.ind.CrossDown(self.signal, self.p.upperband)
class StopTrading(bt.Strategy):
params = ( ('lowerband', 30), ('upperband', 70), ) def print_signal(self): self.log("open {:.2f}\tclose {:.2f} \thigh {:.2f} rsi {:.2f} atr {:.2f}" .format(self.data.open[0], self.data.close[0], self.data.high[0], self.rsi[0], self.atr[0] ) ) def log(self, txt, dt=None): dt = dt or self.datas[0].datetime.date(0) print(dt.isoformat(), txt) def __init__(self): self.dataclose = self.data.close self.atr = bt.ind.ATR() self.rsi = bt.ind.RSI_SMA(period=15) self.crsi = CustomRsi() # create instance crsi self.buy_signal = self.crsi.buysig # access attributes of instance created self.sell_signal = self.crsi.sellsig # access attributes of instance created self.order=None def notify_order(self, order): if order.status in [order.Submitted, order.Accepted]: return if order.status in [order.Completed]: if order.isbuy(): self.log(f'Buy executed for long position {order.executed.price}') elif order.issell(): self.log(f'Close executed for long position {order.executed.price}') self.order = None def notify_trade(self, trade): if trade.isopen: return else: # Trade is closed, log profit / loss, barlen: amount of bars trade was open self.log(f'Profit {trade.pnl} Trade Length: {trade.barlen}') def next(self): self.print_signal() if self.order: return if not self.position: if self.buy_signal: self.log('Going long@{:.2f}'.format(self.dataclose[0])) self.order=self.buy() elif self.position: self.order=self.sell(exectype=bt.Order.StopTrail, trailamount=300)
'''