Recycles the portfolio container to be passed to handle_data.

The creation of a new portfolio ndict on each call of handle_data
was creating a very high performance overhead.

Instead, we use the same the portfolio object for each event,
and replace the values contained within.
This commit is contained in:
Eddie Hebert
2013-01-11 23:30:43 -05:00
parent ca9fdcfe84
commit 1ddfadf5b4
+20 -12
View File
@@ -139,7 +139,6 @@ import math
from zipline.utils.protocol_utils import ndict
import zipline.protocol as zp
import zipline.finance.risk as risk
from zipline.protocol import Portfolio
log = logbook.Logger('Performance')
@@ -443,6 +442,11 @@ class PerformancePeriod(object):
self.calculate_performance()
# An object to recycle via assigning new values
# when returning portfolio information.
# So as not to avoid creating a new object for each event
self._portfolio_store = zp.Portfolio()
def calculate_performance(self):
self.ending_value = self.calculate_positions_value()
@@ -544,17 +548,21 @@ class PerformancePeriod(object):
PerformancePeriod, and in this method we rename some
fields for usability and remove extraneous fields.
"""
return Portfolio({
'capital_used': self.period_capital_used,
'starting_cash': self.starting_cash,
'portfolio_value': self.ending_cash + self.ending_value,
'pnl': self.pnl,
'returns': self.returns,
'cash': self.ending_cash,
'start_date': self.period_open,
'positions': self.get_positions(),
'positions_value': self.ending_value
})
# Recycles containing objects' Portfolio object
# which is used for returning values.
# as_portfolio is called in an inner loop,
# so repeated object creation becomes too expensive
portfolio = self._portfolio_store
portfolio.capital_used = self.period_capital_used,
portfolio.starting_cash = self.starting_cash
portfolio.portfolio_value = self.ending_cash + self.ending_value
portfolio.pnl = self.pnl
portfolio.returns = self.returns
portfolio.cash = self.ending_cash
portfolio.start_date = self.period_open
portfolio.positions = self.get_positions()
portfolio.positions_value = self.ending_value
return portfolio
def get_positions(self):