ziplime 0.1.11__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ziplime-0.1.11/PKG-INFO +56 -0
- ziplime-0.1.11/README.md +36 -0
- ziplime-0.1.11/pyproject.toml +24 -0
- ziplime-0.1.11/ziplime/__init__.py +0 -0
- ziplime-0.1.11/ziplime/__main__.py +507 -0
- ziplime-0.1.11/ziplime/algorithm.py +2342 -0
- ziplime-0.1.11/ziplime/config/__init__.py +0 -0
- ziplime-0.1.11/ziplime/config/register_bundles.py +25 -0
- ziplime-0.1.11/ziplime/constants/__init__.py +0 -0
- ziplime-0.1.11/ziplime/constants/bundles.py +1 -0
- ziplime-0.1.11/ziplime/constants/default_columns.py +17 -0
- ziplime-0.1.11/ziplime/constants/fundamental_data.py +57 -0
- ziplime-0.1.11/ziplime/data/__init__.py +0 -0
- ziplime-0.1.11/ziplime/data/abstract_data_bundle.py +15 -0
- ziplime-0.1.11/ziplime/data/abstract_fundamendal_data_provider.py +18 -0
- ziplime-0.1.11/ziplime/data/abstract_historical_market_data_provider.py +15 -0
- ziplime-0.1.11/ziplime/data/abstract_live_market_data_provider.py +16 -0
- ziplime-0.1.11/ziplime/data/bcolz_daily_bars.py +154 -0
- ziplime-0.1.11/ziplime/data/bcolz_minute_bars.py +1323 -0
- ziplime-0.1.11/ziplime/data/bundles/__init__.py +30 -0
- ziplime-0.1.11/ziplime/data/bundles/core.py +690 -0
- ziplime-0.1.11/ziplime/data/bundles/lime.py +202 -0
- ziplime-0.1.11/ziplime/data/data_portal.py +1238 -0
- ziplime-0.1.11/ziplime/data/data_portal_live.py +86 -0
- ziplime-0.1.11/ziplime/data/history_loader.py +570 -0
- ziplime-0.1.11/ziplime/data/lime_data_provider.py +255 -0
- ziplime-0.1.11/ziplime/data/providers/__init__.py +0 -0
- ziplime-0.1.11/ziplime/data/providers/fundamental_data/__init__.py +0 -0
- ziplime-0.1.11/ziplime/data/providers/fundamental_data/limex_hub_fundamental_data_provider.py +143 -0
- ziplime-0.1.11/ziplime/data/providers/historical_market_data/__init__.py +0 -0
- ziplime-0.1.11/ziplime/data/providers/historical_market_data/limex_hub_historical_market_data_provider.py +97 -0
- ziplime-0.1.11/ziplime/data/providers/live_market_data/__init__.py +0 -0
- ziplime-0.1.11/ziplime/data/providers/live_market_data/lime_trader_sdk_live_market_data_provider.py +77 -0
- ziplime-0.1.11/ziplime/data/storages/__init__.py +0 -0
- ziplime-0.1.11/ziplime/data/storages/bcolz_data_bundle.py +690 -0
- ziplime-0.1.11/ziplime/domain/__init__.py +0 -0
- ziplime-0.1.11/ziplime/domain/column_specification.py +11 -0
- ziplime-0.1.11/ziplime/domain/lime_quote.py +9 -0
- ziplime-0.1.11/ziplime/finance/__init__.py +0 -0
- ziplime-0.1.11/ziplime/finance/blotter/__init__.py +0 -0
- ziplime-0.1.11/ziplime/finance/blotter/lime_trader_sdk_blotter.py +429 -0
- ziplime-0.1.11/ziplime/utils/__init__.py +0 -0
- ziplime-0.1.11/ziplime/utils/bundle_utils.py +59 -0
- ziplime-0.1.11/ziplime/utils/calendar_utils.py +20 -0
- ziplime-0.1.11/ziplime/utils/data.py +68 -0
- ziplime-0.1.11/ziplime/utils/paths.py +213 -0
- ziplime-0.1.11/ziplime/utils/run_algo.py +587 -0
ziplime-0.1.11/PKG-INFO
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: ziplime
|
|
3
|
+
Version: 0.1.11
|
|
4
|
+
Summary:
|
|
5
|
+
Author: Lime Financial
|
|
6
|
+
Author-email: support@lime.co
|
|
7
|
+
Requires-Python: >=3.12,<4.0
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
11
|
+
Requires-Dist: dask (>=2024.9.1,<2025.0.0)
|
|
12
|
+
Requires-Dist: joblib (>=1.4.2,<2.0.0)
|
|
13
|
+
Requires-Dist: lime-trader-sdk (>=0.3.9,<0.4.0)
|
|
14
|
+
Requires-Dist: limexhub (>=0.1.27,<0.2.0)
|
|
15
|
+
Requires-Dist: pygments (>=2.18.0,<3.0.0)
|
|
16
|
+
Requires-Dist: setuptools (>=72.1.0,<73.0.0)
|
|
17
|
+
Requires-Dist: zipline-reloaded (==3.1)
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
|
|
20
|
+
# ziplime
|
|
21
|
+
|
|
22
|
+
Zipline wrapper which enables using Lime data for backtesting
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
```Bash
|
|
27
|
+
poetry add ziplime
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
You can find usage examples below. All commands supported by `zipline` are also supported by `ziplime` with extended
|
|
33
|
+
list of parameters for easier usage.
|
|
34
|
+
|
|
35
|
+
### Data ingestion
|
|
36
|
+
|
|
37
|
+
Data ingestion works by first fetching historical data and then and then running live data fetch in the background.
|
|
38
|
+
|
|
39
|
+
Difference from original zipline:
|
|
40
|
+
|
|
41
|
+
- `--start-date` and `--end-date` parameters - used to fetch bundle data only for specific date period
|
|
42
|
+
- `--symbols` parameter - specifies symbols to fetch data for directly in the command
|
|
43
|
+
- Running live data fetch in the background
|
|
44
|
+
|
|
45
|
+
Example:
|
|
46
|
+
|
|
47
|
+
Ingest data:
|
|
48
|
+
```Bash
|
|
49
|
+
poetry run python -m ziplime ingest -b lime --period day --start-date 2024-06-01 --end-date 2024-07-31 --symbols AAPL,TSLA,AMZN
|
|
50
|
+
```
|
|
51
|
+
Run strategy
|
|
52
|
+
```Bash
|
|
53
|
+
poetry run python -m ziplime run -b lime --start 2024-06-01 --end 2024-07-31 --data-frequency daily --capital-base 100000 --no-benchmark -f test.py
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
|
ziplime-0.1.11/README.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# ziplime
|
|
2
|
+
|
|
3
|
+
Zipline wrapper which enables using Lime data for backtesting
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```Bash
|
|
8
|
+
poetry add ziplime
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
You can find usage examples below. All commands supported by `zipline` are also supported by `ziplime` with extended
|
|
14
|
+
list of parameters for easier usage.
|
|
15
|
+
|
|
16
|
+
### Data ingestion
|
|
17
|
+
|
|
18
|
+
Data ingestion works by first fetching historical data and then and then running live data fetch in the background.
|
|
19
|
+
|
|
20
|
+
Difference from original zipline:
|
|
21
|
+
|
|
22
|
+
- `--start-date` and `--end-date` parameters - used to fetch bundle data only for specific date period
|
|
23
|
+
- `--symbols` parameter - specifies symbols to fetch data for directly in the command
|
|
24
|
+
- Running live data fetch in the background
|
|
25
|
+
|
|
26
|
+
Example:
|
|
27
|
+
|
|
28
|
+
Ingest data:
|
|
29
|
+
```Bash
|
|
30
|
+
poetry run python -m ziplime ingest -b lime --period day --start-date 2024-06-01 --end-date 2024-07-31 --symbols AAPL,TSLA,AMZN
|
|
31
|
+
```
|
|
32
|
+
Run strategy
|
|
33
|
+
```Bash
|
|
34
|
+
poetry run python -m ziplime run -b lime --start 2024-06-01 --end 2024-07-31 --data-frequency daily --capital-base 100000 --no-benchmark -f test.py
|
|
35
|
+
```
|
|
36
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "ziplime"
|
|
3
|
+
version = "0.1.11"
|
|
4
|
+
description = ""
|
|
5
|
+
authors = ["Lime Financial <support@lime.co>"]
|
|
6
|
+
readme = "README.md"
|
|
7
|
+
packages = [{include = "ziplime"}]
|
|
8
|
+
|
|
9
|
+
[tool.poetry.dependencies]
|
|
10
|
+
python = "^3.12"
|
|
11
|
+
zipline-reloaded = "3.1"
|
|
12
|
+
dask = "^2024.9.1"
|
|
13
|
+
setuptools = "^72.1.0"
|
|
14
|
+
lime-trader-sdk = "^0.3.9"
|
|
15
|
+
limexhub = "^0.1.27"
|
|
16
|
+
joblib = "^1.4.2"
|
|
17
|
+
pygments = "^2.18.0"
|
|
18
|
+
|
|
19
|
+
[tool.poetry.scripts]
|
|
20
|
+
weather = "ziplime.cli:cli"
|
|
21
|
+
|
|
22
|
+
[build-system]
|
|
23
|
+
requires = ["poetry-core"]
|
|
24
|
+
build-backend = "poetry.core.masonry.api"
|
|
File without changes
|
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
import logging
|
|
3
|
+
import os
|
|
4
|
+
from functools import partial
|
|
5
|
+
|
|
6
|
+
import pandas as pd
|
|
7
|
+
from zipline.__main__ import ipython_only
|
|
8
|
+
|
|
9
|
+
from zipline.utils.calendar_utils import get_calendar
|
|
10
|
+
from zipline.utils.cli import Date
|
|
11
|
+
|
|
12
|
+
from ziplime.constants.default_columns import DEFAULT_COLUMNS, OHLCV_COLUMNS
|
|
13
|
+
from ziplime.constants.fundamental_data import FUNDAMENTAL_DATA_COLUMNS
|
|
14
|
+
from ziplime.data.storages.bcolz_data_bundle import BcolzDataBundle
|
|
15
|
+
from ziplime.utils.run_algo import _run, BenchmarkSpec
|
|
16
|
+
|
|
17
|
+
import click
|
|
18
|
+
import zipline
|
|
19
|
+
from ziplime.data import bundles as bundles_module
|
|
20
|
+
|
|
21
|
+
from click import DateTime
|
|
22
|
+
from lime_trader.models.market import Period
|
|
23
|
+
from zipline.utils.cli import Timestamp
|
|
24
|
+
from zipline.utils.paths import data_root
|
|
25
|
+
|
|
26
|
+
from ziplime.config.register_bundles import register_lime_symbol_list_equities_bundle
|
|
27
|
+
|
|
28
|
+
from zipline import __main__ as zipline__main__
|
|
29
|
+
from zipline.utils.run_algo import load_extensions
|
|
30
|
+
from zipline.extensions import create_args
|
|
31
|
+
|
|
32
|
+
from ziplime.data.bcolz_daily_bars import ZiplimeBcolzDailyBarWriter
|
|
33
|
+
from ziplime.data.bcolz_minute_bars import ZiplimeBcolzMinuteBarWriter
|
|
34
|
+
from ziplime.utils.bundle_utils import register_default_bundles, get_historical_market_data_provider, \
|
|
35
|
+
get_fundamental_data_provider, get_live_market_data_provider
|
|
36
|
+
|
|
37
|
+
DEFAULT_BUNDLE = "lime"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def validate_date_range(date_min: datetime.datetime, date_max: datetime.datetime):
|
|
41
|
+
def _validate_date_range(ctx, param, value):
|
|
42
|
+
if not date_min < value.replace(tzinfo=datetime.timezone.utc) < date_max:
|
|
43
|
+
raise click.BadParameter(f"Must be between {date_min} and {date_max}")
|
|
44
|
+
return value
|
|
45
|
+
|
|
46
|
+
return _validate_date_range
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@click.group()
|
|
50
|
+
@click.option(
|
|
51
|
+
"-e",
|
|
52
|
+
"--extension",
|
|
53
|
+
multiple=True,
|
|
54
|
+
help="File or module path to a zipline extension to load.",
|
|
55
|
+
)
|
|
56
|
+
@click.option(
|
|
57
|
+
"--strict-extensions/--non-strict-extensions",
|
|
58
|
+
is_flag=True,
|
|
59
|
+
help="If --strict-extensions is passed then zipline will not "
|
|
60
|
+
"run if it cannot load all of the specified extensions. "
|
|
61
|
+
"If this is not passed or --non-strict-extensions is passed "
|
|
62
|
+
"then the failure will be logged but execution will continue.",
|
|
63
|
+
)
|
|
64
|
+
@click.option(
|
|
65
|
+
"--default-extension/--no-default-extension",
|
|
66
|
+
is_flag=True,
|
|
67
|
+
default=True,
|
|
68
|
+
help="Don't load the default zipline extension.py file in $ZIPLINE_HOME.",
|
|
69
|
+
)
|
|
70
|
+
@click.option(
|
|
71
|
+
"-x",
|
|
72
|
+
multiple=True,
|
|
73
|
+
help="Any custom command line arguments to define, in key=value form.",
|
|
74
|
+
)
|
|
75
|
+
@click.pass_context
|
|
76
|
+
def main(ctx, extension, strict_extensions, default_extension, x):
|
|
77
|
+
"""Top level ziplime entry point."""
|
|
78
|
+
# install a logging handler before performing any other operations
|
|
79
|
+
|
|
80
|
+
logging.basicConfig(
|
|
81
|
+
format="[%(asctime)s-%(levelname)s][%(name)s]\n %(message)s",
|
|
82
|
+
level=logging.INFO,
|
|
83
|
+
datefmt="%Y-%m-%dT%H:%M:%S%z",
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
register_default_bundles()
|
|
87
|
+
|
|
88
|
+
create_args(x, zipline.extension_args)
|
|
89
|
+
load_extensions(
|
|
90
|
+
default_extension,
|
|
91
|
+
extension,
|
|
92
|
+
strict_extensions,
|
|
93
|
+
os.environ,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
@main.command(context_settings=dict(
|
|
98
|
+
# ignore_unknown_options=True,
|
|
99
|
+
# allow_extra_args=True,
|
|
100
|
+
))
|
|
101
|
+
@click.option(
|
|
102
|
+
"-b",
|
|
103
|
+
"--bundle",
|
|
104
|
+
default=DEFAULT_BUNDLE,
|
|
105
|
+
metavar="BUNDLE-NAME",
|
|
106
|
+
show_default=True,
|
|
107
|
+
help="The data bundle to ingest.",
|
|
108
|
+
)
|
|
109
|
+
@click.option(
|
|
110
|
+
"-c",
|
|
111
|
+
"--calendar",
|
|
112
|
+
default="NYSE",
|
|
113
|
+
show_default=True,
|
|
114
|
+
help="Default calendar to use.",
|
|
115
|
+
)
|
|
116
|
+
@click.option('--new-bundle-name', default=None)
|
|
117
|
+
@click.option(
|
|
118
|
+
"--start-date",
|
|
119
|
+
type=DateTime(),
|
|
120
|
+
callback=validate_date_range(date_min=datetime.datetime(year=1800,
|
|
121
|
+
month=1,
|
|
122
|
+
day=1,
|
|
123
|
+
tzinfo=datetime.timezone.utc
|
|
124
|
+
),
|
|
125
|
+
date_max=datetime.datetime.now(tz=datetime.timezone.utc),
|
|
126
|
+
)
|
|
127
|
+
)
|
|
128
|
+
@click.option(
|
|
129
|
+
"--end-date",
|
|
130
|
+
type=DateTime(),
|
|
131
|
+
callback=validate_date_range(date_min=datetime.datetime(year=1800,
|
|
132
|
+
month=1,
|
|
133
|
+
day=1,
|
|
134
|
+
tzinfo=datetime.timezone.utc
|
|
135
|
+
),
|
|
136
|
+
date_max=datetime.datetime.now(tz=datetime.timezone.utc),
|
|
137
|
+
)
|
|
138
|
+
)
|
|
139
|
+
@click.option(
|
|
140
|
+
"--period",
|
|
141
|
+
default="day",
|
|
142
|
+
type=click.Choice(['minute', 'hour', 'day', 'week', 'month', 'quarter'], case_sensitive=False),
|
|
143
|
+
)
|
|
144
|
+
@click.option("-s", '--symbols')
|
|
145
|
+
@click.option('--fundamental-data')
|
|
146
|
+
@click.option(
|
|
147
|
+
"--assets-version",
|
|
148
|
+
type=int,
|
|
149
|
+
multiple=True,
|
|
150
|
+
help="Version of the assets db to which to downgrade.",
|
|
151
|
+
)
|
|
152
|
+
@click.option(
|
|
153
|
+
"--show-progress/--no-show-progress",
|
|
154
|
+
default=True,
|
|
155
|
+
help="Print progress information to the terminal.",
|
|
156
|
+
)
|
|
157
|
+
@click.option(
|
|
158
|
+
"--historical-market-data-provider",
|
|
159
|
+
default="limex-hub",
|
|
160
|
+
help="Market data provider for historical data",
|
|
161
|
+
show_default=True,
|
|
162
|
+
)
|
|
163
|
+
@click.option(
|
|
164
|
+
"--fundamental-data-provider",
|
|
165
|
+
default="limex-hub",
|
|
166
|
+
help="Fundamental data provider",
|
|
167
|
+
show_default=True,
|
|
168
|
+
)
|
|
169
|
+
@click.pass_context
|
|
170
|
+
def ingest(ctx, bundle, new_bundle_name, start_date, end_date, period, symbols, fundamental_data, show_progress,
|
|
171
|
+
assets_version, calendar,
|
|
172
|
+
historical_market_data_provider,
|
|
173
|
+
fundamental_data_provider
|
|
174
|
+
):
|
|
175
|
+
"""Top level ziplime entry point."""
|
|
176
|
+
symbols_parsed = symbols.split(',') if symbols else None
|
|
177
|
+
fundamental_data_list = fundamental_data.split(",") if fundamental_data else None
|
|
178
|
+
if new_bundle_name:
|
|
179
|
+
bundle_name = f"{DEFAULT_BUNDLE}-{new_bundle_name}"
|
|
180
|
+
ctx.args = ['-b', new_bundle_name] + ctx.args
|
|
181
|
+
else:
|
|
182
|
+
bundle_name = bundle
|
|
183
|
+
ctx.args = ['-b', bundle] + ctx.args
|
|
184
|
+
# install a logging handler before performing any other operations
|
|
185
|
+
register_lime_symbol_list_equities_bundle(
|
|
186
|
+
bundle_name=bundle_name,
|
|
187
|
+
symbols=symbols_parsed,
|
|
188
|
+
start_session=start_date,
|
|
189
|
+
end_session=end_date,
|
|
190
|
+
period=Period(period),
|
|
191
|
+
calendar_name=calendar,
|
|
192
|
+
fundamental_data_list=fundamental_data_list if fundamental_data_list is not None else [
|
|
193
|
+
col.name for col in
|
|
194
|
+
FUNDAMENTAL_DATA_COLUMNS
|
|
195
|
+
]
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
new_params = dict(**ctx.params)
|
|
199
|
+
|
|
200
|
+
# clean up lime only params and set new bundle name
|
|
201
|
+
new_params["bundle"] = bundle_name
|
|
202
|
+
|
|
203
|
+
fundamental_data_cols = ([
|
|
204
|
+
col
|
|
205
|
+
for col in FUNDAMENTAL_DATA_COLUMNS
|
|
206
|
+
if col.name in set(fundamental_data_list)
|
|
207
|
+
]
|
|
208
|
+
if fundamental_data_list is not None
|
|
209
|
+
else DEFAULT_COLUMNS)
|
|
210
|
+
bundles_module.ingest(
|
|
211
|
+
name=bundle_name,
|
|
212
|
+
environ=os.environ,
|
|
213
|
+
timestamp=pd.Timestamp.utcnow(),
|
|
214
|
+
assets_version=assets_version,
|
|
215
|
+
show_progress=show_progress,
|
|
216
|
+
historical_market_data_provider=get_historical_market_data_provider(code=historical_market_data_provider),
|
|
217
|
+
fundamental_data_provider=get_fundamental_data_provider(code=fundamental_data_provider),
|
|
218
|
+
minute_bar_writer_class=ZiplimeBcolzMinuteBarWriter,
|
|
219
|
+
daily_bar_writer_class=BcolzDataBundle,
|
|
220
|
+
fundamental_data_writer_class=BcolzDataBundle,
|
|
221
|
+
market_data_fields=OHLCV_COLUMNS,
|
|
222
|
+
fundamental_data_fields=fundamental_data_cols,
|
|
223
|
+
minute_bar_writer_cols=fundamental_data_cols,
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
@main.command(context_settings=dict(
|
|
228
|
+
ignore_unknown_options=True,
|
|
229
|
+
allow_extra_args=True,
|
|
230
|
+
))
|
|
231
|
+
@click.option(
|
|
232
|
+
"-b",
|
|
233
|
+
"--bundle",
|
|
234
|
+
default=DEFAULT_BUNDLE,
|
|
235
|
+
metavar="BUNDLE-NAME",
|
|
236
|
+
show_default=True,
|
|
237
|
+
help="The data bundle to clean.",
|
|
238
|
+
)
|
|
239
|
+
@click.option(
|
|
240
|
+
"-e",
|
|
241
|
+
"--before",
|
|
242
|
+
type=Timestamp(),
|
|
243
|
+
help="Clear all data before TIMESTAMP."
|
|
244
|
+
" This may not be passed with -k / --keep-last",
|
|
245
|
+
)
|
|
246
|
+
@click.option(
|
|
247
|
+
"-a",
|
|
248
|
+
"--after",
|
|
249
|
+
type=Timestamp(),
|
|
250
|
+
help="Clear all data after TIMESTAMP"
|
|
251
|
+
" This may not be passed with -k / --keep-last",
|
|
252
|
+
)
|
|
253
|
+
@click.option(
|
|
254
|
+
"-k",
|
|
255
|
+
"--keep-last",
|
|
256
|
+
type=int,
|
|
257
|
+
metavar="N",
|
|
258
|
+
help="Clear all but the last N downloads."
|
|
259
|
+
" This may not be passed with -e / --before or -a / --after",
|
|
260
|
+
)
|
|
261
|
+
@click.pass_context
|
|
262
|
+
def clean(ctx, bundle, before, after, keep_last):
|
|
263
|
+
"""Top level ziplime entry point."""
|
|
264
|
+
|
|
265
|
+
func = getattr(zipline__main__, "clean")
|
|
266
|
+
ctx.forward(func)
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
@main.command(context_settings=dict(
|
|
270
|
+
ignore_unknown_options=True,
|
|
271
|
+
allow_extra_args=True,
|
|
272
|
+
))
|
|
273
|
+
@click.pass_context
|
|
274
|
+
def bundles(ctx):
|
|
275
|
+
"""Top level ziplime entry point."""
|
|
276
|
+
func = getattr(zipline__main__, "bundles")
|
|
277
|
+
ctx.forward(func)
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
@main.command()
|
|
281
|
+
@click.option(
|
|
282
|
+
"-f",
|
|
283
|
+
"--algofile",
|
|
284
|
+
default=None,
|
|
285
|
+
type=click.File("r"),
|
|
286
|
+
help="The file that contains the algorithm to run.",
|
|
287
|
+
)
|
|
288
|
+
@click.option(
|
|
289
|
+
"-t",
|
|
290
|
+
"--algotext",
|
|
291
|
+
help="The algorithm script to run.",
|
|
292
|
+
)
|
|
293
|
+
@click.option(
|
|
294
|
+
"-D",
|
|
295
|
+
"--define",
|
|
296
|
+
multiple=True,
|
|
297
|
+
help="Define a name to be bound in the namespace before executing"
|
|
298
|
+
" the algotext. For example '-Dname=value'. The value may be any "
|
|
299
|
+
"python expression. These are evaluated in order so they may refer "
|
|
300
|
+
"to previously defined names.",
|
|
301
|
+
)
|
|
302
|
+
@click.option(
|
|
303
|
+
"--data-frequency",
|
|
304
|
+
type=click.Choice({"daily", "minute"}),
|
|
305
|
+
default="daily",
|
|
306
|
+
show_default=True,
|
|
307
|
+
help="The data frequency of the simulation.",
|
|
308
|
+
)
|
|
309
|
+
@click.option(
|
|
310
|
+
"--capital-base",
|
|
311
|
+
type=float,
|
|
312
|
+
default=10e6,
|
|
313
|
+
show_default=True,
|
|
314
|
+
help="The starting capital for the simulation.",
|
|
315
|
+
)
|
|
316
|
+
@click.option(
|
|
317
|
+
"-b",
|
|
318
|
+
"--bundle",
|
|
319
|
+
default=DEFAULT_BUNDLE,
|
|
320
|
+
metavar="BUNDLE-NAME",
|
|
321
|
+
show_default=True,
|
|
322
|
+
help="The data bundle to use for the simulation.",
|
|
323
|
+
)
|
|
324
|
+
@click.option(
|
|
325
|
+
"--bundle-timestamp",
|
|
326
|
+
type=Timestamp(),
|
|
327
|
+
default=pd.Timestamp.utcnow(),
|
|
328
|
+
show_default=False,
|
|
329
|
+
help="The date to lookup data on or before.\n" "[default: <current-time>]",
|
|
330
|
+
)
|
|
331
|
+
@click.option(
|
|
332
|
+
"-bf",
|
|
333
|
+
"--benchmark-file",
|
|
334
|
+
default=None,
|
|
335
|
+
type=click.Path(exists=True, dir_okay=False, readable=True, path_type=str),
|
|
336
|
+
help="The csv file that contains the benchmark returns",
|
|
337
|
+
)
|
|
338
|
+
@click.option(
|
|
339
|
+
"--benchmark-symbol",
|
|
340
|
+
default=None,
|
|
341
|
+
type=click.STRING,
|
|
342
|
+
help="The symbol of the instrument to be used as a benchmark "
|
|
343
|
+
"(should exist in the ingested bundle)",
|
|
344
|
+
)
|
|
345
|
+
@click.option(
|
|
346
|
+
"--benchmark-sid",
|
|
347
|
+
default=None,
|
|
348
|
+
type=int,
|
|
349
|
+
help="The sid of the instrument to be used as a benchmark "
|
|
350
|
+
"(should exist in the ingested bundle)",
|
|
351
|
+
)
|
|
352
|
+
@click.option(
|
|
353
|
+
"--no-benchmark",
|
|
354
|
+
is_flag=True,
|
|
355
|
+
default=False,
|
|
356
|
+
help="If passed, use a benchmark of zero returns.",
|
|
357
|
+
)
|
|
358
|
+
@click.option(
|
|
359
|
+
"-s",
|
|
360
|
+
"--start",
|
|
361
|
+
type=Date(as_timestamp=True),
|
|
362
|
+
help="The start date of the simulation.",
|
|
363
|
+
)
|
|
364
|
+
@click.option(
|
|
365
|
+
"-e",
|
|
366
|
+
"--end",
|
|
367
|
+
type=Date(as_timestamp=True),
|
|
368
|
+
help="The end date of the simulation.",
|
|
369
|
+
)
|
|
370
|
+
@click.option(
|
|
371
|
+
"-o",
|
|
372
|
+
"--output",
|
|
373
|
+
default="-",
|
|
374
|
+
metavar="FILENAME",
|
|
375
|
+
show_default=True,
|
|
376
|
+
help="The location to write the perf data. If this is '-' the perf will"
|
|
377
|
+
" be written to stdout.",
|
|
378
|
+
)
|
|
379
|
+
@click.option(
|
|
380
|
+
"--trading-calendar",
|
|
381
|
+
metavar="TRADING-CALENDAR",
|
|
382
|
+
default="XNYS",
|
|
383
|
+
help="The calendar you want to use e.g. XLON. XNYS is the default.",
|
|
384
|
+
)
|
|
385
|
+
@click.option(
|
|
386
|
+
"--print-algo/--no-print-algo",
|
|
387
|
+
is_flag=True,
|
|
388
|
+
default=False,
|
|
389
|
+
help="Print the algorithm to stdout.",
|
|
390
|
+
)
|
|
391
|
+
@click.option(
|
|
392
|
+
"--metrics-set",
|
|
393
|
+
default="default",
|
|
394
|
+
help="The metrics set to use. New metrics sets may be registered in your"
|
|
395
|
+
" extension.py.",
|
|
396
|
+
)
|
|
397
|
+
@click.option(
|
|
398
|
+
"--blotter",
|
|
399
|
+
default="default",
|
|
400
|
+
help="The blotter to use.",
|
|
401
|
+
show_default=True,
|
|
402
|
+
)
|
|
403
|
+
@click.option(
|
|
404
|
+
"--broker",
|
|
405
|
+
default=None,
|
|
406
|
+
help="The broker to use for live trading.",
|
|
407
|
+
show_default=True,
|
|
408
|
+
)
|
|
409
|
+
@click.option(
|
|
410
|
+
"--live-market-data-provider",
|
|
411
|
+
default="lime-trader-sdk",
|
|
412
|
+
help="Market data provider for live trading",
|
|
413
|
+
show_default=True,
|
|
414
|
+
)
|
|
415
|
+
@ipython_only(
|
|
416
|
+
click.option(
|
|
417
|
+
"--local-namespace/--no-local-namespace",
|
|
418
|
+
is_flag=True,
|
|
419
|
+
default=None,
|
|
420
|
+
help="Should the algorithm methods be " "resolved in the local namespace.",
|
|
421
|
+
)
|
|
422
|
+
)
|
|
423
|
+
@click.pass_context
|
|
424
|
+
def run(
|
|
425
|
+
ctx,
|
|
426
|
+
algofile,
|
|
427
|
+
algotext,
|
|
428
|
+
define,
|
|
429
|
+
data_frequency,
|
|
430
|
+
capital_base,
|
|
431
|
+
bundle,
|
|
432
|
+
bundle_timestamp,
|
|
433
|
+
benchmark_file,
|
|
434
|
+
benchmark_symbol,
|
|
435
|
+
benchmark_sid,
|
|
436
|
+
no_benchmark,
|
|
437
|
+
start,
|
|
438
|
+
end,
|
|
439
|
+
output,
|
|
440
|
+
trading_calendar,
|
|
441
|
+
print_algo,
|
|
442
|
+
metrics_set,
|
|
443
|
+
local_namespace,
|
|
444
|
+
blotter,
|
|
445
|
+
broker: str | None,
|
|
446
|
+
live_market_data_provider: str,
|
|
447
|
+
):
|
|
448
|
+
"""Run a backtest for the given algorithm."""
|
|
449
|
+
# check that the start and end dates are passed correctly
|
|
450
|
+
if start is None and end is None:
|
|
451
|
+
# check both at the same time to avoid the case where a user
|
|
452
|
+
# does not pass either of these and then passes the first only
|
|
453
|
+
# to be told they need to pass the second argument also
|
|
454
|
+
ctx.fail(
|
|
455
|
+
"must specify dates with '-s' / '--start' and '-e' / '--end'",
|
|
456
|
+
)
|
|
457
|
+
if start is None:
|
|
458
|
+
ctx.fail("must specify a start date with '-s' / '--start'")
|
|
459
|
+
if end is None:
|
|
460
|
+
ctx.fail("must specify an end date with '-e' / '--end'")
|
|
461
|
+
|
|
462
|
+
if (algotext is not None) == (algofile is not None):
|
|
463
|
+
ctx.fail(
|
|
464
|
+
"must specify exactly one of '-f' / "
|
|
465
|
+
"'--algofile' or"
|
|
466
|
+
" '-t' / '--algotext'",
|
|
467
|
+
)
|
|
468
|
+
|
|
469
|
+
trading_calendar = get_calendar(trading_calendar)
|
|
470
|
+
|
|
471
|
+
benchmark_spec = BenchmarkSpec.from_cli_params(
|
|
472
|
+
no_benchmark=no_benchmark,
|
|
473
|
+
benchmark_sid=benchmark_sid,
|
|
474
|
+
benchmark_symbol=benchmark_symbol,
|
|
475
|
+
benchmark_file=benchmark_file,
|
|
476
|
+
)
|
|
477
|
+
|
|
478
|
+
return _run(
|
|
479
|
+
initialize=None,
|
|
480
|
+
handle_data=None,
|
|
481
|
+
before_trading_start=None,
|
|
482
|
+
analyze=None,
|
|
483
|
+
algofile=algofile,
|
|
484
|
+
algotext=algotext,
|
|
485
|
+
defines=define,
|
|
486
|
+
data_frequency=data_frequency,
|
|
487
|
+
capital_base=capital_base,
|
|
488
|
+
bundle=bundle,
|
|
489
|
+
bundle_timestamp=bundle_timestamp,
|
|
490
|
+
start=start,
|
|
491
|
+
end=end,
|
|
492
|
+
output=output,
|
|
493
|
+
trading_calendar=trading_calendar,
|
|
494
|
+
print_algo=print_algo,
|
|
495
|
+
metrics_set=metrics_set,
|
|
496
|
+
local_namespace=local_namespace,
|
|
497
|
+
environ=os.environ,
|
|
498
|
+
blotter=blotter,
|
|
499
|
+
benchmark_spec=benchmark_spec,
|
|
500
|
+
custom_loader=None,
|
|
501
|
+
broker=broker,
|
|
502
|
+
market_data_provider=get_live_market_data_provider(live_market_data_provider)
|
|
503
|
+
)
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
if __name__ == "__main__":
|
|
507
|
+
main()
|