<NME> trading.py
<BEF> #
# Copyright 2016 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.

import logbook
import pandas as pd

from zipline.utils.memoize import remember_last
from zipline.utils.pandas_utils import normalize_date

log = logbook.Logger('Trading')


DEFAULT_CAPITAL_BASE = 1e5


class SimulationParameters(object):
    def __init__(self,
                 start_session,
                 end_session,
                 trading_calendar,
                 capital_base=DEFAULT_CAPITAL_BASE,
                 emission_rate='daily',
                 data_frequency='daily',
                 arena='backtest'):

        assert type(start_session) == pd.Timestamp
        assert type(end_session) == pd.Timestamp

        assert trading_calendar is not None, \
            "Must pass in trading calendar!"
        assert start_session <= end_session, \
            "Period start falls after period end."
        assert start_session <= trading_calendar.last_trading_session, \
            "Period start falls after the last known trading day."
        assert end_session >= trading_calendar.first_trading_session, \
            "Period end falls before the first known trading day."

        # chop off any minutes or hours on the given start and end dates,
        # as we only support session labels here (and we represent session
        # labels as midnight UTC).
        self._start_session = normalize_date(start_session)
        self._end_session = normalize_date(end_session)
        self._capital_base = capital_base

        self._emission_rate = emission_rate
        self._data_frequency = data_frequency

        # copied to algorithm's environment for runtime access
        self._arena = arena

        self._trading_calendar = trading_calendar

        if not trading_calendar.is_session(self._start_session):
            # if the start date is not a valid session in this calendar,
            # push it forward to the first valid session
            self._start_session = trading_calendar.minute_to_session_label(
                self._start_session
            )

        if not trading_calendar.is_session(self._end_session):
            # if the end date is not a valid session in this calendar,
environment = None


def exchange_dt_in_utc(dt):
    delorean = Delorean(dt, dt.tzinfo)
    return delorean.shift(pytz.utc.zone).datetime


class TransactionSimulator(object):

    def __init__(self):
        self._first_open = trading_calendar.open_and_close_for_session(
            self._start_session
        )[0]
        self._last_close = trading_calendar.open_and_close_for_session(
            self._end_session
        )[1]

    @property
    def capital_base(self):
        return self._capital_base

    @property
    def emission_rate(self):
        return self._emission_rate

    @property
    def data_frequency(self):
        return self._data_frequency

    @data_frequency.setter
    def data_frequency(self, val):
        self._data_frequency = val

    @property
    def arena(self):
        return self._arena

    @arena.setter
    def arena(self, val):
        self._arena = val

    @property
    def start_session(self):
        return self._start_session

    @property
    def end_session(self):
        return self._end_session

    @property
    def first_open(self):
        return self._first_open

    @property
    def last_close(self):
        return self._last_close

    @property
    def trading_calendar(self):
        return self._trading_calendar

    @property
    @remember_last
    def sessions(self):
        return self._trading_calendar.sessions_in_range(
            self.start_session,
            self.end_session
        )

    def create_new(self, start_session, end_session, data_frequency=None):
        if data_frequency is None:
            data_frequency = self.data_frequency

        return SimulationParameters(
            start_session,
            end_session,
            self._trading_calendar,
            capital_base=self.capital_base,
            emission_rate=self.emission_rate,
            data_frequency=data_frequency,
            arena=self.arena
            tzinfo=pytz.utc
        )

    @property
    def period_trading_days(self):
        if self._period_trading_days is None:
    first_open={first_open},
    last_close={last_close},
    trading_calendar={trading_calendar}
)\
""".format(class_name=self.__class__.__name__,
           start_session=self.start_session,
           end_session=self.end_session,
           capital_base=self.capital_base,
           data_frequency=self.data_frequency,
           emission_rate=self.emission_rate,
           first_open=self.first_open,
           last_close=self.last_close,
           trading_calendar=self._trading_calendar)
        )
        # create a new Delorean with the next_open naive date and
        # the correct timezone for the exchange.
        open_delorean = Delorean(next_open, self.exchange_tz)
        open_utc = open_delorean.shift(pytz.utc.zone).datetime

        market_open = open_utc
        market_close = market_open + self.get_trading_day_duration(open_utc)

<MSG> MAINT: Moves exchange to utc conversion inside of environment object.

So that the environments' exchange time is used without having to
specify it independently.

Also, moves uses of Delorean.shift for the exchange conversion inside
of environment to use the exchange_dt_to_utc method.

<DFF> @@ -74,11 +74,6 @@ log = logbook.Logger('Transaction Simulator')
 environment = None
 
 
-def exchange_dt_in_utc(dt):
-    delorean = Delorean(dt, dt.tzinfo)
-    return delorean.shift(pytz.utc.zone).datetime
-
-
 class TransactionSimulator(object):
 
     def __init__(self):
@@ -156,6 +151,10 @@ class TradingEnvironment(object):
             tzinfo=pytz.utc
         )
 
+    def exchange_dt_in_utc(self, dt):
+        delorean = Delorean(dt, self.exchange_tz)
+        return delorean.shift(pytz.utc.zone).datetime
+
     @property
     def period_trading_days(self):
         if self._period_trading_days is None:
@@ -223,8 +222,7 @@ Last successful date: %s" % self.market_open)
         )
         # create a new Delorean with the next_open naive date and
         # the correct timezone for the exchange.
-        open_delorean = Delorean(next_open, self.exchange_tz)
-        open_utc = open_delorean.shift(pytz.utc.zone).datetime
+        open_utc = self.exchange_dt_in_utc(next_open)
 
         market_open = open_utc
         market_close = market_open + self.get_trading_day_duration(open_utc)

{'commit': 'diff --git a/tests/test_perf_tracking.py b/tests/test_perf_tracking.py\nindex 45445e7b..1cfacfcd 100644\n--- a/tests/test_perf_tracking.py\n+++ b/tests/test_perf_tracking.py\n@@ -1033,11 +1033,10 @@ class TestPerformanceTracker(unittest.TestCase):\n \n     def test_minute_tracker(self):\n         """ Tests minute performance tracking."""\n-        exc_tz = pytz.timezone(\'US/Eastern\')\n-        start_dt = trading.exchange_dt_in_utc(\n-            datetime.datetime(2013, 3, 1, 9, 30, tzinfo=exc_tz))\n-        end_dt = trading.exchange_dt_in_utc(\n-            datetime.datetime(2013, 3, 1, 16, 0, tzinfo=exc_tz))\n+        start_dt = trading.environment.exchange_dt_in_utc(\n+            datetime.datetime(2013, 3, 1, 9, 30))\n+        end_dt = trading.environment.exchange_dt_in_utc(\n+            datetime.datetime(2013, 3, 1, 16, 0))\n \n         sim_params = SimulationParameters(\n             period_start=start_dt,\ndiff --git a/zipline/finance/trading.py b/zipline/finance/trading.py\nindex f282c378..c3d22b8e 100644\n--- a/zipline/finance/trading.py\n+++ b/zipline/finance/trading.py\n@@ -74,11 +74,6 @@ log = logbook.Logger(\'Transaction Simulator\')\n environment = None\n \n \n-def exchange_dt_in_utc(dt):\n-    delorean = Delorean(dt, dt.tzinfo)\n-    return delorean.shift(pytz.utc.zone).datetime\n-\n-\n class TransactionSimulator(object):\n \n     def __init__(self):\n@@ -156,6 +151,10 @@ class TradingEnvironment(object):\n             tzinfo=pytz.utc\n         )\n \n+    def exchange_dt_in_utc(self, dt):\n+        delorean = Delorean(dt, self.exchange_tz)\n+        return delorean.shift(pytz.utc.zone).datetime\n+\n     @property\n     def period_trading_days(self):\n         if self._period_trading_days is None:\n@@ -223,8 +222,7 @@ Last successful date: %s" % self.market_open)\n         )\n         # create a new Delorean with the next_open naive date and\n         # the correct timezone for the exchange.\n-        open_delorean = Delorean(next_open, self.exchange_tz)\n-        open_utc = open_delorean.shift(pytz.utc.zone).datetime\n+        open_utc = self.exchange_dt_in_utc(next_open)\n \n         market_open = open_utc\n         market_close = market_open + self.get_trading_day_duration(open_utc)\n', 'commit_subject': 'MAINT: Moves exchange to utc conversion inside of environment object.', 'repo_name': 'quantopian/zipline', 'committer': {'name': 'Eddie Hebert', 'email': 'ad498e5a6de621070e46c1f874129b3d9d811a69@quantopian.com', 'time_sec': '1364488192', 'tz_offset': '-240', 'date': {'seconds': '1364488192'}}, 'commit_tree': '2b19d1438e7d4c0aa8e129439f6a585de3671d69', 'commit_message': "MAINT: Moves exchange to utc conversion inside of environment object.\n\nSo that the environments' exchange time is used without having to\nspecify it independently.\n\nAlso, moves uses of Delorean.shift for the exchange conversion inside\nof environment to use the exchange_dt_to_utc method.\n", 'language_name': 'Shell', 'license': 'apache-2.0', 'hunks': '@@ -74,11 +74,6 @@ log = logbook.Logger(\'Transaction Simulator\')\n environment = None\n \n \n-def exchange_dt_in_utc(dt):\n-    delorean = Delorean(dt, dt.tzinfo)\n-    return delorean.shift(pytz.utc.zone).datetime\n-\n-\n class TransactionSimulator(object):\n \n     def __init__(self):\n@@ -156,6 +151,10 @@ class TradingEnvironment(object):\n             tzinfo=pytz.utc\n         )\n \n+    def exchange_dt_in_utc(self, dt):\n+        delorean = Delorean(dt, self.exchange_tz)\n+        return delorean.shift(pytz.utc.zone).datetime\n+\n     @property\n     def period_trading_days(self):\n         if self._period_trading_days is None:\n@@ -223,8 +222,7 @@ Last successful date: %s" % self.market_open)\n         )\n         # create a new Delorean with the next_open naive date and\n         # the correct timezone for the exchange.\n-        open_delorean = Delorean(next_open, self.exchange_tz)\n-        open_utc = open_delorean.shift(pytz.utc.zone).datetime\n+        open_utc = self.exchange_dt_in_utc(next_open)\n \n         market_open = open_utc\n         market_close = market_open + self.get_trading_day_duration(open_utc)\n', 'addition_count': 5, 'deletion_count': 7, 'src_file': 'a/zipline/finance/trading.py', 'tgt_file': 'b/zipline/finance/trading.py', 'file_extension': '.py', 'before_file': '#\n# Copyright 2016 Quantopian, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the "License");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an "AS IS" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport logbook\nimport pandas as pd\n\nfrom zipline.utils.memoize import remember_last\nfrom zipline.utils.pandas_utils import normalize_date\n\nlog = logbook.Logger(\'Trading\')\n\n\nDEFAULT_CAPITAL_BASE = 1e5\n\n\nclass SimulationParameters(object):\n    def __init__(self,\n                 start_session,\n                 end_session,\n                 trading_calendar,\n                 capital_base=DEFAULT_CAPITAL_BASE,\n                 emission_rate=\'daily\',\n                 data_frequency=\'daily\',\n                 arena=\'backtest\'):\n\n        assert type(start_session) == pd.Timestamp\n        assert type(end_session) == pd.Timestamp\n\n        assert trading_calendar is not None, \\\n            "Must pass in trading calendar!"\n        assert start_session <= end_session, \\\n            "Period start falls after period end."\n        assert start_session <= trading_calendar.last_trading_session, \\\n            "Period start falls after the last known trading day."\n        assert end_session >= trading_calendar.first_trading_session, \\\n            "Period end falls before the first known trading day."\n\n        # chop off any minutes or hours on the given start and end dates,\n        # as we only support session labels here (and we represent session\n        # labels as midnight UTC).\n        self._start_session = normalize_date(start_session)\n        self._end_session = normalize_date(end_session)\n        self._capital_base = capital_base\n\n        self._emission_rate = emission_rate\n        self._data_frequency = data_frequency\n\n        # copied to algorithm\'s environment for runtime access\n        self._arena = arena\n\n        self._trading_calendar = trading_calendar\n\n        if not trading_calendar.is_session(self._start_session):\n            # if the start date is not a valid session in this calendar,\n            # push it forward to the first valid session\n            self._start_session = trading_calendar.minute_to_session_label(\n                self._start_session\n            )\n\n        if not trading_calendar.is_session(self._end_session):\n            # if the end date is not a valid session in this calendar,\nenvironment = None\n\n\ndef exchange_dt_in_utc(dt):\n    delorean = Delorean(dt, dt.tzinfo)\n    return delorean.shift(pytz.utc.zone).datetime\n\n\nclass TransactionSimulator(object):\n\n    def __init__(self):\n        self._first_open = trading_calendar.open_and_close_for_session(\n            self._start_session\n        )[0]\n        self._last_close = trading_calendar.open_and_close_for_session(\n            self._end_session\n        )[1]\n\n    @property\n    def capital_base(self):\n        return self._capital_base\n\n    @property\n    def emission_rate(self):\n        return self._emission_rate\n\n    @property\n    def data_frequency(self):\n        return self._data_frequency\n\n    @data_frequency.setter\n    def data_frequency(self, val):\n        self._data_frequency = val\n\n    @property\n    def arena(self):\n        return self._arena\n\n    @arena.setter\n    def arena(self, val):\n        self._arena = val\n\n    @property\n    def start_session(self):\n        return self._start_session\n\n    @property\n    def end_session(self):\n        return self._end_session\n\n    @property\n    def first_open(self):\n        return self._first_open\n\n    @property\n    def last_close(self):\n        return self._last_close\n\n    @property\n    def trading_calendar(self):\n        return self._trading_calendar\n\n    @property\n    @remember_last\n    def sessions(self):\n        return self._trading_calendar.sessions_in_range(\n            self.start_session,\n            self.end_session\n        )\n\n    def create_new(self, start_session, end_session, data_frequency=None):\n        if data_frequency is None:\n            data_frequency = self.data_frequency\n\n        return SimulationParameters(\n            start_session,\n            end_session,\n            self._trading_calendar,\n            capital_base=self.capital_base,\n            emission_rate=self.emission_rate,\n            data_frequency=data_frequency,\n            arena=self.arena\n            tzinfo=pytz.utc\n        )\n\n    @property\n    def period_trading_days(self):\n        if self._period_trading_days is None:\n    first_open={first_open},\n    last_close={last_close},\n    trading_calendar={trading_calendar}\n)\\\n""".format(class_name=self.__class__.__name__,\n           start_session=self.start_session,\n           end_session=self.end_session,\n           capital_base=self.capital_base,\n           data_frequency=self.data_frequency,\n           emission_rate=self.emission_rate,\n           first_open=self.first_open,\n           last_close=self.last_close,\n           trading_calendar=self._trading_calendar)\n        )\n        # create a new Delorean with the next_open naive date and\n        # the correct timezone for the exchange.\n        open_delorean = Delorean(next_open, self.exchange_tz)\n        open_utc = open_delorean.shift(pytz.utc.zone).datetime\n\n        market_open = open_utc\n        market_close = market_open + self.get_trading_day_duration(open_utc)\n', 'message': "MAINT: Moves exchange to utc conversion inside of environment object.\n\nSo that the environments' exchange time is used without having to\nspecify it independently.\n\nAlso, moves uses of Delorean.shift for the exchange conversion inside\nof environment to use the exchange_dt_to_utc method.\n", 'author_name': 'Eddie Hebert', 'lang': 'py'}