From 7491e1f88ea4f3c3cc585f5352b9363bf3a046e5 Mon Sep 17 00:00:00 2001 From: Thomas Wiecki Date: Thu, 23 Aug 2012 14:33:25 -0400 Subject: [PATCH] Resolved internal conflict due to stashing. --- tests/test_optimize.py | 1 + zipline/gens/tradegens.py | 4 +++ zipline/optimize/algorithms.py | 61 +++++++++++++++++++++++++++------- zipline/optimize/factory.py | 44 ++++++++++-------------- 4 files changed, 71 insertions(+), 39 deletions(-) diff --git a/tests/test_optimize.py b/tests/test_optimize.py index 806f2dc3..52e27bb8 100644 --- a/tests/test_optimize.py +++ b/tests/test_optimize.py @@ -47,6 +47,7 @@ class TestUpDown(TestCase): UpDownSource and BuySellAlgorithm interact correctly." """ + zipline, config = create_predictable_zipline( self.zipline_test_config, offset=0, diff --git a/zipline/gens/tradegens.py b/zipline/gens/tradegens.py index 30d575aa..5716f374 100644 --- a/zipline/gens/tradegens.py +++ b/zipline/gens/tradegens.py @@ -7,7 +7,11 @@ import pytz from itertools import chain, cycle, ifilter, izip, repeat from datetime import datetime, timedelta +import pandas as pd +from copy import copy +from zipline.protocol import DATASOURCE_TYPE +from zipline.utils import ndict from zipline.gens.utils import hash_args, create_trade def date_gen(start = datetime(2006, 6, 6, 12, tzinfo=pytz.utc), diff --git a/zipline/optimize/algorithms.py b/zipline/optimize/algorithms.py index b901bc4c..dc80ef5a 100644 --- a/zipline/optimize/algorithms.py +++ b/zipline/optimize/algorithms.py @@ -46,9 +46,6 @@ class BuySellAlgorithm(object): def set_portfolio(self, portfolio): self.portfolio = portfolio - def set_logger(self, logger): - self.logger = logger - def handle_data(self, frame): order_size = self.buy_or_sell * (self.amount - (self.offset**2)) self.order(self.sid, order_size) @@ -76,15 +73,16 @@ class TradingAlgorithm(object): # Create transforms by wrapping them into StatefulTransforms transforms = [] - for namestring, trans_descr in self.registered_transforms.iteritems(): - sf = StatefulTransform( - trans_descr['class'], - *trans_descr['args'], - **trans_descr['kwargs'] - ) - sf.namestring = namestring + if hasattr(self, 'registered_transforms'): + for namestring, trans_descr in self.registered_transforms.iteritems(): + sf = StatefulTransform( + trans_descr['class'], + *trans_descr['args'], + **trans_descr['kwargs'] + ) + sf.namestring = namestring - transforms.append(sf) + transforms.append(sf) style = SIMULATION_STYLE.FIXED_SLIPPAGE @@ -95,6 +93,7 @@ class TradingAlgorithm(object): self, environment, style) + #self.simulated_trading.trading_client.performance_tracker.compute_risk_metrics = compute_risk_metrics @@ -119,7 +118,7 @@ class TradingAlgorithm(object): self._setup(compute_risk_metrics=compute_risk_metrics) # drain simulated_trading - perfs = list(self.simulated_trading) + perfs = [perf for perf in self.simulated_trading] daily_stats = self._create_daily_stats(perfs) return daily_stats @@ -146,3 +145,41 @@ class TradingAlgorithm(object): self.registered_transforms[tag] = {'class': transform_class, 'args': args, 'kwargs': kwargs} + + +class BuySellAlgorithmNew(TradingAlgorithm): + """Algorithm that buys and sells alternatingly. The amount for + each order can be specified. In addition, an offset that will + quadratically reduce the amount that will be bought can be + specified. + + This algorithm is used to test the parameter optimization + framework. If combined with the UpDown trade source, an offset of + 0 will produce maximum returns. + + """ + + def __init__(self, sids, amount, offset): + self.sids = sids + self.amount = amount + self.incr = 0 + self.done = False + self.order = None + self.frame_count = 0 + self.portfolio = None + self.buy_or_sell = -1 + self.offset = offset + self.orders = [] + self.prices = [] + + def handle_data(self, data): + order_size = self.buy_or_sell * (self.amount - (self.offset**2)) + self.order(self.sid, order_size) + + #sell next time around. + self.buy_or_sell *= -1 + + self.orders.append(order_size) + + self.frame_count += 1 + self.incr += 1 diff --git a/zipline/optimize/factory.py b/zipline/optimize/factory.py index ff91dd35..85ee2c34 100644 --- a/zipline/optimize/factory.py +++ b/zipline/optimize/factory.py @@ -1,21 +1,22 @@ + """ Factory functions to prepare useful data for optimize tests. Author: Thomas V. Wiecki (thomas.wiecki@gmail.com), 2012 """ from datetime import timedelta +import pandas as pd +from copy import copy +from itertools import cycle import zipline.protocol as zp from zipline.utils.factory import get_next_trading_dt, create_trading_environment -from zipline.gens.tradegens import SpecificEquityTrades -from zipline.optimize.algorithms import BuySellAlgorithm +from zipline.gens.tradegens import SpecificEquityTrades, DataFrameSource +from zipline.optimize.algorithms import BuySellAlgorithmNew from zipline.lines import SimulatedTrading from zipline.finance.trading import SIMULATION_STYLE -from copy import copy -from itertools import cycle - def create_updown_trade_source(sid, trade_count, trading_environment, base_price, amplitude): """Create the updown trade source. This source emits events with the price going up and down by the same amount in each @@ -38,8 +39,6 @@ def create_updown_trade_source(sid, trade_count, trading_environment, base_price source : SpecificEquityTrades The trade source emitting up down events. """ - volume = 1000 - events = [] price = base_price-amplitude/2. cur = trading_environment.first_open @@ -47,27 +46,18 @@ def create_updown_trade_source(sid, trade_count, trading_environment, base_price #create iterator to cycle through up and down phases change = cycle([1,-1]) - + prices = [] + dts = [] for i in xrange(trade_count + 2): cur = get_next_trading_dt(cur, one_day, trading_environment) - - event = zp.ndict({ - "type" : zp.DATASOURCE_TYPE.TRADE, - "sid" : sid, - "price" : price, - "volume" : volume, - "dt" : cur, - }) - - events.append(event) + dts.append(cur) + prices.append(price) price += change.next()*amplitude - trading_environment.period_end = cur + df = pd.DataFrame(index=dts, data=prices, columns=[0]) - source = SpecificEquityTrades(event_list=events) - - return source + return df def create_predictable_zipline(config, offset=0, simulate=True): @@ -121,7 +111,7 @@ def create_predictable_zipline(config, offset=0, simulate=True): amplitude) if 'algorithm' not in config: - config['algorithm'] = BuySellAlgorithm(sid, 100, offset) + algorithm = BuySellAlgorithmNew(sid, 100, offset) config['order_count'] = trade_count - 1 config['trade_count'] = trade_count @@ -130,9 +120,9 @@ def create_predictable_zipline(config, offset=0, simulate=True): config['simulation_style'] = SIMULATION_STYLE.FIXED_SLIPPAGE config['devel'] = True - zipline = SimulatedTrading.create_test_zipline(**config) - if simulate: - zipline.drain_zipline(blocking=True) + algorithm.run() + + return algorithm, config + - return zipline, config