diff --git a/tests/test_algorithm_gen.py b/tests/test_algorithm_gen.py index c878d3a5..dac9b0ae 100644 --- a/tests/test_algorithm_gen.py +++ b/tests/test_algorithm_gen.py @@ -159,3 +159,17 @@ class AlgorithmGeneratorTestCase(TestCase): gen = algo.get_generator() results = list(gen) self.assertEqual(results[-2]['progress'], 1.0) + + def test_benchmark_times_match_market_close_for_minutely_data(self): + """ + Benchmark dates should be adjusted so that benchmark events are + emitted at the end of each trading day when working with minutely + data. + Verification relies on the fact that there are no trades so + algo.datetime should be equal to the last benchmark time. + See https://github.com/quantopian/zipline/issues/241 + """ + sim_params = factory.create_simulation_parameters(num_days=1) + algo = TestAlgo(self, sim_params=sim_params, data_frequency='minute') + algo.run(source=[]) + self.assertEqual(algo.datetime, sim_params.last_close) diff --git a/tests/test_tradesimulation.py b/tests/test_tradesimulation.py new file mode 100644 index 00000000..24dcf006 --- /dev/null +++ b/tests/test_tradesimulation.py @@ -0,0 +1,28 @@ +# +# Copyright 2014 Quantopian, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from unittest import TestCase +from zipline.test_algorithms import NoopAlgorithm +from zipline.utils import factory + + +class TestTradeSimulation(TestCase): + + def test_minutely_emissions_generate_performance_stats_for_last_day(self): + params = factory.create_simulation_parameters(num_days=1) + params.emission_rate = 'minute' + algo = NoopAlgorithm() + algo.run(source=[], sim_params=params) + self.assertEqual(algo.perf_tracker.day_count, 1.0) diff --git a/zipline/algorithm.py b/zipline/algorithm.py index 01b1fc54..829d5f0b 100644 --- a/zipline/algorithm.py +++ b/zipline/algorithm.py @@ -59,6 +59,7 @@ DEFAULT_CAPITAL_BASE = float("1.0e5") class TradingAlgorithm(object): + """ Base class for trading algorithms. Inherit and overload initialize() and handle_data(data). @@ -83,6 +84,7 @@ class TradingAlgorithm(object): stats = my_algo.run(data) """ + def __init__(self, *args, **kwargs): """Initialize sids and other state variables. @@ -227,8 +229,14 @@ class TradingAlgorithm(object): skipped. """ if self.benchmark_return_source is None: + env = trading.environment + if (self.data_frequency == 'minute' + or sim_params.emission_rate == 'minute'): + update_time = lambda date: env.get_open_and_close(date)[1] + else: + update_time = lambda date: date benchmark_return_source = [ - Event({'dt': dt, + Event({'dt': update_time(dt), 'returns': ret, 'type': zipline.protocol.DATASOURCE_TYPE.BENCHMARK, 'source_id': 'benchmarks'}) diff --git a/zipline/gens/tradesimulation.py b/zipline/gens/tradesimulation.py index 715ec468..c95b63de 100644 --- a/zipline/gens/tradesimulation.py +++ b/zipline/gens/tradesimulation.py @@ -188,7 +188,7 @@ class AlgorithmSimulator(object): yield daily_rollup tp = self.algo.perf_tracker.todays_performance tp.rollover() - if mkt_close < self.algo.perf_tracker.last_close: + if mkt_close <= self.algo.perf_tracker.last_close: _, mkt_close = \ trading.environment.next_open_and_close( mkt_close diff --git a/zipline/test_algorithms.py b/zipline/test_algorithms.py index 614476ea..3b74d70f 100644 --- a/zipline/test_algorithms.py +++ b/zipline/test_algorithms.py @@ -131,9 +131,15 @@ class NoopAlgorithm(TradingAlgorithm): def get_sid_filter(self): return [] + def initialize(self): + pass + def set_transact_setter(self, txn_sim_callable): pass + def handle_data(self, data): + pass + class ExceptionAlgorithm(TradingAlgorithm): """