From 9db18846c93060426e95b9d8eabbe5e1048e3558 Mon Sep 17 00:00:00 2001 From: fawce Date: Mon, 16 Apr 2012 13:37:54 -0400 Subject: [PATCH 1/6] fixed type-os in serialization code --- zipline/finance/performance.py | 5 +++-- zipline/finance/trading.py | 15 ++++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/zipline/finance/performance.py b/zipline/finance/performance.py index 03c94139..390ae430 100644 --- a/zipline/finance/performance.py +++ b/zipline/finance/performance.py @@ -218,8 +218,8 @@ class PerformanceTracker(): 'period_start' : self.period_start, 'period_end' : self.period_end, 'progress' : self.progress, - 'cumulative_captial_used' : self.cumulative_perf.cumulative_capital_used, - 'max_capital_used' : self.cumulative_perf.max_capital_used, + 'cumulative_capital_used' : self.cumulative_performance.cumulative_capital_used, + 'max_capital_used' : self.cumulative_performance.max_capital_used, 'last_close' : self.market_close, 'last_open' : self.market_open, 'capital_base' : self.capital_base, @@ -271,6 +271,7 @@ class PerformanceTracker(): trading_environment=self.trading_environment ) + # increment the day counter before we move markers forward. self.day_count += 1.0 # calculate progress of test diff --git a/zipline/finance/trading.py b/zipline/finance/trading.py index 97d8cebb..2b088a29 100644 --- a/zipline/finance/trading.py +++ b/zipline/finance/trading.py @@ -2,6 +2,7 @@ import datetime import pytz import math import pandas +import time from collections import Counter @@ -37,8 +38,8 @@ class TradeSimulationClient(qmsg.Component): self.current_dt = trading_environment.period_start self.last_iteration_dur = datetime.timedelta(seconds=0) self.algorithm = None - self.attempts = 0 - self.max_attempts = 1000 + self.max_wait = datetime.timedelta(seconds=10) + self.last_msg_dt = datetime.datetime.utcnow() assert self.trading_environment.frame_index != None self.event_frame = pandas.DataFrame( @@ -75,7 +76,7 @@ class TradeSimulationClient(qmsg.Component): if self.result_feed in socks and \ socks[self.result_feed] == self.zmq.POLLIN: - self.attempts = 0 + self.last_msg_dt = datetime.datetime.utcnow() # get the next message from the result feed msg = self.result_feed.recv() @@ -105,10 +106,10 @@ class TradeSimulationClient(qmsg.Component): # drained. Signal the order_source that we're done, and # the done will cascade through the whole zipline. # shutdown the feedback loop to the OrderDataSource - if self.attempts > self.max_attempts: - self.signal_order_done() - else: - self.attempts += 1 + wait_time = self.last_msg_dt - datetime.datetime.utcnow() + if wait_time > self.max_wait: + self.signal_order_done() + def process_event(self, event): # track the number of transactions, for testing purposes. if(event.TRANSACTION != None): From 5fd30216e53c28bd58434210b9e8d81ca0fdc467 Mon Sep 17 00:00:00 2001 From: fawce Date: Mon, 16 Apr 2012 16:33:53 -0400 Subject: [PATCH 2/6] revised protocol to maintain original structure. --- zipline/finance/performance.py | 19 ++----- zipline/finance/trading.py | 4 +- zipline/protocol.py | 98 +++++++++++++--------------------- 3 files changed, 44 insertions(+), 77 deletions(-) diff --git a/zipline/finance/performance.py b/zipline/finance/performance.py index 390ae430..1c6c8946 100644 --- a/zipline/finance/performance.py +++ b/zipline/finance/performance.py @@ -61,8 +61,6 @@ Performance Tracking | | For details look at the comments for | | | :py:meth:`zipline.finance.risk.RiskMetrics.to_dict`| +-----------------+----------------------------------------------------+ - | timestamp | System time evevent occurs in zipilne | - +-----------------+----------------------------------------------------+ Position Tracking @@ -78,14 +76,10 @@ Position Tracking +-----------------+----------------------------------------------------+ | last_sale_price | price at last sale of the security on the exchange | +-----------------+----------------------------------------------------+ - | last_sale_date | datetime of the last trade of the position's | - | | security on the exchange | - +-----------------+----------------------------------------------------+ | transactions | all the transactions that were acrued into this | | | position. | +-----------------+----------------------------------------------------+ - | timestamp | System time event occurs in zipilne | - +-----------------+----------------------------------------------------+ + Performance Period ================== @@ -116,8 +110,7 @@ Performance Period | returns | percentage returns for the entire portfolio over the | | | period | +---------------+------------------------------------------------------+ - | timestamp | System time evevent occurs in zipilne | - +---------------+------------------------------------------------------+ + """ import datetime @@ -227,7 +220,6 @@ class PerformanceTracker(): 'cumulative_perf' : self.cumulative_performance.to_dict(), 'todays_perf' : self.todays_performance.to_dict(), 'cumulative_risk_metrics' : self.cumulative_risk_metrics.to_dict(), - 'timestamp' : datetime.datetime.now(), } def log_order(self, order): @@ -376,9 +368,7 @@ class Position(): 'sid' : self.sid, 'amount' : self.amount, 'cost_basis' : self.cost_basis, - 'last_sale_price' : self.last_sale_price, - 'last_sale_date' : self.last_sale_date, - 'timestamp' : datetime.datetime.now() + 'last_sale_price' : self.last_sale_price } @@ -444,7 +434,7 @@ class PerformancePeriod(): self.max_leverage = 1.1 * self.max_capital_used / self.starting_cash # add transaction to the list of processed transactions - self.processed_transactions.append(txn) + self.processed_transactions.append(txn.as_dict()) def round_to_nearest(self, x, base=5): return int(base * round(float(x)/base)) @@ -476,7 +466,6 @@ class PerformancePeriod(): 'ending_cash' : self.ending_cash, 'portfolio_value': self.ending_cash + self.ending_value, 'positions' : positions, - 'timestamp' : datetime.datetime.now(), 'pnl' : self.pnl, 'returns' : self.returns, 'transactions' : self.processed_transactions, diff --git a/zipline/finance/trading.py b/zipline/finance/trading.py index 2b088a29..a3bd75b5 100644 --- a/zipline/finance/trading.py +++ b/zipline/finance/trading.py @@ -38,7 +38,7 @@ class TradeSimulationClient(qmsg.Component): self.current_dt = trading_environment.period_start self.last_iteration_dur = datetime.timedelta(seconds=0) self.algorithm = None - self.max_wait = datetime.timedelta(seconds=10) + self.max_wait = datetime.timedelta(seconds=3) self.last_msg_dt = datetime.datetime.utcnow() assert self.trading_environment.frame_index != None @@ -106,7 +106,7 @@ class TradeSimulationClient(qmsg.Component): # drained. Signal the order_source that we're done, and # the done will cascade through the whole zipline. # shutdown the feedback loop to the OrderDataSource - wait_time = self.last_msg_dt - datetime.datetime.utcnow() + wait_time = datetime.datetime.utcnow() - self.last_msg_dt if wait_time > self.max_wait: self.signal_order_done() diff --git a/zipline/protocol.py b/zipline/protocol.py index 17501c05..9908d36b 100644 --- a/zipline/protocol.py +++ b/zipline/protocol.py @@ -626,71 +626,43 @@ def PERF_FRAME(perf): #TODO: add asserts... - #pull some special fields from the perf for easy access - date = perf['last_close'] + # DATE fields: + # started_at, period_start, period_end, last_close, last_open + # pos.last_sale_date + # txn.dt + + assert isinstance(perf['started_at'], datetime.datetime) + assert isinstance(perf['period_start'], datetime.datetime) + assert isinstance(perf['period_end'], datetime.datetime) + assert isinstance(perf['last_close'], datetime.datetime) + assert isinstance(perf['last_open'], datetime.datetime) + + assert isinstance(perf['todays_perf'], dict) + assert isinstance(perf['cumulative_perf'], dict) + tp = perf['todays_perf'] cp = perf['cumulative_perf'] - risk = perf['cumulative_risk_metrics'] - # aggregate the day's transactions, which are nested in their - # respsective positions. - transactions = [] + assert isinstance(tp['transactions'], list) + assert isinstance(cp['transactions'], list) + + perf['started_at'] = EPOCH(perf['started_at']) + perf['period_start'] = EPOCH(perf['period_start']) + perf['period_end'] = EPOCH(perf['period_end']) + perf['last_close'] = EPOCH(perf['last_close']) + perf['last_open'] = EPOCH(perf['last_open']) + for txn in tp['transactions']: - cur = { - 'date':EPOCH(txn.dt), - 'amount': txn.amount, - 'price': txn.price, - 'sid':txn.sid - } - transactions.append(cur) - - positions = [] - for sid, pos in tp['positions'].iteritems(): - cur = { - 'cost_basis':pos['cost_basis'], - 'sid' :pos['sid'], - 'last_sale' :pos['last_sale_price'], - 'amount' :pos['amount'] - } - positions.append(cur) - - daily_perf = { - 'date' : EPOCH(date), - 'returns' : tp['returns'], - 'pnl' : tp['pnl'], - 'market_value' : tp['ending_value'], - 'portfolio_value' : tp['portfolio_value'], - 'starting_cash' : tp['starting_cash'], - 'ending_cash' : tp['ending_cash'], - 'capital_used' : tp['capital_used'], - 'transactions' : transactions, - 'positions' : positions - } - - cumulative_perf = { - 'alpha' : risk['alpha'], - 'beta' : risk['beta'], - 'sharpe' : risk['sharpe'], - 'volatility' : risk['algo_volatility'], - 'benchmark_volatility' : risk['benchmark_volatility'], - 'benchmark_returns' : risk['benchmark_period_return'], - 'max_drawdown' : risk['max_drawdown'], - 'total_returns' : cp['returns'], - 'pnl' : cp['pnl'], - 'capital_used' : cp['capital_used'] - - } + txn['dt'] = EPOCH(txn['dt']) - # nest the cumulative performance data in the daily. - daily_perf['cumulative'] = cumulative_perf - - result = { - 'started_at' : EPOCH(perf['started_at']), - 'daily' : [daily_perf], - 'percent_complete' : perf['progress'], - } + for txn in cp['transactions']: + txn['dt'] = EPOCH(txn['dt']) + - return msgpack.dumps(tuple(['PERF', result])) + for dr in perf['returns']: + dr['dt'] = EPOCH(dr['dt']) + + return msgpack.dumps(tuple(['PERF', perf])) def RISK_FRAME(risk): @@ -698,7 +670,7 @@ def RISK_FRAME(risk): def PERF_UNFRAME(msg): - prefix, payload = msgpack.loads(msg) + prefix, payload = msgpack.loads(msg, use_list=True) return dict(prefix=prefix, payload=payload) # ----------------------- @@ -730,6 +702,12 @@ def EPOCH(utc_datetime): ms = seconds * 1000 return ms +def UN_EPOCH(ms_since_epoch): + seconds_since_epoch = ms_since_epoch / 1000 + delta = datetime.timedelta(seconds = seconds_since_epoch) + dt = UNIX_EPOCH + delta + return dt + def PACK_DATE(event): """ Packs the datetime property of event into msgpack'able longs. From 309f78a03083cf7343b8d4eef54e315d721c5ecd Mon Sep 17 00:00:00 2001 From: fawce Date: Mon, 16 Apr 2012 22:09:16 -0400 Subject: [PATCH 3/6] modification of the transport protocol -- keeping it close to the export of data from the performance tracker. --- zipline/finance/performance.py | 17 +++++++++++++---- zipline/finance/trading.py | 2 +- zipline/protocol.py | 31 +++++++++++++++++++++---------- zipline/test/algorithms.py | 34 +++++++++++++++++++++++++++++++++- 4 files changed, 68 insertions(+), 16 deletions(-) diff --git a/zipline/finance/performance.py b/zipline/finance/performance.py index 1c6c8946..ce1c9bcb 100644 --- a/zipline/finance/performance.py +++ b/zipline/finance/performance.py @@ -218,7 +218,7 @@ class PerformanceTracker(): 'capital_base' : self.capital_base, 'returns' : returns_list, 'cumulative_perf' : self.cumulative_performance.to_dict(), - 'todays_perf' : self.todays_performance.to_dict(), + 'daily_perf' : self.todays_performance.to_dict(), 'cumulative_risk_metrics' : self.cumulative_risk_metrics.to_dict(), } @@ -434,7 +434,7 @@ class PerformancePeriod(): self.max_leverage = 1.1 * self.max_capital_used / self.starting_cash # add transaction to the list of processed transactions - self.processed_transactions.append(txn.as_dict()) + self.processed_transactions.append(txn) def round_to_nearest(self, x, base=5): return int(base * round(float(x)/base)) @@ -456,7 +456,8 @@ class PerformancePeriod(): Creates a dictionary representing the state of this performance period. See header comments for a detailed description. """ - positions = self.get_positions() + positions = self.get_positions_list() + transactions = [x.as_dict() for x in self.processed_transactions] return { 'ending_value' : self.ending_value, @@ -468,7 +469,7 @@ class PerformancePeriod(): 'positions' : positions, 'pnl' : self.pnl, 'returns' : self.returns, - 'transactions' : self.processed_transactions, + 'transactions' : transactions, } def to_namedict(self): @@ -502,6 +503,14 @@ class PerformancePeriod(): return positions + # + def get_positions_list(self): + positions = [] + for sid, pos in self.positions.iteritems(): + cur = pos.to_dict() + positions.append(cur) + return positions + diff --git a/zipline/finance/trading.py b/zipline/finance/trading.py index a3bd75b5..ca357976 100644 --- a/zipline/finance/trading.py +++ b/zipline/finance/trading.py @@ -38,7 +38,7 @@ class TradeSimulationClient(qmsg.Component): self.current_dt = trading_environment.period_start self.last_iteration_dur = datetime.timedelta(seconds=0) self.algorithm = None - self.max_wait = datetime.timedelta(seconds=3) + self.max_wait = datetime.timedelta(seconds=7) self.last_msg_dt = datetime.datetime.utcnow() assert self.trading_environment.frame_index != None diff --git a/zipline/protocol.py b/zipline/protocol.py index 9908d36b..ead035f2 100644 --- a/zipline/protocol.py +++ b/zipline/protocol.py @@ -637,14 +637,16 @@ def PERF_FRAME(perf): assert isinstance(perf['last_close'], datetime.datetime) assert isinstance(perf['last_open'], datetime.datetime) - assert isinstance(perf['todays_perf'], dict) + assert isinstance(perf['daily_perf'], dict) assert isinstance(perf['cumulative_perf'], dict) - tp = perf['todays_perf'] + tp = perf['daily_perf'] cp = perf['cumulative_perf'] assert isinstance(tp['transactions'], list) assert isinstance(cp['transactions'], list) + assert isinstance(tp['positions'], list) + assert isinstance(cp['positions'], list) perf['started_at'] = EPOCH(perf['started_at']) perf['period_start'] = EPOCH(perf['period_start']) @@ -652,18 +654,27 @@ def PERF_FRAME(perf): perf['last_close'] = EPOCH(perf['last_close']) perf['last_open'] = EPOCH(perf['last_open']) - for txn in tp['transactions']: - txn['dt'] = EPOCH(txn['dt']) - - for txn in cp['transactions']: - txn['dt'] = EPOCH(txn['dt']) - - + tp['transactions'] = convert_transactions(tp['transactions']) + cp['transactions'] = convert_transactions(cp['transactions']) + + returns = [] for dr in perf['returns']: - dr['dt'] = EPOCH(dr['dt']) + updated = {} + updated['returns'] = dr['returns'] + updated['date'] = EPOCH(dr['dt']) + returns.append(updated) + + perf['returns'] = returns return msgpack.dumps(tuple(['PERF', perf])) +def convert_transactions(transactions): + results = [] + for txn in transactions: + txn['date'] = EPOCH(txn['dt']) + del(txn['dt']) + results.append(txn) + return results def RISK_FRAME(risk): return msgpack.dumps(tuple(['RISK', risk])) diff --git a/zipline/test/algorithms.py b/zipline/test/algorithms.py index 3a7bfc4d..17873d27 100644 --- a/zipline/test/algorithms.py +++ b/zipline/test/algorithms.py @@ -76,7 +76,39 @@ class TestAlgorithm(): self.incr += 1 def get_sid_filter(self): - return [self.sid] + return [self.sid] + +# +class HeavyBuyAlgorithm(): + """ + This algorithm will send a specified number of orders, to allow unit tests + to verify the orders sent/received, transactions created, and positions + at the close of a simulation. + """ + + def __init__(self, sid, amount): + self.sid = sid + self.amount = amount + self.incr = 0 + self.done = False + self.order = None + self.frame_count = 0 + self.portfolio = None + + def set_order(self, order_callable): + self.order = order_callable + + def set_portfolio(self, portfolio): + self.portfolio = portfolio + + def handle_frame(self, frame): + self.frame_count += 1 + #place an order for 100 shares of sid + self.order(self.sid, self.amount) + self.incr += 1 + + def get_sid_filter(self): + return [self.sid] class NoopAlgorithm(object): """ From 7eb0ba67ac0daf4dc0232ed9143f05e44d78ca76 Mon Sep 17 00:00:00 2001 From: fawce Date: Tue, 17 Apr 2012 17:54:25 -0400 Subject: [PATCH 4/6] clarifying the results protocol for the backtest. --- zipline/finance/risk.py | 8 ++++---- zipline/finance/trading.py | 26 ++++++++++++-------------- zipline/protocol.py | 26 ++++++++++++++++++-------- 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/zipline/finance/risk.py b/zipline/finance/risk.py index 7fa1d103..fc4bb076 100644 --- a/zipline/finance/risk.py +++ b/zipline/finance/risk.py @@ -352,10 +352,10 @@ class RiskReport(): provided for each period. """ return { - '1_month' : [x.to_dict() for x in self.month_periods], - '3_month' : [x.to_dict() for x in self.three_month_periods], - '6_month' : [x.to_dict() for x in self.six_month_periods], - '12_month' : [x.to_dict() for x in self.year_periods] + 'one_month' : [x.to_dict() for x in self.month_periods], + 'three_month' : [x.to_dict() for x in self.three_month_periods], + 'six_month' : [x.to_dict() for x in self.six_month_periods], + 'twelve_month' : [x.to_dict() for x in self.year_periods] } def periodsInRange(self, months_per, start, end): diff --git a/zipline/finance/trading.py b/zipline/finance/trading.py index ca357976..045f9471 100644 --- a/zipline/finance/trading.py +++ b/zipline/finance/trading.py @@ -421,20 +421,7 @@ class TransactionSimulator(qmsg.BaseTransform): # we cap the volume share at 25% of a trade if volume_share == .25: break - - if simulated_amount == 0: - warning = """ -Calculated a zero volume transation on trade: -{event} -for order: -{order} - """ - warning = warning.format( - event=str(event), - order=str(order) - ) - qutil.LOGGER.warn(warning) - + orders = [ x for x in orders if abs(x.amount - x.filled) > 0 and x.dt.day >= event.dt.day] self.open_orders[event.sid] = orders @@ -449,6 +436,17 @@ for order: direction ) else: + warning = """ +Calculated a zero volume transaction on trade: +{event} +for order: +{order} + """ + warning = warning.format( + event=str(event), + order=str(order) + ) + qutil.LOGGER.warn(warning) return None diff --git a/zipline/protocol.py b/zipline/protocol.py index ead035f2..5663b5d7 100644 --- a/zipline/protocol.py +++ b/zipline/protocol.py @@ -615,10 +615,8 @@ def PERF_FRAME(perf): """ Frame the performance update created at the end of each simulated trading day. The msgpack is a tuple with the first element statically set to 'PERF'. - Frames prepared by this method are sent via the same socket as - Frames prepared by RISK_FRAME. So, both methods prefix the payload with - a shorthand for their type. That way, all messages received from the socket - can be PERF_UNFRAMED(), whether they are risk or perf. + Like RISK_FRAME, this method calls BT_UPDATE_FRAME internally, so that + clients can call BT_UPDATE_UNFRAME for all messages from the backtest. :param perf: the dictionary created by zipline.trade_client.perf :rvalue: a msgpack string @@ -666,7 +664,7 @@ def PERF_FRAME(perf): perf['returns'] = returns - return msgpack.dumps(tuple(['PERF', perf])) + return BT_UPDATE_FRAME('PERF', perf) def convert_transactions(transactions): results = [] @@ -677,10 +675,22 @@ def convert_transactions(transactions): return results def RISK_FRAME(risk): - return msgpack.dumps(tuple(['RISK', risk])) + return BT_UPDATE_FRAME('RISK', risk) - -def PERF_UNFRAME(msg): +def BT_UPDATE_FRAME(prefix, payload): + """ + Frames prepared by RISK_FRAME and PERF_FRAME methods are sent via the same + socket. This method provides a prefix to allow for muxing the messages + onto a single socket. + """ + return msgpack.dumps(tuple([prefix, payload])) + +def BT_UPDATE_UNFRAME(msg): + """ + Risk and Perf framing methods prefix the payload with + a shorthand for their type. That way, all messages received from the socket + can be PERF_FRAMED(), whether they are risk or perf. + """ prefix, payload = msgpack.loads(msg, use_list=True) return dict(prefix=prefix, payload=payload) From 6561292e4cabbe0018d326ae40092cfff53ffc0c Mon Sep 17 00:00:00 2001 From: fawce Date: Wed, 18 Apr 2012 10:55:21 -0400 Subject: [PATCH 5/6] some efficiency changes - no longer transferring the list of daily returns, no longer holding transactions in the daily and the cumulative performance periods. --- zipline/finance/performance.py | 13 +++++++++---- zipline/finance/trading.py | 6 +++--- zipline/protocol.py | 16 +--------------- zipline/test/test_finance.py | 8 -------- 4 files changed, 13 insertions(+), 30 deletions(-) diff --git a/zipline/finance/performance.py b/zipline/finance/performance.py index ce1c9bcb..9eb936a2 100644 --- a/zipline/finance/performance.py +++ b/zipline/finance/performance.py @@ -178,7 +178,9 @@ class PerformanceTracker(): # initial portfolio positions have zero value 0, # initial cash is your capital base. - starting_cash = self.capital_base + starting_cash = self.capital_base, + # save the transactions for the daily periods + keep_transactions = True ) def get_portfolio(self): @@ -288,7 +290,8 @@ class PerformanceTracker(): self.todays_performance = PerformancePeriod( self.todays_performance.positions, self.todays_performance.ending_value, - self.todays_performance.ending_cash + self.todays_performance.ending_cash, + keep_transactions = True ) def handle_simulation_end(self): @@ -374,7 +377,7 @@ class Position(): class PerformancePeriod(): - def __init__(self, initial_positions, starting_value, starting_cash): + def __init__(self, initial_positions, starting_value, starting_cash, keep_transactions=False): self.ending_value = 0.0 self.period_capital_used = 0.0 self.pnl = 0.0 @@ -384,6 +387,7 @@ class PerformancePeriod(): #cash balance at start of period self.starting_cash = starting_cash self.ending_cash = starting_cash + self.keep_transactions = keep_transactions self.processed_transactions = [] self.cumulative_capital_used = 0.0 self.max_capital_used = 0.0 @@ -434,7 +438,8 @@ class PerformancePeriod(): self.max_leverage = 1.1 * self.max_capital_used / self.starting_cash # add transaction to the list of processed transactions - self.processed_transactions.append(txn) + if self.keep_transactions: + self.processed_transactions.append(txn) def round_to_nearest(self, x, base=5): return int(base * round(float(x)/base)) diff --git a/zipline/finance/trading.py b/zipline/finance/trading.py index 045f9471..9a950e61 100644 --- a/zipline/finance/trading.py +++ b/zipline/finance/trading.py @@ -439,12 +439,12 @@ class TransactionSimulator(qmsg.BaseTransform): warning = """ Calculated a zero volume transaction on trade: {event} -for order: -{order} +for orders: +{orders} """ warning = warning.format( event=str(event), - order=str(order) + orders=str(orders) ) qutil.LOGGER.warn(warning) return None diff --git a/zipline/protocol.py b/zipline/protocol.py index 5663b5d7..4cdc54f4 100644 --- a/zipline/protocol.py +++ b/zipline/protocol.py @@ -623,11 +623,6 @@ def PERF_FRAME(perf): """ #TODO: add asserts... - - # DATE fields: - # started_at, period_start, period_end, last_close, last_open - # pos.last_sale_date - # txn.dt assert isinstance(perf['started_at'], datetime.datetime) assert isinstance(perf['period_start'], datetime.datetime) @@ -654,16 +649,7 @@ def PERF_FRAME(perf): tp['transactions'] = convert_transactions(tp['transactions']) cp['transactions'] = convert_transactions(cp['transactions']) - - returns = [] - for dr in perf['returns']: - updated = {} - updated['returns'] = dr['returns'] - updated['date'] = EPOCH(dr['dt']) - returns.append(updated) - - perf['returns'] = returns - + return BT_UPDATE_FRAME('PERF', perf) def convert_transactions(transactions): diff --git a/zipline/test/test_finance.py b/zipline/test/test_finance.py index 2ff7da61..a85f220d 100644 --- a/zipline/test/test_finance.py +++ b/zipline/test/test_finance.py @@ -139,14 +139,6 @@ class FinanceTestCase(TestCase): zipline.trading_client.order_count ) - # the number of transactions in the performance tracker's cumulative - # period should be the same as the number of orders place by the - # algorithm. - self.assertEqual( - zipline.trading_client.order_count, - len(zipline.trading_client.perf.cumulative_performance.processed_transactions) - ) - @timed(EXTENDED_TIMEOUT) def test_aggressive_buying(self): From 1b5b92d75f0e5c08f47ac1629af0fdcc719f0892 Mon Sep 17 00:00:00 2001 From: fawce Date: Wed, 18 Apr 2012 12:27:09 -0400 Subject: [PATCH 6/6] dropped unwanted fields. --- zipline/finance/performance.py | 8 -------- zipline/protocol.py | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/zipline/finance/performance.py b/zipline/finance/performance.py index 9eb936a2..8fd3d3d6 100644 --- a/zipline/finance/performance.py +++ b/zipline/finance/performance.py @@ -38,10 +38,6 @@ Performance Tracking +-----------------+----------------------------------------------------+ | capital_base | The initial capital assumed for this tracker. | +-----------------+----------------------------------------------------+ - | returns | List of dicts representing daily returns. See the | - | | comments for | - | | :py:meth:`zipline.finance.risk.DailyReturn.to_dict`| - +-----------------+----------------------------------------------------+ | cumulative_perf | A dictionary representing the cumulative | | | performance through all the events delivered to | | | this tracker. For details see the comments on | @@ -205,9 +201,6 @@ class PerformanceTracker(): Creates a dictionary representing the state of this tracker. Returns a dict object of the form described in header comments. """ - - returns_list = [x.to_dict() for x in self.returns] - return { 'started_at' : self.started_at, 'period_start' : self.period_start, @@ -218,7 +211,6 @@ class PerformanceTracker(): 'last_close' : self.market_close, 'last_open' : self.market_open, 'capital_base' : self.capital_base, - 'returns' : returns_list, 'cumulative_perf' : self.cumulative_performance.to_dict(), 'daily_perf' : self.todays_performance.to_dict(), 'cumulative_risk_metrics' : self.cumulative_risk_metrics.to_dict(), diff --git a/zipline/protocol.py b/zipline/protocol.py index 4cdc54f4..b3558b6e 100644 --- a/zipline/protocol.py +++ b/zipline/protocol.py @@ -649,7 +649,7 @@ def PERF_FRAME(perf): tp['transactions'] = convert_transactions(tp['transactions']) cp['transactions'] = convert_transactions(cp['transactions']) - + return BT_UPDATE_FRAME('PERF', perf) def convert_transactions(transactions):