mirror of
https://github.com/wassname/catalyst.git
synced 2026-07-11 07:28:22 +08:00
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:
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -544,6 +544,7 @@ class PerformancePeriod(object):
|
||||
del(portfolio['max_capital_used'])
|
||||
|
||||
portfolio['positions'] = self.get_positions()
|
||||
|
||||
return ndict(portfolio)
|
||||
|
||||
def get_positions(self):
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user