mirror of
https://github.com/wassname/catalyst.git
synced 2026-07-13 17:42:42 +08:00
Merge pull request #58 from quantopian/placeholder-object-in-performance-inner-loop
Recycles objects for portfolio and positions.
This commit is contained in:
@@ -136,10 +136,8 @@ import datetime
|
||||
import pytz
|
||||
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 +441,12 @@ 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()
|
||||
self._positions_store = zp.Positions()
|
||||
|
||||
def calculate_performance(self):
|
||||
self.ending_value = self.calculate_positions_value()
|
||||
|
||||
@@ -544,25 +548,33 @@ 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):
|
||||
|
||||
positions = ndict(internal=position_ndict())
|
||||
positions = self._positions_store
|
||||
|
||||
for sid, pos in self.positions.iteritems():
|
||||
cur = pos.to_dict()
|
||||
positions[sid] = ndict(cur)
|
||||
if sid not in positions:
|
||||
positions[sid] = zp.Position(sid)
|
||||
position = positions[sid]
|
||||
position.amount = pos.amount
|
||||
position.cost_basis = pos.cost_basis
|
||||
position.last_sale_price = pos.last_sale_price
|
||||
|
||||
return positions
|
||||
|
||||
@@ -580,11 +592,3 @@ class positiondict(dict):
|
||||
pos = Position(key)
|
||||
self[key] = pos
|
||||
return pos
|
||||
|
||||
|
||||
class position_ndict(dict):
|
||||
|
||||
def __missing__(self, key):
|
||||
pos = Position(key)
|
||||
self[key] = ndict(pos.to_dict())
|
||||
return pos
|
||||
|
||||
@@ -65,3 +65,23 @@ class Portfolio(object):
|
||||
|
||||
def __repr__(self):
|
||||
return "Portfolio({0})".format(self.__dict__)
|
||||
|
||||
|
||||
class Position(object):
|
||||
|
||||
def __init__(self, sid):
|
||||
self.sid = sid
|
||||
self.amount = 0
|
||||
self.cost_basis = 0.0 # per share
|
||||
self.last_sale_price = 0.0
|
||||
|
||||
def __repr__(self):
|
||||
return "Position({0})".format(self.__dict__)
|
||||
|
||||
|
||||
class Positions(dict):
|
||||
|
||||
def __missing__(self, key):
|
||||
pos = Position(key)
|
||||
self[key] = pos
|
||||
return pos
|
||||
|
||||
Reference in New Issue
Block a user