sell a position after 2 days
-
I want to buy a position and sell it after 2 days and I've tried to return the day I opened the position into init but it gives me
TypeError: 'GapUp' object is not an iterator
I just started with Backtrader an I have no clue on how to solve this issue, thanks in advance to whoever can give me some hint.
import backtrader as bt from datetime import datetime, timedelta, date #datetime.datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0) class GapUp(bt.Strategy): def __init__(self): self.change = bt.ind.PctChange() self.dataclose = self.datas[0].close self.currdate = self.datas[0].datetime.date(0) position_date = next(self) def next(self): if self.change >= 0.05: self.buy(size=1) print(self.datas[0].datetime.date(0)) print(self.datas[0].close[0]) return self.datas[0].datetime.date(0) #if self.currdate >= self.position_date + datetime.timedelta(days=2): # close() cerebro = bt.Cerebro() cerebro.addstrategy(GapUp) data = bt.feeds.YahooFinanceCSVData(dataname='^GSPC.csv', fromdate=datetime(2018,1,1), todate=datetime(2019,11,1)) cerebro.adddata(data) cerebro.broker.setcash(100000.0) cerebro.run() cerebro.plot()
-
__init__()
is called once at the very beginning of the run. I doubt that you will be able to return something from the following run to the__init()__
.If you want to exit after N bars, than:
- in
notify_order()
get order execution bar
self.bar_executed = len(self)
- in the
next()
calculate position duration based on current strategy length
self.duration = len(self) - self.bar_executed + 1
- if it is 2, then issue the order to close position
if self.duration == 2: self.close()
- in
-
@PatrikMuniak said in sell a position after 2 days:
I want to buy a position and sell it after 2 days
Notice that using anything which is
datetime
related won't usually work unless you don't mind weekends and trading holidays adding days to the count. -
@ab_trader
Thanks a lot for replying, I've tried to implement what you've said and I managed to make it work until the graph. The issue is that even if I don't get any error the sell is not working, i.e the plot() shows just buys but not sells.This is how I tried to implement you answer:
import backtrader as bt from datetime import datetime, timedelta, date class GapUp(bt.Strategy): def __init__(self): self.change = bt.ind.PctChange() self.dataclose = self.datas[0].close self.currdate = self.datas[0].datetime.date(0) def notify_order(self, order): self.bar_executed = len(self) def next(self): if self.change >= 0.05: self.buy(size=1) self.notify_order(self) self.duration = len(self) - self.bar_executed + 1 if self.duration == 2: self.close() cerebro = bt.Cerebro() cerebro.addstrategy(GapUp) data = bt.feeds.YahooFinanceCSVData(dataname='^GSPC.csv', fromdate=datetime(2018,1,1), todate=datetime(2019,11,1)) cerebro.adddata(data) cerebro.broker.setcash(100000.0) cerebro.run() cerebro.plot()
-
@PatrikMuniak every
next()
you callnotify_order()
and set yourself.bar_executed
to length of the data. So yourself.duration
vaule is equal to 1 on everynext()
call. No surprise you have no sells. -
@ab_trader thanks for sharing this idea. I am trying to implement the code but am having the same issue above. The
self.duration
value is constantly one, and one has to call thenotify_order()
innext()
otherwise you get an error aboutbar_executed
. How can one track the number of bars in a trade? Can you use something related to theTrade
functions? I'll attach my code. Thank you -
there is no need to call
self.notify_order()
in thenext()
. in order to avoid an error withbar_executed
you need to operate with it only if the position exists. otherwsie use ofbar_executed
is meaningless.also don't post pictures, but text; please read the note about backticks on top of the page.