Accessing variable defined in strategy from main Cerebro
-
Hello,
I am simply trying to access a variable I have defined as "roi" within my strategy class from the main function where I am trying to access this variable so that I can write it to a csv.
The reason I am trying to do something like this is because I don't know how to get Cerebro to tell me my % returns on only money invested during the strategy, and not my % returns based on the starting and ending values including cash. So if there is a way to do this easier, please let me know.
I tried to make it a global variable by name it at the top of each function accessing it but that didn't work and I'm unsure how to do this. Any help would be sincerely appreciated.
import backtrader as bt import datetime import math class exampleSizer(bt.Sizer): params = (('size',1),) def _getsizing(self, comminfo, cash, data, isbuy): return self.p.size class buynhold_1(bt.Strategy): params = ( ('start_date', None), ('end_date', None), ('sizer', None), ) def __init__(self): self.dataclose = self.datas[0].close() #self.currdate = self.datas[0].datetime.date(0) #if self.p.sizer is not None: #self.sizer = self.p.sizer def start(self): self.val_start = self.broker.get_cash() # keep the starting cash def nextstart(self): # Buy all the available cash #self.buy() self.bar_executed = 0 def within_range(self): date = self.datas[0].datetime.datetime(0) if date >= self.p.start_date and date <= self.p.end_date: return True else: return False def next(self): self.currdate = self.datas[0].datetime.datetime(0) print(self.currdate) self.duration = len(self) - self.bar_executed + 1 print(self.getposition().size) if not self.position: if self.within_range(): self.buy() #self.bar_executed = len(self) elif self.currdate >= self.p.end_date: self.value = self.broker.getvalue()-self.broker.getcash() self.close() #else: #self.duration = len(self) - self.bar_executed + 1 def stop(self): global roi # calculate the actual returns print(self.value) roi = ((self.broker.get_value() -self.val_start) / (self.value)) print('ROI: {:.2f}%'.format(100.0 * self.roi)) #return self.roi
and the main:
cerebro.adddata(data) # Set our desired cash start cerebro.broker.setcash(3000.0) # Add strategy to Cerebro cerebro.addstrategy(buynhold_1, start_date = start_date, end_date = end_date, sizer = pos ) #add the sizer cerebro.addsizer(exampleSizer, size = pos) if __name__ == '__main__': # Run Cerebro Engine start_portfolio_value = cerebro.broker.getvalue() result = cerebro.run() print(roi) #This is the value that I want #cerebro.plot() end_portfolio_value = cerebro.broker.getvalue() pnl = end_portfolio_value - start_portfolio_value #roi = end_portfolio_value / start_portfolio_value - 1 print(f'Starting Portfolio Value: {start_portfolio_value:2f}') print(f'Final Portfolio Value: {end_portfolio_value:2f}') print(f'PnL: {pnl:.2f}') #write to csv for saving file_name = "".join((stock,"_OT.csv")) with open(file_name,'w',newline='') as file: writer = csv.writer(file) #writer.writerow(["Stock","Return"]) writer.writerow(["TSLA",pnl,roi])
-
@Carson-Lansdowne said in Accessing variable defined in strategy from main Cerebro:
Hey Carson,
def stop(self): global roi # calculate the actual returns print(self.value) roi = ((self.broker.get_value() -self.val_start) / (self.value)) print('ROI: {:.2f}%'.format(100.0 * self.roi)) #return self.roi
This snippet is copied from your code as it was.
You have defined a new variableglobal roi
but you are trying to access it as aclass attribute
. Try usingroi
instead ofself.roi
in the print statement of your method. Hope it works. :) -
@Soham-Jain This was super helpful, but I guess I should have been more clear. I want to access this ROI variable from the main part of my code, where I am instantiating Cerebro and running my strategy -- essentially, I want to write it to the csv with my pnl at the end of that code snippet. Haven't had any luck doing this by making it a global variable..
-