mirror of
https://github.com/wassname/catalyst.git
synced 2026-08-07 11:20:19 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65c6322ba5 | ||
|
|
4a2d5678ad | ||
|
|
06399caa2b | ||
|
|
4c84ea8efc | ||
|
|
c85e698ee2 | ||
|
|
423e30da1e | ||
|
|
c29b1ef3c1 | ||
|
|
17f9906df4 | ||
|
|
41b5135ed4 | ||
|
|
af85ee31c9 | ||
|
|
132dffd239 | ||
|
|
887a7cc825 | ||
|
|
22249506e6 | ||
|
|
b979ffd123 | ||
|
|
0db9950347 | ||
|
|
7c4467d800 | ||
|
|
30dbeaa5fb | ||
|
|
4d6837b5d6 | ||
|
|
098a4c4fc6 | ||
|
|
f5cb6e38d6 | ||
|
|
2d5d2b21ee |
+2
-2
@@ -1,11 +1,11 @@
|
|||||||
#
|
#
|
||||||
# Dockerfile for an image with the currently checked out version of catalyst installed. To build:
|
# Dockerfile for an image with the currently checked out version of catalyst installed. To build:
|
||||||
#
|
#
|
||||||
# docker build -t quantopian/catalyst .
|
# docker build -t enigmampc/catalyst .
|
||||||
#
|
#
|
||||||
# To run the container:
|
# To run the container:
|
||||||
#
|
#
|
||||||
# docker run -v /path/to/your/notebooks:/projects -v ~/.catalyst:/root/.catalyst -p 8888:8888/tcp --name catalyst -it quantopian/catalyst
|
# docker run -v /path/to/your/notebooks:/projects -v ~/.catalyst:/root/.catalyst -p 8888:8888/tcp --name catalyst -it enigmampc/catalyst
|
||||||
#
|
#
|
||||||
# To access Jupyter when running docker locally (you may need to add NAT rules):
|
# To access Jupyter when running docker locally (you may need to add NAT rules):
|
||||||
#
|
#
|
||||||
|
|||||||
+5
-5
@@ -1,15 +1,15 @@
|
|||||||
#
|
#
|
||||||
# Dockerfile for an image with the currently checked out version of catalyst installed. To build:
|
# Dockerfile for an image with the currently checked out version of catalyst installed. To build:
|
||||||
#
|
#
|
||||||
# docker build -t quantopian/catalystdev -f Dockerfile-dev .
|
# docker build -t enigmampc/catalystdev -f Dockerfile-dev .
|
||||||
#
|
#
|
||||||
# Note: the dev build requires a quantopian/catalyst image, which you can build as follows:
|
# Note: the dev build requires a enigmampc/catalyst image, which you can build as follows:
|
||||||
#
|
#
|
||||||
# docker build -t quantopian/catalyst -f Dockerfile .
|
# docker build -t enigmampc/catalyst -f Dockerfile .
|
||||||
#
|
#
|
||||||
# To run the container:
|
# To run the container:
|
||||||
#
|
#
|
||||||
# docker run -v /path/to/your/notebooks:/projects -v ~/.catalyst:/root/.catalyst -p 8888:8888/tcp --name catalystdev -it quantopian/catalystdev
|
# docker run -v /path/to/your/notebooks:/projects -v ~/.catalyst:/root/.catalyst -p 8888:8888/tcp --name catalystdev -it enigmampc/catalystdev
|
||||||
#
|
#
|
||||||
# To access Jupyter when running docker locally (you may need to add NAT rules):
|
# To access Jupyter when running docker locally (you may need to add NAT rules):
|
||||||
#
|
#
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
#
|
#
|
||||||
# docker exec -it catalystdev catalyst run -f /projects/my_algo.py --start 2015-1-1 --end 2016-1-1 /projects/result.pickle
|
# docker exec -it catalystdev catalyst run -f /projects/my_algo.py --start 2015-1-1 --end 2016-1-1 /projects/result.pickle
|
||||||
#
|
#
|
||||||
FROM quantopian/catalyst
|
FROM enigmampc/catalyst
|
||||||
|
|
||||||
WORKDIR /catalyst
|
WORKDIR /catalyst
|
||||||
|
|
||||||
|
|||||||
+9
-3
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
|version tag|
|
|version tag|
|
||||||
|version status|
|
|version status|
|
||||||
|
|forum|
|
||||||
|discord|
|
|discord|
|
||||||
|twitter|
|
|twitter|
|
||||||
|
|
||||||
@@ -22,9 +23,11 @@ visit `enigma.co <https://www.enigma.co>`_ to learn more about Catalyst.
|
|||||||
Catalyst builds on top of the well-established
|
Catalyst builds on top of the well-established
|
||||||
`Zipline <https://github.com/quantopian/zipline>`_ project. We did our best to
|
`Zipline <https://github.com/quantopian/zipline>`_ project. We did our best to
|
||||||
minimize structural changes to the general API to maximize compatibility with
|
minimize structural changes to the general API to maximize compatibility with
|
||||||
existing trading algorithms, developer knowledge, and tutorials. Join us on
|
existing trading algorithms, developer knowledge, and tutorials. Join us on the
|
||||||
`Discord <https://discord.gg/SJK32GY>`_ where we have a *#catalyst_dev* channel
|
`Catalyst Forum <https://catalyst.enigma.co/>`_ for questions around Catalyst,
|
||||||
for questions around Catalyst, algorithmic trading and technical support.
|
algorithmic trading and technical support. We also have a
|
||||||
|
`Discord <https://discord.gg/SJK32GY>`_ group with the *#catalyst_dev* and
|
||||||
|
*#catalyst_setup* dedicated channels.
|
||||||
|
|
||||||
Overview
|
Overview
|
||||||
========
|
========
|
||||||
@@ -60,6 +63,9 @@ Go to our `Documentation Website <https://enigmampc.github.io/catalyst/>`_.
|
|||||||
|
|
||||||
.. |version status| image:: https://img.shields.io/pypi/pyversions/enigma-catalyst.svg
|
.. |version status| image:: https://img.shields.io/pypi/pyversions/enigma-catalyst.svg
|
||||||
:target: https://pypi.python.org/pypi/enigma-catalyst
|
:target: https://pypi.python.org/pypi/enigma-catalyst
|
||||||
|
|
||||||
|
.. |forum| image:: https://img.shields.io/badge/forum-join-green.svg
|
||||||
|
:target: https://catalyst.enigma.co/
|
||||||
|
|
||||||
.. |discord| image:: https://img.shields.io/badge/discord-join%20chat-green.svg
|
.. |discord| image:: https://img.shields.io/badge/discord-join%20chat-green.svg
|
||||||
:target: https://discordapp.com/invite/SJK32GY
|
:target: https://discordapp.com/invite/SJK32GY
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import warnings
|
|||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
|
||||||
from pandas.tslib import normalize_date
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
@@ -564,7 +563,7 @@ cdef class BarData:
|
|||||||
})
|
})
|
||||||
|
|
||||||
cdef bool _is_stale_for_asset(self, asset, dt, adjusted_dt, data_portal):
|
cdef bool _is_stale_for_asset(self, asset, dt, adjusted_dt, data_portal):
|
||||||
session_label = normalize_date(dt) # FIXME
|
session_label = dt.normalize_date() # FIXME
|
||||||
|
|
||||||
if not asset.is_alive_for_session(session_label):
|
if not asset.is_alive_for_session(session_label):
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import logbook
|
|||||||
import pytz
|
import pytz
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from contextlib2 import ExitStack
|
from contextlib2 import ExitStack
|
||||||
from pandas.tseries.tools import normalize_date
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from itertools import chain, repeat
|
from itertools import chain, repeat
|
||||||
@@ -1345,7 +1344,7 @@ class TradingAlgorithm(object):
|
|||||||
# Make sure the asset exists, and that there is a last price for it.
|
# Make sure the asset exists, and that there is a last price for it.
|
||||||
# FIXME: we should use BarData's can_trade logic here, but I haven't
|
# FIXME: we should use BarData's can_trade logic here, but I haven't
|
||||||
# yet found a good way to do that.
|
# yet found a good way to do that.
|
||||||
normalized_date = normalize_date(self.datetime)
|
normalized_date = self.datetime.normalize()
|
||||||
|
|
||||||
if normalized_date < asset.start_date:
|
if normalized_date < asset.start_date:
|
||||||
raise CannotOrderDelistedAsset(
|
raise CannotOrderDelistedAsset(
|
||||||
@@ -1392,7 +1391,7 @@ class TradingAlgorithm(object):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if asset.auto_close_date:
|
if asset.auto_close_date:
|
||||||
day = normalize_date(self.get_datetime())
|
day = self.get_datetime().normalize()
|
||||||
|
|
||||||
if day > min(asset.end_date, asset.auto_close_date):
|
if day > min(asset.end_date, asset.auto_close_date):
|
||||||
# If we are after the asset's end date or auto close date, warn
|
# If we are after the asset's end date or auto close date, warn
|
||||||
@@ -2475,7 +2474,7 @@ class TradingAlgorithm(object):
|
|||||||
"""
|
"""
|
||||||
Internal implementation of `pipeline_output`.
|
Internal implementation of `pipeline_output`.
|
||||||
"""
|
"""
|
||||||
today = normalize_date(self.get_datetime())
|
today = self.get_datetime().normalize()
|
||||||
data = NO_DATA = object()
|
data = NO_DATA = object()
|
||||||
try:
|
try:
|
||||||
data = self._pipeline_cache.unwrap(today)
|
data = self._pipeline_cache.unwrap(today)
|
||||||
|
|||||||
@@ -630,23 +630,28 @@ cdef class TradingPair(Asset):
|
|||||||
and whose second element is a tuple of all the attributes that should
|
and whose second element is a tuple of all the attributes that should
|
||||||
be serialized/deserialized during pickling.
|
be serialized/deserialized during pickling.
|
||||||
"""
|
"""
|
||||||
#TODO: make sure that all fields set there
|
# added arguments for catalyst
|
||||||
return (self.__class__, (self.symbol,
|
return (self.__class__, (self.symbol,
|
||||||
self.exchange,
|
self.exchange,
|
||||||
self.start_date,
|
self.start_date,
|
||||||
self.asset_name,
|
self.asset_name,
|
||||||
self.sid,
|
self.sid,
|
||||||
self.leverage,
|
self.leverage,
|
||||||
|
self.end_daily,
|
||||||
|
self.end_minute,
|
||||||
self.end_date,
|
self.end_date,
|
||||||
|
self.exchange_symbol,
|
||||||
self.first_traded,
|
self.first_traded,
|
||||||
self.auto_close_date,
|
self.auto_close_date,
|
||||||
self.exchange_full,
|
self.exchange_full,
|
||||||
self.min_trade_size,
|
self.min_trade_size,
|
||||||
self.max_trade_size,
|
self.max_trade_size,
|
||||||
|
self.maker,
|
||||||
|
self.taker,
|
||||||
self.lot,
|
self.lot,
|
||||||
self.decimals,
|
self.decimals,
|
||||||
self.taker,
|
self.trading_state,
|
||||||
self.maker))
|
self.data_source))
|
||||||
|
|
||||||
def make_asset_array(int size, Asset asset):
|
def make_asset_array(int size, Asset asset):
|
||||||
cdef np.ndarray out = np.empty([size], dtype=object)
|
cdef np.ndarray out = np.empty([size], dtype=object)
|
||||||
|
|||||||
@@ -24,8 +24,7 @@ AUTO_INGEST = False
|
|||||||
|
|
||||||
AUTH_SERVER = 'https://data.enigma.co'
|
AUTH_SERVER = 'https://data.enigma.co'
|
||||||
|
|
||||||
# TODO: switch to mainnet
|
ETH_REMOTE_NODE = 'https://mainnet.infura.io'
|
||||||
ETH_REMOTE_NODE = 'https://rinkeby.infura.io/'
|
|
||||||
|
|
||||||
MARKETPLACE_CONTRACT = 'https://raw.githubusercontent.com/enigmampc/' \
|
MARKETPLACE_CONTRACT = 'https://raw.githubusercontent.com/enigmampc/' \
|
||||||
'catalyst/master/catalyst/marketplace/' \
|
'catalyst/master/catalyst/marketplace/' \
|
||||||
@@ -35,7 +34,6 @@ MARKETPLACE_CONTRACT_ABI = 'https://raw.githubusercontent.com/enigmampc/' \
|
|||||||
'catalyst/master/catalyst/marketplace/' \
|
'catalyst/master/catalyst/marketplace/' \
|
||||||
'contract_marketplace_abi.json'
|
'contract_marketplace_abi.json'
|
||||||
|
|
||||||
# TODO: switch to mainnet
|
|
||||||
ENIGMA_CONTRACT = 'https://raw.githubusercontent.com/enigmampc/' \
|
ENIGMA_CONTRACT = 'https://raw.githubusercontent.com/enigmampc/' \
|
||||||
'catalyst/master/catalyst/marketplace/' \
|
'catalyst/master/catalyst/marketplace/' \
|
||||||
'contract_enigma_address.txt'
|
'contract_enigma_address.txt'
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import numpy as np
|
|||||||
from numpy import float64, int64, nan
|
from numpy import float64, int64, nan
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from pandas import isnull
|
from pandas import isnull
|
||||||
from pandas.tslib import normalize_date
|
|
||||||
from six import iteritems
|
from six import iteritems
|
||||||
from six.moves import reduce
|
from six.moves import reduce
|
||||||
|
|
||||||
@@ -439,7 +438,7 @@ class DataPortal(object):
|
|||||||
(isinstance(asset, (Asset, ContinuousFuture))))
|
(isinstance(asset, (Asset, ContinuousFuture))))
|
||||||
|
|
||||||
def _get_fetcher_value(self, asset, field, dt):
|
def _get_fetcher_value(self, asset, field, dt):
|
||||||
day = normalize_date(dt)
|
day = dt.normalize()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return \
|
return \
|
||||||
@@ -1130,7 +1129,7 @@ class DataPortal(object):
|
|||||||
if self._asset_start_dates[sid] > dt:
|
if self._asset_start_dates[sid] > dt:
|
||||||
raise NoTradeDataAvailableTooEarly(
|
raise NoTradeDataAvailableTooEarly(
|
||||||
sid=sid,
|
sid=sid,
|
||||||
dt=normalize_date(dt),
|
dt=dt.normalize(),
|
||||||
start_dt=start_date
|
start_dt=start_date
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1138,7 +1137,7 @@ class DataPortal(object):
|
|||||||
if self._asset_end_dates[sid] < dt:
|
if self._asset_end_dates[sid] < dt:
|
||||||
raise NoTradeDataAvailableTooLate(
|
raise NoTradeDataAvailableTooLate(
|
||||||
sid=sid,
|
sid=sid,
|
||||||
dt=normalize_date(dt),
|
dt=dt.normalize(),
|
||||||
end_dt=end_date
|
end_dt=end_date
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1262,7 +1261,7 @@ class DataPortal(object):
|
|||||||
if self._extra_source_df is None:
|
if self._extra_source_df is None:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
day = normalize_date(dt)
|
day = dt.normalize()
|
||||||
|
|
||||||
if day in self._extra_source_df.index:
|
if day in self._extra_source_df.index:
|
||||||
assets = self._extra_source_df.loc[day]['sid']
|
assets = self._extra_source_df.loc[day]['sid']
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ from abc import (
|
|||||||
from numpy import concatenate
|
from numpy import concatenate
|
||||||
from lru import LRU
|
from lru import LRU
|
||||||
from pandas import isnull
|
from pandas import isnull
|
||||||
from pandas.tslib import normalize_date
|
|
||||||
from toolz import sliding_window
|
from toolz import sliding_window
|
||||||
|
|
||||||
from six import with_metaclass
|
from six import with_metaclass
|
||||||
@@ -93,8 +92,8 @@ class HistoryCompatibleUSEquityAdjustmentReader(object):
|
|||||||
The adjustments as a dict of loc -> Float64Multiply
|
The adjustments as a dict of loc -> Float64Multiply
|
||||||
"""
|
"""
|
||||||
sid = int(asset)
|
sid = int(asset)
|
||||||
start = normalize_date(dts[0])
|
start = dts[0].normalize()
|
||||||
end = normalize_date(dts[-1])
|
end = dts[-1].normalize()
|
||||||
adjs = {}
|
adjs = {}
|
||||||
if field != 'volume':
|
if field != 'volume':
|
||||||
mergers = self._adjustments_reader.get_adjustments_for_sid(
|
mergers = self._adjustments_reader.get_adjustments_for_sid(
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ from pandas import (
|
|||||||
to_datetime,
|
to_datetime,
|
||||||
Timestamp,
|
Timestamp,
|
||||||
)
|
)
|
||||||
from pandas.tslib import iNaT
|
|
||||||
from six import (
|
from six import (
|
||||||
iteritems,
|
iteritems,
|
||||||
string_types,
|
string_types,
|
||||||
@@ -422,7 +421,7 @@ class BcolzDailyBarWriter(object):
|
|||||||
)
|
)
|
||||||
|
|
||||||
full_table.attrs['first_trading_day'] = (
|
full_table.attrs['first_trading_day'] = (
|
||||||
earliest_date if earliest_date is not None else iNaT
|
earliest_date if earliest_date is not None else NaT
|
||||||
)
|
)
|
||||||
|
|
||||||
full_table.attrs['first_row'] = first_row
|
full_table.attrs['first_row'] = first_row
|
||||||
|
|||||||
@@ -62,7 +62,6 @@ from __future__ import division
|
|||||||
import logbook
|
import logbook
|
||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from pandas.tseries.tools import normalize_date
|
|
||||||
|
|
||||||
from catalyst.finance.performance.period import PerformancePeriod
|
from catalyst.finance.performance.period import PerformancePeriod
|
||||||
from catalyst.errors import NoFurtherDataError
|
from catalyst.errors import NoFurtherDataError
|
||||||
@@ -344,7 +343,7 @@ class PerformanceTracker(object):
|
|||||||
"""
|
"""
|
||||||
self.position_tracker.sync_last_sale_prices(dt, False, data_portal)
|
self.position_tracker.sync_last_sale_prices(dt, False, data_portal)
|
||||||
self.update_performance()
|
self.update_performance()
|
||||||
todays_date = normalize_date(dt)
|
todays_date = dt.normalize()
|
||||||
account = self.get_account(False)
|
account = self.get_account(False)
|
||||||
|
|
||||||
bench_returns = self.all_benchmark_returns.loc[todays_date:dt]
|
bench_returns = self.all_benchmark_returns.loc[todays_date:dt]
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import logbook
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from pandas.tseries.tools import normalize_date
|
|
||||||
|
|
||||||
from six import iteritems
|
from six import iteritems
|
||||||
|
|
||||||
@@ -80,7 +79,7 @@ class RiskMetricsCumulative(object):
|
|||||||
# on the first day.
|
# on the first day.
|
||||||
self.day_before_start = self.start_session - self.sessions.freq
|
self.day_before_start = self.start_session - self.sessions.freq
|
||||||
|
|
||||||
last_day = normalize_date(sim_params.end_session)
|
last_day = sim_params.end_session.normalize()
|
||||||
if last_day not in self.sessions:
|
if last_day not in self.sessions:
|
||||||
last_day = pd.tseries.index.DatetimeIndex(
|
last_day = pd.tseries.index.DatetimeIndex(
|
||||||
[last_day]
|
[last_day]
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ from functools import partial
|
|||||||
|
|
||||||
import logbook
|
import logbook
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from pandas.tslib import normalize_date
|
|
||||||
from six import string_types
|
from six import string_types
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine
|
||||||
|
|
||||||
@@ -164,8 +163,8 @@ class SimulationParameters(object):
|
|||||||
# chop off any minutes or hours on the given start and end dates,
|
# chop off any minutes or hours on the given start and end dates,
|
||||||
# as we only support session labels here (and we represent session
|
# as we only support session labels here (and we represent session
|
||||||
# labels as midnight UTC).
|
# labels as midnight UTC).
|
||||||
self._start_session = normalize_date(start_session)
|
self._start_session = start_session.normalize()
|
||||||
self._end_session = normalize_date(end_session)
|
self._end_session = end_session.normalize()
|
||||||
self._capital_base = capital_base
|
self._capital_base = capital_base
|
||||||
|
|
||||||
self._emission_rate = emission_rate
|
self._emission_rate = emission_rate
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
from contextlib2 import ExitStack
|
from contextlib2 import ExitStack
|
||||||
from logbook import Logger, Processor
|
from logbook import Logger, Processor
|
||||||
from pandas.tslib import normalize_date
|
|
||||||
from catalyst.protocol import BarData
|
from catalyst.protocol import BarData
|
||||||
from catalyst.utils.api_support import ZiplineAPI
|
from catalyst.utils.api_support import ZiplineAPI
|
||||||
from six import viewkeys
|
from six import viewkeys
|
||||||
@@ -229,7 +228,7 @@ class AlgorithmSimulator(object):
|
|||||||
elif action == SESSION_END:
|
elif action == SESSION_END:
|
||||||
# End of the session.
|
# End of the session.
|
||||||
if emission_rate == 'daily':
|
if emission_rate == 'daily':
|
||||||
handle_benchmark(normalize_date(dt))
|
handle_benchmark(dt).normalize()
|
||||||
execute_order_cancellation_policy()
|
execute_order_cancellation_policy()
|
||||||
|
|
||||||
yield self._get_daily_message(dt, algo, algo.perf_tracker)
|
yield self._get_daily_message(dt, algo, algo.perf_tracker)
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
0x39a54f480d922a58c963de8091a6c9afc69db2cf
|
0xf0ee6b27b759c9893ce4f094b49ad28fd15a23e4
|
||||||
@@ -1 +1 @@
|
|||||||
0xa2b37c6cd52f60fd4eb46ca59fafcf22d081aebc
|
0xa64927358a82254be92eb1f1cb01de68d1787004
|
||||||
@@ -20,7 +20,6 @@ from requests_toolbelt.multipart.decoder import \
|
|||||||
from catalyst.constants import (
|
from catalyst.constants import (
|
||||||
LOG_LEVEL, AUTH_SERVER, ETH_REMOTE_NODE, MARKETPLACE_CONTRACT,
|
LOG_LEVEL, AUTH_SERVER, ETH_REMOTE_NODE, MARKETPLACE_CONTRACT,
|
||||||
MARKETPLACE_CONTRACT_ABI, ENIGMA_CONTRACT, ENIGMA_CONTRACT_ABI)
|
MARKETPLACE_CONTRACT_ABI, ENIGMA_CONTRACT, ENIGMA_CONTRACT_ABI)
|
||||||
from catalyst.utils.cli import maybe_show_progress
|
|
||||||
from catalyst.exchange.utils.stats_utils import set_print_settings
|
from catalyst.exchange.utils.stats_utils import set_print_settings
|
||||||
from catalyst.marketplace.marketplace_errors import (
|
from catalyst.marketplace.marketplace_errors import (
|
||||||
MarketplacePubAddressEmpty, MarketplaceDatasetNotFound,
|
MarketplacePubAddressEmpty, MarketplaceDatasetNotFound,
|
||||||
@@ -70,7 +69,10 @@ class Marketplace:
|
|||||||
contract_url.info().get_content_charset()).strip())
|
contract_url.info().get_content_charset()).strip())
|
||||||
|
|
||||||
abi_url = urllib.urlopen(MARKETPLACE_CONTRACT_ABI)
|
abi_url = urllib.urlopen(MARKETPLACE_CONTRACT_ABI)
|
||||||
abi = json.load(abi_url)
|
abi_url = abi_url.read().decode(
|
||||||
|
abi_url.info().get_content_charset())
|
||||||
|
|
||||||
|
abi = json.loads(abi_url)
|
||||||
|
|
||||||
self.mkt_contract = self.web3.eth.contract(
|
self.mkt_contract = self.web3.eth.contract(
|
||||||
self.mkt_contract_address,
|
self.mkt_contract_address,
|
||||||
@@ -84,7 +86,10 @@ class Marketplace:
|
|||||||
contract_url.info().get_content_charset()).strip())
|
contract_url.info().get_content_charset()).strip())
|
||||||
|
|
||||||
abi_url = urllib.urlopen(ENIGMA_CONTRACT_ABI)
|
abi_url = urllib.urlopen(ENIGMA_CONTRACT_ABI)
|
||||||
abi = json.load(abi_url)
|
abi_url = abi_url.read().decode(
|
||||||
|
abi_url.info().get_content_charset())
|
||||||
|
|
||||||
|
abi = json.loads(abi_url)
|
||||||
|
|
||||||
self.eng_contract = self.web3.eth.contract(
|
self.eng_contract = self.web3.eth.contract(
|
||||||
self.eng_contract_address,
|
self.eng_contract_address,
|
||||||
@@ -518,7 +523,7 @@ class Marketplace:
|
|||||||
# iter(decoder.parts),
|
# iter(decoder.parts),
|
||||||
# True,
|
# True,
|
||||||
# label='Processing files') as part:
|
# label='Processing files') as part:
|
||||||
counter = 0
|
counter = 1
|
||||||
for part in decoder.parts:
|
for part in decoder.parts:
|
||||||
log.info("Processing file {} of {}".format(
|
log.info("Processing file {} of {}".format(
|
||||||
counter, len(decoder.parts)))
|
counter, len(decoder.parts)))
|
||||||
@@ -638,7 +643,7 @@ class Marketplace:
|
|||||||
def register(self):
|
def register(self):
|
||||||
while True:
|
while True:
|
||||||
desc = input('Enter the name of the dataset to register: ')
|
desc = input('Enter the name of the dataset to register: ')
|
||||||
dataset = desc.lower()
|
dataset = desc.lower().strip()
|
||||||
provider_info = self.mkt_contract.functions.getDataProviderInfo(
|
provider_info = self.mkt_contract.functions.getDataProviderInfo(
|
||||||
Web3.toHex(dataset)
|
Web3.toHex(dataset)
|
||||||
).call()
|
).call()
|
||||||
@@ -778,26 +783,32 @@ class Marketplace:
|
|||||||
else:
|
else:
|
||||||
key, secret = get_key_secret(provider_info[0], match['wallet'])
|
key, secret = get_key_secret(provider_info[0], match['wallet'])
|
||||||
|
|
||||||
headers = get_signed_headers(dataset, key, secret)
|
|
||||||
filenames = glob.glob(os.path.join(datadir, '*.csv'))
|
filenames = glob.glob(os.path.join(datadir, '*.csv'))
|
||||||
|
|
||||||
if not filenames:
|
if not filenames:
|
||||||
raise MarketplaceNoCSVFiles(datadir=datadir)
|
raise MarketplaceNoCSVFiles(datadir=datadir)
|
||||||
|
|
||||||
files = []
|
files = []
|
||||||
for file in filenames:
|
for idx, file in enumerate(filenames):
|
||||||
|
log.info('Uploading file {} of {}: {}'.format(
|
||||||
|
idx+1, len(filenames), file))
|
||||||
|
files = []
|
||||||
files.append(('file', open(file, 'rb')))
|
files.append(('file', open(file, 'rb')))
|
||||||
|
|
||||||
r = requests.post('{}/marketplace/publish'.format(AUTH_SERVER),
|
headers = get_signed_headers(dataset, key, secret)
|
||||||
files=files,
|
r = requests.post('{}/marketplace/publish'.format(AUTH_SERVER),
|
||||||
headers=headers)
|
files=files,
|
||||||
|
headers=headers)
|
||||||
|
|
||||||
if r.status_code != 200:
|
if r.status_code != 200:
|
||||||
raise MarketplaceHTTPRequest(request='upload file',
|
raise MarketplaceHTTPRequest(request='upload file',
|
||||||
error=r.status_code)
|
error=r.status_code)
|
||||||
|
|
||||||
if 'error' in r.json():
|
if 'error' in r.json():
|
||||||
raise MarketplaceHTTPRequest(request='upload file',
|
raise MarketplaceHTTPRequest(request='upload file',
|
||||||
error=r.json()['error'])
|
error=r.json()['error'])
|
||||||
|
|
||||||
print('Dataset {} uploaded successfully.'.format(dataset))
|
log.info('File processed successfully.')
|
||||||
|
|
||||||
|
print('\nDataset {} uploaded and processed successfully.'.format(
|
||||||
|
dataset))
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ def get_signed_headers(ds_name, key, secret):
|
|||||||
-------
|
-------
|
||||||
|
|
||||||
"""
|
"""
|
||||||
nonce = str(int(time.time()))
|
nonce = str(int(time.time() * 1000))
|
||||||
|
|
||||||
signature = hmac.new(
|
signature = hmac.new(
|
||||||
secret.encode('utf-8'),
|
secret.encode('utf-8'),
|
||||||
|
|||||||
@@ -640,12 +640,9 @@ class TradingCalendar(with_metaclass(ABCMeta)):
|
|||||||
"""
|
"""
|
||||||
sched = self.schedule
|
sched = self.schedule
|
||||||
|
|
||||||
# `market_open` and `market_close` should be timezone aware, but pandas
|
|
||||||
# 0.16.1 does not appear to support this:
|
|
||||||
# http://pandas.pydata.org/pandas-docs/stable/whatsnew.html#datetime-with-tz # noqa
|
|
||||||
return (
|
return (
|
||||||
sched.at[session_label, 'market_open'].tz_localize('UTC'),
|
sched.at[session_label, 'market_open'],
|
||||||
sched.at[session_label, 'market_close'].tz_localize('UTC'),
|
sched.at[session_label, 'market_close'],
|
||||||
)
|
)
|
||||||
|
|
||||||
def session_open(self, session_label):
|
def session_open(self, session_label):
|
||||||
|
|||||||
@@ -117,9 +117,9 @@ def create_dividend(sid, payment, declared_date, ex_date, pay_date):
|
|||||||
'net_amount': payment,
|
'net_amount': payment,
|
||||||
'payment_sid': None,
|
'payment_sid': None,
|
||||||
'ratio': None,
|
'ratio': None,
|
||||||
'declared_date': pd.tslib.normalize_date(declared_date),
|
'declared_date': pd.tslib.declared_date.normalize(),
|
||||||
'ex_date': pd.tslib.normalize_date(ex_date),
|
'ex_date': pd.tslib.ex_date.normalize(),
|
||||||
'pay_date': pd.tslib.normalize_date(pay_date),
|
'pay_date': pd.tslib.pay_date.normalize(),
|
||||||
'type': DATASOURCE_TYPE.DIVIDEND,
|
'type': DATASOURCE_TYPE.DIVIDEND,
|
||||||
'source_id': 'MockDividendSource'
|
'source_id': 'MockDividendSource'
|
||||||
})
|
})
|
||||||
@@ -134,9 +134,9 @@ def create_stock_dividend(sid, payment_sid, ratio, declared_date,
|
|||||||
'ratio': ratio,
|
'ratio': ratio,
|
||||||
'net_amount': None,
|
'net_amount': None,
|
||||||
'gross_amount': None,
|
'gross_amount': None,
|
||||||
'dt': pd.tslib.normalize_date(declared_date),
|
'dt': pd.tslib.declared_date.normalize(),
|
||||||
'ex_date': pd.tslib.normalize_date(ex_date),
|
'ex_date': pd.tslib.ex_date.normalize(),
|
||||||
'pay_date': pd.tslib.normalize_date(pay_date),
|
'pay_date': pd.tslib.pay_date.normalize(),
|
||||||
'type': DATASOURCE_TYPE.DIVIDEND,
|
'type': DATASOURCE_TYPE.DIVIDEND,
|
||||||
'source_id': 'MockDividendSource'
|
'source_id': 'MockDividendSource'
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -263,8 +263,8 @@ def _run(handle_data,
|
|||||||
# We still need to support bundles for other misc data, but we
|
# We still need to support bundles for other misc data, but we
|
||||||
# can handle this later.
|
# can handle this later.
|
||||||
|
|
||||||
if start != pd.tslib.normalize_date(start) or \
|
if start != pd.tslib.start.normalize() or \
|
||||||
end != pd.tslib.normalize_date(end):
|
end != pd.tslib.end.normalize():
|
||||||
# todo: add to Sim_Params the option to start & end at specific times
|
# todo: add to Sim_Params the option to start & end at specific times
|
||||||
log.warn(
|
log.warn(
|
||||||
"Catalyst currently starts and ends on the start and "
|
"Catalyst currently starts and ends on the start and "
|
||||||
|
|||||||
@@ -562,6 +562,10 @@ If after following the instructions above, and going through the
|
|||||||
*Troubleshooting* sections, you still experience problems installing Catalyst,
|
*Troubleshooting* sections, you still experience problems installing Catalyst,
|
||||||
you can seek additional help through the following channels:
|
you can seek additional help through the following channels:
|
||||||
|
|
||||||
|
- Join our `Catalyst Forum <https://catalyst.enigma.co/>`_, and browse a variety
|
||||||
|
of topics and conversations around common issues that others face when using
|
||||||
|
Catalyst, and how to resolve them. And join the conversation!
|
||||||
|
|
||||||
- Join our `Discord community <https://discord.gg/SJK32GY>`_, and head over
|
- Join our `Discord community <https://discord.gg/SJK32GY>`_, and head over
|
||||||
the #catalyst_dev channel where many other users (as well as the project
|
the #catalyst_dev channel where many other users (as well as the project
|
||||||
developers) hang out, and can assist you with your particular issue. The
|
developers) hang out, and can assist you with your particular issue. The
|
||||||
|
|||||||
@@ -2,6 +2,30 @@
|
|||||||
Release Notes
|
Release Notes
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
Version 0.5.8
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
**Release Date**: 2018-03-29
|
||||||
|
|
||||||
|
Bug Fixes
|
||||||
|
~~~~~~~~~
|
||||||
|
- Fix proper release of Data Marketplace on mainnet.
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.5.7
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
**Release Date**: 2018-03-29
|
||||||
|
|
||||||
|
Build
|
||||||
|
~~~~~
|
||||||
|
- Data Marketplace deployed on mainnet.
|
||||||
|
- Added progress indicators for publishing data, and made the data publishing
|
||||||
|
synchronous to provide feedback to the publisher.
|
||||||
|
|
||||||
|
Bug Fixes
|
||||||
|
~~~~~~~~~
|
||||||
|
- Added arguments to the ``reduce`` function in tha Asset class :issue:`214`,
|
||||||
|
:issue:`287`
|
||||||
|
|
||||||
Version 0.5.6
|
Version 0.5.6
|
||||||
^^^^^^^^^^^^^
|
^^^^^^^^^^^^^
|
||||||
**Release Date**: 2018-03-22
|
**Release Date**: 2018-03-22
|
||||||
@@ -9,9 +33,9 @@ Version 0.5.6
|
|||||||
Build
|
Build
|
||||||
~~~~~
|
~~~~~
|
||||||
- Data Marketplace: ensures compatibility across wallets, now fully supporting
|
- Data Marketplace: ensures compatibility across wallets, now fully supporting
|
||||||
`ledger`, `trezor`, `keystore`, `private key`. Partial support for `metamask`
|
``ledger``, ``trezor``, ``keystore``, ``private key``. Partial support for
|
||||||
(includes sign_msg, but not sign_tx). Current support for `Digital Bitbox` is
|
``metamask`` (includes sign_msg, but not sign_tx). Current support for
|
||||||
unknown.
|
``Digital Bitbox`` is unknown, but believed to be supported.
|
||||||
- Data Marketplace: Switched online provider from MyEtherWallet to MyCrypto.
|
- Data Marketplace: Switched online provider from MyEtherWallet to MyCrypto.
|
||||||
- Data Marketplace: Added progress indicator for data ingestion.
|
- Data Marketplace: Added progress indicator for data ingestion.
|
||||||
|
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ def _filter_requirements(lines_iter, filter_names=None,
|
|||||||
|
|
||||||
REQ_UPPER_BOUNDS = {
|
REQ_UPPER_BOUNDS = {
|
||||||
'bcolz': '<1',
|
'bcolz': '<1',
|
||||||
'pandas': '<0.20',
|
'pandas': '>=0.22',
|
||||||
'empyrical': '<0.2.2',
|
'empyrical': '<0.2.2',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import datetime
|
|||||||
from math import sqrt
|
from math import sqrt
|
||||||
|
|
||||||
from nose_parameterized import parameterized
|
from nose_parameterized import parameterized
|
||||||
from pandas.tslib import normalize_date
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import pytz
|
import pytz
|
||||||
@@ -1108,8 +1107,8 @@ class OrdersStopTestCase(WithSimParams,
|
|||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
days = pd.date_range(
|
days = pd.date_range(
|
||||||
start=normalize_date(self.minutes[0]),
|
start=self.minutes[0].normalize(),
|
||||||
end=normalize_date(self.minutes[-1])
|
end=self.minutes[-1].normalize()
|
||||||
)
|
)
|
||||||
with tmp_bcolz_equity_minute_bar_reader(
|
with tmp_bcolz_equity_minute_bar_reader(
|
||||||
self.trading_calendar, days, assets) as reader:
|
self.trading_calendar, days, assets) as reader:
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ from pandas import (
|
|||||||
Series,
|
Series,
|
||||||
Timestamp,
|
Timestamp,
|
||||||
)
|
)
|
||||||
from pandas.tseries.tools import normalize_date
|
|
||||||
from six import iteritems, itervalues
|
from six import iteritems, itervalues
|
||||||
|
|
||||||
from catalyst.algorithm import TradingAlgorithm
|
from catalyst.algorithm import TradingAlgorithm
|
||||||
@@ -530,7 +529,7 @@ class PipelineAlgorithmTestCase(WithBcolzEquityDailyBarReaderFromCSVs,
|
|||||||
attach_pipeline(pipeline, 'test')
|
attach_pipeline(pipeline, 'test')
|
||||||
|
|
||||||
def handle_data(context, data):
|
def handle_data(context, data):
|
||||||
today = normalize_date(get_datetime())
|
today = get_datetime().normalize()
|
||||||
results = pipeline_output('test')
|
results = pipeline_output('test')
|
||||||
expect_over_300 = {
|
expect_over_300 = {
|
||||||
AAPL: today < self.AAPL_split_date,
|
AAPL: today < self.AAPL_split_date,
|
||||||
|
|||||||
@@ -395,7 +395,6 @@ def handle_data(context, data):
|
|||||||
|
|
||||||
algocode = """
|
algocode = """
|
||||||
from pandas import Timestamp
|
from pandas import Timestamp
|
||||||
from pandas.tseries.tools import normalize_date
|
|
||||||
from catalyst.api import fetch_csv, record, sid, get_datetime
|
from catalyst.api import fetch_csv, record, sid, get_datetime
|
||||||
|
|
||||||
def initialize(context):
|
def initialize(context):
|
||||||
@@ -411,7 +410,7 @@ def initialize(context):
|
|||||||
context.bar_count = 0
|
context.bar_count = 0
|
||||||
|
|
||||||
def handle_data(context, data):
|
def handle_data(context, data):
|
||||||
expected = context.expected_sids[normalize_date(get_datetime())]
|
expected = context.expected_sids[get_datetime().normalize()]
|
||||||
actual = data.fetcher_assets
|
actual = data.fetcher_assets
|
||||||
for stk in expected:
|
for stk in expected:
|
||||||
if stk not in actual:
|
if stk not in actual:
|
||||||
|
|||||||
Reference in New Issue
Block a user