{"action":"created","comment":{"url":"https://api.github.com/repos/quantopian/zipline/pulls/comments/49392286","id":49392286,"diff_hunk":"@@ -0,0 +1,72 @@\n+import datetime\n+\n+import pandas as pd\n+\n+\n+def normalize_data_query_time(dt, time, tz):\n+    \"\"\"Apply the correct time and timezone to a date.\n+\n+    Parameters\n+    ----------\n+    dt : pd.Timestamp\n+        The original datetime that represents the date.\n+    time : datetime.time\n+        The time to query before.\n+    tz : tzinfo\n+        The timezone the time applies to.\n+\n+    Returns\n+    -------\n+    query_dt : pd.Timestamp\n+        The timestamp with the correct time and date in utc.\n+    \"\"\"\n+    # merge the correct date with the time in the given timezone then convert\n+    # back to utc\n+    return pd.Timestamp(\n+        datetime.datetime.combine(dt.date(), time),\n+        tz=tz,\n+    ).tz_convert('utc')\n+\n+\n+def normalize_timestamp_to_query_time(df,\n+                                      time,\n+                                      tz,\n+                                      inplace=False,\n+                                      ts_field='timestamp'):\n+    \"\"\"Update the timestamp field of a dataframe to normalize dates around\n+    some data query time/timezone.\n+\n+    Parameters\n+    ----------\n+    df : pd.DataFrame\n+        The dataframe to update. This needs a column named ``ts_field``.\n+    time : datetime.time\n+        The time to query before.\n+    tz : tzinfo\n+        The timezone the time applies to.\n+    inplace : bool, optional\n+        Update the dataframe in place.\n+    ts_field : str, optional\n+        The name of the timestamp field in ``df``.\n+\n+    Returns\n+    -------\n+    df : pd.DataFrame\n+        The dataframe with the timestamp field normalized. If ``inplace`` is\n+        true, then this will be the same object as ``df`` otherwise this will\n+        be a copy.\n+    \"\"\"\n+    if not inplace:\n+        # don't mutate the dataframe in place\n+        df = df.copy()\n+\n+    dtidx = pd.DatetimeIndex(df.loc[:, ts_field], tz='utc')\n+    dtidx_local_time = dtidx.tz_convert(tz)\n+    to_roll_forward = dtidx_local_time.time > time\n+    # for all of the times that are greater than our query time add 1\n+    # day and truncate to the date\n+    df.loc[to_roll_forward, ts_field] = (\n+        dtidx_local_time[to_roll_forward] + datetime.timedelta(days=1)","path":"zipline/pipeline/loaders/utils.py","position":81,"original_position":69,"commit_id":"68f0f7e7aea7dc55559579432a51c67fc1207cff","original_commit_id":"3756228bc9941b569c9a07e1d4337217a56f4b2e","user":{"login":"richafrank","id":2123660,"avatar_url":"https://avatars.githubusercontent.com/u/2123660?v=3","gravatar_id":"","url":"https://api.github.com/users/richafrank","html_url":"https://github.com/richafrank","followers_url":"https://api.github.com/users/richafrank/followers","following_url":"https://api.github.com/users/richafrank/following{/other_user}","gists_url":"https://api.github.com/users/richafrank/gists{/gist_id}","starred_url":"https://api.github.com/users/richafrank/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/richafrank/subscriptions","organizations_url":"https://api.github.com/users/richafrank/orgs","repos_url":"https://api.github.com/users/richafrank/repos","events_url":"https://api.github.com/users/richafrank/events{/privacy}","received_events_url":"https://api.github.com/users/richafrank/received_events","type":"User","site_admin":false},"body":"Makes sense.","created_at":"2016-01-11T22:57:31Z","updated_at":"2016-01-11T22:57:31Z","html_url":"https://github.com/quantopian/zipline/pull/947#discussion_r49392286","pull_request_url":"https://api.github.com/repos/quantopian/zipline/pulls/947","_links":{"self":{"href":"https://api.github.com/repos/quantopian/zipline/pulls/comments/49392286"},"html":{"href":"https://github.com/quantopian/zipline/pull/947#discussion_r49392286"},"pull_request":{"href":"https://api.github.com/repos/quantopian/zipline/pulls/947"}}},"pull_request":{"url":"https://api.github.com/repos/quantopian/zipline/pulls/947","id":55384669,"html_url":"https://github.com/quantopian/zipline/pull/947","diff_url":"https://github.com/quantopian/zipline/pull/947.diff","patch_url":"https://github.com/quantopian/zipline/pull/947.patch","issue_url":"https://api.github.com/repos/quantopian/zipline/issues/947","number":947,"state":"open","locked":false,"title":"allows users to specify the cutoff time for data query in blaze loaders","user":{"login":"llllllllll","id":3064397,"avatar_url":"https://avatars.githubusercontent.com/u/3064397?v=3","gravatar_id":"","url":"https://api.github.com/users/llllllllll","html_url":"https://github.com/llllllllll","followers_url":"https://api.github.com/users/llllllllll/followers","following_url":"https://api.github.com/users/llllllllll/following{/other_user}","gists_url":"https://api.github.com/users/llllllllll/gists{/gist_id}","starred_url":"https://api.github.com/users/llllllllll/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/llllllllll/subscriptions","organizations_url":"https://api.github.com/users/llllllllll/orgs","repos_url":"https://api.github.com/users/llllllllll/repos","events_url":"https://api.github.com/users/llllllllll/events{/privacy}","received_events_url":"https://api.github.com/users/llllllllll/received_events","type":"User","site_admin":false},"body":"This allows people to set their cutoff time to the time they will\r\nactually execute 'before_trading_start'. Currently this is just passed\r\nto the constructor of the loader; however, I would like to make this\r\nmanaged by the algorithm simulation runner. This would help keep all of\r\nthe loaders in sync and lock 'before_trading_start's execution to the\r\ntime the data is queried for.","created_at":"2016-01-07T20:16:28Z","updated_at":"2016-01-11T22:57:31Z","closed_at":null,"merged_at":null,"merge_commit_sha":"fbeb01965d4a31de8c0016f6edd1245f8da7d65b","assignee":{"login":"richafrank","id":2123660,"avatar_url":"https://avatars.githubusercontent.com/u/2123660?v=3","gravatar_id":"","url":"https://api.github.com/users/richafrank","html_url":"https://github.com/richafrank","followers_url":"https://api.github.com/users/richafrank/followers","following_url":"https://api.github.com/users/richafrank/following{/other_user}","gists_url":"https://api.github.com/users/richafrank/gists{/gist_id}","starred_url":"https://api.github.com/users/richafrank/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/richafrank/subscriptions","organizations_url":"https://api.github.com/users/richafrank/orgs","repos_url":"https://api.github.com/users/richafrank/repos","events_url":"https://api.github.com/users/richafrank/events{/privacy}","received_events_url":"https://api.github.com/users/richafrank/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/quantopian/zipline/pulls/947/commits","review_comments_url":"https://api.github.com/repos/quantopian/zipline/pulls/947/comments","review_comment_url":"https://api.github.com/repos/quantopian/zipline/pulls/comments{/number}","comments_url":"https://api.github.com/repos/quantopian/zipline/issues/947/comments","statuses_url":"https://api.github.com/repos/quantopian/zipline/statuses/68f0f7e7aea7dc55559579432a51c67fc1207cff","head":{"label":"quantopian:data-query-time","ref":"data-query-time","sha":"68f0f7e7aea7dc55559579432a51c67fc1207cff","user":{"login":"quantopian","id":1393215,"avatar_url":"https://avatars.githubusercontent.com/u/1393215?v=3","gravatar_id":"","url":"https://api.github.com/users/quantopian","html_url":"https://github.com/quantopian","followers_url":"https://api.github.com/users/quantopian/followers","following_url":"https://api.github.com/users/quantopian/following{/other_user}","gists_url":"https://api.github.com/users/quantopian/gists{/gist_id}","starred_url":"https://api.github.com/users/quantopian/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/quantopian/subscriptions","organizations_url":"https://api.github.com/users/quantopian/orgs","repos_url":"https://api.github.com/users/quantopian/repos","events_url":"https://api.github.com/users/quantopian/events{/privacy}","received_events_url":"https://api.github.com/users/quantopian/received_events","type":"Organization","site_admin":false},"repo":{"id":6297520,"name":"zipline","full_name":"quantopian/zipline","owner":{"login":"quantopian","id":1393215,"avatar_url":"https://avatars.githubusercontent.com/u/1393215?v=3","gravatar_id":"","url":"https://api.github.com/users/quantopian","html_url":"https://github.com/quantopian","followers_url":"https://api.github.com/users/quantopian/followers","following_url":"https://api.github.com/users/quantopian/following{/other_user}","gists_url":"https://api.github.com/users/quantopian/gists{/gist_id}","starred_url":"https://api.github.com/users/quantopian/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/quantopian/subscriptions","organizations_url":"https://api.github.com/users/quantopian/orgs","repos_url":"https://api.github.com/users/quantopian/repos","events_url":"https://api.github.com/users/quantopian/events{/privacy}","received_events_url":"https://api.github.com/users/quantopian/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/quantopian/zipline","description":"Zipline, a Pythonic Algorithmic Trading Library","fork":false,"url":"https://api.github.com/repos/quantopian/zipline","forks_url":"https://api.github.com/repos/quantopian/zipline/forks","keys_url":"https://api.github.com/repos/quantopian/zipline/keys{/key_id}","collaborators_url":"https://api.github.com/repos/quantopian/zipline/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/quantopian/zipline/teams","hooks_url":"https://api.github.com/repos/quantopian/zipline/hooks","issue_events_url":"https://api.github.com/repos/quantopian/zipline/issues/events{/number}","events_url":"https://api.github.com/repos/quantopian/zipline/events","assignees_url":"https://api.github.com/repos/quantopian/zipline/assignees{/user}","branches_url":"https://api.github.com/repos/quantopian/zipline/branches{/branch}","tags_url":"https://api.github.com/repos/quantopian/zipline/tags","blobs_url":"https://api.github.com/repos/quantopian/zipline/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/quantopian/zipline/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/quantopian/zipline/git/refs{/sha}","trees_url":"https://api.github.com/repos/quantopian/zipline/git/trees{/sha}","statuses_url":"https://api.github.com/repos/quantopian/zipline/statuses/{sha}","languages_url":"https://api.github.com/repos/quantopian/zipline/languages","stargazers_url":"https://api.github.com/repos/quantopian/zipline/stargazers","contributors_url":"https://api.github.com/repos/quantopian/zipline/contributors","subscribers_url":"https://api.github.com/repos/quantopian/zipline/subscribers","subscription_url":"https://api.github.com/repos/quantopian/zipline/subscription","commits_url":"https://api.github.com/repos/quantopian/zipline/commits{/sha}","git_commits_url":"https://api.github.com/repos/quantopian/zipline/git/commits{/sha}","comments_url":"https://api.github.com/repos/quantopian/zipline/comments{/number}","issue_comment_url":"https://api.github.com/repos/quantopian/zipline/issues/comments{/number}","contents_url":"https://api.github.com/repos/quantopian/zipline/contents/{+path}","compare_url":"https://api.github.com/repos/quantopian/zipline/compare/{base}...{head}","merges_url":"https://api.github.com/repos/quantopian/zipline/merges","archive_url":"https://api.github.com/repos/quantopian/zipline/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/quantopian/zipline/downloads","issues_url":"https://api.github.com/repos/quantopian/zipline/issues{/number}","pulls_url":"https://api.github.com/repos/quantopian/zipline/pulls{/number}","milestones_url":"https://api.github.com/repos/quantopian/zipline/milestones{/number}","notifications_url":"https://api.github.com/repos/quantopian/zipline/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/quantopian/zipline/labels{/name}","releases_url":"https://api.github.com/repos/quantopian/zipline/releases{/id}","created_at":"2012-10-19T15:50:29Z","updated_at":"2016-01-11T21:15:27Z","pushed_at":"2016-01-11T20:16:49Z","git_url":"git://github.com/quantopian/zipline.git","ssh_url":"git@github.com:quantopian/zipline.git","clone_url":"https://github.com/quantopian/zipline.git","svn_url":"https://github.com/quantopian/zipline","homepage":"","size":14681,"stargazers_count":2806,"watchers_count":2806,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":805,"mirror_url":null,"open_issues_count":157,"forks":805,"open_issues":157,"watchers":2806,"default_branch":"master"}},"base":{"label":"quantopian:master","ref":"master","sha":"d3d362f56fed184b99e6acc82b805b704398c3a9","user":{"login":"quantopian","id":1393215,"avatar_url":"https://avatars.githubusercontent.com/u/1393215?v=3","gravatar_id":"","url":"https://api.github.com/users/quantopian","html_url":"https://github.com/quantopian","followers_url":"https://api.github.com/users/quantopian/followers","following_url":"https://api.github.com/users/quantopian/following{/other_user}","gists_url":"https://api.github.com/users/quantopian/gists{/gist_id}","starred_url":"https://api.github.com/users/quantopian/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/quantopian/subscriptions","organizations_url":"https://api.github.com/users/quantopian/orgs","repos_url":"https://api.github.com/users/quantopian/repos","events_url":"https://api.github.com/users/quantopian/events{/privacy}","received_events_url":"https://api.github.com/users/quantopian/received_events","type":"Organization","site_admin":false},"repo":{"id":6297520,"name":"zipline","full_name":"quantopian/zipline","owner":{"login":"quantopian","id":1393215,"avatar_url":"https://avatars.githubusercontent.com/u/1393215?v=3","gravatar_id":"","url":"https://api.github.com/users/quantopian","html_url":"https://github.com/quantopian","followers_url":"https://api.github.com/users/quantopian/followers","following_url":"https://api.github.com/users/quantopian/following{/other_user}","gists_url":"https://api.github.com/users/quantopian/gists{/gist_id}","starred_url":"https://api.github.com/users/quantopian/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/quantopian/subscriptions","organizations_url":"https://api.github.com/users/quantopian/orgs","repos_url":"https://api.github.com/users/quantopian/repos","events_url":"https://api.github.com/users/quantopian/events{/privacy}","received_events_url":"https://api.github.com/users/quantopian/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/quantopian/zipline","description":"Zipline, a Pythonic Algorithmic Trading Library","fork":false,"url":"https://api.github.com/repos/quantopian/zipline","forks_url":"https://api.github.com/repos/quantopian/zipline/forks","keys_url":"https://api.github.com/repos/quantopian/zipline/keys{/key_id}","collaborators_url":"https://api.github.com/repos/quantopian/zipline/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/quantopian/zipline/teams","hooks_url":"https://api.github.com/repos/quantopian/zipline/hooks","issue_events_url":"https://api.github.com/repos/quantopian/zipline/issues/events{/number}","events_url":"https://api.github.com/repos/quantopian/zipline/events","assignees_url":"https://api.github.com/repos/quantopian/zipline/assignees{/user}","branches_url":"https://api.github.com/repos/quantopian/zipline/branches{/branch}","tags_url":"https://api.github.com/repos/quantopian/zipline/tags","blobs_url":"https://api.github.com/repos/quantopian/zipline/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/quantopian/zipline/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/quantopian/zipline/git/refs{/sha}","trees_url":"https://api.github.com/repos/quantopian/zipline/git/trees{/sha}","statuses_url":"https://api.github.com/repos/quantopian/zipline/statuses/{sha}","languages_url":"https://api.github.com/repos/quantopian/zipline/languages","stargazers_url":"https://api.github.com/repos/quantopian/zipline/stargazers","contributors_url":"https://api.github.com/repos/quantopian/zipline/contributors","subscribers_url":"https://api.github.com/repos/quantopian/zipline/subscribers","subscription_url":"https://api.github.com/repos/quantopian/zipline/subscription","commits_url":"https://api.github.com/repos/quantopian/zipline/commits{/sha}","git_commits_url":"https://api.github.com/repos/quantopian/zipline/git/commits{/sha}","comments_url":"https://api.github.com/repos/quantopian/zipline/comments{/number}","issue_comment_url":"https://api.github.com/repos/quantopian/zipline/issues/comments{/number}","contents_url":"https://api.github.com/repos/quantopian/zipline/contents/{+path}","compare_url":"https://api.github.com/repos/quantopian/zipline/compare/{base}...{head}","merges_url":"https://api.github.com/repos/quantopian/zipline/merges","archive_url":"https://api.github.com/repos/quantopian/zipline/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/quantopian/zipline/downloads","issues_url":"https://api.github.com/repos/quantopian/zipline/issues{/number}","pulls_url":"https://api.github.com/repos/quantopian/zipline/pulls{/number}","milestones_url":"https://api.github.com/repos/quantopian/zipline/milestones{/number}","notifications_url":"https://api.github.com/repos/quantopian/zipline/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/quantopian/zipline/labels{/name}","releases_url":"https://api.github.com/repos/quantopian/zipline/releases{/id}","created_at":"2012-10-19T15:50:29Z","updated_at":"2016-01-11T21:15:27Z","pushed_at":"2016-01-11T20:16:49Z","git_url":"git://github.com/quantopian/zipline.git","ssh_url":"git@github.com:quantopian/zipline.git","clone_url":"https://github.com/quantopian/zipline.git","svn_url":"https://github.com/quantopian/zipline","homepage":"","size":14681,"stargazers_count":2806,"watchers_count":2806,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":805,"mirror_url":null,"open_issues_count":157,"forks":805,"open_issues":157,"watchers":2806,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/quantopian/zipline/pulls/947"},"html":{"href":"https://github.com/quantopian/zipline/pull/947"},"issue":{"href":"https://api.github.com/repos/quantopian/zipline/issues/947"},"comments":{"href":"https://api.github.com/repos/quantopian/zipline/issues/947/comments"},"review_comments":{"href":"https://api.github.com/repos/quantopian/zipline/pulls/947/comments"},"review_comment":{"href":"https://api.github.com/repos/quantopian/zipline/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/quantopian/zipline/pulls/947/commits"},"statuses":{"href":"https://api.github.com/repos/quantopian/zipline/statuses/68f0f7e7aea7dc55559579432a51c67fc1207cff"}}}}