From a3235bb1a5be795a550073f5a15467fcf506f425 Mon Sep 17 00:00:00 2001 From: Eddie Hebert Date: Fri, 11 Jan 2013 23:54:52 -0500 Subject: [PATCH] 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. --- zipline/finance/performance.py | 20 ++++++++------------ zipline/protocol.py | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/zipline/finance/performance.py b/zipline/finance/performance.py index 3543f7ed..78130c05 100644 --- a/zipline/finance/performance.py +++ b/zipline/finance/performance.py @@ -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 diff --git a/zipline/protocol.py b/zipline/protocol.py index 9e71d3ae..25f1b90b 100644 --- a/zipline/protocol.py +++ b/zipline/protocol.py @@ -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