We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
conflicting CLI flags for `clean`
Dear Zipline Maintainers,

Before I tell you about my issue, let me describe my environment:

# Environment

* Operating System: `OS X 10.12.1`
* Python Version: `2.7`
* Python Bitness: `64`
* How did you install Zipline: `conda`
* Python packages: _default_

Now that you know a little about me, let me tell you about the issue I am
having:

# Description of Issue
The CLI command `zipline clean` has conflicting flags for `-b, --bundle` and `-b, --before`. 

```
(zipline-venv) pgeez$ zipline clean --help
Usage: zipline clean [OPTIONS]

  Clean up data downloaded with the ingest command.

Options:
  -b, --bundle BUNDLE-NAME  The data bundle to clean.  [default: quantopian-
                            quandl]
  -b, --before TIMESTAMP    Clear all data before TIMESTAMP. This may not be
                            passed with -k / --keep-last
  -a, --after TIMESTAMP     Clear all data after TIMESTAMP This may not be
                            passed with -k / --keep-last
  -k, --keep-last N         Clear all but the last N downloads. This may not
                            be passed with -b / --before or -a / --after
  --help                    Show this message and exit.
```


* What happened instead?
Because of the conflict, `-b` defaults to `--before`.

Sincerely,
pgeez


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `zipline/__main__.py`
Content:
```
1 import errno
2 import os
3 from functools import wraps
4 
5 import click
6 import logbook
7 import pandas as pd
8 from six import text_type
9 
10 from zipline.data import bundles as bundles_module
11 from zipline.utils.cli import Date, Timestamp
12 from zipline.utils.run_algo import _run, load_extensions
13 
14 try:
15     __IPYTHON__
16 except NameError:
17     __IPYTHON__ = False
18 
19 
20 @click.group()
21 @click.option(
22     '-e',
23     '--extension',
24     multiple=True,
25     help='File or module path to a zipline extension to load.',
26 )
27 @click.option(
28     '--strict-extensions/--non-strict-extensions',
29     is_flag=True,
30     help='If --strict-extensions is passed then zipline will not run if it'
31     ' cannot load all of the specified extensions. If this is not passed or'
32     ' --non-strict-extensions is passed then the failure will be logged but'
33     ' execution will continue.',
34 )
35 @click.option(
36     '--default-extension/--no-default-extension',
37     is_flag=True,
38     default=True,
39     help="Don't load the default zipline extension.py file in $ZIPLINE_HOME.",
40 )
41 def main(extension, strict_extensions, default_extension):
42     """Top level zipline entry point.
43     """
44     # install a logbook handler before performing any other operations
45     logbook.StderrHandler().push_application()
46     load_extensions(
47         default_extension,
48         extension,
49         strict_extensions,
50         os.environ,
51     )
52 
53 
54 def extract_option_object(option):
55     """Convert a click.option call into a click.Option object.
56 
57     Parameters
58     ----------
59     option : decorator
60         A click.option decorator.
61 
62     Returns
63     -------
64     option_object : click.Option
65         The option object that this decorator will create.
66     """
67     @option
68     def opt():
69         pass
70 
71     return opt.__click_params__[0]
72 
73 
74 def ipython_only(option):
75     """Mark that an option should only be exposed in IPython.
76 
77     Parameters
78     ----------
79     option : decorator
80         A click.option decorator.
81 
82     Returns
83     -------
84     ipython_only_dec : decorator
85         A decorator that correctly applies the argument even when not
86         using IPython mode.
87     """
88     if __IPYTHON__:
89         return option
90 
91     argname = extract_option_object(option).name
92 
93     def d(f):
94         @wraps(f)
95         def _(*args, **kwargs):
96             kwargs[argname] = None
97             return f(*args, **kwargs)
98         return _
99     return d
100 
101 
102 @main.command()
103 @click.option(
104     '-f',
105     '--algofile',
106     default=None,
107     type=click.File('r'),
108     help='The file that contains the algorithm to run.',
109 )
110 @click.option(
111     '-t',
112     '--algotext',
113     help='The algorithm script to run.',
114 )
115 @click.option(
116     '-D',
117     '--define',
118     multiple=True,
119     help="Define a name to be bound in the namespace before executing"
120     " the algotext. For example '-Dname=value'. The value may be any python"
121     " expression. These are evaluated in order so they may refer to previously"
122     " defined names.",
123 )
124 @click.option(
125     '--data-frequency',
126     type=click.Choice({'daily', 'minute'}),
127     default='daily',
128     show_default=True,
129     help='The data frequency of the simulation.',
130 )
131 @click.option(
132     '--capital-base',
133     type=float,
134     default=10e6,
135     show_default=True,
136     help='The starting capital for the simulation.',
137 )
138 @click.option(
139     '-b',
140     '--bundle',
141     default='quantopian-quandl',
142     metavar='BUNDLE-NAME',
143     show_default=True,
144     help='The data bundle to use for the simulation.',
145 )
146 @click.option(
147     '--bundle-timestamp',
148     type=Timestamp(),
149     default=pd.Timestamp.utcnow(),
150     show_default=False,
151     help='The date to lookup data on or before.\n'
152     '[default: <current-time>]'
153 )
154 @click.option(
155     '-s',
156     '--start',
157     type=Date(tz='utc', as_timestamp=True),
158     help='The start date of the simulation.',
159 )
160 @click.option(
161     '-e',
162     '--end',
163     type=Date(tz='utc', as_timestamp=True),
164     help='The end date of the simulation.',
165 )
166 @click.option(
167     '-o',
168     '--output',
169     default='-',
170     metavar='FILENAME',
171     show_default=True,
172     help="The location to write the perf data. If this is '-' the perf will"
173     " be written to stdout.",
174 )
175 @click.option(
176     '--print-algo/--no-print-algo',
177     is_flag=True,
178     default=False,
179     help='Print the algorithm to stdout.',
180 )
181 @ipython_only(click.option(
182     '--local-namespace/--no-local-namespace',
183     is_flag=True,
184     default=None,
185     help='Should the algorithm methods be resolved in the local namespace.'
186 ))
187 @click.pass_context
188 def run(ctx,
189         algofile,
190         algotext,
191         define,
192         data_frequency,
193         capital_base,
194         bundle,
195         bundle_timestamp,
196         start,
197         end,
198         output,
199         print_algo,
200         local_namespace):
201     """Run a backtest for the given algorithm.
202     """
203     # check that the start and end dates are passed correctly
204     if start is None and end is None:
205         # check both at the same time to avoid the case where a user
206         # does not pass either of these and then passes the first only
207         # to be told they need to pass the second argument also
208         ctx.fail(
209             "must specify dates with '-s' / '--start' and '-e' / '--end'",
210         )
211     if start is None:
212         ctx.fail("must specify a start date with '-s' / '--start'")
213     if end is None:
214         ctx.fail("must specify an end date with '-e' / '--end'")
215 
216     if (algotext is not None) == (algofile is not None):
217         ctx.fail(
218             "must specify exactly one of '-f' / '--algofile' or"
219             " '-t' / '--algotext'",
220         )
221 
222     perf = _run(
223         initialize=None,
224         handle_data=None,
225         before_trading_start=None,
226         analyze=None,
227         algofile=algofile,
228         algotext=algotext,
229         defines=define,
230         data_frequency=data_frequency,
231         capital_base=capital_base,
232         data=None,
233         bundle=bundle,
234         bundle_timestamp=bundle_timestamp,
235         start=start,
236         end=end,
237         output=output,
238         print_algo=print_algo,
239         local_namespace=local_namespace,
240         environ=os.environ,
241     )
242 
243     if output == '-':
244         click.echo(str(perf))
245     elif output != os.devnull:  # make the zipline magic not write any data
246         perf.to_pickle(output)
247 
248     return perf
249 
250 
251 def zipline_magic(line, cell=None):
252     """The zipline IPython cell magic.
253     """
254     load_extensions(
255         default=True,
256         extensions=[],
257         strict=True,
258         environ=os.environ,
259     )
260     try:
261         return run.main(
262             # put our overrides at the start of the parameter list so that
263             # users may pass values with higher precedence
264             [
265                 '--algotext', cell,
266                 '--output', os.devnull,  # don't write the results by default
267             ] + ([
268                 # these options are set when running in line magic mode
269                 # set a non None algo text to use the ipython user_ns
270                 '--algotext', '',
271                 '--local-namespace',
272             ] if cell is None else []) + line.split(),
273             '%s%%zipline' % ((cell or '') and '%'),
274             # don't use system exit and propogate errors to the caller
275             standalone_mode=False,
276         )
277     except SystemExit as e:
278         # https://github.com/mitsuhiko/click/pull/533
279         # even in standalone_mode=False `--help` really wants to kill us ;_;
280         if e.code:
281             raise ValueError('main returned non-zero status code: %d' % e.code)
282 
283 
284 @main.command()
285 @click.option(
286     '-b',
287     '--bundle',
288     default='quantopian-quandl',
289     metavar='BUNDLE-NAME',
290     show_default=True,
291     help='The data bundle to ingest.',
292 )
293 @click.option(
294     '--assets-version',
295     type=int,
296     multiple=True,
297     help='Version of the assets db to which to downgrade.',
298 )
299 @click.option(
300     '--show-progress/--no-show-progress',
301     default=True,
302     help='Print progress information to the terminal.'
303 )
304 def ingest(bundle, assets_version, show_progress):
305     """Ingest the data for the given bundle.
306     """
307     bundles_module.ingest(
308         bundle,
309         os.environ,
310         pd.Timestamp.utcnow(),
311         assets_version,
312         show_progress,
313     )
314 
315 
316 @main.command()
317 @click.option(
318     '-b',
319     '--bundle',
320     default='quantopian-quandl',
321     metavar='BUNDLE-NAME',
322     show_default=True,
323     help='The data bundle to clean.',
324 )
325 @click.option(
326     '-b',
327     '--before',
328     type=Timestamp(),
329     help='Clear all data before TIMESTAMP.'
330     ' This may not be passed with -k / --keep-last',
331 )
332 @click.option(
333     '-a',
334     '--after',
335     type=Timestamp(),
336     help='Clear all data after TIMESTAMP'
337     ' This may not be passed with -k / --keep-last',
338 )
339 @click.option(
340     '-k',
341     '--keep-last',
342     type=int,
343     metavar='N',
344     help='Clear all but the last N downloads.'
345     ' This may not be passed with -b / --before or -a / --after',
346 )
347 def clean(bundle, before, after, keep_last):
348     """Clean up data downloaded with the ingest command.
349     """
350     bundles_module.clean(
351         bundle,
352         before,
353         after,
354         keep_last,
355     )
356 
357 
358 @main.command()
359 def bundles():
360     """List all of the available data bundles.
361     """
362     for bundle in sorted(bundles_module.bundles.keys()):
363         if bundle.startswith('.'):
364             # hide the test data
365             continue
366         try:
367             ingestions = list(
368                 map(text_type, bundles_module.ingestions_for_bundle(bundle))
369             )
370         except OSError as e:
371             if e.errno != errno.ENOENT:
372                 raise
373             ingestions = []
374 
375         # If we got no ingestions, either because the directory didn't exist or
376         # because there were no entries, print a single message indicating that
377         # no ingestions have yet been made.
378         for timestamp in ingestions or ["<no ingestions>"]:
379             click.echo("%s %s" % (bundle, timestamp))
380 
381 
382 if __name__ == '__main__':
383     main()
384
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/zipline/__main__.py b/zipline/__main__.py
--- a/zipline/__main__.py
+++ b/zipline/__main__.py
@@ -323,7 +323,7 @@
     help='The data bundle to clean.',
 )
 @click.option(
-    '-b',
+    '-e',
     '--before',
     type=Timestamp(),
     help='Clear all data before TIMESTAMP.'

{"golden_diff": "diff --git a/zipline/__main__.py b/zipline/__main__.py\n--- a/zipline/__main__.py\n+++ b/zipline/__main__.py\n@@ -323,7 +323,7 @@\n     help='The data bundle to clean.',\n )\n @click.option(\n-    '-b',\n+    '-e',\n     '--before',\n     type=Timestamp(),\n     help='Clear all data before TIMESTAMP.'\n", "issue": "conflicting CLI flags for `clean`\nDear Zipline Maintainers,\r\n\r\nBefore I tell you about my issue, let me describe my environment:\r\n\r\n# Environment\r\n\r\n* Operating System: `OS X 10.12.1`\r\n* Python Version: `2.7`\r\n* Python Bitness: `64`\r\n* How did you install Zipline: `conda`\r\n* Python packages: _default_\r\n\r\nNow that you know a little about me, let me tell you about the issue I am\r\nhaving:\r\n\r\n# Description of Issue\r\nThe CLI command `zipline clean` has conflicting flags for `-b, --bundle` and `-b, --before`. \r\n\r\n```\r\n(zipline-venv) pgeez$ zipline clean --help\r\nUsage: zipline clean [OPTIONS]\r\n\r\n  Clean up data downloaded with the ingest command.\r\n\r\nOptions:\r\n  -b, --bundle BUNDLE-NAME  The data bundle to clean.  [default: quantopian-\r\n                            quandl]\r\n  -b, --before TIMESTAMP    Clear all data before TIMESTAMP. This may not be\r\n                            passed with -k / --keep-last\r\n  -a, --after TIMESTAMP     Clear all data after TIMESTAMP This may not be\r\n                            passed with -k / --keep-last\r\n  -k, --keep-last N         Clear all but the last N downloads. This may not\r\n                            be passed with -b / --before or -a / --after\r\n  --help                    Show this message and exit.\r\n```\r\n\r\n\r\n* What happened instead?\r\nBecause of the conflict, `-b` defaults to `--before`.\r\n\r\nSincerely,\r\npgeez\r\n\n", "before_files": [{"content": "import errno\nimport os\nfrom functools import wraps\n\nimport click\nimport logbook\nimport pandas as pd\nfrom six import text_type\n\nfrom zipline.data import bundles as bundles_module\nfrom zipline.utils.cli import Date, Timestamp\nfrom zipline.utils.run_algo import _run, load_extensions\n\ntry:\n    __IPYTHON__\nexcept NameError:\n    __IPYTHON__ = False\n\n\n@click.group()\n@click.option(\n    '-e',\n    '--extension',\n    multiple=True,\n    help='File or module path to a zipline extension to load.',\n)\n@click.option(\n    '--strict-extensions/--non-strict-extensions',\n    is_flag=True,\n    help='If --strict-extensions is passed then zipline will not run if it'\n    ' cannot load all of the specified extensions. If this is not passed or'\n    ' --non-strict-extensions is passed then the failure will be logged but'\n    ' execution will continue.',\n)\n@click.option(\n    '--default-extension/--no-default-extension',\n    is_flag=True,\n    default=True,\n    help=\"Don't load the default zipline extension.py file in $ZIPLINE_HOME.\",\n)\ndef main(extension, strict_extensions, default_extension):\n    \"\"\"Top level zipline entry point.\n    \"\"\"\n    # install a logbook handler before performing any other operations\n    logbook.StderrHandler().push_application()\n    load_extensions(\n        default_extension,\n        extension,\n        strict_extensions,\n        os.environ,\n    )\n\n\ndef extract_option_object(option):\n    \"\"\"Convert a click.option call into a click.Option object.\n\n    Parameters\n    ----------\n    option : decorator\n        A click.option decorator.\n\n    Returns\n    -------\n    option_object : click.Option\n        The option object that this decorator will create.\n    \"\"\"\n    @option\n    def opt():\n        pass\n\n    return opt.__click_params__[0]\n\n\ndef ipython_only(option):\n    \"\"\"Mark that an option should only be exposed in IPython.\n\n    Parameters\n    ----------\n    option : decorator\n        A click.option decorator.\n\n    Returns\n    -------\n    ipython_only_dec : decorator\n        A decorator that correctly applies the argument even when not\n        using IPython mode.\n    \"\"\"\n    if __IPYTHON__:\n        return option\n\n    argname = extract_option_object(option).name\n\n    def d(f):\n        @wraps(f)\n        def _(*args, **kwargs):\n            kwargs[argname] = None\n            return f(*args, **kwargs)\n        return _\n    return d\n\n\n@main.command()\n@click.option(\n    '-f',\n    '--algofile',\n    default=None,\n    type=click.File('r'),\n    help='The file that contains the algorithm to run.',\n)\n@click.option(\n    '-t',\n    '--algotext',\n    help='The algorithm script to run.',\n)\n@click.option(\n    '-D',\n    '--define',\n    multiple=True,\n    help=\"Define a name to be bound in the namespace before executing\"\n    \" the algotext. For example '-Dname=value'. The value may be any python\"\n    \" expression. These are evaluated in order so they may refer to previously\"\n    \" defined names.\",\n)\n@click.option(\n    '--data-frequency',\n    type=click.Choice({'daily', 'minute'}),\n    default='daily',\n    show_default=True,\n    help='The data frequency of the simulation.',\n)\n@click.option(\n    '--capital-base',\n    type=float,\n    default=10e6,\n    show_default=True,\n    help='The starting capital for the simulation.',\n)\n@click.option(\n    '-b',\n    '--bundle',\n    default='quantopian-quandl',\n    metavar='BUNDLE-NAME',\n    show_default=True,\n    help='The data bundle to use for the simulation.',\n)\n@click.option(\n    '--bundle-timestamp',\n    type=Timestamp(),\n    default=pd.Timestamp.utcnow(),\n    show_default=False,\n    help='The date to lookup data on or before.\\n'\n    '[default: <current-time>]'\n)\n@click.option(\n    '-s',\n    '--start',\n    type=Date(tz='utc', as_timestamp=True),\n    help='The start date of the simulation.',\n)\n@click.option(\n    '-e',\n    '--end',\n    type=Date(tz='utc', as_timestamp=True),\n    help='The end date of the simulation.',\n)\n@click.option(\n    '-o',\n    '--output',\n    default='-',\n    metavar='FILENAME',\n    show_default=True,\n    help=\"The location to write the perf data. If this is '-' the perf will\"\n    \" be written to stdout.\",\n)\n@click.option(\n    '--print-algo/--no-print-algo',\n    is_flag=True,\n    default=False,\n    help='Print the algorithm to stdout.',\n)\n@ipython_only(click.option(\n    '--local-namespace/--no-local-namespace',\n    is_flag=True,\n    default=None,\n    help='Should the algorithm methods be resolved in the local namespace.'\n))\n@click.pass_context\ndef run(ctx,\n        algofile,\n        algotext,\n        define,\n        data_frequency,\n        capital_base,\n        bundle,\n        bundle_timestamp,\n        start,\n        end,\n        output,\n        print_algo,\n        local_namespace):\n    \"\"\"Run a backtest for the given algorithm.\n    \"\"\"\n    # check that the start and end dates are passed correctly\n    if start is None and end is None:\n        # check both at the same time to avoid the case where a user\n        # does not pass either of these and then passes the first only\n        # to be told they need to pass the second argument also\n        ctx.fail(\n            \"must specify dates with '-s' / '--start' and '-e' / '--end'\",\n        )\n    if start is None:\n        ctx.fail(\"must specify a start date with '-s' / '--start'\")\n    if end is None:\n        ctx.fail(\"must specify an end date with '-e' / '--end'\")\n\n    if (algotext is not None) == (algofile is not None):\n        ctx.fail(\n            \"must specify exactly one of '-f' / '--algofile' or\"\n            \" '-t' / '--algotext'\",\n        )\n\n    perf = _run(\n        initialize=None,\n        handle_data=None,\n        before_trading_start=None,\n        analyze=None,\n        algofile=algofile,\n        algotext=algotext,\n        defines=define,\n        data_frequency=data_frequency,\n        capital_base=capital_base,\n        data=None,\n        bundle=bundle,\n        bundle_timestamp=bundle_timestamp,\n        start=start,\n        end=end,\n        output=output,\n        print_algo=print_algo,\n        local_namespace=local_namespace,\n        environ=os.environ,\n    )\n\n    if output == '-':\n        click.echo(str(perf))\n    elif output != os.devnull:  # make the zipline magic not write any data\n        perf.to_pickle(output)\n\n    return perf\n\n\ndef zipline_magic(line, cell=None):\n    \"\"\"The zipline IPython cell magic.\n    \"\"\"\n    load_extensions(\n        default=True,\n        extensions=[],\n        strict=True,\n        environ=os.environ,\n    )\n    try:\n        return run.main(\n            # put our overrides at the start of the parameter list so that\n            # users may pass values with higher precedence\n            [\n                '--algotext', cell,\n                '--output', os.devnull,  # don't write the results by default\n            ] + ([\n                # these options are set when running in line magic mode\n                # set a non None algo text to use the ipython user_ns\n                '--algotext', '',\n                '--local-namespace',\n            ] if cell is None else []) + line.split(),\n            '%s%%zipline' % ((cell or '') and '%'),\n            # don't use system exit and propogate errors to the caller\n            standalone_mode=False,\n        )\n    except SystemExit as e:\n        # https://github.com/mitsuhiko/click/pull/533\n        # even in standalone_mode=False `--help` really wants to kill us ;_;\n        if e.code:\n            raise ValueError('main returned non-zero status code: %d' % e.code)\n\n\n@main.command()\n@click.option(\n    '-b',\n    '--bundle',\n    default='quantopian-quandl',\n    metavar='BUNDLE-NAME',\n    show_default=True,\n    help='The data bundle to ingest.',\n)\n@click.option(\n    '--assets-version',\n    type=int,\n    multiple=True,\n    help='Version of the assets db to which to downgrade.',\n)\n@click.option(\n    '--show-progress/--no-show-progress',\n    default=True,\n    help='Print progress information to the terminal.'\n)\ndef ingest(bundle, assets_version, show_progress):\n    \"\"\"Ingest the data for the given bundle.\n    \"\"\"\n    bundles_module.ingest(\n        bundle,\n        os.environ,\n        pd.Timestamp.utcnow(),\n        assets_version,\n        show_progress,\n    )\n\n\n@main.command()\n@click.option(\n    '-b',\n    '--bundle',\n    default='quantopian-quandl',\n    metavar='BUNDLE-NAME',\n    show_default=True,\n    help='The data bundle to clean.',\n)\n@click.option(\n    '-b',\n    '--before',\n    type=Timestamp(),\n    help='Clear all data before TIMESTAMP.'\n    ' This may not be passed with -k / --keep-last',\n)\n@click.option(\n    '-a',\n    '--after',\n    type=Timestamp(),\n    help='Clear all data after TIMESTAMP'\n    ' This may not be passed with -k / --keep-last',\n)\n@click.option(\n    '-k',\n    '--keep-last',\n    type=int,\n    metavar='N',\n    help='Clear all but the last N downloads.'\n    ' This may not be passed with -b / --before or -a / --after',\n)\ndef clean(bundle, before, after, keep_last):\n    \"\"\"Clean up data downloaded with the ingest command.\n    \"\"\"\n    bundles_module.clean(\n        bundle,\n        before,\n        after,\n        keep_last,\n    )\n\n\n@main.command()\ndef bundles():\n    \"\"\"List all of the available data bundles.\n    \"\"\"\n    for bundle in sorted(bundles_module.bundles.keys()):\n        if bundle.startswith('.'):\n            # hide the test data\n            continue\n        try:\n            ingestions = list(\n                map(text_type, bundles_module.ingestions_for_bundle(bundle))\n            )\n        except OSError as e:\n            if e.errno != errno.ENOENT:\n                raise\n            ingestions = []\n\n        # If we got no ingestions, either because the directory didn't exist or\n        # because there were no entries, print a single message indicating that\n        # no ingestions have yet been made.\n        for timestamp in ingestions or [\"<no ingestions>\"]:\n            click.echo(\"%s %s\" % (bundle, timestamp))\n\n\nif __name__ == '__main__':\n    main()\n", "path": "zipline/__main__.py"}], "after_files": [{"content": "import errno\nimport os\nfrom functools import wraps\n\nimport click\nimport logbook\nimport pandas as pd\nfrom six import text_type\n\nfrom zipline.data import bundles as bundles_module\nfrom zipline.utils.cli import Date, Timestamp\nfrom zipline.utils.run_algo import _run, load_extensions\n\ntry:\n    __IPYTHON__\nexcept NameError:\n    __IPYTHON__ = False\n\n\n@click.group()\n@click.option(\n    '-e',\n    '--extension',\n    multiple=True,\n    help='File or module path to a zipline extension to load.',\n)\n@click.option(\n    '--strict-extensions/--non-strict-extensions',\n    is_flag=True,\n    help='If --strict-extensions is passed then zipline will not run if it'\n    ' cannot load all of the specified extensions. If this is not passed or'\n    ' --non-strict-extensions is passed then the failure will be logged but'\n    ' execution will continue.',\n)\n@click.option(\n    '--default-extension/--no-default-extension',\n    is_flag=True,\n    default=True,\n    help=\"Don't load the default zipline extension.py file in $ZIPLINE_HOME.\",\n)\ndef main(extension, strict_extensions, default_extension):\n    \"\"\"Top level zipline entry point.\n    \"\"\"\n    # install a logbook handler before performing any other operations\n    logbook.StderrHandler().push_application()\n    load_extensions(\n        default_extension,\n        extension,\n        strict_extensions,\n        os.environ,\n    )\n\n\ndef extract_option_object(option):\n    \"\"\"Convert a click.option call into a click.Option object.\n\n    Parameters\n    ----------\n    option : decorator\n        A click.option decorator.\n\n    Returns\n    -------\n    option_object : click.Option\n        The option object that this decorator will create.\n    \"\"\"\n    @option\n    def opt():\n        pass\n\n    return opt.__click_params__[0]\n\n\ndef ipython_only(option):\n    \"\"\"Mark that an option should only be exposed in IPython.\n\n    Parameters\n    ----------\n    option : decorator\n        A click.option decorator.\n\n    Returns\n    -------\n    ipython_only_dec : decorator\n        A decorator that correctly applies the argument even when not\n        using IPython mode.\n    \"\"\"\n    if __IPYTHON__:\n        return option\n\n    argname = extract_option_object(option).name\n\n    def d(f):\n        @wraps(f)\n        def _(*args, **kwargs):\n            kwargs[argname] = None\n            return f(*args, **kwargs)\n        return _\n    return d\n\n\n@main.command()\n@click.option(\n    '-f',\n    '--algofile',\n    default=None,\n    type=click.File('r'),\n    help='The file that contains the algorithm to run.',\n)\n@click.option(\n    '-t',\n    '--algotext',\n    help='The algorithm script to run.',\n)\n@click.option(\n    '-D',\n    '--define',\n    multiple=True,\n    help=\"Define a name to be bound in the namespace before executing\"\n    \" the algotext. For example '-Dname=value'. The value may be any python\"\n    \" expression. These are evaluated in order so they may refer to previously\"\n    \" defined names.\",\n)\n@click.option(\n    '--data-frequency',\n    type=click.Choice({'daily', 'minute'}),\n    default='daily',\n    show_default=True,\n    help='The data frequency of the simulation.',\n)\n@click.option(\n    '--capital-base',\n    type=float,\n    default=10e6,\n    show_default=True,\n    help='The starting capital for the simulation.',\n)\n@click.option(\n    '-b',\n    '--bundle',\n    default='quantopian-quandl',\n    metavar='BUNDLE-NAME',\n    show_default=True,\n    help='The data bundle to use for the simulation.',\n)\n@click.option(\n    '--bundle-timestamp',\n    type=Timestamp(),\n    default=pd.Timestamp.utcnow(),\n    show_default=False,\n    help='The date to lookup data on or before.\\n'\n    '[default: <current-time>]'\n)\n@click.option(\n    '-s',\n    '--start',\n    type=Date(tz='utc', as_timestamp=True),\n    help='The start date of the simulation.',\n)\n@click.option(\n    '-e',\n    '--end',\n    type=Date(tz='utc', as_timestamp=True),\n    help='The end date of the simulation.',\n)\n@click.option(\n    '-o',\n    '--output',\n    default='-',\n    metavar='FILENAME',\n    show_default=True,\n    help=\"The location to write the perf data. If this is '-' the perf will\"\n    \" be written to stdout.\",\n)\n@click.option(\n    '--print-algo/--no-print-algo',\n    is_flag=True,\n    default=False,\n    help='Print the algorithm to stdout.',\n)\n@ipython_only(click.option(\n    '--local-namespace/--no-local-namespace',\n    is_flag=True,\n    default=None,\n    help='Should the algorithm methods be resolved in the local namespace.'\n))\n@click.pass_context\ndef run(ctx,\n        algofile,\n        algotext,\n        define,\n        data_frequency,\n        capital_base,\n        bundle,\n        bundle_timestamp,\n        start,\n        end,\n        output,\n        print_algo,\n        local_namespace):\n    \"\"\"Run a backtest for the given algorithm.\n    \"\"\"\n    # check that the start and end dates are passed correctly\n    if start is None and end is None:\n        # check both at the same time to avoid the case where a user\n        # does not pass either of these and then passes the first only\n        # to be told they need to pass the second argument also\n        ctx.fail(\n            \"must specify dates with '-s' / '--start' and '-e' / '--end'\",\n        )\n    if start is None:\n        ctx.fail(\"must specify a start date with '-s' / '--start'\")\n    if end is None:\n        ctx.fail(\"must specify an end date with '-e' / '--end'\")\n\n    if (algotext is not None) == (algofile is not None):\n        ctx.fail(\n            \"must specify exactly one of '-f' / '--algofile' or\"\n            \" '-t' / '--algotext'\",\n        )\n\n    perf = _run(\n        initialize=None,\n        handle_data=None,\n        before_trading_start=None,\n        analyze=None,\n        algofile=algofile,\n        algotext=algotext,\n        defines=define,\n        data_frequency=data_frequency,\n        capital_base=capital_base,\n        data=None,\n        bundle=bundle,\n        bundle_timestamp=bundle_timestamp,\n        start=start,\n        end=end,\n        output=output,\n        print_algo=print_algo,\n        local_namespace=local_namespace,\n        environ=os.environ,\n    )\n\n    if output == '-':\n        click.echo(str(perf))\n    elif output != os.devnull:  # make the zipline magic not write any data\n        perf.to_pickle(output)\n\n    return perf\n\n\ndef zipline_magic(line, cell=None):\n    \"\"\"The zipline IPython cell magic.\n    \"\"\"\n    load_extensions(\n        default=True,\n        extensions=[],\n        strict=True,\n        environ=os.environ,\n    )\n    try:\n        return run.main(\n            # put our overrides at the start of the parameter list so that\n            # users may pass values with higher precedence\n            [\n                '--algotext', cell,\n                '--output', os.devnull,  # don't write the results by default\n            ] + ([\n                # these options are set when running in line magic mode\n                # set a non None algo text to use the ipython user_ns\n                '--algotext', '',\n                '--local-namespace',\n            ] if cell is None else []) + line.split(),\n            '%s%%zipline' % ((cell or '') and '%'),\n            # don't use system exit and propogate errors to the caller\n            standalone_mode=False,\n        )\n    except SystemExit as e:\n        # https://github.com/mitsuhiko/click/pull/533\n        # even in standalone_mode=False `--help` really wants to kill us ;_;\n        if e.code:\n            raise ValueError('main returned non-zero status code: %d' % e.code)\n\n\n@main.command()\n@click.option(\n    '-b',\n    '--bundle',\n    default='quantopian-quandl',\n    metavar='BUNDLE-NAME',\n    show_default=True,\n    help='The data bundle to ingest.',\n)\n@click.option(\n    '--assets-version',\n    type=int,\n    multiple=True,\n    help='Version of the assets db to which to downgrade.',\n)\n@click.option(\n    '--show-progress/--no-show-progress',\n    default=True,\n    help='Print progress information to the terminal.'\n)\ndef ingest(bundle, assets_version, show_progress):\n    \"\"\"Ingest the data for the given bundle.\n    \"\"\"\n    bundles_module.ingest(\n        bundle,\n        os.environ,\n        pd.Timestamp.utcnow(),\n        assets_version,\n        show_progress,\n    )\n\n\n@main.command()\n@click.option(\n    '-b',\n    '--bundle',\n    default='quantopian-quandl',\n    metavar='BUNDLE-NAME',\n    show_default=True,\n    help='The data bundle to clean.',\n)\n@click.option(\n    '-e',\n    '--before',\n    type=Timestamp(),\n    help='Clear all data before TIMESTAMP.'\n    ' This may not be passed with -k / --keep-last',\n)\n@click.option(\n    '-a',\n    '--after',\n    type=Timestamp(),\n    help='Clear all data after TIMESTAMP'\n    ' This may not be passed with -k / --keep-last',\n)\n@click.option(\n    '-k',\n    '--keep-last',\n    type=int,\n    metavar='N',\n    help='Clear all but the last N downloads.'\n    ' This may not be passed with -b / --before or -a / --after',\n)\ndef clean(bundle, before, after, keep_last):\n    \"\"\"Clean up data downloaded with the ingest command.\n    \"\"\"\n    bundles_module.clean(\n        bundle,\n        before,\n        after,\n        keep_last,\n    )\n\n\n@main.command()\ndef bundles():\n    \"\"\"List all of the available data bundles.\n    \"\"\"\n    for bundle in sorted(bundles_module.bundles.keys()):\n        if bundle.startswith('.'):\n            # hide the test data\n            continue\n        try:\n            ingestions = list(\n                map(text_type, bundles_module.ingestions_for_bundle(bundle))\n            )\n        except OSError as e:\n            if e.errno != errno.ENOENT:\n                raise\n            ingestions = []\n\n        # If we got no ingestions, either because the directory didn't exist or\n        # because there were no entries, print a single message indicating that\n        # no ingestions have yet been made.\n        for timestamp in ingestions or [\"<no ingestions>\"]:\n            click.echo(\"%s %s\" % (bundle, timestamp))\n\n\nif __name__ == '__main__':\n    main()\n", "path": "zipline/__main__.py"}]}