Locks down the ability to easily override the algo's portfolio.

Starting down the path of making the portfolio completely read-only
with respect to the handle_data in algo.

The portfolio should only be changed during the course of running
the algorithm by the simulator.

This doesn't do a 100% protection, i.e. an algo could use _portfolio,
or the set_attr property, but hoping this helps guides algo writing
to treat the portfolio as read-only.
This commit is contained in:
Eddie Hebert
2012-11-02 16:32:50 -04:00
parent 96ba4c7d6c
commit 086c12ddf8
4 changed files with 45 additions and 2 deletions
+23
View File
@@ -19,6 +19,7 @@ import zipline.utils.simfactory as simfactory
from zipline.test_algorithms import (
ExceptionAlgorithm,
DivByZeroAlgorithm,
SetPortfolioAlgorithm,
)
from zipline.finance.slippage import FixedSlippage
from zipline.transforms.utils import StatefulTransform
@@ -113,3 +114,25 @@ class ExceptionTestCase(TestCase):
self.assertEqual(ctx.exception.message,
'integer division or modulo by zero')
def test_set_portfolio(self):
"""
Are we protected against overwriting an algo's portfolio?
"""
# Simulation
# ----------
self.zipline_test_config['algorithm'] = \
SetPortfolioAlgorithm(
self.zipline_test_config['sid']
)
zipline = simfactory.create_test_zipline(
**self.zipline_test_config
)
with self.assertRaises(AttributeError) as ctx:
output, _ = drain_zipline(self, zipline)
self.assertEqual(ctx.exception.message,
"can't set attribute")
+6 -2
View File
@@ -66,7 +66,7 @@ class TradingAlgorithm(object):
self.done = False
self.order = None
self.frame_count = 0
self.portfolio = None
self._portfolio = None
self.datetime = None
self.registered_transforms = {}
@@ -217,8 +217,12 @@ class TradingAlgorithm(object):
'args': args,
'kwargs': kwargs}
@property
def portfolio(self):
return self._portfolio
def set_portfolio(self, portfolio):
self.portfolio = portfolio
self._portfolio = portfolio
def set_order(self, order_callable):
self.order = order_callable
+1
View File
@@ -544,6 +544,7 @@ class PerformancePeriod(object):
del(portfolio['max_capital_used'])
portfolio['positions'] = self.get_positions()
return ndict(portfolio)
def get_positions(self):
+15
View File
@@ -283,3 +283,18 @@ class BatchTransformAlgorithm(TradingAlgorithm):
self.history_return_args.append(
self.return_args_batch.handle_data(
data, *self.args, **self.kwargs))
class SetPortfolioAlgorithm(TradingAlgorithm):
"""
An algorithm that tries to set the portfolio directly.
The portfolio should be treated as a read-only object
within the algorithm.
"""
def initialize(self, *args, **kwargs):
pass
def handle_data(self, data):
self.portfolio = 3