Compare commits

..
50 Commits
Author SHA1 Message Date
wassname b4faf9158d fix typos 2018-03-31 10:44:32 +08:00
wassname dfb1bf51bd fix tslib deprecation 2018-03-31 10:05:38 +08:00
wassname f946062265 update requirements 2018-03-31 10:05:04 +08:00
wassname 65c6322ba5 change pandas dependancy 2018-03-31 09:52:48 +08:00
wassname 4a2d5678ad use dt.normalize() in pd>=0.20 2018-03-31 09:51:15 +08:00
wassname 06399caa2b fix error converting tzaware to tzaware 2018-03-31 09:50:41 +08:00
Victor Grau Serrat 4c84ea8efc DOC: release notes 0.5.8 2018-03-29 10:23:38 -06:00
Victor Grau Serrat c85e698ee2 BLD: [mktplace] switch to mainnet 2018-03-29 10:00:35 -06:00
Victor Grau Serrat 423e30da1e Merge branch 'develop' 2018-03-29 08:28:05 -06:00
Victor Grau Serrat c29b1ef3c1 BLD: deployment of marketplace on mainnet 2018-03-29 08:26:09 -06:00
Victor Grau Serrat 17f9906df4 DOC: updated release notes for 0.5.7 2018-03-29 08:01:58 -06:00
Avishai WeingartenandGitHub 41b5135ed4 Merge pull request #220 from westurner/feature/fix-docker-tags
BLD: Dockerfile[-dev]: s/quantopian/enigmampc/g
2018-03-29 08:49:52 +03:00
Victor Grau Serrat af85ee31c9 BUG: [mktplace] progress counters start at 1, not 0 2018-03-27 18:12:08 -06:00
Victor Grau Serrat 132dffd239 BLD: [mktplace] progress indicator for publishing data 2018-03-27 13:22:30 -06:00
VictorandGitHub 887a7cc825 BUG: [mktplace] removing whitespace from datasets to register 2018-03-26 17:22:53 -06:00
AvishaiW 22249506e6 BUG: #214 #287 added arguments to the _reduce_ function in tha Asset class 2018-03-25 22:53:01 +03:00
Victor Grau Serrat b979ffd123 BLD: [mktplace] json handling improvement 2018-03-23 12:38:37 -06:00
Victor Grau Serrat 0db9950347 DOC: link to forum from install doc 2018-03-22 15:24:50 -06:00
Victor 7c4467d800 DOC: added forum button in README 2018-03-22 15:21:17 -06:00
Victor 30dbeaa5fb DOC: Updated README with link to the forum. 2018-03-22 15:21:13 -06:00
VictorandGitHub 4d6837b5d6 DOC: Updated README with link to the forum. 2018-03-22 15:18:55 -06:00
VictorandGitHub 098a4c4fc6 DOC: added forum button in README 2018-03-22 15:15:31 -06:00
Victor Grau Serrat f5cb6e38d6 DOC: fixed formatting of release notes 2018-03-22 12:13:55 -06:00
Victor Grau Serrat 1bd65397b6 Merge branch 'develop' 2018-03-22 12:02:15 -06:00
Victor Grau Serrat c768b207bc MAINT: [marketplace] output formatting address list 2018-03-22 12:01:21 -06:00
VictorandGitHub e18686d5c5 Merge pull request #278 from izokay/develop
BUG: Error when ingesting marketcap on windows
2018-03-22 12:23:29 -05:00
VictorandGitHub b7779cf363 MAINT: general bug fix for existing path across OS 2018-03-22 11:23:06 -06:00
Victor Grau Serrat 28819b8a32 DOC: updated release notes for 0.5.6 2018-03-21 22:29:21 -06:00
Victor Grau Serrat a56d7f34c7 BLD: [mktplace] support for most wallets, switch to mycrypto 2018-03-21 20:35:18 -05:00
AvishaiW 9f0b3303f1 BUG: #285 #271 changed benchmark to be constant, so it wouldn't ingest data at all, for now 2018-03-21 21:19:40 +02:00
EmbarAlmog 9d7a35658b ENH: when ingesting data of non-existing pair it is now throwing log warning. 2018-03-20 16:12:13 +02:00
Victor Grau Serrat c58cebd1eb ENH: progress on marketplace bundle ingestion 2018-03-19 11:50:39 -06:00
Frederic Fortier 027cdba474 Merge branch 'develop' 2018-03-19 13:12:08 -04:00
Frederic Fortier d223529100 DOC: updated release notes of 0.5.5 2018-03-19 13:11:31 -04:00
Frederic Fortier 1e02506ab4 Merge branch 'develop' 2018-03-19 13:07:06 -04:00
lenak25 2a97ade68e BLD: support hourly freq in live and backtest, as reported on issue #227 and issue #114 2018-03-19 16:44:44 +02:00
lenak25 9648767e9a STY: flake8 fixes 2018-03-19 15:53:06 +02:00
lenak25 98449b2088 BLD: fix issue #274 - a bug in which a wrong bar number was returned when requesting day freq history candles in backtest 2018-03-19 11:06:47 +02:00
Frederic Fortier 91d16aba3b DOC: documented the get_frequency function for additional clarity 2018-03-17 18:32:28 -04:00
izokayandGitHub 9eb649371b BUG: Error when ingesting on windows
Error message: Cannot create a file when that file already exists: '.catalyst\\data\\marketplace\\temp_bundles\\marketcap-hourly-2018' -> '.catalyst\\data\\marketplace\\marketcap'
2018-03-16 16:50:31 -04:00
izokayandGitHub 7f2ded65bc Merge pull request #2 from enigmampc/develop
Develop
2018-03-16 16:45:03 -04:00
Frederic Fortier b76b4458cb Merge branch 'vonpupp-fix_hourly_candles' into develop 2018-03-16 15:49:39 -04:00
Frederic Fortier decbdbf6ea Merge branch 'fix_hourly_candles' of https://github.com/vonpupp/catalyst into vonpupp-fix_hourly_candles 2018-03-16 15:49:28 -04:00
Albert De La Fuente Vigliotti 685ce25b85 Fix H candle support 2018-03-16 16:02:40 -03:00
Avishai WeingartenandGitHub 1cafcc1417 BUG: removed one out of two matplotlib appearences in 2.7 yml 2018-03-16 14:40:05 +02:00
VictorandGitHub 0d77854782 Merge pull request #275 from izokay/patch-1
typo on creating env for python 3.6
2018-03-15 15:18:07 -06:00
izokayandGitHub 4cb8d54d97 typo on creating env for python 3.6 2018-03-15 15:41:30 -04:00
Victor Grau Serrat 7b796a4276 MAINT: [mktplace] sign_msg opens browser window 2018-03-15 12:59:59 -04:00
AvishaiW 41a4c7072f DOC: fixed a mistake on the installation tutorial 2018-03-14 09:44:24 +02:00
westurner 2d5d2b21ee BLD: Dockerfile[-dev]: s/quantopian/enigmampc/g 2018-02-09 01:40:43 -05:00
42 changed files with 403 additions and 178 deletions
+2 -2
View File
@@ -1,11 +1,11 @@
#
# 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:
#
# 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):
#
+5 -5
View File
@@ -1,15 +1,15 @@
#
# 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:
#
# 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):
#
@@ -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
#
FROM quantopian/catalyst
FROM enigmampc/catalyst
WORKDIR /catalyst
+9 -3
View File
@@ -5,6 +5,7 @@
|version tag|
|version status|
|forum|
|discord|
|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
`Zipline <https://github.com/quantopian/zipline>`_ project. We did our best to
minimize structural changes to the general API to maximize compatibility with
existing trading algorithms, developer knowledge, and tutorials. Join us on
`Discord <https://discord.gg/SJK32GY>`_ where we have a *#catalyst_dev* channel
for questions around Catalyst, algorithmic trading and technical support.
existing trading algorithms, developer knowledge, and tutorials. Join us on the
`Catalyst Forum <https://catalyst.enigma.co/>`_ for questions around Catalyst,
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
========
@@ -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
: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
:target: https://discordapp.com/invite/SJK32GY
+1 -1
View File
@@ -580,7 +580,7 @@ def ingest_exchange(ctx, exchange_name, data_frequency, start, end,
exchange_bundle = ExchangeBundle(exchange_name)
click.echo('Ingesting exchange bundle {}...'.format(exchange_name),
click.echo('Trying to ingest exchange bundle {}...'.format(exchange_name),
sys.stdout)
exchange_bundle.ingest(
data_frequency=data_frequency,
+1 -2
View File
@@ -16,7 +16,6 @@ import warnings
from contextlib import contextmanager
from functools import wraps
from pandas.tslib import normalize_date
import pandas as pd
import numpy as np
@@ -564,7 +563,7 @@ cdef class BarData:
})
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):
return False
+3 -4
View File
@@ -21,7 +21,6 @@ import logbook
import pytz
import pandas as pd
from contextlib2 import ExitStack
from pandas.tseries.tools import normalize_date
import numpy as np
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.
# FIXME: we should use BarData's can_trade logic here, but I haven't
# 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:
raise CannotOrderDelistedAsset(
@@ -1392,7 +1391,7 @@ class TradingAlgorithm(object):
)
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 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`.
"""
today = normalize_date(self.get_datetime())
today = self.get_datetime().normalize()
data = NO_DATA = object()
try:
data = self._pipeline_cache.unwrap(today)
+8 -3
View File
@@ -630,23 +630,28 @@ cdef class TradingPair(Asset):
and whose second element is a tuple of all the attributes that should
be serialized/deserialized during pickling.
"""
#TODO: make sure that all fields set there
# added arguments for catalyst
return (self.__class__, (self.symbol,
self.exchange,
self.start_date,
self.asset_name,
self.sid,
self.leverage,
self.end_daily,
self.end_minute,
self.end_date,
self.exchange_symbol,
self.first_traded,
self.auto_close_date,
self.exchange_full,
self.min_trade_size,
self.max_trade_size,
self.maker,
self.taker,
self.lot,
self.decimals,
self.taker,
self.maker))
self.trading_state,
self.data_source))
def make_asset_array(int size, Asset asset):
cdef np.ndarray out = np.empty([size], dtype=object)
+4 -3
View File
@@ -24,8 +24,7 @@ AUTO_INGEST = False
AUTH_SERVER = 'https://data.enigma.co'
# TODO: switch to mainnet
ETH_REMOTE_NODE = 'https://rinkeby.infura.io/'
ETH_REMOTE_NODE = 'https://mainnet.infura.io'
MARKETPLACE_CONTRACT = 'https://raw.githubusercontent.com/enigmampc/' \
'catalyst/master/catalyst/marketplace/' \
@@ -35,7 +34,6 @@ MARKETPLACE_CONTRACT_ABI = 'https://raw.githubusercontent.com/enigmampc/' \
'catalyst/master/catalyst/marketplace/' \
'contract_marketplace_abi.json'
# TODO: switch to mainnet
ENIGMA_CONTRACT = 'https://raw.githubusercontent.com/enigmampc/' \
'catalyst/master/catalyst/marketplace/' \
'contract_enigma_address.txt'
@@ -43,3 +41,6 @@ ENIGMA_CONTRACT = 'https://raw.githubusercontent.com/enigmampc/' \
ENIGMA_CONTRACT_ABI = 'https://raw.githubusercontent.com/enigmampc/' \
'catalyst/master/catalyst/marketplace/' \
'contract_enigma_abi.json'
SUPPORTED_WALLETS = ['metamask', 'ledger', 'trezor', 'bitbox', 'keystore',
'key']
+4 -5
View File
@@ -20,7 +20,6 @@ import numpy as np
from numpy import float64, int64, nan
import pandas as pd
from pandas import isnull
from pandas.tslib import normalize_date
from six import iteritems
from six.moves import reduce
@@ -439,7 +438,7 @@ class DataPortal(object):
(isinstance(asset, (Asset, ContinuousFuture))))
def _get_fetcher_value(self, asset, field, dt):
day = normalize_date(dt)
day = dt.normalize()
try:
return \
@@ -1130,7 +1129,7 @@ class DataPortal(object):
if self._asset_start_dates[sid] > dt:
raise NoTradeDataAvailableTooEarly(
sid=sid,
dt=normalize_date(dt),
dt=dt.normalize(),
start_dt=start_date
)
@@ -1138,7 +1137,7 @@ class DataPortal(object):
if self._asset_end_dates[sid] < dt:
raise NoTradeDataAvailableTooLate(
sid=sid,
dt=normalize_date(dt),
dt=dt.normalize(),
end_dt=end_date
)
@@ -1262,7 +1261,7 @@ class DataPortal(object):
if self._extra_source_df is None:
return []
day = normalize_date(dt)
day = dt.normalize()
if day in self._extra_source_df.index:
assets = self._extra_source_df.loc[day]['sid']
+2 -3
View File
@@ -21,7 +21,6 @@ from abc import (
from numpy import concatenate
from lru import LRU
from pandas import isnull
from pandas.tslib import normalize_date
from toolz import sliding_window
from six import with_metaclass
@@ -93,8 +92,8 @@ class HistoryCompatibleUSEquityAdjustmentReader(object):
The adjustments as a dict of loc -> Float64Multiply
"""
sid = int(asset)
start = normalize_date(dts[0])
end = normalize_date(dts[-1])
start = dts[0].normalize()
end = dts[-1].normalize()
adjs = {}
if field != 'volume':
mergers = self._adjustments_reader.get_adjustments_for_sid(
+1 -2
View File
@@ -49,7 +49,6 @@ from pandas import (
to_datetime,
Timestamp,
)
from pandas.tslib import iNaT
from six import (
iteritems,
string_types,
@@ -422,7 +421,7 @@ class BcolzDailyBarWriter(object):
)
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
+3
View File
@@ -190,6 +190,9 @@ class CCXT(Exchange):
if data_frequency == 'minute' and not freq.endswith('T'):
continue
elif data_frequency == 'hourly' and not freq.endswith('D'):
continue
elif data_frequency == 'daily' and not freq.endswith('D'):
continue
+3 -12
View File
@@ -13,7 +13,6 @@ from catalyst.exchange.exchange_errors import MismatchingBaseCurrencies, \
PricingDataNotLoadedError, \
NoDataAvailableOnExchange, NoValueForField, \
NoCandlesReceivedFromExchange, \
InvalidHistoryFrequencyAlias, \
TickerNotFoundError, NotEnoughCashError
from catalyst.exchange.utils.datetime_utils import get_delta, \
get_periods_range, \
@@ -200,12 +199,8 @@ class Exchange:
)
assets.append(asset)
except SymbolNotFoundOnExchange:
log.debug(
'skipping non-existent market {} {}'.format(
self.name, symbol
)
)
except SymbolNotFoundOnExchange as e:
log.warn(e)
return assets
def get_asset(self, symbol, data_frequency=None, is_exchange_symbol=False,
@@ -509,10 +504,6 @@ class Exchange:
frequency, data_frequency, supported_freqs=['T', 'D', 'H']
)
if unit == 'H':
raise InvalidHistoryFrequencyAlias(
freq=frequency)
# we want to avoid receiving empty candles
# so we request more than needed
# TODO: consider defining a const per asset
@@ -616,7 +607,7 @@ class Exchange:
# TODO: this function needs some work,
# we're currently using it just for benchmark data
freq, candle_size, unit, data_frequency = get_frequency(
frequency, data_frequency
frequency, data_frequency, supported_freqs=['T', 'D']
)
adj_bar_count = candle_size * bar_count
try:
+45 -44
View File
@@ -22,7 +22,7 @@ from catalyst.exchange.exchange_errors import EmptyValuesInBundleError, \
PricingDataNotLoadedError, DataCorruptionError, PricingDataValueError
from catalyst.exchange.utils.bundle_utils import range_in_bundle, \
get_bcolz_chunk, get_df_from_arrays, get_assets
from catalyst.exchange.utils.datetime_utils import get_delta, get_start_dt, \
from catalyst.exchange.utils.datetime_utils import get_start_dt, \
get_period_label, get_month_start_end, get_year_start_end
from catalyst.exchange.utils.exchange_utils import get_exchange_folder, \
save_exchange_symbols, mixin_market_params, get_catalyst_symbol
@@ -232,12 +232,12 @@ class ExchangeBundle:
problem = '{name} ({start_dt} to {end_dt}) has empty ' \
'periods: {dates}'.format(
name=asset.symbol,
start_dt=asset.start_date.strftime(
DATE_TIME_FORMAT),
end_dt=end_dt.strftime(DATE_TIME_FORMAT),
dates=[date.strftime(
DATE_TIME_FORMAT) for date in dates])
name=asset.symbol,
start_dt=asset.start_date.strftime(
DATE_TIME_FORMAT),
end_dt=end_dt.strftime(DATE_TIME_FORMAT),
dates=[date.strftime(
DATE_TIME_FORMAT) for date in dates])
if empty_rows_behavior == 'warn':
log.warn(problem)
@@ -286,12 +286,12 @@ class ExchangeBundle:
problem = '{name} ({start_dt} to {end_dt}) has {threshold} ' \
'identical close values on: {dates}'.format(
name=asset.symbol,
start_dt=asset.start_date.strftime(DATE_TIME_FORMAT),
end_dt=end_dt.strftime(DATE_TIME_FORMAT),
threshold=threshold,
dates=[pd.to_datetime(date).strftime(DATE_TIME_FORMAT)
for date in dates])
name=asset.symbol,
start_dt=asset.start_date.strftime(DATE_TIME_FORMAT),
end_dt=end_dt.strftime(DATE_TIME_FORMAT),
threshold=threshold,
dates=[pd.to_datetime(date).strftime(DATE_TIME_FORMAT)
for date in dates])
problems.append(problem)
@@ -458,7 +458,7 @@ class ExchangeBundle:
last_entry = None
if start is None or \
(earliest_trade is not None and earliest_trade > start):
(earliest_trade is not None and earliest_trade > start):
start = earliest_trade
if last_entry is not None and (end is None or end > last_entry):
@@ -598,16 +598,41 @@ class ExchangeBundle:
# we want to give an end_date far in time
writer = self.get_writer(start_dt, end_dt, data_frequency)
if show_breakdown:
for asset in chunks:
if chunks:
for asset in chunks:
with maybe_show_progress(
chunks[asset],
show_progress,
label='Ingesting {frequency} price data for '
'{symbol} on {exchange}'.format(
exchange=self.exchange_name,
frequency=data_frequency,
symbol=asset.symbol
)) as it:
for chunk in it:
problems += self.ingest_ctable(
asset=chunk['asset'],
data_frequency=data_frequency,
period=chunk['period'],
writer=writer,
empty_rows_behavior='strip',
cleanup=True
)
else:
all_chunks = list(chain.from_iterable(itervalues(chunks)))
# We sort the chunks by end date to ingest most recent data first
if all_chunks:
all_chunks.sort(
key=lambda chunk: pd.to_datetime(chunk['period'])
)
with maybe_show_progress(
chunks[asset],
all_chunks,
show_progress,
label='Ingesting {frequency} price data for '
'{symbol} on {exchange}'.format(
label='Ingesting {frequency} price data on '
'{exchange}'.format(
exchange=self.exchange_name,
frequency=data_frequency,
symbol=asset.symbol
)) as it:
)) as it:
for chunk in it:
problems += self.ingest_ctable(
asset=chunk['asset'],
@@ -617,30 +642,6 @@ class ExchangeBundle:
empty_rows_behavior='strip',
cleanup=True
)
else:
all_chunks = list(chain.from_iterable(itervalues(chunks)))
# We sort the chunks by end date to ingest most recent data first
all_chunks.sort(
key=lambda chunk: pd.to_datetime(chunk['period'])
)
with maybe_show_progress(
all_chunks,
show_progress,
label='Ingesting {frequency} price data on '
'{exchange}'.format(
exchange=self.exchange_name,
frequency=data_frequency,
)) as it:
for chunk in it:
problems += self.ingest_ctable(
asset=chunk['asset'],
data_frequency=data_frequency,
period=chunk['period'],
writer=writer,
empty_rows_behavior='strip',
cleanup=True
)
if show_report and len(problems) > 0:
log.info('problems during ingestion:{}\n'.format(
+2 -2
View File
@@ -296,7 +296,7 @@ class DataPortalExchangeBacktest(DataPortalExchangeBase):
bundle = self.exchange_bundles[exchange_name] # type: ExchangeBundle
freq, candle_size, unit, adj_data_frequency = get_frequency(
frequency, data_frequency
frequency, data_frequency, supported_freqs=['T', 'D']
)
adj_bar_count = candle_size * bar_count
@@ -312,7 +312,7 @@ class DataPortalExchangeBacktest(DataPortalExchangeBase):
algo_end_dt=self._last_available_session,
)
start_dt = get_start_dt(end_dt, adj_bar_count, data_frequency)
start_dt = get_start_dt(end_dt, adj_bar_count, adj_data_frequency)
df = resample_history_df(pd.DataFrame(series), freq, field, start_dt)
return df
+7 -4
View File
@@ -249,9 +249,12 @@ def get_year_start_end(dt, first_day=None, last_day=None):
return year_start, year_end
def get_frequency(freq, data_frequency=None, supported_freqs=['D', 'T']):
def get_frequency(freq, data_frequency=None, supported_freqs=['D', 'H', 'T']):
"""
Get the frequency parameters.
Takes an arbitrary candle size (e.g. 15T) and converts to the lowest
common denominator supported by the data bundles (e.g. 1T). The data
bundles only support 1T and 1D frequencies. If another frequency
is requested, Catalyst must request the underlying data and resample.
Notes
-----
@@ -306,14 +309,14 @@ def get_frequency(freq, data_frequency=None, supported_freqs=['D', 'T']):
data_frequency = 'minute'
elif unit.lower() == 'h':
data_frequency = 'minute'
if 'H' in supported_freqs:
unit = 'H'
alias = '{}H'.format(candle_size)
else:
candle_size = candle_size * 60
alias = '{}T'.format(candle_size)
data_frequency = 'minute'
else:
raise InvalidHistoryFrequencyAlias(freq=freq)
+1 -2
View File
@@ -62,7 +62,6 @@ from __future__ import division
import logbook
import pandas as pd
from pandas.tseries.tools import normalize_date
from catalyst.finance.performance.period import PerformancePeriod
from catalyst.errors import NoFurtherDataError
@@ -344,7 +343,7 @@ class PerformanceTracker(object):
"""
self.position_tracker.sync_last_sale_prices(dt, False, data_portal)
self.update_performance()
todays_date = normalize_date(dt)
todays_date = dt.normalize()
account = self.get_account(False)
bench_returns = self.all_benchmark_returns.loc[todays_date:dt]
+1 -2
View File
@@ -18,7 +18,6 @@ import logbook
import numpy as np
import pandas as pd
from pandas.tseries.tools import normalize_date
from six import iteritems
@@ -80,7 +79,7 @@ class RiskMetricsCumulative(object):
# on the first day.
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:
last_day = pd.tseries.index.DatetimeIndex(
[last_day]
+20 -8
View File
@@ -16,7 +16,6 @@ from functools import partial
import logbook
import pandas as pd
from pandas.tslib import normalize_date
from six import string_types
from sqlalchemy import create_engine
@@ -95,11 +94,24 @@ class TradingEnvironment(object):
if not trading_calendar:
trading_calendar = get_calendar("NYSE")
self.benchmark_returns, self.treasury_curves = load(
trading_calendar.day,
trading_calendar.schedule.index,
self.bm_symbol,
)
# todo: uncomment and add a well defined benchmark
# self.benchmark_returns, self.treasury_curves = load(
# trading_calendar.day,
# trading_calendar.schedule.index,
# self.bm_symbol,
# exchange=exchange,
# )
start_data = get_calendar('OPEN').first_trading_session
end_data = pd.Timestamp.utcnow()
treasure_cols = ['1month', '3month', '6month', '1year', '2year',
'3year', '5year', '7year', '10year', '20year', '30year']
self.benchmark_returns = pd.DataFrame(data=0.001,
index=pd.date_range(start_data, end_data),
columns=['close'])
self.treasury_curves = pd.DataFrame(data=0.001,
index=pd.date_range(start_data, end_data),
columns=treasure_cols)
self.exchange_tz = exchange_tz
@@ -151,8 +163,8 @@ class SimulationParameters(object):
# chop off any minutes or hours on the given start and end dates,
# as we only support session labels here (and we represent session
# labels as midnight UTC).
self._start_session = normalize_date(start_session)
self._end_session = normalize_date(end_session)
self._start_session = start_session.normalize()
self._end_session = end_session.normalize()
self._capital_base = capital_base
self._emission_rate = emission_rate
+1 -2
View File
@@ -14,7 +14,6 @@
# limitations under the License.
from contextlib2 import ExitStack
from logbook import Logger, Processor
from pandas.tslib import normalize_date
from catalyst.protocol import BarData
from catalyst.utils.api_support import ZiplineAPI
from six import viewkeys
@@ -229,7 +228,7 @@ class AlgorithmSimulator(object):
elif action == SESSION_END:
# End of the session.
if emission_rate == 'daily':
handle_benchmark(normalize_date(dt))
handle_benchmark(dt).normalize()
execute_order_cancellation_policy()
yield self._get_daily_message(dt, algo, algo.perf_tracker)
@@ -1 +1 @@
0x39a54f480d922a58c963de8091a6c9afc69db2cf
0xf0ee6b27b759c9893ce4f094b49ad28fd15a23e4
@@ -1 +1 @@
0xa2b37c6cd52f60fd4eb46ca59fafcf22d081aebc
0xa64927358a82254be92eb1f1cb01de68d1787004
+46 -24
View File
@@ -69,7 +69,10 @@ class Marketplace:
contract_url.info().get_content_charset()).strip())
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_address,
@@ -83,7 +86,10 @@ class Marketplace:
contract_url.info().get_content_charset()).strip())
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_address,
@@ -126,9 +132,10 @@ class Marketplace:
else:
while True:
for i in range(0, len(self.addresses)):
print('{}\t{}\t{}'.format(
print('{}\t{}\t{}\t{}'.format(
i,
self.addresses[i]['pubAddr'],
self.addresses[i]['wallet'].ljust(10),
self.addresses[i]['desc'])
)
address_i = int(input('Choose your address associated with '
@@ -145,7 +152,7 @@ class Marketplace:
def sign_transaction(self, tx):
url = 'https://www.myetherwallet.com/#offline-transaction'
url = 'https://www.mycrypto.com/#offline-transaction'
print('\nVisit {url} and enter the following parameters:\n\n'
'From Address:\t\t{_from}\n'
'\n\tClick the "Generate Information" button\n\n'
@@ -430,10 +437,9 @@ class Marketplace:
merge_bundles(zsource, ztarget)
else:
shutil.rmtree(bundle_folder, ignore_errors=True)
os.rename(tmp_bundle, bundle_folder)
pass
def ingest(self, ds_name=None, start=None, end=None, force_download=False):
if ds_name is None:
@@ -498,20 +504,29 @@ class Marketplace:
key = self.addresses[address_i]['key']
secret = self.addresses[address_i]['secret']
else:
key, secret = get_key_secret(address)
key, secret = get_key_secret(address,
self.addresses[address_i]['wallet'])
headers = get_signed_headers(ds_name, key, secret)
log.debug('Starting download of dataset for ingestion...')
log.info('Starting download of dataset for ingestion...')
r = requests.post(
'{}/marketplace/ingest'.format(AUTH_SERVER),
headers=headers,
stream=True,
)
if r.status_code == 200:
log.info('Dataset downloaded successfully. Processing dataset...')
target_path = get_temp_bundles_folder()
try:
decoder = MultipartDecoder.from_response(r)
# with maybe_show_progress(
# iter(decoder.parts),
# True,
# label='Processing files') as part:
counter = 1
for part in decoder.parts:
log.info("Processing file {} of {}".format(
counter, len(decoder.parts)))
h = part.headers[b'Content-Disposition'].decode('utf-8')
# Extracting the filename from the header
name = re.search(r'filename="(.*)"', h).group(1)
@@ -525,6 +540,7 @@ class Marketplace:
f.write(part.content)
self.process_temp_bundle(ds_name, filename)
counter += 1
except NonMultipartContentTypeException:
response = r.json()
@@ -592,7 +608,6 @@ class Marketplace:
folder = get_bundle_folder(ds_name, data_frequency)
shutil.rmtree(folder)
pass
def create_metadata(self, key, secret, ds_name, data_frequency, desc,
has_history=True, has_live=True):
@@ -628,7 +643,7 @@ class Marketplace:
def register(self):
while True:
desc = input('Enter the name of the dataset to register: ')
dataset = desc.lower()
dataset = desc.lower().strip()
provider_info = self.mkt_contract.functions.getDataProviderInfo(
Web3.toHex(dataset)
).call()
@@ -684,7 +699,8 @@ class Marketplace:
key = self.addresses[address_i]['key']
secret = self.addresses[address_i]['secret']
else:
key, secret = get_key_secret(address)
key, secret = get_key_secret(address,
self.addresses[address_i]['wallet'])
grains = to_grains(price)
@@ -765,28 +781,34 @@ class Marketplace:
key = match['key']
secret = match['secret']
else:
key, secret = get_key_secret(provider_info[0])
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'))
if not filenames:
raise MarketplaceNoCSVFiles(datadir=datadir)
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')))
r = requests.post('{}/marketplace/publish'.format(AUTH_SERVER),
files=files,
headers=headers)
headers = get_signed_headers(dataset, key, secret)
r = requests.post('{}/marketplace/publish'.format(AUTH_SERVER),
files=files,
headers=headers)
if r.status_code != 200:
raise MarketplaceHTTPRequest(request='upload file',
error=r.status_code)
if r.status_code != 200:
raise MarketplaceHTTPRequest(request='upload file',
error=r.status_code)
if 'error' in r.json():
raise MarketplaceHTTPRequest(request='upload file',
error=r.json()['error'])
if 'error' in r.json():
raise MarketplaceHTTPRequest(request='upload file',
error=r.json()['error'])
print('Dataset {} uploaded successfully.'.format(dataset))
log.info('File processed successfully.')
print('\nDataset {} uploaded and processed successfully.'.format(
dataset))
+19 -9
View File
@@ -1,5 +1,6 @@
import hashlib
import hmac
import webbrowser
import requests
import time
@@ -9,10 +10,10 @@ from catalyst.marketplace.marketplace_errors import (
MarketplaceEmptySignature)
from catalyst.marketplace.utils.path_utils import (
get_user_pubaddr, save_user_pubaddr)
from catalyst.constants import AUTH_SERVER
from catalyst.constants import AUTH_SERVER, SUPPORTED_WALLETS
def get_key_secret(pubAddr, wallet='mew'):
def get_key_secret(pubAddr, wallet):
"""
Obtain a new key/secret pair from authentication server
@@ -42,14 +43,22 @@ def get_key_secret(pubAddr, wallet='mew'):
auth_type, auth_info = header.split(None, 1)
d = requests.utils.parse_dict_header(auth_info)
nonce = '0x{}'.format(d['nonce'])
nonce = 'Catalyst nonce: 0x{}'.format(d['nonce'])
if wallet in SUPPORTED_WALLETS:
url = 'https://www.mycrypto.com/signmsg.html'
if wallet == 'mew':
print('\nObtaining a key/secret pair to streamline all future '
'requests with the authentication server.\n'
'Visit https://www.myetherwallet.com/signmsg.html and sign the '
'following message:\n{}'.format(nonce))
signature = input('Copy and Paste the "sig" field from '
'Visit {url} and sign the '
'following message (copy the entire line, without the '
'line break at the end):\n\n{nonce}'.format(
url=url,
nonce=nonce))
webbrowser.open_new(url)
signature = input('\nCopy and Paste the "sig" field from '
'the signature here (without the double quotes, '
'only the HEX value):\n')
else:
@@ -83,7 +92,8 @@ def get_key_secret(pubAddr, wallet='mew'):
addresses = get_user_pubaddr()
match = next((l for l in addresses if
l['pubAddr'] == pubAddr), None)
l['pubAddr'].lower() == pubAddr.lower()), None)
match['key'] = response.json()['key']
match['secret'] = response.json()['secret']
@@ -113,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(
secret.encode('utf-8'),
+49 -2
View File
@@ -2,6 +2,7 @@ import os
import json
import tarfile
from catalyst.constants import SUPPORTED_WALLETS
from catalyst.utils.deprecate import deprecated
from catalyst.utils.paths import data_root, ensure_directory
from catalyst.marketplace.marketplace_errors import MarketplaceJSONError
@@ -131,17 +132,63 @@ def get_user_pubaddr(environ=None):
try:
d = data[0]['pubAddr']
except Exception as e:
return [data, ]
data = [data, ]
changed = False
for idx, d in enumerate(data):
try:
if d['wallet'] not in SUPPORTED_WALLETS:
data[idx]['wallet'] = _choose_wallet(
d['pubAddr'], False)
changed = True
except KeyError:
data[idx]['wallet'] = _choose_wallet(
d['pubAddr'], True)
changed = True
if changed:
save_user_pubaddr(data)
return data
else:
data = []
data.append(dict(pubAddr='', desc=''))
data.append(dict(pubAddr='', desc='', wallet=''))
with open(filename, 'w') as f:
json.dump(data, f, sort_keys=False, indent=2,
separators=(',', ':'))
return data
def _choose_wallet(pubAddr, missing):
while True:
if missing:
print('\nYou need to specify a wallet for address '
'{}.'.format(pubAddr))
else:
print('\nThe wallet specified for address {} is not '
'supported.'.format(pubAddr))
print('Please choose among the following options:')
for idx, wallet in enumerate(SUPPORTED_WALLETS):
print('{}\t{}'.format(idx, wallet))
lw = len(SUPPORTED_WALLETS)-1
w = input('Choose a number between 0 and {}: '.format(
lw))
try:
w = int(w)
except ValueError:
print('Enter a number between 0 and {}'.format(lw))
else:
if w not in range(0, lw+1):
print('Enter a number between 0 and '
'{}'.format(lw))
else:
return SUPPORTED_WALLETS[w]
def save_user_pubaddr(data, environ=None):
"""
Saves the user's public addresses and their related metadata in
+49
View File
@@ -0,0 +1,49 @@
import pytz
from datetime import datetime
from catalyst.api import symbol
from catalyst.utils.run_algo import run_algorithm
coin = 'btc'
base_currency = 'usd'
n_candles = 5
def initialize(context):
context.symbol = symbol('%s_%s' % (coin, base_currency))
def handle_data_polo_partial_candles(context, data):
history = data.history(symbol('btc_usdt'), ['volume'],
bar_count=10,
frequency='4H')
print('\nnow: %s\n%s' % (data.current_dt, history))
if not hasattr(context, 'i'):
context.i = 0
context.i += 1
if context.i > 5:
raise Exception('stop')
live = False
if live:
run_algorithm(initialize=lambda ctx: True,
handle_data=handle_data_polo_partial_candles,
exchange_name='poloniex',
base_currency='usdt',
algo_namespace='ns',
live=True,
data_frequency='minute',
capital_base=3000)
else:
run_algorithm(initialize=lambda ctx: True,
handle_data=handle_data_polo_partial_candles,
exchange_name='poloniex',
base_currency='usdt',
algo_namespace='ns',
live=False,
data_frequency='minute',
capital_base=3000,
start=datetime(2018, 2, 2, 0, 0, 0, 0, pytz.utc),
end=datetime(2018, 2, 20, 0, 0, 0, 0, pytz.utc)
)
+35
View File
@@ -0,0 +1,35 @@
import pytz
from datetime import datetime
from catalyst.api import symbol
from catalyst.utils.run_algo import run_algorithm
coin = 'btc'
base_currency = 'usd'
def initialize(context):
context.symbol = symbol('%s_%s' % (coin, base_currency))
def handle_data_polo_partial_candles(context, data):
history = data.history(symbol('btc_usdt'), ['volume'],
bar_count=10,
frequency='1D')
print('\nnow: %s\n%s' % (data.current_dt, history))
if not hasattr(context, 'i'):
context.i = 0
context.i += 1
if context.i > 5:
raise Exception('stop')
run_algorithm(initialize=lambda ctx: True,
handle_data=handle_data_polo_partial_candles,
exchange_name='poloniex',
base_currency='usdt',
algo_namespace='ns',
live=False,
data_frequency='minute',
capital_base=3000,
start=datetime(2018, 2, 2, 0, 0, 0, 0, pytz.utc),
end=datetime(2018, 2, 20, 0, 0, 0, 0, pytz.utc))
@@ -7,7 +7,7 @@ from pandas.tseries.holiday import (
USLaborDay,
USThanksgivingDay
)
from pandas.tslib import Timestamp
from pandas import Timestamp
from pytz import timezone
from catalyst.utils.calendars import TradingCalendar
+2 -5
View File
@@ -640,12 +640,9 @@ class TradingCalendar(with_metaclass(ABCMeta)):
"""
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 (
sched.at[session_label, 'market_open'].tz_localize('UTC'),
sched.at[session_label, 'market_close'].tz_localize('UTC'),
sched.at[session_label, 'market_open'],
sched.at[session_label, 'market_close'],
)
def session_open(self, session_label):
+6 -6
View File
@@ -117,9 +117,9 @@ def create_dividend(sid, payment, declared_date, ex_date, pay_date):
'net_amount': payment,
'payment_sid': None,
'ratio': None,
'declared_date': pd.tslib.normalize_date(declared_date),
'ex_date': pd.tslib.normalize_date(ex_date),
'pay_date': pd.tslib.normalize_date(pay_date),
'declared_date': declared_date.normalize(),
'ex_date': ex_date.normalize(),
'pay_date': pay_date.normalize(),
'type': DATASOURCE_TYPE.DIVIDEND,
'source_id': 'MockDividendSource'
})
@@ -134,9 +134,9 @@ def create_stock_dividend(sid, payment_sid, ratio, declared_date,
'ratio': ratio,
'net_amount': None,
'gross_amount': None,
'dt': pd.tslib.normalize_date(declared_date),
'ex_date': pd.tslib.normalize_date(ex_date),
'pay_date': pd.tslib.normalize_date(pay_date),
'dt': declared_date.normalize(),
'ex_date': ex_date.normalize(),
'pay_date': pay_date.normalize(),
'type': DATASOURCE_TYPE.DIVIDEND,
'source_id': 'MockDividendSource'
})
+3 -3
View File
@@ -263,9 +263,9 @@ def _run(handle_data,
# We still need to support bundles for other misc data, but we
# can handle this later.
if start != pd.tslib.normalize_date(start) or \
end != pd.tslib.normalize_date(end):
# todo: add to Sim_Params the option to start & end at specific times
if start != pd.Timestamp(start).normalize() or \
end != pd.Timestamp(end).normalize():
# todo: add to Sim_Params the option to start & end at specific times
log.warn(
"Catalyst currently starts and ends on the start and "
"end of the dates specified, respectively. We hope to "
+5 -1
View File
@@ -143,7 +143,7 @@ with the following steps:
.. code-block:: bash
conda create --name catalyst python=2.7 scipy zlib
conda create --name catalyst python=3.6 scipy zlib
3. Activate the environment:
@@ -562,6 +562,10 @@ If after following the instructions above, and going through the
*Troubleshooting* sections, you still experience problems installing Catalyst,
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
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
+52 -1
View File
@@ -2,6 +2,57 @@
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
^^^^^^^^^^^^^
**Release Date**: 2018-03-22
Build
~~~~~
- Data Marketplace: ensures compatibility across wallets, now fully supporting
``ledger``, ``trezor``, ``keystore``, ``private key``. Partial support for
``metamask`` (includes sign_msg, but not sign_tx). Current support for
``Digital Bitbox`` is unknown, but believed to be supported.
- Data Marketplace: Switched online provider from MyEtherWallet to MyCrypto.
- Data Marketplace: Added progress indicator for data ingestion.
Bug Fixes
~~~~~~~~~
- Changed benchmark to be constant, so it doesn't ingest data at all. Temporary
fix for :issue:`271`, :issue:`285`
Version 0.5.5
^^^^^^^^^^^^^
**Release Date**: 2018-03-19
Bug Fixes
~~~~~~~~~
- Fixed an issue with the data history in daily frequency :issue:`274`
- Fix hourly frequency issues :issue:`227` and :issue:`114`
Version 0.5.4
^^^^^^^^^^^^^
**Release Date**: 2018-03-14
@@ -27,7 +78,7 @@ Bug Fixes
:issue:`253`
- Upgraded Data Marketplace to Web3==4.0.0b11, which was breaking some
functionality from prior version 4.0.0b7 :issue:`257`
- Always request more data to avoid empty bars and always give the exact bar
- Always request more data to avoid empty bars and always give the exact bar
number :issue:`260`
Documentation
+2 -3
View File
@@ -5,7 +5,6 @@ channels:
dependencies:
- certifi=2016.2.28=py27_0
- mkl=2017.0.3
- matplotlib=2.1.2=py36_0
- numpy=1.13.1=py27_0
- openssl=1.0.2l
- pip=9.0.1=py27_1
@@ -40,11 +39,11 @@ dependencies:
- lru-dict==1.1.6
- mako==1.0.7
- markupsafe==1.0
- matplotlib==2.1.0
- matplotlib==2.1.2
- multipledispatch==0.4.9
- networkx==2.0
- numexpr==2.6.4
- pandas==0.19.2
- pandas==0.22.0
- pandas-datareader==0.5.0
- patsy==0.4.1
- pyparsing==2.2.0
+1 -1
View File
@@ -62,7 +62,7 @@ dependencies:
- multipledispatch==0.4.9
- networkx==2.1
- numexpr==2.6.4
- pandas==0.19.2
- pandas==0.22.0
- pandas-datareader==0.6.0
- patsy==0.5.0
- pycares==2.3.0
+1 -1
View File
@@ -19,7 +19,7 @@ requests-file==1.4.1
# scipy and pandas are required for statsmodels,
# statsmodels in turn is required for some pandas packages
scipy==0.17.1
pandas==0.19.2
pandas==0.22.0
pandas-datareader==0.2.1
# Needed for parts of pandas.stats
patsy==0.4.0
+1 -1
View File
@@ -165,7 +165,7 @@ def _filter_requirements(lines_iter, filter_names=None,
REQ_UPPER_BOUNDS = {
'bcolz': '<1',
'pandas': '<0.20',
'pandas': '>=0.22',
'empyrical': '<0.2.2',
}
+1 -1
View File
@@ -24,7 +24,7 @@ import numpy as np
import pandas as pd
from nose_parameterized import parameterized
from pandas import read_csv
from pandas.tslib import Timedelta
from pandas import Timedelta
from pandas.util.testing import assert_index_equal
from pytz import timezone
from toolz import concat
+2 -3
View File
@@ -21,7 +21,6 @@ import datetime
from math import sqrt
from nose_parameterized import parameterized
from pandas.tslib import normalize_date
import numpy as np
import pandas as pd
import pytz
@@ -1108,8 +1107,8 @@ class OrdersStopTestCase(WithSimParams,
)),
)
days = pd.date_range(
start=normalize_date(self.minutes[0]),
end=normalize_date(self.minutes[-1])
start=self.minutes[0].normalize(),
end=self.minutes[-1].normalize()
)
with tmp_bcolz_equity_minute_bar_reader(
self.trading_calendar, days, assets) as reader:
+1 -2
View File
@@ -27,7 +27,6 @@ from pandas import (
Series,
Timestamp,
)
from pandas.tseries.tools import normalize_date
from six import iteritems, itervalues
from catalyst.algorithm import TradingAlgorithm
@@ -530,7 +529,7 @@ class PipelineAlgorithmTestCase(WithBcolzEquityDailyBarReaderFromCSVs,
attach_pipeline(pipeline, 'test')
def handle_data(context, data):
today = normalize_date(get_datetime())
today = get_datetime().normalize()
results = pipeline_output('test')
expect_over_300 = {
AAPL: today < self.AAPL_split_date,
+1 -1
View File
@@ -17,7 +17,7 @@ from collections import OrderedDict
from numpy import array, append, nan, full
from numpy.testing import assert_almost_equal
import pandas as pd
from pandas.tslib import Timedelta
from pandas import Timedelta
from catalyst.assets import Equity, Future
from catalyst.data.data_portal import HISTORY_FREQUENCIES, OHLCV_FIELDS
+1 -2
View File
@@ -395,7 +395,6 @@ def handle_data(context, data):
algocode = """
from pandas import Timestamp
from pandas.tseries.tools import normalize_date
from catalyst.api import fetch_csv, record, sid, get_datetime
def initialize(context):
@@ -411,7 +410,7 @@ def initialize(context):
context.bar_count = 0
def handle_data(context, data):
expected = context.expected_sids[normalize_date(get_datetime())]
expected = context.expected_sids[get_datetime().normalize()]
actual = data.fetcher_assets
for stk in expected:
if stk not in actual: