Recycles objects for positions.

Instead of creating a new ndict for each position on every event,
we change the values in the object that held the previous position.

The creation of new objects on each event was incurring too much
overhead.

Changes the position type returned by performance module.

For improved speed, changes from ndict to a simple Python object,
since the cost of setting ndict values is too expensive for the
number of times that positions are returned.

Also, changes the containing type of the positions to be dictionary
with the __missing__ overloaded, instead of the ndict that had that
behavior, to reduce the penalty of using ndicts.
This commit is contained in:
Eddie Hebert
2013-01-11 23:54:52 -05:00
committed by Thomas Wiecki
parent a889f814fc
commit a3235bb1a5
2 changed files with 28 additions and 12 deletions
+8 -12
View File
@@ -136,7 +136,6 @@ import datetime
import pytz
import math
from zipline.utils.protocol_utils import ndict
import zipline.protocol as zp
import zipline.finance.risk as risk
@@ -446,6 +445,7 @@ class PerformancePeriod(object):
# 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()
@@ -566,11 +566,15 @@ class PerformancePeriod(object):
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
@@ -588,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
+20
View File
@@ -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